mirror of
https://github.com/Anime-Game-Servers/Grasscutter-Quests.git
synced 2024-11-26 22:10:26 +00:00
Start moving some models to AnimeGameModels and implement small things depeding on them
* Add rewards based on excel for ScenePointUnlock * Properly handle multi level city/statue updates Use animegamemodels for the following: * Activity * ActivityCondExcelConfigData -> ActivityCondData * ActivityData * ActivityWatcherData * Avatar * AvatarCostumeData * AvatarCurveData * AvatarData (and moved caching to its own model) * AvatarFettersLevelData * AvatarFlycloakData * AvatarLevelData * City * CityData * StatuePromoteData -> CityLevelUpData * Dungeon * DungeonData * DungeonPassConfigData * Quest * TriggerExcelConfigData -> TriggerData * Rewards * RewardData * TowerRewardData * Scene * SceneData * SceneTagData -> SceneTagConfigData * Shop * ActivityShopData * ShopGoodsData * ShopRefreshType * ShopType * World * WorldAreaData * WorldLevelData
This commit is contained in:
parent
95b26b5ba4
commit
f6756d6621
@ -95,6 +95,9 @@ dependencies {
|
||||
|
||||
implementation("org.anime_game_servers.multi_proto:gi-jvm:0.2.32")
|
||||
|
||||
implementation("org.anime_game_servers.data_models:GIData:0.2")
|
||||
implementation("org.anime_game_servers.data_models:loader-jvm:0.2")
|
||||
|
||||
implementation group: 'com.esotericsoftware', name : 'reflectasm', version: '1.11.9'
|
||||
implementation group: 'com.github.davidmoten', name : 'rtree-multi', version: '0.1'
|
||||
|
||||
@ -255,3 +258,8 @@ public final class BuildConfig {
|
||||
}
|
||||
|
||||
task generateActivityConditions(type: GenerateActivityConditions)
|
||||
|
||||
// For terminal interacting in IDEA running
|
||||
run {
|
||||
standardInput = System.in
|
||||
}
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -7,16 +7,8 @@ import emu.grasscutter.command.CommandMap;
|
||||
import emu.grasscutter.command.DefaultPermissionHandler;
|
||||
import emu.grasscutter.command.PermissionHandler;
|
||||
import emu.grasscutter.config.ConfigContainer;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.ResourceLoader;
|
||||
import emu.grasscutter.data.excels.AvatarData;
|
||||
import emu.grasscutter.data.excels.AvatarSkillDepotData;
|
||||
import emu.grasscutter.data.excels.TowerFloorData;
|
||||
import emu.grasscutter.data.excels.TowerLevelData;
|
||||
import emu.grasscutter.database.DatabaseManager;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.avatar.TowerAvatar;
|
||||
import emu.grasscutter.game.dungeons.dungeon_entry.PlayerDungeonExitInfo;
|
||||
import emu.grasscutter.plugin.PluginManager;
|
||||
import emu.grasscutter.plugin.api.ServerHook;
|
||||
import emu.grasscutter.server.game.GameServer;
|
||||
@ -50,7 +42,6 @@ import org.slf4j.LoggerFactory;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.Optional;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.SERVER;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
@ -119,7 +110,11 @@ public final class Grasscutter {
|
||||
ResourceLoader.loadAll();
|
||||
|
||||
// Generate handbooks.
|
||||
try {
|
||||
Tools.createGmHandbooks();
|
||||
} catch (Exception e) {
|
||||
getLogger().error("Failed to generate GM handbooks.", e);
|
||||
}
|
||||
|
||||
// Generate gacha mappings.
|
||||
Tools.generateGachaMappings();
|
||||
|
@ -4,7 +4,7 @@ import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameDepot;
|
||||
import emu.grasscutter.data.excels.AvatarData;
|
||||
import emu.grasscutter.data.custom.AvatarDataCache;
|
||||
import emu.grasscutter.data.excels.AvatarSkillDepotData;
|
||||
import emu.grasscutter.data.excels.ItemData;
|
||||
import emu.grasscutter.data.excels.ReliquaryAffixData;
|
||||
@ -17,6 +17,8 @@ import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.utils.SparseSet;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.game_data_models.gi.data.entities.avatar.AvatarData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -62,7 +64,7 @@ public final class GiveCommand implements CommandHandler {
|
||||
public int mainPropId = -1;
|
||||
public List<Integer> appendPropIdList;
|
||||
public ItemData data;
|
||||
public AvatarData avatarData;
|
||||
public AvatarDataCache avatarData;
|
||||
public GiveAllType giveAllType = GiveAllType.NONE;
|
||||
}
|
||||
|
||||
@ -103,9 +105,9 @@ public final class GiveCommand implements CommandHandler {
|
||||
}
|
||||
param.data = GameData.getItemDataMap().get(param.id);
|
||||
if ((param.id > 10_000_000) && (param.id < 12_000_000))
|
||||
param.avatarData = GameData.getAvatarDataMap().get(param.id);
|
||||
param.avatarData = GameData.getAvatarInfoCacheMap().get(param.id);
|
||||
else if ((param.id > 1000) && (param.id < 1100))
|
||||
param.avatarData = GameData.getAvatarDataMap().get(param.id - 1000 + 10_000_000);
|
||||
param.avatarData = GameData.getAvatarInfoCacheMap().get(param.id - 1000 + 10_000_000);
|
||||
isRelic = ((param.data != null) && (param.data.getItemType() == ItemType.ITEM_RELIQUARY));
|
||||
|
||||
if (!isRelic && !args.isEmpty() && (param.amount == 1)) { // A concession for the people that truly hate [x<amount>].
|
||||
@ -218,7 +220,7 @@ public final class GiveCommand implements CommandHandler {
|
||||
return makeAvatar(param.avatarData, param.lvl, Avatar.getMinPromoteLevel(param.lvl), param.constellation, param.skillLevel);
|
||||
}
|
||||
|
||||
private static Avatar makeAvatar(AvatarData avatarData, int level, int promoteLevel, int constellation, int skillLevel) {
|
||||
private static Avatar makeAvatar(AvatarDataCache avatarData, int level, int promoteLevel, int constellation, int skillLevel) {
|
||||
Avatar avatar = new Avatar(avatarData);
|
||||
avatar.setLevel(level);
|
||||
avatar.setPromoteLevel(promoteLevel);
|
||||
@ -232,7 +234,7 @@ public final class GiveCommand implements CommandHandler {
|
||||
private static void giveAllAvatars(Player player, GiveItemParameters param) {
|
||||
int promoteLevel = Avatar.getMinPromoteLevel(param.lvl);
|
||||
if (param.constellation < 0 || param.constellation > 6) param.constellation = 6; // constellation's default is -1 so if no parameters set for constellations it'll automatically be 6
|
||||
for (AvatarData avatarData : GameData.getAvatarDataMap().values()) {
|
||||
for (val avatarData : GameData.getAvatarInfoCacheMap().values()) {
|
||||
int id = avatarData.getId();
|
||||
if (id < 10000002 || id >= 11000000) continue; // Exclude test avatars
|
||||
// Don't try to add each avatar to the current team
|
||||
|
@ -3,8 +3,8 @@ package emu.grasscutter.command.commands;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import lombok.val;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -24,15 +24,15 @@ public final class ResetConstCommand implements CommandHandler {
|
||||
targetPlayer.getAvatars().forEach(this::resetConstellation);
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.resetConst.reset_all"));
|
||||
} else {
|
||||
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
|
||||
val entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Avatar avatar = entity.getAvatar();
|
||||
val avatar = entity.getAvatar();
|
||||
this.resetConstellation(avatar);
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.resetConst.success", avatar.getAvatarData().getName()));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.resetConst.success", avatar.getAvatarData().getBaseName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,9 @@ package emu.grasscutter.command.commands;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.game.world.World;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import lombok.val;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -34,11 +31,11 @@ public final class SetConstCommand implements CommandHandler {
|
||||
}
|
||||
// If it's either empty or anything else other than "all" just do normal setConstellation
|
||||
if (args.size() == 1) {
|
||||
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
|
||||
val entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
|
||||
if (entity == null) return;
|
||||
Avatar avatar = entity.getAvatar();
|
||||
val avatar = entity.getAvatar();
|
||||
this.setConstellation(targetPlayer, avatar, constLevel);
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.success", avatar.getAvatarData().getName(), constLevel);
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.success", avatar.getAvatarData().getBaseName(), constLevel);
|
||||
return;
|
||||
}
|
||||
// Check if there's an additional argument which is "all", if it does then go setAllConstellation
|
||||
@ -53,7 +50,7 @@ public final class SetConstCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
private void setConstellation(Player player, Avatar avatar, int constLevel) {
|
||||
int currentConstLevel = avatar.getCoreProudSkillLevel();
|
||||
val currentConstLevel = avatar.getCoreProudSkillLevel();
|
||||
avatar.forceConstellationLevel(constLevel);
|
||||
|
||||
// force player to reload scene when necessary
|
||||
@ -79,9 +76,9 @@ public final class SetConstCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
private void reloadScene(Player player) {
|
||||
World world = player.getWorld();
|
||||
Scene scene = player.getScene();
|
||||
Position pos = player.getPosition();
|
||||
val world = player.getWorld();
|
||||
val scene = player.getScene();
|
||||
val pos = player.getPosition();
|
||||
world.transferPlayerToScene(player, 1, pos, null);
|
||||
world.transferPlayerToScene(player, scene.getId(), pos, null);
|
||||
scene.broadcastPacket(new PacketSceneEntityAppearNotify(player));
|
||||
|
@ -36,7 +36,7 @@ public final class SetFetterLevelCommand implements CommandHandler {
|
||||
|
||||
avatar.setFetterLevel(fetterLevel);
|
||||
if (fetterLevel != 10) {
|
||||
avatar.setFetterExp(GameData.getAvatarFetterLevelDataMap().get(fetterLevel).getExp());
|
||||
avatar.setFetterExp(GameData.getAvatarFetterLevelDataMap().get(fetterLevel).getNeedExp());
|
||||
}
|
||||
avatar.save();
|
||||
|
||||
|
@ -5,12 +5,12 @@ import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.activity.trialavatar.TrialAvatarActivityHandler;
|
||||
import emu.grasscutter.game.activity.trialavatar.TrialAvatarPlayerData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActivityType;
|
||||
import emu.grasscutter.server.packet.send.PacketActivityInfoNotify;
|
||||
import emu.grasscutter.utils.JsonUtils;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityType;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
|
8
src/main/java/emu/grasscutter/data/AutoResource.java
Normal file
8
src/main/java/emu/grasscutter/data/AutoResource.java
Normal file
@ -0,0 +1,8 @@
|
||||
package emu.grasscutter.data;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface AutoResource {
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
package emu.grasscutter.data;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.binout.*;
|
||||
import emu.grasscutter.data.binout.config.*;
|
||||
@ -12,6 +15,13 @@ import emu.grasscutter.data.custom.TrialAvatarActivityCustomData;
|
||||
import emu.grasscutter.data.custom.TrialAvatarCustomData;
|
||||
import emu.grasscutter.data.excels.*;
|
||||
import emu.grasscutter.data.server.*;
|
||||
import emu.grasscutter.data.binout.routes.Route;
|
||||
import emu.grasscutter.data.custom.*;
|
||||
import emu.grasscutter.data.server.DropSubfieldMapping;
|
||||
import emu.grasscutter.data.server.DropTableExcelConfigData;
|
||||
import emu.grasscutter.data.server.GadgetMapping;
|
||||
import emu.grasscutter.data.server.MonsterMapping;
|
||||
import emu.grasscutter.data.server.SubfieldMapping;
|
||||
import emu.grasscutter.game.dungeons.DungeonDropEntry;
|
||||
import emu.grasscutter.game.dungeons.dungeon_entry.DungeonEntries;
|
||||
import emu.grasscutter.game.quest.QuestEncryptionKey;
|
||||
@ -20,12 +30,32 @@ import emu.grasscutter.utils.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Tolerate;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.game_data_models.gi.custom.activity.ActivityExtraInfo;
|
||||
import org.anime_game_servers.game_data_models.gi.custom.weather.WeatherMapping;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.*;
|
||||
import org.anime_game_servers.game_data_models.gi.data.city.CityData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.city.CityLevelUpData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.entities.avatar.*;
|
||||
import org.anime_game_servers.game_data_models.gi.data.entities.avatar.AvatarCurveData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.entities.avatar.AvatarData;
|
||||
import org.anime_game_servers.gi_lua.models.quest.QuestData;
|
||||
import org.anime_game_servers.gi_lua.models.quest.RewindData;
|
||||
import org.anime_game_servers.gi_lua.models.scene.DummyPoint;
|
||||
import org.anime_game_servers.gi_lua.models.scene.SceneGroupReplacement;
|
||||
import org.anime_game_servers.game_data_models.gi.data.quest.TriggerData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.rewards.TransPointRewardData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.rewards.RewardData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.rewards.TowerRewardData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.scene.SceneData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.scene.SceneTagConfigData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.scene.WorldAreaConfigData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.shop.ShopGoodsData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.talks.TalkData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.watcher.ActivityWatcherData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.world.WorldLevelData;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Field;
|
||||
@ -46,29 +76,32 @@ public class GameData {
|
||||
@Getter private static final Int2ObjectMap<DungeonEntries> dungeonEntriesMap = new Int2ObjectOpenHashMap<>();
|
||||
protected static final Map<String, AbilityData> abilityDataMap = new HashMap<>();
|
||||
protected static final Int2ObjectMap<ScenePointEntry> scenePointEntryMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<MainQuestData> mainQuestData = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<MainQuestData> mainQuestDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<QuestEncryptionKey> questsKeys = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<SceneNpcBornData> npcBornData = new Int2ObjectOpenHashMap<>();
|
||||
private static final Map<String, AbilityEmbryoEntry> abilityEmbryos = new HashMap<>();
|
||||
@Getter private static final Int2ObjectMap<SceneNpcBornData> npcBornData = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Map<String, AbilityEmbryoEntry> abilityEmbryos = new HashMap<>();
|
||||
@QuickAccessCache @Getter private static final Map<Long, String> textHashMap = new HashMap<>();
|
||||
|
||||
// ExcelConfigs
|
||||
@Getter private static final Int2ObjectMap<ActivityCondExcelConfigData> activityCondExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DungeonPassConfigData> dungeonPassConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<ActivityCondData> activityCondExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<DungeonPassData> dungeonPassConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DungeonChallengeConfigData> dungeonChallengeConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<Int2ObjectMap<Route>> sceneRouteData = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter private static final ArrayList<CodexReliquaryData> codexReliquaryArrayList = new ArrayList<>();
|
||||
@Getter private static final Int2ObjectMap<ActivityData> activityDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<ActivityShopData> activityShopDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<ActivityWatcherData> activityWatcherDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarCostumeData> avatarCostumeDataItemIdMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarCostumeData> avatarCostumeDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<ActivityData> activityDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<ActivityShopOverallData> activityShopDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<ActivityShopSheetData> activityShopSheetDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<ActivityWatcherData> activityWatcherDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@QuickAccessCache @Getter private static final Int2ObjectMap<AvatarCostumeData> avatarCostumeDataItemIdMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@QuickAccessCache @Getter private static final Int2ObjectMap<AvatarDataCache> avatarInfoCacheMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<AvatarCostumeData> avatarCostumeDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarReplaceCostumeData> avatarReplaceCostumeDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarCurveData> avatarCurveDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarData> avatarDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarFetterLevelData> avatarFetterLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarFlycloakData> avatarFlycloakDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarLevelData> avatarLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<AvatarCurveData> avatarCurveDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<AvatarData> avatarDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<AvatarFettersLevelData> avatarFetterLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<AvatarFlycloakData> avatarFlycloakDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<AvatarLevelData> avatarLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarSkillData> avatarSkillDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarSkillDepotData> avatarSkillDepotDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarTalentData> avatarTalentDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@ -81,7 +114,8 @@ public class GameData {
|
||||
@Getter private static final Int2ObjectMap<BlossomSectionOrderData> blossomSectionOrderDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<BuffData> buffDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<ChapterData> chapterDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<CityData> cityDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<CityData> cityDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<CityLevelUpData> cityLevelUpDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<CodexAnimalData> codexAnimalDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<CodexMaterialData> codexMaterialDataIdMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<CodexQuestData> codexQuestDataIdMap = new Int2ObjectOpenHashMap<>();
|
||||
@ -93,7 +127,7 @@ public class GameData {
|
||||
@Getter private static final Int2ObjectMap<CookRecipeData> cookRecipeDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<CompoundData> compoundDataMap=new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DungeonElementChallengeData> dungeonElementChallengeDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DungeonEntryData> dungeonEntryDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DungeonRosterData> dungeonRosterDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@ -126,35 +160,35 @@ public class GameData {
|
||||
@Getter private static final Int2ObjectMap<ReliquaryAffixData> reliquaryAffixDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<ReliquaryMainPropData> reliquaryMainPropDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<ReliquarySetData> reliquarySetDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<RewardPreviewData> rewardPreviewDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<SceneTagData> sceneTagDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<SceneTagConfigData> sceneTagConfigDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<TalkData> talkDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<TowerBuffData> towerBuffDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<TowerFloorData> towerFloorDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<TowerLevelData> towerLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<TowerRewardData> towerRewardDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource private static final Int2ObjectMap<TowerRewardData> towerRewardDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<TowerScheduleData> towerScheduleDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<TrialAvatarData> trialAvatarDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<TrialAvatarActivityData> trialAvatarActivityDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<TrialAvatarActivityDataData> trialAvatarActivityDataDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<TrialAvatarTemplateData> trialAvatarTemplateDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<TrialReliquaryData> trialReliquaryDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<TriggerExcelConfigData> triggerExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Map<String, TriggerExcelConfigData> triggerDataByNameMap = new HashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<TriggerData> triggerExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@QuickAccessCache @Getter private static final Map<String, TriggerData> triggerDataByNameMap = new HashMap<>();
|
||||
@Getter private static final Int2ObjectMap<WeaponCurveData> weaponCurveDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<WeaponLevelData> weaponLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<WeaponPromoteData> weaponPromoteDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<StatuePromoteData> statuePromoteDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<WeatherData> weatherDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<WeatherTemplateData> weatherTemplateDataMap = new Int2ObjectOpenHashMap<>(); //Unused
|
||||
@Getter private static final Map<String, WeatherTemplateData> weatherTemplateDataByNameMap = new HashMap<>();
|
||||
@Getter private static final Int2ObjectMap<WorldAreaData> worldAreaDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AvatarPromoteData> avatarPromoteDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<WorldAreaConfigData> worldAreaDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AvatarPromoteData> avatarPromoteDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<FetterData> fetterDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ReliquaryLevelData> reliquaryLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<RewindData> rewindDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<QuestData> teleportDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<Map<String, DummyPoint>> dummyPointMap = new Int2ObjectOpenHashMap<>();
|
||||
@ -167,18 +201,22 @@ public class GameData {
|
||||
private static final Int2ObjectMap<CodexViewpointData> codexViewpointDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter private static final Int2ObjectMap<List<DungeonDropEntry>> dungeonDropDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<TransPointRewardData> transPointRewardData = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter @Setter private static ConfigGlobalCombat configGlobalCombat = null;
|
||||
|
||||
// from scripts
|
||||
@Getter private static final Int2ObjectMap<SceneGroupReplacement> groupReplacements = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
// Custom community server resources
|
||||
@Getter private static final Int2ObjectMap<GadgetMapping> gadgetMappingMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<SubfieldMapping> subfieldMappingMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DropSubfieldMapping> dropSubfieldMappingMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<DropTableExcelConfigData> dropTableExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<MonsterMapping> monsterMappingMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<ActivityCondGroup> activityCondGroupMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<SceneGroupReplacement> groupReplacements = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<WeatherMapping> weatherMappingMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<ActivityCondGroupData> activityCondGroupMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<ActivityExtraInfo> activityExtraInfoMap = new Int2ObjectOpenHashMap<>();
|
||||
@AutoResource @Getter private static final Int2ObjectMap<WeatherMapping> weatherMappingMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
// Cache
|
||||
@Getter private static final IntList scenePointIdList = new IntArrayList();
|
||||
@ -188,7 +226,7 @@ public class GameData {
|
||||
@Getter private static final Map<String, ConfigLevelEntity> configLevelEntityDataMap = new HashMap<>();
|
||||
@Getter private static final Map<String, GuideTriggerData> guideTriggerDataStringMap = new HashMap<>();
|
||||
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
||||
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
|
||||
@QuickAccessCache private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
|
||||
protected static Int2ObjectMap<IntSet> proudSkillGroupLevels = new Int2ObjectOpenHashMap<>();
|
||||
protected static Int2IntMap proudSkillGroupMaxLevels = new Int2IntOpenHashMap();
|
||||
protected static Int2ObjectMap<IntSet> avatarSkillLevels = new Int2ObjectOpenHashMap<>();
|
||||
@ -201,28 +239,17 @@ public class GameData {
|
||||
@Getter private static final Map<Integer, List<WeatherAreaPointData>> weatherAreaPointData = new HashMap<>();
|
||||
@Getter private static final Map<Integer, List<ScenePointArrayData>> scenePointArrayData = new HashMap<>();
|
||||
|
||||
// Getters with wrong names, remove later
|
||||
@Deprecated(forRemoval = true) public static Int2ObjectMap<CodexReliquaryData> getcodexReliquaryIdMap() {return codexReliquaryDataIdMap;}
|
||||
@Deprecated(forRemoval = true) public static Int2ObjectMap<DungeonEntryData> getDungeonEntryDatatMap() {return dungeonEntryDataMap;}
|
||||
@Deprecated(forRemoval = true) @Tolerate public static ArrayList<CodexReliquaryData> getcodexReliquaryArrayList() {return codexReliquaryArrayList;}
|
||||
|
||||
// Getters with different names that stay for now
|
||||
public static Int2ObjectMap<MainQuestData> getMainQuestDataMap() {return mainQuestData;}
|
||||
public static Int2ObjectMap<QuestEncryptionKey> getMainQuestEncryptionMap() {return questsKeys;}
|
||||
public static Int2ObjectMap<SceneNpcBornData> getSceneNpcBornData() {return npcBornData;}
|
||||
public static Map<String, AbilityEmbryoEntry> getAbilityEmbryoInfo() {return abilityEmbryos;}
|
||||
|
||||
// Getters that get values rather than containers. If Lombok ever gets syntactic sugar for this, we should adopt that.
|
||||
public static AbilityData getAbilityData(String abilityName) {return abilityDataMap.get(abilityName);}
|
||||
public static IntSet getAvatarSkillLevels(int avatarSkillId) {return avatarSkillLevels.get(avatarSkillId);}
|
||||
public static IntSet getProudSkillGroupLevels(int proudSkillGroupId) {return proudSkillGroupLevels.get(proudSkillGroupId);}
|
||||
@Nullable public static AbilityData getAbilityData(String abilityName) {return abilityDataMap.get(abilityName);}
|
||||
@Nullable public static IntSet getAvatarSkillLevels(int avatarSkillId) {return avatarSkillLevels.get(avatarSkillId);}
|
||||
public static int getProudSkillGroupMaxLevel(int proudSkillGroupId) {return proudSkillGroupMaxLevels.getOrDefault(proudSkillGroupId, 0);}
|
||||
@Nullable public static AbilityEmbryoEntry getAbilityEmbryo(String name) {return abilityEmbryos.get(name);}
|
||||
@Nullable public static SceneNpcBornData getSceneNpcBornData(int npcId) {return npcBornData.get(npcId);}
|
||||
|
||||
// Multi-keyed getters
|
||||
public static AvatarPromoteData getAvatarPromoteData(int promoteId, int promoteLevel) {
|
||||
return avatarPromoteDataMap.get((promoteId << 8) + promoteLevel);
|
||||
}
|
||||
|
||||
public static TowerRewardData getTowerRewardData(int levelIndex, int floorIndex) {
|
||||
return towerRewardDataMap.get((levelIndex << 4) + floorIndex);
|
||||
}
|
||||
@ -231,8 +258,8 @@ public class GameData {
|
||||
return weaponPromoteDataMap.get((promoteId << 8) + promoteLevel);
|
||||
}
|
||||
|
||||
public static StatuePromoteData getStatuePromoteData(int cityId, int promoteLevel) {
|
||||
return statuePromoteDataMap.get((cityId << 8) + promoteLevel);
|
||||
public static CityLevelUpData getCityLevelUpData(int cityId, int promoteLevel) {
|
||||
return cityLevelUpDataMap.get(CityLevelUpData.getKey(cityId, promoteLevel));
|
||||
}
|
||||
|
||||
public static ReliquaryLevelData getRelicLevelData(int rankLevel, int level) {
|
||||
@ -249,7 +276,7 @@ public class GameData {
|
||||
}
|
||||
|
||||
public static int getAvatarFetterLevelExpRequired(int level) {
|
||||
return Optional.ofNullable(avatarFetterLevelDataMap.get(level)).map(AvatarFetterLevelData::getExp).orElse(0);
|
||||
return Optional.ofNullable(avatarFetterLevelDataMap.get(level)).map(AvatarFettersLevelData::getNeedExp).orElse(0);
|
||||
}
|
||||
|
||||
public static int getRelicExpRequired(int rankLevel, int level) {
|
||||
@ -275,7 +302,6 @@ public class GameData {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static int getWeaponExpRequired(int rankLevel, int level) {
|
||||
WeaponLevelData levelData = weaponLevelDataMap.get(level);
|
||||
if (levelData == null) {
|
||||
@ -304,9 +330,9 @@ public class GameData {
|
||||
public static Map<Integer, List<ShopGoodsData>> getShopGoodsDataEntries() {
|
||||
if (shopGoods.isEmpty()) {
|
||||
shopGoodsDataMap.forEach((k, v) -> {
|
||||
if (!shopGoods.containsKey(v.getShopType()))
|
||||
shopGoods.put(v.getShopType(), new ArrayList<>());
|
||||
shopGoods.get(v.getShopType()).add(v);
|
||||
val shopTypeId = v.getShopType().getIntKey();
|
||||
shopGoods.computeIfAbsent(shopTypeId, key -> new ArrayList<>())
|
||||
.add(v);
|
||||
});
|
||||
}
|
||||
|
||||
@ -335,11 +361,18 @@ public class GameData {
|
||||
return beginCondQuestMap.get(SubQuestData.questConditionKey(questCond, param0, questStr));
|
||||
}
|
||||
|
||||
public static TriggerExcelConfigData getQuestTriggerDataByName(int groupId, String triggerName){
|
||||
public static TriggerData getQuestTriggerDataByName(int groupId, String triggerName){
|
||||
return triggerDataByNameMap.get(groupId + triggerName);
|
||||
}
|
||||
public static void putQuestTriggerDataCache(TriggerData trigger){
|
||||
triggerDataByNameMap.put(trigger.getGroupId()+trigger.getTriggerName(), trigger);
|
||||
}
|
||||
|
||||
public static CodexViewpointData getViewCodexByGroupdCfg(int groupId, int cfgId){
|
||||
public static void putAvatarCostumeDataCache(AvatarCostumeData data){
|
||||
avatarCostumeDataItemIdMap.put(data.getItemId(), data);
|
||||
}
|
||||
|
||||
public static CodexViewpointData getViewCodexByGroupdCfg(int groupId, int cfgId) {
|
||||
return codexViewpointDataIdMap.get(CodexViewpointData.getViewpointId(groupId, cfgId));
|
||||
}
|
||||
}
|
||||
|
8
src/main/java/emu/grasscutter/data/QuickAccessCache.java
Normal file
8
src/main/java/emu/grasscutter/data/QuickAccessCache.java
Normal file
@ -0,0 +1,8 @@
|
||||
package emu.grasscutter.data;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface QuickAccessCache {
|
||||
}
|
@ -2,6 +2,8 @@ package emu.grasscutter.data;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.Loggers;
|
||||
import emu.grasscutter.data.binout.*;
|
||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
||||
@ -13,14 +15,18 @@ import emu.grasscutter.data.common.ScenePointArrayData;
|
||||
import emu.grasscutter.data.common.WeatherAreaPointData;
|
||||
import emu.grasscutter.data.common.quest.MainQuestData;
|
||||
import emu.grasscutter.data.common.quest.SubQuestData;
|
||||
import emu.grasscutter.data.custom.AvatarDataCache;
|
||||
import emu.grasscutter.data.custom.TrialAvatarActivityCustomData;
|
||||
import emu.grasscutter.data.custom.TrialAvatarCustomData;
|
||||
import emu.grasscutter.data.excels.TrialAvatarActivityDataData;
|
||||
import emu.grasscutter.data.server.*;
|
||||
import emu.grasscutter.data.server.DropSubfieldMapping;
|
||||
import emu.grasscutter.data.server.DropTableExcelConfigData;
|
||||
import emu.grasscutter.data.server.GadgetMapping;
|
||||
import emu.grasscutter.data.server.MonsterMapping;
|
||||
import emu.grasscutter.data.server.SubfieldMapping;
|
||||
import emu.grasscutter.game.ability.Ability;
|
||||
import emu.grasscutter.game.dungeons.DungeonDrop;
|
||||
import emu.grasscutter.game.dungeons.dungeon_entry.DungeonEntries;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonType;
|
||||
import emu.grasscutter.game.managers.blossom.BlossomConfig;
|
||||
import emu.grasscutter.game.quest.QuestEncryptionKey;
|
||||
import emu.grasscutter.game.quest.enums.QuestCond;
|
||||
@ -38,17 +44,30 @@ import it.unimi.dsi.fastutil.Pair;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntArraySet;
|
||||
import kotlin.Unit;
|
||||
import kotlinx.serialization.json.Json;
|
||||
import kotlinx.serialization.json.JsonKt;
|
||||
import lombok.val;
|
||||
|
||||
import org.anime_game_servers.core.base.interfaces.IntKey;
|
||||
import org.anime_game_servers.game_data_models.gi.GIDataModelRegistry;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonType;
|
||||
import org.anime_game_servers.game_data_models.gi.helpers.TextHashUtilsKt;
|
||||
import org.anime_game_servers.game_data_models.loader.*;
|
||||
import org.anime_game_servers.gi_lua.models.loader.SceneReplacementScriptLoadParams;
|
||||
import org.anime_game_servers.gi_lua.models.loader.ShardQuestScriptLoadParams;
|
||||
import org.anime_game_servers.gi_lua.models.quest.QuestData;
|
||||
import org.anime_game_servers.gi_lua.models.quest.RewindData;
|
||||
import org.anime_game_servers.gi_lua.models.scene.SceneGroupReplacement;
|
||||
import org.reflections.Reflections;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
@ -69,10 +88,36 @@ public class ResourceLoader {
|
||||
|
||||
private static final Set<String> loadedResources = new CopyOnWriteArraySet<>();
|
||||
|
||||
private static DefaultDataLoader dataLoader;
|
||||
|
||||
private static void initDataLoader() {
|
||||
val json = JsonKt.Json(Json.Default, (jsonBuilder -> {
|
||||
jsonBuilder.setIgnoreUnknownKeys(true);
|
||||
jsonBuilder.setLenient(true);
|
||||
jsonBuilder.setAllowComments(true);
|
||||
jsonBuilder.setAllowTrailingComma(true);
|
||||
return Unit.INSTANCE;
|
||||
}));
|
||||
|
||||
val jsonParser = new JsonDataParser(json);
|
||||
dataLoader = new DefaultDataLoader();
|
||||
// register GI Models
|
||||
dataLoader.registerDataClassSource(GIDataModelRegistry.INSTANCE);
|
||||
|
||||
// add default json parser
|
||||
dataLoader.setParser(FileType.JSON, jsonParser);
|
||||
|
||||
// add paths for each type
|
||||
val resourcePath = new JvmPathFile(getResourcePath(""));
|
||||
dataLoader.addFolderTypeSource(FolderType.EXCEL, resourcePath);
|
||||
dataLoader.addFolderTypeSource(FolderType.BINOUT, resourcePath);
|
||||
dataLoader.addFolderTypeSource(FolderType.GENERATED, resourcePath);
|
||||
dataLoader.addFolderTypeSource(FolderType.CUSTOM, resourcePath);
|
||||
}
|
||||
|
||||
// Get a list of all resource classes, sorted by loadPriority
|
||||
public static List<Class<?>> getResourceDefClasses() {
|
||||
Reflections reflections = new Reflections(ResourceLoader.class.getPackage().getName());
|
||||
Set<?> classes = reflections.getSubTypesOf(GameResource.class);
|
||||
Set<?> classes = Grasscutter.reflector.getSubTypesOf(GameResource.class);
|
||||
|
||||
List<Class<?>> classList = new ArrayList<>(classes.size());
|
||||
classes.forEach(o -> {
|
||||
@ -89,8 +134,7 @@ public class ResourceLoader {
|
||||
|
||||
// Get a list containing sets of all resource classes, sorted by loadPriority
|
||||
protected static List<Set<Class<?>>> getResourceDefClassesPrioritySets() {
|
||||
val reflections = new Reflections(ResourceLoader.class.getPackage().getName());
|
||||
val classes = reflections.getSubTypesOf(GameResource.class);
|
||||
val classes = Grasscutter.reflector.getSubTypesOf(GameResource.class);
|
||||
val priorities = ResourceType.LoadPriority.getInOrder();
|
||||
logger.debug("Priorities are {}", priorities);
|
||||
val map = new LinkedHashMap<ResourceType.LoadPriority, Set<Class<?>>>(priorities.size());
|
||||
@ -111,6 +155,8 @@ public class ResourceLoader {
|
||||
if (loadedAll) return;
|
||||
logger.info(translate("messages.status.resources.loading"));
|
||||
|
||||
initDataLoader();
|
||||
|
||||
loadConfigData();
|
||||
// Load ability lists
|
||||
loadAbilityEmbryos();
|
||||
@ -119,6 +165,8 @@ public class ResourceLoader {
|
||||
loadAbilityModifiers();
|
||||
// Load resources
|
||||
loadResources(true);
|
||||
loadExcel();
|
||||
initExcelCaches();
|
||||
// Process into depots
|
||||
GameDepot.load();
|
||||
// Load spawn data and quests
|
||||
@ -142,9 +190,7 @@ public class ResourceLoader {
|
||||
loadScriptData();
|
||||
loadGadgetMappings();
|
||||
loadSubfieldMappings();
|
||||
loadWeatherMappings();
|
||||
loadMonsterMappings();
|
||||
loadActivityCondGroups();
|
||||
loadTrialAvatarCustomData();
|
||||
loadGlobalCombatConfig();
|
||||
EntityControllerScriptManager.load();
|
||||
@ -152,6 +198,90 @@ public class ResourceLoader {
|
||||
loadedAll = true;
|
||||
}
|
||||
|
||||
|
||||
public static void loadExcel() {
|
||||
getAnimeGameModelsMaps();
|
||||
}
|
||||
|
||||
public static void getAnimeGameModelsMaps() {
|
||||
val fields = GameData.class.getDeclaredFields();
|
||||
Arrays.stream(fields).parallel()
|
||||
.filter(field -> field.getAnnotation(AutoResource.class) != null && field.getAnnotation(QuickAccessCache.class) == null)
|
||||
.forEach(field -> {
|
||||
try {
|
||||
val type = field.getType();
|
||||
if (type.equals(Int2ObjectMap.class)) {
|
||||
loadInt2ObjectMap(field);
|
||||
} else if (Map.class.isAssignableFrom(type)) {
|
||||
loadGenericMap(field);
|
||||
} else {
|
||||
logger.info("Field {} is not a map", field.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Error loading field {}", field.getName(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void loadInt2ObjectMap(Field field) throws IllegalAccessException {
|
||||
val arguments = ((ParameterizedType) field.getGenericType()).getActualTypeArguments();
|
||||
if (arguments.length != 1)
|
||||
throw new RuntimeException("expected 1 generic type argument for Int2ObjectMap");
|
||||
val type = arguments[0];
|
||||
if (!(type instanceof Class<?>)) {
|
||||
return;
|
||||
}
|
||||
if (!(IntKey.class.isAssignableFrom((Class<?>) type))) {
|
||||
return;
|
||||
}
|
||||
|
||||
val targetClass = (Class<? extends IntKey>) arguments[0];
|
||||
|
||||
val list = dataLoader.loadListBlocking(targetClass);
|
||||
if(list != null){
|
||||
field.setAccessible(true);
|
||||
val map = (Int2ObjectMap<Object>) field.get(null);
|
||||
field.setAccessible(false);
|
||||
list.forEach(value -> map.put(value.getIntKey(), value));
|
||||
logger.error("loaded {} entries for {}", map.size(), targetClass.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadGenericMap(Field field){
|
||||
val genericType = field.getGenericType();
|
||||
if(!(genericType instanceof ParameterizedType)){
|
||||
return;
|
||||
}
|
||||
val arguments = ((ParameterizedType) genericType).getActualTypeArguments();
|
||||
if (arguments.length != 2)
|
||||
throw new RuntimeException("expected 2 generic type arguments for Map");
|
||||
val keyType = arguments[0];
|
||||
val valueType = arguments[1];
|
||||
|
||||
if (!(keyType instanceof Class<?>)) {
|
||||
return;
|
||||
}
|
||||
if (!(valueType instanceof Class<?>)) {
|
||||
return;
|
||||
}
|
||||
if(((Class<?>)valueType).getPackage().getName().contains("grasscutter")){
|
||||
return;
|
||||
}
|
||||
if(keyType.equals(String.class)){
|
||||
//TODO handle StringKey
|
||||
}
|
||||
}
|
||||
|
||||
public static void initExcelCaches(){
|
||||
GameData.getTriggerExcelConfigDataMap().values().forEach(GameData::putQuestTriggerDataCache);
|
||||
initAvatarCaches();
|
||||
}
|
||||
|
||||
public static void initAvatarCaches(){
|
||||
GameData.getAvatarCostumeDataMap().values().forEach(GameData::putAvatarCostumeDataCache);
|
||||
GameData.getAvatarDataMap().forEach((id, data) -> GameData.getAvatarInfoCacheMap().put(id, new AvatarDataCache(data)));
|
||||
}
|
||||
|
||||
public static void loadResources() {
|
||||
loadResources(false);
|
||||
}
|
||||
@ -406,7 +536,7 @@ public class ResourceLoader {
|
||||
}
|
||||
|
||||
for (AbilityEmbryoEntry entry : embryoList) {
|
||||
GameData.getAbilityEmbryoInfo().put(entry.getName(), entry);
|
||||
GameData.getAbilityEmbryos().put(entry.getName(), entry);
|
||||
}
|
||||
}
|
||||
|
||||
@ -677,10 +807,10 @@ public class ResourceLoader {
|
||||
}
|
||||
|
||||
data.setIndex(SceneIndexManager.buildIndex(3, data.getBornPosList(), item -> item.getPos().toPoint()));
|
||||
GameData.getSceneNpcBornData().put(data.getSceneId(), data);
|
||||
GameData.getNpcBornData().put(data.getSceneId(), data);
|
||||
} catch (IOException ignored) {}
|
||||
});
|
||||
logger.debug("Loaded {} SceneNpcBornDatas.", GameData.getSceneNpcBornData().size());
|
||||
logger.debug("Loaded {} SceneNpcBornDatas.", GameData.getNpcBornData().size());
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to load SceneNpcBorn folder.");
|
||||
}
|
||||
@ -714,6 +844,9 @@ public class ResourceLoader {
|
||||
try {
|
||||
val name = path.getFileName().toString().replace(".json", "");
|
||||
targetMap.put(name, JsonUtils.loadToClass(path, configClass));
|
||||
val textHashBase = "Data/_"+folderPath+name+".MiHoYoBinData";
|
||||
val textHash = TextHashUtilsKt.getTextHash(textHashBase);
|
||||
GameData.getTextHashMap().put(textHash, name);
|
||||
} catch (Exception e) {
|
||||
logger.error("failed to load {} entries for {}", className, path.toString(), e);
|
||||
}
|
||||
@ -900,18 +1033,6 @@ public class ResourceLoader {
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadWeatherMappings() {
|
||||
try {
|
||||
val weatherMap = GameData.getWeatherMappingMap();
|
||||
try {
|
||||
JsonUtils.loadToList(getResourcePath("Server/WeatherMapping.json"), WeatherMapping.class).forEach(entry -> weatherMap.put(entry.getAreaId(), entry));;
|
||||
} catch (IOException | NullPointerException ignored) {}
|
||||
logger.debug("Loaded {} weather mappings.", weatherMap.size());
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to load weather mappings.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadMonsterMappings() {
|
||||
try {
|
||||
val monsterMap = GameData.getMonsterMappingMap();
|
||||
@ -924,18 +1045,6 @@ public class ResourceLoader {
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadActivityCondGroups() {
|
||||
try {
|
||||
val gadgetMap = GameData.getActivityCondGroupMap();
|
||||
try {
|
||||
JsonUtils.loadToList(getResourcePath("Server/ActivityCondGroups.json"), ActivityCondGroup.class).forEach(entry -> gadgetMap.put(entry.getCondGroupId(), entry));
|
||||
} catch (IOException | NullPointerException ignored) {}
|
||||
logger.debug("Loaded {} ActivityCondGroups.", gadgetMap.size());
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to load ActivityCondGroups.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadTrialAvatarCustomData() {
|
||||
try {
|
||||
String pathName = "TrialAvatar/";
|
||||
|
215
src/main/java/emu/grasscutter/data/custom/AvatarDataCache.java
Normal file
215
src/main/java/emu/grasscutter/data/custom/AvatarDataCache.java
Normal file
@ -0,0 +1,215 @@
|
||||
package emu.grasscutter.data.custom;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.binout.AbilityEmbryoEntry;
|
||||
import emu.grasscutter.data.binout.config.ConfigEntityAvatar;
|
||||
import emu.grasscutter.data.excels.AvatarPromoteData;
|
||||
import emu.grasscutter.data.excels.AvatarSkillDepotData;
|
||||
import emu.grasscutter.utils.Language;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.game_data_models.gi.data.entities.CreatureExcelConfig;
|
||||
import org.anime_game_servers.game_data_models.gi.data.entities.avatar.AvatarCurveData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.entities.avatar.AvatarData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.entities.avatar.GrowthCurveType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.entities.avatar.WeaponType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Data
|
||||
public class AvatarDataCache {
|
||||
// baseData
|
||||
private int avatarId;
|
||||
private AvatarData avatarData;
|
||||
private ConfigEntityAvatar configEntityAvatar;
|
||||
private String baseName;
|
||||
|
||||
// abilities
|
||||
private Map<Integer, AvatarSkillDepotData> skillDepots;
|
||||
private int defaultSkillDepotId;
|
||||
private IntList abilities;
|
||||
private List<String> abilityNames = new ArrayList<>();
|
||||
|
||||
// stat/prop growth
|
||||
private float[] hpGrowthCurve;
|
||||
private float[] attackGrowthCurve;
|
||||
private float[] defenseGrowthCurve;
|
||||
|
||||
// promote data
|
||||
private Map<Integer, AvatarPromoteData> promoteData;
|
||||
|
||||
// friendship level
|
||||
private List<Integer> fetters;
|
||||
private int nameCardRewardId;
|
||||
private int nameCardId;
|
||||
private static Pattern baseNamePattern = Pattern.compile("ConfigAvatar_(.+)");
|
||||
|
||||
public AvatarDataCache(AvatarData data) {
|
||||
this.avatarId = data.getId();
|
||||
this.avatarData = data;
|
||||
|
||||
val configDataName = GameData.getTextHashMap().get(data.getCombatConfigHashJvm());
|
||||
configEntityAvatar = GameData.getAvatarConfigData().get(configDataName);
|
||||
|
||||
initBaseName(configDataName);
|
||||
|
||||
initSkillDepotData();
|
||||
initFriendshipData();
|
||||
initAscensionData();
|
||||
initGrowthCurveData();
|
||||
rebuildAbilityEmbryo();
|
||||
}
|
||||
private void initBaseName(String configDataName){
|
||||
if(configDataName!=null) {
|
||||
val matcher = baseNamePattern.matcher(configDataName);
|
||||
if (matcher.find()) {
|
||||
this.baseName = matcher.group(1);
|
||||
} else {
|
||||
this.baseName = configDataName;
|
||||
}
|
||||
} else {
|
||||
this.baseName = Language.getTextMapKey(avatarData.getNameTextMapHash()).get(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void initSkillDepotData(){
|
||||
defaultSkillDepotId = avatarData.getSkillDepotId();
|
||||
var candDepotIds = avatarData.getCandSkillDepotIdsNonNull();
|
||||
if (candDepotIds.isEmpty()) {
|
||||
candDepotIds = List.of(defaultSkillDepotId);
|
||||
}
|
||||
this.skillDepots = candDepotIds.stream()
|
||||
.map(depotId -> GameData.getAvatarSkillDepotDataMap().get(depotId))
|
||||
.collect(Collectors.toMap(AvatarSkillDepotData::getId, depot -> depot));
|
||||
}
|
||||
|
||||
private void initFriendshipData(){
|
||||
this.fetters = GameData.getFetterDataEntries().get(this.avatarId);
|
||||
|
||||
if (GameData.getFetterCharacterCardDataMap().get(this.avatarId) != null) {
|
||||
this.nameCardRewardId = GameData.getFetterCharacterCardDataMap().get(this.avatarId).getRewardId();
|
||||
}
|
||||
|
||||
if (GameData.getRewardDataMap().get(this.nameCardRewardId) != null) {
|
||||
this.nameCardId = GameData.getRewardDataMap().get(this.nameCardRewardId).getRewardItemList().get(0).getItemId();
|
||||
}
|
||||
}
|
||||
|
||||
private void initAscensionData(){
|
||||
val promoteId = this.avatarData.getAvatarPromoteId();
|
||||
this.promoteData = GameData.getAvatarPromoteDataMap().values().stream()
|
||||
.filter(data -> data.getAvatarPromoteId() == promoteId)
|
||||
.collect(Collectors.toMap(AvatarPromoteData::getPromoteLevel, data -> data));
|
||||
}
|
||||
|
||||
private void initGrowthCurveData(){
|
||||
int size = GameData.getAvatarCurveDataMap().size();
|
||||
this.hpGrowthCurve = new float[size];
|
||||
this.attackGrowthCurve = new float[size];
|
||||
this.defenseGrowthCurve = new float[size];
|
||||
for (val curveData : GameData.getAvatarCurveDataMap().values()) {
|
||||
int level = curveData.getLevel() - 1;
|
||||
for (CreatureExcelConfig.FightPropGrowConfig growCurve : this.avatarData.getPropGrowCurvesNonNull()) {
|
||||
val targetMap = switch (growCurve.getTypeNonNull()) {
|
||||
case FIGHT_PROP_BASE_HP:
|
||||
yield this.hpGrowthCurve;
|
||||
case FIGHT_PROP_BASE_ATTACK:
|
||||
yield this.attackGrowthCurve;
|
||||
case FIGHT_PROP_BASE_DEFENSE:
|
||||
yield this.defenseGrowthCurve;
|
||||
default:
|
||||
yield null;
|
||||
};
|
||||
if (targetMap == null) {
|
||||
Grasscutter.getLogger().warn("Unknown prop: {}", growCurve.getType());
|
||||
continue;
|
||||
}
|
||||
targetMap[level] = getGrowthCurveValue(curveData, growCurve.getGrowCurve());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (PropGrowCurve growCurve : this.PropGrowCurves) {
|
||||
FightProperty prop = FightProperty.getPropByName(growCurve.getType());
|
||||
this.growthCurveMap.put(prop.getId(), growCurve.getGrowCurve());
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void rebuildAbilityEmbryo() {
|
||||
// Cache abilities
|
||||
|
||||
AbilityEmbryoEntry info = GameData.getAbilityEmbryo(this.baseName);
|
||||
if (info != null) {
|
||||
this.abilities = new IntArrayList(info.getAbilities().length);
|
||||
for (String ability : info.getAbilities()) {
|
||||
this.abilities.add(Utils.abilityHash(ability));
|
||||
abilityNames.add(ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getId(){
|
||||
return avatarId;
|
||||
}
|
||||
|
||||
private float getGrowthCurveValue(AvatarCurveData curveData, GrowthCurveType growthCurveType) {
|
||||
val curveInfos = curveData.getCurveInfosNonNull();
|
||||
return curveInfos.stream()
|
||||
.filter(info -> growthCurveType.equals(info.getType()))
|
||||
.findFirst().map(AvatarCurveData.GrowCurveInfo::getValue).orElse(1f);
|
||||
}
|
||||
|
||||
public float getBaseHp(int level) {
|
||||
val hpBase = avatarData.getHpBase();
|
||||
try {
|
||||
return hpBase * this.hpGrowthCurve[level - 1];
|
||||
} catch (Exception e) {
|
||||
return hpBase;
|
||||
}
|
||||
}
|
||||
|
||||
public float getBaseAttack(int level) {
|
||||
val atkBase = avatarData.getAttackBase();
|
||||
try {
|
||||
return atkBase * this.attackGrowthCurve[level - 1];
|
||||
} catch (Exception e) {
|
||||
return atkBase;
|
||||
}
|
||||
}
|
||||
|
||||
public float getBaseDefense(int level) {
|
||||
val defenseBase = avatarData.getAttackBase();
|
||||
try {
|
||||
return defenseBase * this.defenseGrowthCurve[level - 1];
|
||||
} catch (Exception e) {
|
||||
return defenseBase;
|
||||
}
|
||||
}
|
||||
|
||||
public float getBaseCritical() {
|
||||
return avatarData.getCritical();
|
||||
}
|
||||
|
||||
public float getBaseCriticalHurt() {
|
||||
return avatarData.getCriticalHurt();
|
||||
}
|
||||
|
||||
public int getInitialWeapon(){
|
||||
return avatarData.getInitialWeapon();
|
||||
}
|
||||
|
||||
@NonNull public WeaponType getWeaponType(){
|
||||
return avatarData.getWeaponTypeNonNull();
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditions;
|
||||
import emu.grasscutter.game.quest.enums.LogicType;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "NewActivityCondExcelConfigData.json")
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ActivityCondExcelConfigData extends GameResource {
|
||||
int condId;
|
||||
LogicType condComb;
|
||||
List<ActivityConfigCondition> cond;
|
||||
|
||||
public static class ActivityConfigCondition {
|
||||
@Getter
|
||||
private ActivityConditions type;
|
||||
@Getter
|
||||
private List<Integer> param;
|
||||
|
||||
public int[] paramArray() {
|
||||
return param.stream().mapToInt(Integer::intValue).toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return condId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
cond.removeIf(c -> c.type == null);
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@ResourceType(name = "NewActivityExcelConfigData.json", loadPriority = ResourceType.LoadPriority.LOW)
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ActivityData extends GameResource {
|
||||
int activityId;
|
||||
String activityType;
|
||||
List<Integer> condGroupId;
|
||||
List<Integer> watcherId;
|
||||
List<ActivityWatcherData> watcherDataList;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.activityId;
|
||||
}
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.watcherDataList = watcherId.stream().map(item -> GameData.getActivityWatcherDataMap().get(item.intValue()))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
}
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.shop.ShopType;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "ActivityShopOverallExcelConfigData.json")
|
||||
public class ActivityShopData extends GameResource {
|
||||
@Getter
|
||||
private int scheduleId;
|
||||
@Getter
|
||||
private ShopType shopType;
|
||||
@Getter
|
||||
private List<Integer> sheetList;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return getShopTypeId();
|
||||
}
|
||||
|
||||
public int getShopTypeId() {
|
||||
if (this.shopType == null)
|
||||
this.shopType = ShopType.SHOP_TYPE_NONE;
|
||||
return shopType.shopTypeId;
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
@ResourceType(name = "NewActivityWatcherConfigData.json", loadPriority = ResourceType.LoadPriority.HIGH)
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
|
@ -1,37 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarCostumeExcelConfigData.json")
|
||||
public class AvatarCostumeData extends GameResource {
|
||||
@SerializedName(value = "skinId", alternate = "costumeId")
|
||||
private int skinId;
|
||||
private int itemId;
|
||||
private int characterId;
|
||||
private int quality;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.skinId;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return this.itemId;
|
||||
}
|
||||
|
||||
public int getCharacterId() {
|
||||
return characterId;
|
||||
}
|
||||
|
||||
public int getQuality() {
|
||||
return quality;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
GameData.getAvatarCostumeDataItemIdMap().put(this.getItemId(), this);
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.CurveInfo;
|
||||
|
||||
@ResourceType(name = "AvatarCurveExcelConfigData.json")
|
||||
public class AvatarCurveData extends GameResource {
|
||||
private int level;
|
||||
private CurveInfo[] curveInfos;
|
||||
|
||||
private Map<String, Float> curveInfoMap;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public Map<String, Float> getCurveInfos() {
|
||||
return curveInfoMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.curveInfoMap = new HashMap<>();
|
||||
Stream.of(this.curveInfos).forEach(info -> this.curveInfoMap.put(info.getType(), info.getValue()));
|
||||
}
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||
import emu.grasscutter.data.binout.AbilityEmbryoEntry;
|
||||
import emu.grasscutter.data.common.PropGrowCurve;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.props.WeaponType;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "AvatarExcelConfigData.json", loadPriority = LoadPriority.LOW)
|
||||
public class AvatarData extends GameResource {
|
||||
|
||||
private String iconName;
|
||||
@Getter private String bodyType;
|
||||
@Getter private String qualityType;
|
||||
@Getter private int chargeEfficiency;
|
||||
@Getter private int initialWeapon;
|
||||
@Getter private WeaponType weaponType;
|
||||
@Getter private String imageName;
|
||||
@Getter private int avatarPromoteId;
|
||||
@Getter private String cutsceneShow;
|
||||
@Getter private int skillDepotId;
|
||||
@Getter private int staminaRecoverSpeed;
|
||||
@Getter private List<Integer> candSkillDepotIds;
|
||||
@Getter private String avatarIdentityType;
|
||||
@Getter private List<Integer> avatarPromoteRewardLevelList;
|
||||
@Getter private List<Integer> avatarPromoteRewardIdList;
|
||||
|
||||
@Getter private long nameTextMapHash;
|
||||
|
||||
private float hpBase;
|
||||
private float attackBase;
|
||||
private float defenseBase;
|
||||
private float critical;
|
||||
private float criticalHurt;
|
||||
|
||||
private List<PropGrowCurve> propGrowCurves;
|
||||
@Getter(onMethod = @__(@Override))
|
||||
private int id;
|
||||
|
||||
// Transient
|
||||
@Getter private String name;
|
||||
|
||||
private Int2ObjectMap<String> growthCurveMap;
|
||||
private float[] hpGrowthCurve;
|
||||
private float[] attackGrowthCurve;
|
||||
private float[] defenseGrowthCurve;
|
||||
@Getter private AvatarSkillDepotData skillDepot;
|
||||
@Getter private IntList abilities;
|
||||
@Getter private List<String> abilitieNames = new ArrayList<>();
|
||||
|
||||
@Getter private List<Integer> fetters;
|
||||
@Getter private int nameCardRewardId;
|
||||
@Getter private int nameCardId;
|
||||
|
||||
public float getBaseHp(int level) {
|
||||
try {
|
||||
return this.hpBase * this.hpGrowthCurve[level - 1];
|
||||
} catch (Exception e) {
|
||||
return this.hpBase;
|
||||
}
|
||||
}
|
||||
|
||||
public float getBaseAttack(int level) {
|
||||
try {
|
||||
return this.attackBase * this.attackGrowthCurve[level - 1];
|
||||
} catch (Exception e) {
|
||||
return this.attackBase;
|
||||
}
|
||||
}
|
||||
|
||||
public float getBaseDefense(int level) {
|
||||
try {
|
||||
return this.defenseBase * this.defenseGrowthCurve[level - 1];
|
||||
} catch (Exception e) {
|
||||
return this.defenseBase;
|
||||
}
|
||||
}
|
||||
|
||||
public float getBaseCritical() {
|
||||
return this.critical;
|
||||
}
|
||||
|
||||
public float getBaseCriticalHurt() {
|
||||
return this.criticalHurt;
|
||||
}
|
||||
|
||||
public float getGrowthCurveById(int level, FightProperty prop) {
|
||||
String growCurve = this.growthCurveMap.get(prop.getId());
|
||||
if (growCurve == null) {
|
||||
return 1f;
|
||||
}
|
||||
AvatarCurveData curveData = GameData.getAvatarCurveDataMap().get(level);
|
||||
if (curveData == null) {
|
||||
return 1f;
|
||||
}
|
||||
return curveData.getCurveInfos().getOrDefault(growCurve, 1f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.skillDepot = GameData.getAvatarSkillDepotDataMap().get(this.skillDepotId);
|
||||
|
||||
// Get fetters from GameData
|
||||
this.fetters = GameData.getFetterDataEntries().get(this.id);
|
||||
|
||||
if (GameData.getFetterCharacterCardDataMap().get(this.id) != null) {
|
||||
this.nameCardRewardId = GameData.getFetterCharacterCardDataMap().get(this.id).getRewardId();
|
||||
}
|
||||
|
||||
if (GameData.getRewardDataMap().get(this.nameCardRewardId) != null) {
|
||||
this.nameCardId = GameData.getRewardDataMap().get(this.nameCardRewardId).getRewardItemList().get(0).getItemId();
|
||||
}
|
||||
|
||||
int size = GameData.getAvatarCurveDataMap().size();
|
||||
this.hpGrowthCurve = new float[size];
|
||||
this.attackGrowthCurve = new float[size];
|
||||
this.defenseGrowthCurve = new float[size];
|
||||
for (AvatarCurveData curveData : GameData.getAvatarCurveDataMap().values()) {
|
||||
int level = curveData.getLevel() - 1;
|
||||
for (PropGrowCurve growCurve : this.propGrowCurves) {
|
||||
FightProperty prop = FightProperty.getPropByName(growCurve.getType());
|
||||
switch (prop) {
|
||||
case FIGHT_PROP_BASE_HP:
|
||||
this.hpGrowthCurve[level] = curveData.getCurveInfos().get(growCurve.getGrowCurve());
|
||||
break;
|
||||
case FIGHT_PROP_BASE_ATTACK:
|
||||
this.attackGrowthCurve[level] = curveData.getCurveInfos().get(growCurve.getGrowCurve());
|
||||
break;
|
||||
case FIGHT_PROP_BASE_DEFENSE:
|
||||
this.defenseGrowthCurve[level] = curveData.getCurveInfos().get(growCurve.getGrowCurve());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (PropGrowCurve growCurve : this.PropGrowCurves) {
|
||||
FightProperty prop = FightProperty.getPropByName(growCurve.getType());
|
||||
this.growthCurveMap.put(prop.getId(), growCurve.getGrowCurve());
|
||||
}
|
||||
*/
|
||||
|
||||
rebuildAbilityEmbryo();
|
||||
}
|
||||
|
||||
public void rebuildAbilityEmbryo(){// rebuild ability for different scene
|
||||
// Cache abilities
|
||||
String[] split = this.iconName.split("_");
|
||||
if (split.length > 0) {
|
||||
this.name = split[split.length - 1];
|
||||
|
||||
AbilityEmbryoEntry info = GameData.getAbilityEmbryoInfo().get(this.name);
|
||||
if (info != null) {
|
||||
this.abilities = new IntArrayList(info.getAbilities().length);
|
||||
for (String ability : info.getAbilities()) {
|
||||
this.abilities.add(Utils.abilityHash(ability));
|
||||
abilitieNames.add(ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarFettersLevelExcelConfigData.json")
|
||||
public class AvatarFetterLevelData extends GameResource {
|
||||
private int fetterLevel;
|
||||
private int needExp;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.fetterLevel;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return fetterLevel;
|
||||
}
|
||||
|
||||
public int getExp() {
|
||||
return needExp;
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarFlycloakExcelConfigData.json")
|
||||
public class AvatarFlycloakData extends GameResource {
|
||||
private int flycloakId;
|
||||
private long nameTextMapHash;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.flycloakId;
|
||||
}
|
||||
|
||||
public long getNameTextMapHash() {
|
||||
return nameTextMapHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarLevelExcelConfigData.json")
|
||||
public class AvatarLevelData extends GameResource {
|
||||
private int level;
|
||||
private int exp;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public int getExp() {
|
||||
return exp;
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "CityConfigData.json", loadPriority = ResourceType.LoadPriority.HIGH)
|
||||
@Getter
|
||||
@Setter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class CityData extends GameResource {
|
||||
int cityId;
|
||||
int sceneId;
|
||||
List<Integer> areaIdVec;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.cityId;
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.dungeons.enums.*;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ResourceType(name = "DungeonExcelConfigData.json")
|
||||
@ToString
|
||||
@Data
|
||||
public class DungeonData extends GameResource {
|
||||
|
||||
@Getter(onMethod = @__(@Override))
|
||||
private int id;
|
||||
private int serialId;
|
||||
private int sceneId;
|
||||
private int showLevel;
|
||||
private int levelRevise;
|
||||
private DungeonType type;
|
||||
private DungeonSubType subType;
|
||||
private DungeonPlayType playType;
|
||||
private DungeonInvolveType involveType;
|
||||
private int limitLevel;
|
||||
private int passCond;
|
||||
private int reviveMaxCount;
|
||||
private int settleCountdownTime;
|
||||
private int failSettleCountdownTime;
|
||||
private int quitSettleCountdownTime;
|
||||
private List<SettleShowType> settleShows;
|
||||
@SerializedName(value = "passRewardPreviewID", alternate = {"passRewardPreviewId"})
|
||||
private int passRewardPreviewId;
|
||||
private int passJumpDungeon;
|
||||
private int statueCostID;
|
||||
private int statueCostCount;
|
||||
private String stateType;
|
||||
|
||||
// not part of DungeonExcelConfigData
|
||||
private RewardPreviewData rewardPreviewData;
|
||||
|
||||
public DungeonType getType() {
|
||||
return Optional.ofNullable(this.type).orElse(DungeonType.DUNGEON_NONE);
|
||||
}
|
||||
|
||||
public DungeonSubType getSubType() {
|
||||
return Optional.ofNullable(this.subType).orElse(DungeonSubType.DUNGEON_SUB_NONE);
|
||||
}
|
||||
|
||||
public DungeonPlayType getPlayType() {
|
||||
return Optional.ofNullable(this.playType).orElse(DungeonPlayType.DUNGEON_PLAY_TYPE_NONE);
|
||||
}
|
||||
|
||||
public DungeonInvolveType getInvolveType() {
|
||||
return Optional.ofNullable(this.involveType).orElse(DungeonInvolveType.INVOLVE_NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
Optional.ofNullable(GameData.getRewardPreviewDataMap().get(this.passRewardPreviewId))
|
||||
.ifPresent(d -> this.rewardPreviewData = d);
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.quest.enums.LogicType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "DungeonPassExcelConfigData.json")
|
||||
@AllArgsConstructor
|
||||
public class DungeonPassConfigData extends GameResource {
|
||||
|
||||
public static final DungeonPassConfigData EMPTY =
|
||||
new DungeonPassConfigData(0, LogicType.LOGIC_OR, List.of(
|
||||
new DungeonPassCondition(DungeonPassConditionType.DUNGEON_COND_NONE, new int[]{0})
|
||||
));
|
||||
|
||||
static {
|
||||
GameData.getDungeonPassConfigDataMap().put(EMPTY.getId(), EMPTY);
|
||||
}
|
||||
|
||||
@Getter private int id;
|
||||
@Getter private LogicType logicType;
|
||||
@Getter private List<DungeonPassCondition> conds;
|
||||
|
||||
@Data @AllArgsConstructor
|
||||
public static class DungeonPassCondition{
|
||||
@Getter private DungeonPassConditionType condType;
|
||||
@Getter int[] param;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
conds = conds.stream().filter(condition -> condition.getCondType()!=null).toList();
|
||||
}
|
||||
}
|
@ -6,7 +6,9 @@ import emu.grasscutter.data.ResourceType;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import org.anime_game_servers.game_data_models.gi.data.city.CityData;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "InvestigationMonsterConfigData.json", loadPriority = ResourceType.LoadPriority.LOW)
|
||||
@ -22,10 +24,8 @@ public class InvestigationMonsterData extends GameResource {
|
||||
String mapMarkCreateType;
|
||||
String monsterCategory;
|
||||
|
||||
CityData cityData;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.cityData = GameData.getCityDataMap().get(cityId);
|
||||
@Nullable
|
||||
public CityData getCityData(){
|
||||
return GameData.getCityDataMap().get(cityId);
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
|
||||
@ResourceType(name = "RewardExcelConfigData.json")
|
||||
public class RewardData extends GameResource {
|
||||
public int rewardId;
|
||||
public List<ItemParamData> rewardItemList;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return rewardId;
|
||||
}
|
||||
|
||||
public List<ItemParamData> getRewardItemList() {
|
||||
return rewardItemList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
rewardItemList = rewardItemList.stream().filter(i -> i.getId() > 0).toList();
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "SceneExcelConfigData.json")
|
||||
@Getter
|
||||
public class SceneData extends GameResource {
|
||||
@Getter(onMethod = @__(@Override))
|
||||
private int id;
|
||||
@SerializedName("type")
|
||||
private SceneType sceneType;
|
||||
private String scriptData;
|
||||
@Getter private String levelEntityConfig;
|
||||
@Getter private List<Integer> specifiedAvatarList;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "SceneTagConfigData.json")
|
||||
@Getter
|
||||
public class SceneTagData extends GameResource {
|
||||
@Getter(onMethod = @__(@Override))
|
||||
private int id;
|
||||
private String sceneTagName;
|
||||
private int sceneId;
|
||||
private boolean isDefaultValid;
|
||||
private boolean isSkipLoading;
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import emu.grasscutter.game.shop.ShopInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "ShopGoodsExcelConfigData.json")
|
||||
public class ShopGoodsData extends GameResource {
|
||||
private int goodsId;
|
||||
private int shopType;
|
||||
private int itemId;
|
||||
|
||||
private int itemCount;
|
||||
|
||||
private int costScoin;
|
||||
private int costHcoin;
|
||||
private int costMcoin;
|
||||
|
||||
private List<ItemParamData> costItems;
|
||||
private int minPlayerLevel;
|
||||
private int maxPlayerLevel;
|
||||
|
||||
private int buyLimit;
|
||||
@SerializedName(value="subTabId", alternate={"secondarySheetId"})
|
||||
private int subTabId;
|
||||
|
||||
private String refreshType;
|
||||
private transient ShopInfo.ShopRefreshType refreshTypeEnum;
|
||||
|
||||
private int refreshParam;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if (this.refreshType == null)
|
||||
this.refreshTypeEnum = ShopInfo.ShopRefreshType.NONE;
|
||||
else {
|
||||
this.refreshTypeEnum = switch (this.refreshType) {
|
||||
case "SHOP_REFRESH_DAILY" -> ShopInfo.ShopRefreshType.SHOP_REFRESH_DAILY;
|
||||
case "SHOP_REFRESH_WEEKLY" -> ShopInfo.ShopRefreshType.SHOP_REFRESH_WEEKLY;
|
||||
case "SHOP_REFRESH_MONTHLY" -> ShopInfo.ShopRefreshType.SHOP_REFRESH_MONTHLY;
|
||||
default -> ShopInfo.ShopRefreshType.NONE;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return getGoodsId();
|
||||
}
|
||||
|
||||
public int getGoodsId() {
|
||||
return goodsId;
|
||||
}
|
||||
|
||||
public int getShopType() {
|
||||
return shopType;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
public int getItemCount() {
|
||||
return itemCount;
|
||||
}
|
||||
|
||||
public int getCostScoin() {
|
||||
return costScoin;
|
||||
}
|
||||
|
||||
public int getCostHcoin() {
|
||||
return costHcoin;
|
||||
}
|
||||
|
||||
public int getCostMcoin() {
|
||||
return costMcoin;
|
||||
}
|
||||
|
||||
public List<ItemParamData> getCostItems() {
|
||||
return costItems;
|
||||
}
|
||||
|
||||
public int getMinPlayerLevel() {
|
||||
return minPlayerLevel;
|
||||
}
|
||||
|
||||
public int getMaxPlayerLevel() {
|
||||
return maxPlayerLevel;
|
||||
}
|
||||
|
||||
public int getBuyLimit() {
|
||||
return buyLimit;
|
||||
}
|
||||
|
||||
public int getSubTabId() {
|
||||
return subTabId;
|
||||
}
|
||||
|
||||
public ShopInfo.ShopRefreshType getRefreshType() {
|
||||
return refreshTypeEnum;
|
||||
}
|
||||
|
||||
public int getRefreshParam() {
|
||||
return refreshParam;
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@ResourceType(name = "StatuePromoteExcelConfigData.json")
|
||||
public class StatuePromoteData extends GameResource {
|
||||
@Getter @Setter private int level;
|
||||
@Getter @Setter private int cityId;
|
||||
@Getter @Setter private ItemParamData[] costItems;
|
||||
@Getter @Setter private int[] rewardIdList;
|
||||
@Getter @Setter private int stamina;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return (cityId << 8) + level;
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import lombok.val;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@ResourceType(name = "TowerRewardExcelConfigData.json")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ToString
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
public class TowerRewardData extends GameResource {
|
||||
@SerializedName(value = "levelIndex", alternate = {"IEPBHNILIDB"})
|
||||
private int levelIndex;
|
||||
@SerializedName(value = "floorIndex", alternate = {"DGKHCGBPFDM"})
|
||||
private int floorIndex;
|
||||
@SerializedName(value = "threeStarsReward", alternate = {"BCOFGJBABGD"})
|
||||
private int threeStarsReward;
|
||||
@SerializedName(value = "sixStarsReward", alternate = {"CAEOHANFNAP"})
|
||||
private int sixStarsReward;
|
||||
@SerializedName(value = "nineStarsReward", alternate = {"DGJDIBJKGMI"})
|
||||
private int nineStarsReward;
|
||||
@SerializedName(value = "chamberBountyRewards", alternate = {"MHDLDDFOIJD"})
|
||||
private List<Integer> chamberBountyRewards;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return (this.levelIndex << 4) + this.floorIndex;
|
||||
}
|
||||
|
||||
public List<Integer> getStarRewardsByStarCount(int starCount) {
|
||||
val fullStarRewards = List.of(this.threeStarsReward, this.sixStarsReward, this.nineStarsReward);
|
||||
return IntStream.rangeClosed(0, starCount).map(i -> (int) Math.floor((float) i / 3) - 1).filter(i -> i >= 0)
|
||||
.distinct().mapToObj(fullStarRewards::get).toList();
|
||||
}
|
||||
|
||||
public List<Integer> getFirstPassRewardByStarCount(int starCount) {
|
||||
return IntStream.rangeClosed(0, starCount).map(i -> (int) Math.floor((float) i / 3) - 1).filter(i -> i >= 0)
|
||||
.distinct().mapToObj(this.chamberBountyRewards::get).toList();
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "TriggerExcelConfigData.json") @Getter
|
||||
public class TriggerExcelConfigData extends GameResource {
|
||||
@Getter private int id;
|
||||
private int sceneId;
|
||||
private int groupId;
|
||||
private String triggerName;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
GameData.getTriggerDataByNameMap().put(groupId+triggerName, this);
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "WorldAreaConfigData.json")
|
||||
public class WorldAreaData extends GameResource {
|
||||
private int ID;
|
||||
@Getter @SerializedName("AreaID1")
|
||||
private int areaID1;
|
||||
@Getter @SerializedName("AreaID2")
|
||||
private int areaID2;
|
||||
@Getter @SerializedName("SceneID")
|
||||
private int sceneID;
|
||||
@Getter
|
||||
private ElementType elementType;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return (this.areaID2 << 16) + this.areaID1;
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "WorldLevelExcelConfigData.json")
|
||||
public class WorldLevelData extends GameResource {
|
||||
private int level;
|
||||
private int monsterLevel;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public int getMonsterLevel() {
|
||||
return monsterLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package emu.grasscutter.data.server;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ActivityCondGroup {
|
||||
int condGroupId;
|
||||
List<Integer> condIds;
|
||||
}
|
73
src/main/java/emu/grasscutter/game/LogicTypeUtils.java
Normal file
73
src/main/java/emu/grasscutter/game/LogicTypeUtils.java
Normal file
@ -0,0 +1,73 @@
|
||||
package emu.grasscutter.game;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import org.anime_game_servers.game_data_models.gi.data.general.LogicType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
public class LogicTypeUtils {
|
||||
public static boolean calculate(LogicType logicType, int[] progress) {
|
||||
if (progress.length == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (logicType == null) {
|
||||
return progress[0] == 1;
|
||||
}
|
||||
|
||||
switch (logicType) {
|
||||
case LOGIC_AND -> {
|
||||
return Arrays.stream(progress).allMatch(i -> i == 1);
|
||||
}
|
||||
case LOGIC_OR -> {
|
||||
return Arrays.stream(progress).anyMatch(i -> i == 1);
|
||||
}
|
||||
case LOGIC_NOT -> {
|
||||
return Arrays.stream(progress).noneMatch(i -> i == 1);
|
||||
}
|
||||
case LOGIC_A_AND_ETCOR -> {
|
||||
return progress[0] == 1 && Arrays.stream(progress).skip(1).anyMatch(i -> i == 1);
|
||||
}
|
||||
case LOGIC_A_AND_B_AND_ETCOR -> {
|
||||
return progress[0] == 1 && progress[1] == 1 && Arrays.stream(progress).skip(2).anyMatch(i -> i == 1);
|
||||
}
|
||||
case LOGIC_A_OR_ETCAND -> {
|
||||
return progress[0] == 1 || Arrays.stream(progress).skip(1).allMatch(i -> i == 1);
|
||||
}
|
||||
case LOGIC_A_OR_B_OR_ETCAND -> {
|
||||
return progress[0] == 1 || progress[1] == 1 || Arrays.stream(progress).skip(2).allMatch(i -> i == 1);
|
||||
}
|
||||
case LOGIC_A_AND_B_OR_ETCAND -> {
|
||||
return progress[0] == 1 && progress[1] == 1 || Arrays.stream(progress).skip(2).allMatch(i -> i == 1);
|
||||
}
|
||||
default -> {
|
||||
return Arrays.stream(progress).anyMatch(i -> i == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply logic type to all predicates
|
||||
*
|
||||
* @param logicType type of logic that should be applied to predicates
|
||||
* @param predicates list of predicates for which logicType will be applied
|
||||
* @return result of applying logicType to predicates
|
||||
*/
|
||||
public static boolean calculate(@NotNull LogicType logicType, List<BooleanSupplier> predicates) {
|
||||
switch (logicType) {
|
||||
case LOGIC_AND -> {
|
||||
return predicates.stream().allMatch(BooleanSupplier::getAsBoolean);
|
||||
}
|
||||
case LOGIC_OR -> {
|
||||
return predicates.stream().anyMatch(BooleanSupplier::getAsBoolean);
|
||||
}
|
||||
default -> {
|
||||
Grasscutter.getLogger().error("Unimplemented logic operation was called");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,9 +8,9 @@ import emu.grasscutter.game.ability.Ability;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
import emu.grasscutter.game.entity.EntityItem;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.ability.action.AbilityActionGenerateElemBall;
|
||||
import org.anime_game_servers.game_data_models.gi.data.scene.SceneType;
|
||||
|
||||
@AbilityAction(AbilityModifierAction.Type.GenerateElemBall)
|
||||
public class ActionGenerateElemBall extends AbilityActionHandler {
|
||||
@ -34,7 +34,7 @@ public class ActionGenerateElemBall extends AbilityActionHandler {
|
||||
return true;
|
||||
}
|
||||
} else if(action.dropType == DropType.BigWorldOnly) {
|
||||
if(owner.getScene().getSceneData().getSceneType() != SceneType.SCENE_WORLD) {
|
||||
if(owner.getScene().getSceneData().getType() != SceneType.SCENE_WORLD) {
|
||||
logger.warn("This level config only allows element balls on big world");
|
||||
return true;
|
||||
}
|
||||
|
@ -2,11 +2,8 @@ package emu.grasscutter.game.activity;
|
||||
|
||||
import com.esotericsoftware.reflectasm.ConstructorAccess;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.ActivityData;
|
||||
import emu.grasscutter.data.server.ActivityCondGroup;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionExecutor;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.game.quest.enums.QuestCond;
|
||||
import emu.grasscutter.utils.DateHelper;
|
||||
import lombok.AccessLevel;
|
||||
@ -15,6 +12,9 @@ import lombok.Setter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.activity.general.ActivityInfo;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondGroupData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.watcher.WatcherTriggerType;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@ -30,6 +30,7 @@ public abstract class ActivityHandler {
|
||||
@Getter ActivityData activityData;
|
||||
Map<WatcherTriggerType, List<ActivityWatcher>> watchersMap = new HashMap<>();
|
||||
|
||||
|
||||
abstract public void onProtoBuild(PlayerActivityData playerActivityData, ActivityInfo activityInfo);
|
||||
abstract public void onInitPlayerActivityData(PlayerActivityData playerActivityData);
|
||||
|
||||
@ -37,8 +38,14 @@ public abstract class ActivityHandler {
|
||||
activityData = GameData.getActivityDataMap().get(activityConfigItem.getActivityId());
|
||||
|
||||
// add watcher to map by id
|
||||
activityData.getWatcherDataList().forEach(watcherData -> {
|
||||
var watcherType = activityWatcherTypeMap.get(watcherData.getTriggerConfig().getWatcherTriggerType());
|
||||
activityData.getWatcherIds().forEach(watcherId -> {
|
||||
val watcherData = GameData.getActivityWatcherDataMap().get(watcherId.intValue());
|
||||
if(watcherData == null || watcherData.getTriggerConfig() == null || watcherData.getTriggerConfig().getTriggerType() == null){
|
||||
// todo log
|
||||
return;
|
||||
}
|
||||
val triggerType = watcherData.getTriggerConfig().getTriggerType();
|
||||
var watcherType = activityWatcherTypeMap.get(triggerType);
|
||||
ActivityWatcher watcher;
|
||||
if(watcherType != null){
|
||||
watcher = (ActivityWatcher) watcherType.newInstance();
|
||||
@ -49,8 +56,8 @@ public abstract class ActivityHandler {
|
||||
watcher.setWatcherId(watcherData.getId());
|
||||
watcher.setActivityHandler(this);
|
||||
watcher.setActivityWatcherData(watcherData);
|
||||
watchersMap.computeIfAbsent(watcherData.getTriggerConfig().getWatcherTriggerType(), k -> new ArrayList<>());
|
||||
watchersMap.get(watcherData.getTriggerConfig().getWatcherTriggerType()).add(watcher);
|
||||
watchersMap.computeIfAbsent(triggerType, k -> new ArrayList<>());
|
||||
watchersMap.get(triggerType).add(watcher);
|
||||
});
|
||||
}
|
||||
|
||||
@ -59,7 +66,7 @@ public abstract class ActivityHandler {
|
||||
return;
|
||||
}
|
||||
val questManager = player.getQuestManager();
|
||||
activityData.getCondGroupId().forEach(condGroupId -> {
|
||||
activityData.getCondGroupIds().forEach(condGroupId -> {
|
||||
val condGroup = GameData.getActivityCondGroupMap().get((int)condGroupId);
|
||||
if(condGroup != null)
|
||||
condGroup.getCondIds().forEach(condID -> questManager.queueEvent(QuestCond.QUEST_COND_ACTIVITY_COND, condID));
|
||||
@ -70,9 +77,9 @@ public abstract class ActivityHandler {
|
||||
if(activityData == null){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return activityData.getCondGroupId().stream().map(condGroupId -> GameData.getActivityCondGroupMap().get((int)condGroupId))
|
||||
return activityData.getCondGroupIds().stream().map(condGroupId -> GameData.getActivityCondGroupMap().get((int)condGroupId))
|
||||
.filter(Objects::nonNull)
|
||||
.map(ActivityCondGroup::getCondIds)
|
||||
.map(ActivityCondGroupData::getCondIds)
|
||||
.flatMap(Collection::stream)
|
||||
.toList();
|
||||
}
|
||||
|
@ -7,17 +7,16 @@ import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.activity.condition.*;
|
||||
import emu.grasscutter.game.player.BasePlayerManager;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActivityType;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.server.packet.send.PacketActivityScheduleInfoNotify;
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.activity.general.ActivityInfo;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.watcher.WatcherTriggerType;
|
||||
|
||||
@Getter
|
||||
public class ActivityManager extends BasePlayerManager {
|
||||
@ -37,7 +36,7 @@ public class ActivityManager extends BasePlayerManager {
|
||||
// scan activity type handler & watcher type
|
||||
var activityHandlerTypeMap = new HashMap<ActivityType, ConstructorAccess<?>>();
|
||||
var activityWatcherTypeMap = new HashMap<WatcherTriggerType, ConstructorAccess<?>>();
|
||||
var reflections = new Reflections(ActivityManager.class.getPackage().getName());
|
||||
var reflections = Grasscutter.reflector;
|
||||
|
||||
reflections.getSubTypesOf(ActivityHandler.class).forEach(item -> {
|
||||
var typeName = item.getAnnotation(GameActivity.class);
|
||||
@ -51,12 +50,14 @@ public class ActivityManager extends BasePlayerManager {
|
||||
try {
|
||||
DataLoader.loadList("ActivityConfig.json", ActivityConfigItem.class).forEach(item -> {
|
||||
item.onLoad();
|
||||
var activityData = GameData.getActivityDataMap().get(item.getActivityId());
|
||||
val activityData = GameData.getActivityDataMap().get(item.getActivityId());
|
||||
if (activityData == null) {
|
||||
Grasscutter.getLogger().warn("activity {} not exist.", item.getActivityId());
|
||||
return;
|
||||
}
|
||||
var activityHandlerType = activityHandlerTypeMap.get(ActivityType.getTypeByName(activityData.getActivityType()));
|
||||
|
||||
// todo handle exception
|
||||
val activityHandlerType = activityHandlerTypeMap.get(activityData.getActivityType());
|
||||
ActivityHandler activityHandler;
|
||||
|
||||
if (activityHandlerType != null) {
|
||||
|
@ -1,10 +1,10 @@
|
||||
package emu.grasscutter.game.activity;
|
||||
|
||||
import emu.grasscutter.data.excels.ActivityWatcherData;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import org.anime_game_servers.game_data_models.gi.data.watcher.ActivityWatcherData;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
@ -1,6 +1,6 @@
|
||||
package emu.grasscutter.game.activity;
|
||||
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.watcher.WatcherTriggerType;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
@ -1,9 +1,9 @@
|
||||
package emu.grasscutter.game.activity;
|
||||
|
||||
import emu.grasscutter.game.props.ActivityType;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.activity.general.ActivityInfo;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityType;
|
||||
|
||||
@GameActivity(ActivityType.NONE)
|
||||
@GameActivity(ActivityType.NEW_ACTIVITY_GENERAL)
|
||||
public class DefaultActivityHandler extends ActivityHandler{
|
||||
@Override
|
||||
public void onProtoBuild(PlayerActivityData playerActivityData, ActivityInfo activityInfo) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package emu.grasscutter.game.activity;
|
||||
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import static org.anime_game_servers.game_data_models.gi.data.watcher.WatcherTriggerType.TRIGGER_NONE;
|
||||
|
||||
@ActivityWatcherType(WatcherTriggerType.TRIGGER_NONE)
|
||||
@ActivityWatcherType(TRIGGER_NONE)
|
||||
public class DefaultWatcher extends ActivityWatcher{
|
||||
@Override
|
||||
protected boolean isMeet(String... param) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package emu.grasscutter.game.activity;
|
||||
|
||||
import emu.grasscutter.game.props.ActivityType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityType;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
@ -4,19 +4,17 @@ import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import dev.morphia.annotations.Transient;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import emu.grasscutter.data.excels.ActivityWatcherData;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.server.packet.send.PacketActivityUpdateWatcherNotify;
|
||||
import emu.grasscutter.utils.JsonUtils;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.activity.general.ActivityWatcherInfo;
|
||||
import org.anime_game_servers.game_data_models.gi.data.watcher.ActivityWatcherData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@ -77,21 +75,16 @@ public class PlayerActivityData {
|
||||
return;
|
||||
}
|
||||
|
||||
var reward = Optional.of(watcher)
|
||||
val reward = Optional.of(watcher)
|
||||
.map(WatcherInfo::getMetadata)
|
||||
.map(ActivityWatcherData::getRewardID)
|
||||
.map(ActivityWatcherData::getRewardId)
|
||||
.map(id -> GameData.getRewardDataMap().get(id.intValue()));
|
||||
|
||||
if (reward.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<GameItem> rewards = new ArrayList<>();
|
||||
for (ItemParamData param : reward.get().getRewardItemList()) {
|
||||
rewards.add(new GameItem(param.getId(), Math.max(param.getCount(), 1)));
|
||||
}
|
||||
|
||||
player.getInventory().addItems(rewards, ActionReason.ActivityWatcher);
|
||||
player.getInventory().addRewardData(reward.get(), ActionReason.ActivityWatcher);
|
||||
watcher.setTakenReward(true);
|
||||
save();
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ package emu.grasscutter.game.activity.aster;
|
||||
import emu.grasscutter.game.activity.ActivityHandler;
|
||||
import emu.grasscutter.game.activity.GameActivity;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.props.ActivityType;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.activity.general.ActivityInfo;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.activity.aster.*;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.Vector;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -1,11 +1,13 @@
|
||||
package emu.grasscutter.game.activity.condition;
|
||||
|
||||
import emu.grasscutter.data.excels.ActivityCondExcelConfigData;
|
||||
import emu.grasscutter.game.activity.ActivityConfigItem;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base handler for all activity conditions that are listed in NewActivityCondExcelConfigData.json ({@link ActivityCondExcelConfigData})
|
||||
* Base handler for all activity conditions that are listed in NewActivityCondExcelConfigData.json ({@link ActivityCondData})
|
||||
*/
|
||||
public abstract class ActivityConditionBaseHandler {
|
||||
|
||||
@ -17,5 +19,5 @@ public abstract class ActivityConditionBaseHandler {
|
||||
* @param params params for handler
|
||||
* @return result of condition calculation
|
||||
*/
|
||||
public abstract boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, int... params);
|
||||
public abstract boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, List<Integer> params);
|
||||
}
|
||||
|
@ -1,17 +1,18 @@
|
||||
package emu.grasscutter.game.activity.condition;
|
||||
|
||||
import emu.grasscutter.data.excels.ActivityCondExcelConfigData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondition;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondData;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
|
||||
/**
|
||||
* This annotation marks condition types for NewActivityCondExcelConfigData.json ({@link ActivityCondExcelConfigData}). To use it you should mark
|
||||
* This annotation marks condition types for NewActivityCondExcelConfigData.json ({@link ActivityCondData}). To use it you should mark
|
||||
* class that extends ActivityConditionBaseHandler, and it will be automatically picked during activity manager initiation.
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ActivityCondition {
|
||||
ActivityConditions value();
|
||||
public @interface ActivityConditionHandler {
|
||||
ActivityCondition value();
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
package emu.grasscutter.game.activity.condition;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.excels.ActivityCondExcelConfigData;
|
||||
import org.reflections.Reflections;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondition;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Class that used for scanning classpath, picking up all activity conditions (for NewActivityCondExcelConfigData.json {@link ActivityCondExcelConfigData})
|
||||
* and saving them to map. Check for more info {@link ActivityCondition}
|
||||
* Class that used for scanning classpath, picking up all activity conditions (for NewActivityCondExcelConfigData.json {@link ActivityCondData})
|
||||
* and saving them to map. Check for more info {@link ActivityConditionHandler}
|
||||
*/
|
||||
public class AllActivityConditionBuilder {
|
||||
|
||||
@ -19,20 +19,19 @@ public class AllActivityConditionBuilder {
|
||||
*
|
||||
* @return map containing all condition handlers for NewActivityCondExcelConfigData.json
|
||||
*/
|
||||
static public Map<ActivityConditions, ActivityConditionBaseHandler> buildActivityConditions() {
|
||||
static public Map<ActivityCondition, ActivityConditionBaseHandler> buildActivityConditions() {
|
||||
return new AllActivityConditionBuilder().initActivityConditions();
|
||||
}
|
||||
|
||||
private Map<ActivityConditions, ActivityConditionBaseHandler> initActivityConditions() {
|
||||
Reflections reflector = Grasscutter.reflector;
|
||||
return reflector.getTypesAnnotatedWith(ActivityCondition.class).stream()
|
||||
private Map<ActivityCondition, ActivityConditionBaseHandler> initActivityConditions() {
|
||||
return Grasscutter.reflector.getTypesAnnotatedWith(ActivityConditionHandler.class).stream()
|
||||
.map(this::newInstance)
|
||||
.map(h -> new AbstractMap.SimpleEntry<>(extractActionType(h), h))
|
||||
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
|
||||
}
|
||||
|
||||
private ActivityConditions extractActionType(ActivityConditionBaseHandler e) {
|
||||
ActivityCondition condition = e.getClass().getAnnotation(ActivityCondition.class);
|
||||
private ActivityCondition extractActionType(ActivityConditionBaseHandler e) {
|
||||
ActivityConditionHandler condition = e.getClass().getAnnotation(ActivityConditionHandler.class);
|
||||
if (condition == null) {
|
||||
Grasscutter.getLogger().error("Failed to read command type for class {}", e.getClass().getName());
|
||||
return null;
|
||||
|
@ -1,12 +1,15 @@
|
||||
package emu.grasscutter.game.activity.condition;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.excels.ActivityCondExcelConfigData;
|
||||
import emu.grasscutter.game.LogicTypeUtils;
|
||||
import emu.grasscutter.game.activity.ActivityConfigItem;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.activity.condition.all.UnknownActivityConditionHandler;
|
||||
import emu.grasscutter.game.quest.enums.LogicType;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondition;
|
||||
import org.anime_game_servers.game_data_models.gi.data.general.LogicType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -16,17 +19,17 @@ import java.util.stream.Collectors;
|
||||
public class BasicActivityConditionExecutor implements ActivityConditionExecutor {
|
||||
|
||||
private final Map<Integer, ActivityConfigItem> activityConfigItemMap;
|
||||
private final Int2ObjectMap<ActivityCondExcelConfigData> activityConditions;
|
||||
private final Int2ObjectMap<ActivityCondData> activityConditions;
|
||||
|
||||
private final Int2ObjectMap<PlayerActivityData> playerActivityDataByActivityCondId;
|
||||
private final Map<ActivityConditions, ActivityConditionBaseHandler> activityConditionsHandlers;
|
||||
private final Map<ActivityCondition, ActivityConditionBaseHandler> activityConditionsHandlers;
|
||||
|
||||
private static final UnknownActivityConditionHandler UNKNOWN_CONDITION_HANDLER = new UnknownActivityConditionHandler();
|
||||
|
||||
public BasicActivityConditionExecutor(Map<Integer, ActivityConfigItem> activityConfigItemMap,
|
||||
Int2ObjectMap<ActivityCondExcelConfigData> activityConditions,
|
||||
Int2ObjectMap<ActivityCondData> activityConditions,
|
||||
Int2ObjectMap<PlayerActivityData> playerActivityDataByActivityCondId,
|
||||
Map<ActivityConditions, ActivityConditionBaseHandler> activityConditionsHandlers) {
|
||||
Map<ActivityCondition, ActivityConditionBaseHandler> activityConditionsHandlers) {
|
||||
this.activityConfigItemMap = activityConfigItemMap;
|
||||
this.activityConditions = activityConditions;
|
||||
this.playerActivityDataByActivityCondId = playerActivityDataByActivityCondId;
|
||||
@ -42,14 +45,14 @@ public class BasicActivityConditionExecutor implements ActivityConditionExecutor
|
||||
|
||||
@Override
|
||||
public boolean meetsCondition(int activityCondId) {
|
||||
ActivityCondExcelConfigData condData = activityConditions.get(activityCondId);
|
||||
val condData = activityConditions.get(activityCondId);
|
||||
|
||||
if (condData == null) {
|
||||
Grasscutter.getLogger().error("Could not find condition for activity with id = {}", activityCondId);
|
||||
return false;
|
||||
}
|
||||
|
||||
LogicType condComb = condData.getCondComb();
|
||||
var condComb = condData.getCondComb();
|
||||
if (condComb == null) {
|
||||
condComb = LogicType.LOGIC_AND;
|
||||
}
|
||||
@ -59,13 +62,16 @@ public class BasicActivityConditionExecutor implements ActivityConditionExecutor
|
||||
return false;
|
||||
}
|
||||
ActivityConfigItem activityConfig = activityConfigItemMap.get(activity.getActivityId());
|
||||
if(condData.getCond() == null){
|
||||
return false;
|
||||
}
|
||||
List<BooleanSupplier> predicates = condData.getCond()
|
||||
.stream()
|
||||
.map(c -> (BooleanSupplier) () ->
|
||||
activityConditionsHandlers
|
||||
.getOrDefault(c.getType(), UNKNOWN_CONDITION_HANDLER).execute(activity, activityConfig, c.paramArray()))
|
||||
.getOrDefault(c.getType(), UNKNOWN_CONDITION_HANDLER).execute(activity, activityConfig, c.getParam()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return LogicType.calculate(condComb, predicates);
|
||||
return LogicTypeUtils.calculate(condComb, predicates);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
package emu.grasscutter.game.activity.condition;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.ActivityCondExcelConfigData;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import it.unimi.dsi.fastutil.ints.AbstractInt2ObjectMap.BasicEntry;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectRBTreeMap;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondData;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -17,12 +17,12 @@ public class PlayerActivityDataMappingBuilder {
|
||||
|
||||
private final Map<Integer, PlayerActivityData> playerActivityDataMap;
|
||||
|
||||
private final Int2ObjectMap<ActivityCondExcelConfigData> activityCondMap;
|
||||
private final Int2ObjectMap<ActivityCondData> activityCondMap;
|
||||
|
||||
/**
|
||||
* Build mapping for PlayerActivityData.
|
||||
*
|
||||
* @return mapping for activity data. Key is condId from NewActivityCondExcelConfigData.json ({@link ActivityCondExcelConfigData}) resource,
|
||||
* @return mapping for activity data. Key is condId from NewActivityCondExcelConfigData.json ({@link ActivityCondData}) resource,
|
||||
* value is {@link PlayerActivityData} class for related activity.
|
||||
*/
|
||||
public static Int2ObjectMap<PlayerActivityData> buildPlayerActivityDataByActivityCondId(Map<Integer, PlayerActivityData> activities) {
|
||||
@ -53,7 +53,7 @@ public class PlayerActivityDataMappingBuilder {
|
||||
|
||||
/**
|
||||
* Detect activity data id by cond id. Cond id comes from condId field from NewActivityCondExcelConfigData.json.
|
||||
* See {@link ActivityCondExcelConfigData} for condId.
|
||||
* See {@link ActivityCondData} for condId.
|
||||
* <p>
|
||||
* Generally, there are 3 cases:
|
||||
* <ol>
|
||||
|
@ -2,15 +2,18 @@ package emu.grasscutter.game.activity.condition.all;
|
||||
|
||||
import emu.grasscutter.game.activity.ActivityConfigItem;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.activity.condition.ActivityCondition;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionHandler;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionBaseHandler;
|
||||
|
||||
import static emu.grasscutter.game.activity.condition.ActivityConditions.NEW_ACTIVITY_COND_DAYS_LESS;
|
||||
import java.util.List;
|
||||
|
||||
@ActivityCondition(NEW_ACTIVITY_COND_DAYS_LESS)
|
||||
import static org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondition.NEW_ACTIVITY_COND_DAYS_LESS;
|
||||
|
||||
|
||||
@ActivityConditionHandler(NEW_ACTIVITY_COND_DAYS_LESS)
|
||||
public class DayLess extends ActivityConditionBaseHandler {
|
||||
@Override
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, int... params) {
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, List<Integer> params) {
|
||||
return true; //TODO implement this and add possibility to always return true
|
||||
}
|
||||
}
|
||||
|
@ -2,20 +2,20 @@ package emu.grasscutter.game.activity.condition.all;
|
||||
|
||||
import emu.grasscutter.game.activity.ActivityConfigItem;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.activity.condition.ActivityCondition;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionHandler;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionBaseHandler;
|
||||
import static org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondition.NEW_ACTIVITY_COND_DAYS_GREAT_EQUAL;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.game.activity.condition.ActivityConditions.NEW_ACTIVITY_COND_DAYS_GREAT_EQUAL;
|
||||
|
||||
@ActivityCondition(NEW_ACTIVITY_COND_DAYS_GREAT_EQUAL)
|
||||
@ActivityConditionHandler(NEW_ACTIVITY_COND_DAYS_GREAT_EQUAL)
|
||||
public class DaysGreatEqual extends ActivityConditionBaseHandler {
|
||||
@Override
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, int... params) {
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, List<Integer> params) {
|
||||
Date activityBeginTime = activityConfig.getBeginTime();
|
||||
long timeDiff = System.currentTimeMillis() - activityBeginTime.getTime();
|
||||
int days = (int) (timeDiff / (1000 * 60 * 60 * 24L));
|
||||
return days + 1 >= params[0];
|
||||
return days + 1 >= params.get(0);
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,19 @@ package emu.grasscutter.game.activity.condition.all;
|
||||
|
||||
import emu.grasscutter.game.activity.ActivityConfigItem;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.activity.condition.ActivityCondition;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionHandler;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionBaseHandler;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditions;
|
||||
import lombok.val;
|
||||
|
||||
@ActivityCondition(ActivityConditions.NEW_ACTIVITY_COND_FINISH_WATCHER)
|
||||
import java.util.List;
|
||||
|
||||
import static org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondition.NEW_ACTIVITY_COND_FINISH_WATCHER;
|
||||
|
||||
@ActivityConditionHandler(NEW_ACTIVITY_COND_FINISH_WATCHER)
|
||||
public class FinishWatcher extends ActivityConditionBaseHandler {
|
||||
|
||||
@Override
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, int... params) {
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, List<Integer> params) {
|
||||
val watcherMap = activityData.getWatcherInfoMap();
|
||||
for (int param : params) {
|
||||
val watcher = watcherMap.get(param);
|
||||
|
@ -2,21 +2,23 @@ package emu.grasscutter.game.activity.condition.all;
|
||||
|
||||
import emu.grasscutter.game.activity.ActivityConfigItem;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.activity.condition.ActivityCondition;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionHandler;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionBaseHandler;
|
||||
|
||||
import static emu.grasscutter.game.activity.condition.ActivityConditions.NEW_ACTIVITY_COND_NOT_FINISH_TALK;
|
||||
import java.util.List;
|
||||
|
||||
@ActivityCondition(NEW_ACTIVITY_COND_NOT_FINISH_TALK)
|
||||
import static org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondition.NEW_ACTIVITY_COND_NOT_FINISH_TALK;
|
||||
|
||||
@ActivityConditionHandler(NEW_ACTIVITY_COND_NOT_FINISH_TALK)
|
||||
public class NotFinishTalk extends ActivityConditionBaseHandler {
|
||||
@Override
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, int... params) {
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, List<Integer> params) {
|
||||
return activityData
|
||||
.getPlayer()
|
||||
.getQuestManager()
|
||||
.getMainQuests()
|
||||
.int2ObjectEntrySet()
|
||||
.stream()
|
||||
.noneMatch(q -> q.getValue().getTalks().get(params[0]) != null); //FIXME taken from ContentCompleteTalk
|
||||
.noneMatch(q -> q.getValue().getTalks().get(params.get(0)) != null); //FIXME taken from ContentCompleteTalk
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,18 @@ package emu.grasscutter.game.activity.condition.all;
|
||||
|
||||
import emu.grasscutter.game.activity.ActivityConfigItem;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.activity.condition.ActivityCondition;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionHandler;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionBaseHandler;
|
||||
|
||||
import static emu.grasscutter.game.activity.condition.ActivityConditions.NEW_ACTIVITY_COND_PLAYER_LEVEL_GREAT_EQUAL;
|
||||
import java.util.List;
|
||||
|
||||
@ActivityCondition(NEW_ACTIVITY_COND_PLAYER_LEVEL_GREAT_EQUAL)
|
||||
import static org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondition.NEW_ACTIVITY_COND_PLAYER_LEVEL_GREAT_EQUAL;
|
||||
|
||||
@ActivityConditionHandler(NEW_ACTIVITY_COND_PLAYER_LEVEL_GREAT_EQUAL)
|
||||
public class PlayerLevelGreatEqualActivityActivityCondition extends ActivityConditionBaseHandler {
|
||||
|
||||
@Override
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, int... params) {
|
||||
return activityData.getPlayer().getLevel() >= params[0];
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, List<Integer> params) {
|
||||
return activityData.getPlayer().getLevel() >= params.get(0);
|
||||
}
|
||||
}
|
||||
|
@ -2,21 +2,23 @@ package emu.grasscutter.game.activity.condition.all;
|
||||
|
||||
import emu.grasscutter.game.activity.ActivityConfigItem;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.activity.condition.ActivityCondition;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionHandler;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionBaseHandler;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
import org.anime_game_servers.core.gi.enums.QuestState;
|
||||
|
||||
import static emu.grasscutter.game.activity.condition.ActivityConditions.NEW_ACTIVITY_COND_QUEST_FINISH;
|
||||
import java.util.List;
|
||||
|
||||
@ActivityCondition(NEW_ACTIVITY_COND_QUEST_FINISH)
|
||||
import static org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondition.NEW_ACTIVITY_COND_QUEST_FINISH;
|
||||
|
||||
@ActivityConditionHandler(NEW_ACTIVITY_COND_QUEST_FINISH)
|
||||
public class QuestFinished extends ActivityConditionBaseHandler {
|
||||
@Override
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, int... params) {
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, List<Integer> params) {
|
||||
GameQuest quest = activityData
|
||||
.getPlayer()
|
||||
.getQuestManager()
|
||||
.getQuestById(params[0]);
|
||||
.getQuestById(params.get(0));
|
||||
|
||||
return quest != null && quest.getState() == QuestState.QUEST_STATE_FINISHED;
|
||||
}
|
||||
|
@ -2,15 +2,17 @@ package emu.grasscutter.game.activity.condition.all;
|
||||
|
||||
import emu.grasscutter.game.activity.ActivityConfigItem;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.activity.condition.ActivityCondition;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionHandler;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionBaseHandler;
|
||||
|
||||
import static emu.grasscutter.game.activity.condition.ActivityConditions.NEW_ACTIVITY_COND_SALESMAN_CAN_DELIVER;
|
||||
import java.util.List;
|
||||
|
||||
@ActivityCondition(NEW_ACTIVITY_COND_SALESMAN_CAN_DELIVER)
|
||||
import static org.anime_game_servers.game_data_models.gi.data.activity.ActivityCondition.NEW_ACTIVITY_COND_SALESMAN_CAN_DELIVER;
|
||||
|
||||
@ActivityConditionHandler(NEW_ACTIVITY_COND_SALESMAN_CAN_DELIVER)
|
||||
public class SalesmanCanDeliver extends ActivityConditionBaseHandler {
|
||||
@Override
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, int... params) {
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, List<Integer> params) {
|
||||
//TODO need to reverse engineer this logic.
|
||||
//This condition appears only in one condition "condId": 5003001
|
||||
//and this condition accept no params. I have no idea how to implement it
|
||||
|
@ -5,13 +5,15 @@ import emu.grasscutter.game.activity.ActivityConfigItem;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditionBaseHandler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class is used when condition was not found
|
||||
*/
|
||||
public class UnknownActivityConditionHandler extends ActivityConditionBaseHandler {
|
||||
|
||||
@Override
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, int... params) {
|
||||
public boolean execute(PlayerActivityData activityData, ActivityConfigItem activityConfig, List<Integer> params) {
|
||||
Grasscutter.getLogger().error("Called unknown condition handler");
|
||||
return false;
|
||||
}
|
||||
|
@ -3,12 +3,11 @@ package emu.grasscutter.game.activity.musicgame;
|
||||
import emu.grasscutter.game.activity.ActivityHandler;
|
||||
import emu.grasscutter.game.activity.GameActivity;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.props.ActivityType;
|
||||
import emu.grasscutter.utils.JsonUtils;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.activity.general.ActivityInfo;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.activity.music_game.MusicGameActivityDetailInfo;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.activity.user_generated_content.music_game.UgcMusicBriefInfo;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityType;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -2,9 +2,9 @@ package emu.grasscutter.game.activity.musicgame;
|
||||
|
||||
import emu.grasscutter.game.activity.ActivityWatcher;
|
||||
import emu.grasscutter.game.activity.ActivityWatcherType;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import static org.anime_game_servers.game_data_models.gi.data.watcher.WatcherTriggerType.TRIGGER_FLEUR_FAIR_MUSIC_GAME_REACH_SCORE;
|
||||
|
||||
@ActivityWatcherType(WatcherTriggerType.TRIGGER_FLEUR_FAIR_MUSIC_GAME_REACH_SCORE)
|
||||
@ActivityWatcherType(TRIGGER_FLEUR_FAIR_MUSIC_GAME_REACH_SCORE)
|
||||
public class MusicGameScoreTrigger extends ActivityWatcher {
|
||||
@Override
|
||||
protected boolean isMeet(String... param) {
|
||||
|
@ -3,12 +3,13 @@ package emu.grasscutter.game.activity.trialavatar;
|
||||
import emu.grasscutter.game.activity.ActivityWatcher;
|
||||
import emu.grasscutter.game.activity.ActivityWatcherType;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
|
||||
import lombok.val;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ActivityWatcherType(WatcherTriggerType.TRIGGER_FINISH_CHALLENGE)
|
||||
import static org.anime_game_servers.game_data_models.gi.data.watcher.WatcherTriggerType.TRIGGER_FINISH_CHALLENGE;
|
||||
|
||||
@ActivityWatcherType(TRIGGER_FINISH_CHALLENGE)
|
||||
public class TrialAvatarActivityChallengeTrigger extends ActivityWatcher {
|
||||
@Override
|
||||
protected boolean isMeet(String... param) {
|
||||
|
@ -10,11 +10,9 @@ import emu.grasscutter.game.activity.DefaultWatcher;
|
||||
import emu.grasscutter.game.dungeons.settle_listeners.TrialAvatarDungeonSettleListener;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.game.activity.ActivityHandler;
|
||||
import emu.grasscutter.game.activity.GameActivity;
|
||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||
import emu.grasscutter.game.props.ActivityType;
|
||||
import emu.grasscutter.server.packet.send.PacketActivityInfoNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketScenePlayerLocationNotify;
|
||||
import emu.grasscutter.utils.JsonUtils;
|
||||
@ -22,6 +20,8 @@ import emu.grasscutter.utils.JsonUtils;
|
||||
import java.util.*;
|
||||
import lombok.*;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.activity.general.ActivityInfo;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.watcher.WatcherTriggerType;
|
||||
|
||||
@GameActivity(ActivityType.NEW_ACTIVITY_TRIAL_AVATAR)
|
||||
public class TrialAvatarActivityHandler extends ActivityHandler {
|
||||
@ -108,7 +108,7 @@ public class TrialAvatarActivityHandler extends ActivityHandler {
|
||||
val rewardParam = GameData.getRewardDataMap().get(rewardInfo.getRewardId());
|
||||
if (rewardParam == null) return false;
|
||||
|
||||
player.getInventory().addItemParamDatas(rewardParam.getRewardItemList(), ActionReason.TrialAvatarActivityFirstPassReward);
|
||||
player.getInventory().addRewardData(rewardParam, ActionReason.TrialAvatarActivityFirstPassReward);
|
||||
rewardInfo.setReceivedReward(true);
|
||||
playerActivityData.get().setDetail(trialAvatarPlayerData);
|
||||
playerActivityData.get().save();
|
||||
|
@ -12,6 +12,7 @@ import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import emu.grasscutter.data.custom.AvatarDataCache;
|
||||
import lombok.*;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.PropValue;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.avatar.*;
|
||||
@ -45,7 +46,7 @@ public class Avatar {
|
||||
@Indexed @Getter private int ownerId; // id of player that this avatar belongs to
|
||||
|
||||
@Transient private Player owner;
|
||||
@Transient @Getter protected AvatarData data;
|
||||
@Transient @Getter protected AvatarDataCache data;
|
||||
@Transient @Getter protected AvatarSkillDepotData skillDepot;
|
||||
@Transient @Getter protected long guid; // Player unique id
|
||||
@Getter protected int avatarId; // id of avatar
|
||||
@ -89,14 +90,14 @@ public class Avatar {
|
||||
|
||||
// On creation
|
||||
public Avatar(int avatarId) {
|
||||
this(GameData.getAvatarDataMap().get(avatarId));
|
||||
this(GameData.getAvatarInfoCacheMap().get(avatarId));
|
||||
}
|
||||
|
||||
public Avatar(AvatarData data) {
|
||||
public Avatar(AvatarDataCache data) {
|
||||
this();
|
||||
this.avatarId = data.getId();
|
||||
this.nameCardRewardId = data.getNameCardRewardId();
|
||||
this.nameCardId = data.getNameCardId();
|
||||
this.nameCardRewardId = GameData.getFetterCharacterCardDataMap().get(this.avatarId).getRewardId();
|
||||
this.nameCardId = GameData.getRewardDataMap().get(this.nameCardRewardId).getRewardItemList().get(0).getItemId();
|
||||
this.data = data;
|
||||
this.bornTime = (int) (System.currentTimeMillis() / 1000);
|
||||
this.flyCloak = 140001;
|
||||
@ -111,7 +112,8 @@ public class Avatar {
|
||||
.forEach(id -> this.setFightProperty(id, 0f));
|
||||
|
||||
// Skill depot
|
||||
this.setSkillDepotData(data.getSkillDepot(), false);
|
||||
val skillDepot = data.getSkillDepots().get(data.getDefaultSkillDepotId());
|
||||
this.setSkillDepotData(skillDepot, false);
|
||||
|
||||
// Set stats
|
||||
this.recalcStats();
|
||||
@ -130,11 +132,11 @@ public class Avatar {
|
||||
return id;
|
||||
}
|
||||
|
||||
public AvatarData getAvatarData() {
|
||||
public AvatarDataCache getAvatarData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
protected void setAvatarData(AvatarData data) {
|
||||
protected void setAvatarData(AvatarDataCache data) {
|
||||
if (this.data != null) return;
|
||||
this.data = data; // Used while loading this from the database
|
||||
}
|
||||
@ -214,7 +216,7 @@ public class Avatar {
|
||||
* @return false if failed or already using that element, true if it actually changed
|
||||
*/
|
||||
public boolean changeElement(@Nonnull ElementType elementTypeToChange) {
|
||||
val candSkillDepotIdsList = data.getCandSkillDepotIds();
|
||||
val candSkillDepotIdsList = data.getAvatarData().getCandSkillDepotIds();
|
||||
val candSkillDepotIndex = elementTypeToChange.getDepotIndex();
|
||||
|
||||
// if no candidate skill to change or index out of bound
|
||||
@ -225,7 +227,7 @@ public class Avatar {
|
||||
int candSkillDepotId = candSkillDepotIdsList.get(candSkillDepotIndex);
|
||||
|
||||
// Sanity checks for skill depots
|
||||
val skillDepot = GameData.getAvatarSkillDepotDataMap().get(candSkillDepotId);
|
||||
val skillDepot = data.getSkillDepots().get(candSkillDepotId);
|
||||
if (skillDepot == null || skillDepot.getId() == skillDepotId) {
|
||||
return false;
|
||||
}
|
||||
@ -386,7 +388,7 @@ public class Avatar {
|
||||
public void recalcStats(boolean forceSendAbilityChange) {
|
||||
// Setup
|
||||
var data = this.getAvatarData();
|
||||
var promoteData = GameData.getAvatarPromoteData(data.getAvatarPromoteId(), this.getPromoteLevel());
|
||||
var promoteData = data.getPromoteData().get(this.getPromoteLevel());
|
||||
var setMap = new Int2IntOpenHashMap();
|
||||
|
||||
// Extra ability embryos
|
||||
|
@ -4,7 +4,6 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.AvatarData;
|
||||
import emu.grasscutter.data.excels.AvatarSkillDepotData;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
@ -18,6 +17,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
|
||||
@Getter
|
||||
public class AvatarStorage extends BasePlayerManager implements Iterable<Avatar> {
|
||||
@ -147,7 +147,7 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<Avatar>
|
||||
continue;
|
||||
}
|
||||
|
||||
AvatarData avatarData = GameData.getAvatarDataMap().get(avatar.getAvatarId());
|
||||
val avatarData = GameData.getAvatarInfoCacheMap().get(avatar.getAvatarId());
|
||||
AvatarSkillDepotData skillDepot = GameData.getAvatarSkillDepotDataMap().get(avatar.getSkillDepotId());
|
||||
if (avatarData == null || skillDepot == null) {
|
||||
continue;
|
||||
|
@ -4,7 +4,6 @@ import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.BaseTrialAvatarData;
|
||||
import emu.grasscutter.data.common.BaseTrialAvatarTemplateData;
|
||||
import emu.grasscutter.data.excels.AvatarCostumeData;
|
||||
import emu.grasscutter.data.excels.TrialReliquaryData;
|
||||
import emu.grasscutter.game.entity.EntityWeapon;
|
||||
import emu.grasscutter.game.inventory.EquipType;
|
||||
@ -13,6 +12,7 @@ import emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.game_data_models.gi.data.entities.avatar.AvatarCostumeData;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.avatar.AvatarInfo;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.avatar.GrantReason;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.avatar.TrialAvatarGrantRecord;
|
||||
|
@ -15,6 +15,7 @@ import org.anime_game_servers.multi_proto.gi.messages.battle_pass.BattlePassCycl
|
||||
import org.anime_game_servers.multi_proto.gi.messages.battle_pass.BattlePassRewardTakeOption;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.battle_pass.BattlePassSchedule;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.battle_pass.BattlePassUnlockStatus;
|
||||
import org.anime_game_servers.game_data_models.gi.data.quest.GainItem;
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
@ -23,10 +24,8 @@ import dev.morphia.annotations.Indexed;
|
||||
import emu.grasscutter.GameConstants;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import emu.grasscutter.data.excels.BattlePassRewardData;
|
||||
import emu.grasscutter.data.excels.ItemData;
|
||||
import emu.grasscutter.data.excels.RewardData;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.inventory.MaterialType;
|
||||
@ -191,7 +190,7 @@ public class BattlePassManager extends BasePlayerDataManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void takeRewardsFromSelectChest(ItemData rewardItemData, int index, ItemParamData entry, List<GameItem> rewardItems) {
|
||||
private void takeRewardsFromSelectChest(ItemData rewardItemData, int index, GainItem entry, List<GameItem> rewardItems) {
|
||||
// Sanity checks.
|
||||
if (rewardItemData.getItemUse().size() < 1) {
|
||||
return;
|
||||
@ -209,15 +208,15 @@ public class BattlePassManager extends BasePlayerDataManager {
|
||||
|
||||
// For ITEM_USE_ADD_SELECT_ITEM chests, we can directly add the item specified in the chest's data.
|
||||
if (rewardItemData.getItemUse().get(0).getUseOp() == ItemUseOp.ITEM_USE_ADD_SELECT_ITEM) {
|
||||
GameItem rewardItem = new GameItem(GameData.getItemDataMap().get(chosenId), entry.getItemCount());
|
||||
GameItem rewardItem = new GameItem(GameData.getItemDataMap().get(chosenId), entry.getCount());
|
||||
rewardItems.add(rewardItem);
|
||||
}
|
||||
// For ITEM_USE_GRANT_SELECT_REWARD chests, we have to again look up reward data.
|
||||
else if (rewardItemData.getItemUse().get(0).getUseOp() == ItemUseOp.ITEM_USE_GRANT_SELECT_REWARD) {
|
||||
RewardData selectedReward = GameData.getRewardDataMap().get(chosenId);
|
||||
val selectedReward = GameData.getRewardDataMap().get(chosenId);
|
||||
|
||||
for (var r : selectedReward.getRewardItemList()) {
|
||||
GameItem rewardItem = new GameItem(GameData.getItemDataMap().get(r.getItemId()), r.getItemCount());
|
||||
GameItem rewardItem = new GameItem(GameData.getItemDataMap().get(r.getItemId()), r.getCount());
|
||||
rewardItems.add(rewardItem);
|
||||
}
|
||||
}
|
||||
@ -265,7 +264,7 @@ public class BattlePassManager extends BasePlayerDataManager {
|
||||
int index = option.getOptionIdx();
|
||||
|
||||
// Make sure we have reward data.
|
||||
RewardData reward = GameData.getRewardDataMap().get(tag.getRewardId());
|
||||
val reward = GameData.getRewardDataMap().get(tag.getRewardId());
|
||||
if (reward == null) {
|
||||
continue;
|
||||
}
|
||||
@ -280,7 +279,7 @@ public class BattlePassManager extends BasePlayerDataManager {
|
||||
}
|
||||
// All other rewards directly give us the right item.
|
||||
else {
|
||||
GameItem rewardItem = new GameItem(rewardItemData, entry.getItemCount());
|
||||
GameItem rewardItem = new GameItem(rewardItemData, entry.getCount());
|
||||
rewardItems.add(rewardItem);
|
||||
}
|
||||
}
|
||||
|
@ -2,18 +2,14 @@ package emu.grasscutter.game.dungeons;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.DungeonData;
|
||||
import emu.grasscutter.data.excels.DungeonElementChallengeData;
|
||||
import emu.grasscutter.data.excels.DungeonPassConfigData;
|
||||
import emu.grasscutter.game.LogicTypeUtils;
|
||||
import emu.grasscutter.game.activity.trialavatar.TrialAvatarActivityHandler;
|
||||
import emu.grasscutter.game.dungeons.dungeon_results.BaseDungeonResult;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.ActivityType;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.game.quest.enums.LogicType;
|
||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.server.packet.send.PacketDungeonDataNotify;
|
||||
@ -30,14 +26,20 @@ import lombok.Setter;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.avatar.GrantReason;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.scene.entity.WeeklyBossResinDiscountInfo;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
import org.anime_game_servers.gi_lua.models.ScriptArgs;
|
||||
import org.anime_game_servers.gi_lua.models.constants.EventType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.anime_game_servers.game_data_models.gi.data.general.UnsetTypesKt.UnsetInt;
|
||||
|
||||
/**
|
||||
* TODO handle time limits
|
||||
* TODO handle respawn points
|
||||
@ -48,7 +50,7 @@ public class DungeonManager {
|
||||
|
||||
@Getter private final Scene scene;
|
||||
@Getter private final DungeonData dungeonData;
|
||||
@Getter private final DungeonPassConfigData passConfigData;
|
||||
@Getter private final DungeonPassData passConfigData;
|
||||
|
||||
@Getter private final int[] finishedConditions;
|
||||
@Getter private final IntSet rewardedPlayers = new IntOpenHashSet();
|
||||
@ -76,7 +78,7 @@ public class DungeonManager {
|
||||
}
|
||||
|
||||
public boolean isFinishedSuccessfully() {
|
||||
return LogicType.calculate(this.passConfigData.getLogicType(), this.finishedConditions);
|
||||
return LogicTypeUtils.calculate(this.passConfigData.getLogicTypeNonNull(), this.finishedConditions);
|
||||
}
|
||||
|
||||
public int getLevelForMonster(int id) {
|
||||
@ -120,7 +122,7 @@ public class DungeonManager {
|
||||
|
||||
private boolean hasRewards(){
|
||||
//TODO check dungeonData.passRewardId and dungeondata.passRewardPreviewId only as fallback
|
||||
return this.dungeonData.getRewardPreviewData() != null && this.dungeonData.getRewardPreviewData().getPreviewItems().length > 0;
|
||||
return this.dungeonData.getPassRewardPreviewId()!=UnsetInt || this.dungeonData.getPassRewardId()!=UnsetInt;
|
||||
}
|
||||
|
||||
private boolean hasPlayerClaimedRewards(Player player){
|
||||
@ -159,7 +161,7 @@ public class DungeonManager {
|
||||
|
||||
// Spend the condensed resin and only proceed if the transaction succeeds.
|
||||
return player.getResinManager().useCondensedResin(1);
|
||||
} else if (this.dungeonData.getStatueCostID() == 106) {
|
||||
} else if (this.dungeonData.getStatueCostId() == 106) {
|
||||
// Spend the resin and only proceed if the transaction succeeds.
|
||||
return player.getResinManager().useResin(resinCost);
|
||||
} //TODO should we maybe support other currencies here?
|
||||
@ -170,6 +172,7 @@ public class DungeonManager {
|
||||
val rewards = new ArrayList<GameItem>();
|
||||
final int dungeonId = this.dungeonData.getId();
|
||||
// If we have specific drop data for this dungeon, we use it.
|
||||
// TODO use statueDrop for this, in combination with DropTable and leaf data
|
||||
if (GameData.getDungeonDropDataMap().containsKey(dungeonId)) {
|
||||
val dropEntries = GameData.getDungeonDropDataMap().get(dungeonId);
|
||||
|
||||
@ -209,8 +212,12 @@ public class DungeonManager {
|
||||
// Otherwise, we fall back to the preview data.
|
||||
else {
|
||||
Grasscutter.getLogger().info("No drop data found or dungeon {}, falling back to preview data ...", dungeonId);
|
||||
Arrays.stream(this.dungeonData.getRewardPreviewData().getPreviewItems())
|
||||
.map(param -> new GameItem(param.getId(), Math.max(param.getCount(), 1)))
|
||||
//val rewardData = GameData.getRewardDataMap().get(this.dungeonData.getPassRewardId());
|
||||
|
||||
val rewardPreviewData = GameData.getRewardDataMap().get(this.dungeonData.getPassRewardPreviewId());
|
||||
|
||||
rewardPreviewData.getRewardItemList().stream()
|
||||
.map(param -> new GameItem(param.getItemId(), Math.max(param.getCount(), 1)))
|
||||
.forEach(rewards::add);
|
||||
}
|
||||
|
||||
@ -266,7 +273,7 @@ public class DungeonManager {
|
||||
this.dungeonData.getId());
|
||||
|
||||
// Battle pass trigger
|
||||
if (this.dungeonData.getType().isCountsToBattlepass() && successfully) {
|
||||
if (successfully) {
|
||||
p.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_FINISH_DUNGEON);
|
||||
}
|
||||
if(dungeonData.getPassJumpDungeon() > 0){
|
||||
|
@ -4,24 +4,24 @@ import emu.grasscutter.GameConstants;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.PointData;
|
||||
import emu.grasscutter.data.excels.DungeonData;
|
||||
import emu.grasscutter.data.excels.DungeonPassConfigData;
|
||||
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||
import emu.grasscutter.game.dungeons.dungeon_entry.DungeonEntries;
|
||||
import emu.grasscutter.game.dungeons.dungeon_entry.PlayerDungeonExitInfo;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonType;
|
||||
import emu.grasscutter.game.dungeons.handlers.DungeonBaseHandler;
|
||||
import emu.grasscutter.game.dungeons.pass_condition.BaseCondition;
|
||||
import emu.grasscutter.game.dungeons.settle_listeners.BasicDungeonSettleListener;
|
||||
import emu.grasscutter.game.dungeons.settle_listeners.DungeonSettleListener;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import emu.grasscutter.server.game.BaseGameSystem;
|
||||
import emu.grasscutter.server.game.GameServer;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.scene.SceneType;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.util.Optional;
|
||||
@ -56,7 +56,7 @@ public class DungeonSystem extends BaseGameSystem {
|
||||
});
|
||||
}
|
||||
|
||||
public boolean triggerCondition(DungeonPassConfigData.DungeonPassCondition condition, int... params) {
|
||||
public boolean triggerCondition(DungeonPassData.DungeonPassCondition condition, int... params) {
|
||||
val handler = this.passCondHandlers.get(condition.getCondType().ordinal());
|
||||
|
||||
if (handler == null) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package emu.grasscutter.game.dungeons;
|
||||
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
@ -2,12 +2,10 @@ package emu.grasscutter.game.dungeons.challenge;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.dungeons.challenge.trigger.*;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.entity.EntityGadget;
|
||||
import emu.grasscutter.game.entity.EntityMonster;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.props.ElementReactionType;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.server.packet.send.PacketDungeonChallengeBeginNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify;
|
||||
@ -15,10 +13,12 @@ import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
import org.anime_game_servers.gi_lua.models.ScriptArgs;
|
||||
import org.anime_game_servers.gi_lua.models.constants.EventType;
|
||||
import org.anime_game_servers.gi_lua.models.scene.group.SceneGroup;
|
||||
import org.anime_game_servers.gi_lua.models.scene.group.SceneTrigger;
|
||||
import org.anime_game_servers.game_data_models.gi.data.watcher.WatcherTriggerType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -3,11 +3,11 @@ package emu.grasscutter.game.dungeons.dungeon_entry;
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.grasscutter.GameConstants;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.DungeonData;
|
||||
import emu.grasscutter.data.excels.DungeonRosterData;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonData;
|
||||
|
||||
import java.time.*;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
|
@ -3,7 +3,6 @@ package emu.grasscutter.game.dungeons.dungeon_entry;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.binout.ScenePointEntry;
|
||||
import emu.grasscutter.data.common.PointData;
|
||||
import emu.grasscutter.data.excels.DungeonData;
|
||||
import emu.grasscutter.data.excels.DungeonRosterData;
|
||||
import emu.grasscutter.data.excels.DungeonSerialData;
|
||||
import emu.grasscutter.game.player.BasePlayerManager;
|
||||
@ -17,6 +16,7 @@ import lombok.val;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.dungeon.entry.DungeonEntryInfo;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.scene.entity.WeeklyBossResinDiscountInfo;
|
||||
import org.anime_game_servers.core.gi.enums.QuestState;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonData;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -1,14 +1,13 @@
|
||||
package emu.grasscutter.game.dungeons.dungeon_entry;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.PointData;
|
||||
import emu.grasscutter.data.excels.SceneData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import lombok.*;
|
||||
import org.anime_game_servers.game_data_models.gi.data.scene.SceneData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.scene.SceneType;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@ -27,7 +26,7 @@ public class PlayerDungeonExitInfo {
|
||||
}
|
||||
|
||||
public void setAll(Player player, int dungeonId, int pointId) {
|
||||
val fromBigWorld = Optional.ofNullable(player.getScene()).map(Scene::getSceneData).map(SceneData::getSceneType)
|
||||
val fromBigWorld = Optional.ofNullable(player.getScene()).map(Scene::getSceneData).map(SceneData::getType)
|
||||
.filter(sceneType -> sceneType == SceneType.SCENE_WORLD);
|
||||
if (fromBigWorld.isEmpty()) return; // only set player exits location if player comes in from big world
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package emu.grasscutter.game.dungeons.dungeon_results;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonData;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.dungeons.DungeonEndStats;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
@ -14,12 +13,12 @@ import lombok.val;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.dungeon.StrengthenPointData;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.dungeon.progression.DungeonSettleNotify;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.dungeon.progression.ParamList;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.InvolveType;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static emu.grasscutter.game.dungeons.enums.DungeonInvolveType.INVOLVE_SINGLE_MULTIPLE;
|
||||
|
||||
/**
|
||||
* Shows dungeon results
|
||||
* */
|
||||
@ -46,7 +45,7 @@ public class BaseDungeonResult {
|
||||
* */
|
||||
private void getStrengthenPointData(DungeonSettleNotify builder) {
|
||||
if (this.dungeonStats.dungeonResult().isSuccess() ||
|
||||
this.dungeonData.getInvolveType() != INVOLVE_SINGLE_MULTIPLE) return;
|
||||
this.dungeonData.getInvolveType() != InvolveType.INVOLVE_SINGLE_MULTIPLE) return;
|
||||
|
||||
val playerActiveTeam = this.player.getTeamManager().getActiveTeam();
|
||||
builder.setStrengthenPointDataMap(Arrays.stream(StrengthenPointType.values()).collect(
|
||||
|
@ -1,6 +1,5 @@
|
||||
package emu.grasscutter.game.dungeons.dungeon_results;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonData;
|
||||
import emu.grasscutter.game.dungeons.DungeonEndStats;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
@ -9,6 +8,7 @@ import lombok.val;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.dungeon.progression.DungeonSettleNotify;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.spiral_abyss.run.ContinueStateType;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.spiral_abyss.run.TowerLevelEndNotify;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonData;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
@ -1,12 +1,12 @@
|
||||
package emu.grasscutter.game.dungeons.dungeon_results;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonData;
|
||||
import emu.grasscutter.game.dungeons.DungeonEndStats;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import lombok.Builder;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.activity.trial.TrialAvatarFirstPassDungeonNotify;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.dungeon.progression.DungeonSettleNotify;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonData;
|
||||
|
||||
public class TrialAvatarDungeonResult extends BaseDungeonResult {
|
||||
int trialCharacterIndexId;
|
||||
|
@ -1,7 +0,0 @@
|
||||
package emu.grasscutter.game.dungeons.enums;
|
||||
|
||||
public enum DungeonInvolveType {
|
||||
INVOLVE_NONE,
|
||||
INVOLVE_ONLY_SINGLE,
|
||||
INVOLVE_SINGLE_MULTIPLE
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package emu.grasscutter.game.dungeons.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.anime_game_servers.core.base.interfaces.IntValueEnum;
|
||||
|
||||
public enum DungeonPassConditionType implements IntValueEnum {
|
||||
DUNGEON_COND_NONE(0),
|
||||
DUNGEON_COND_KILL_MONSTER(3),
|
||||
DUNGEON_COND_KILL_GROUP_MONSTER(5),
|
||||
DUNGEON_COND_KILL_TYPE_MONSTER(7),
|
||||
DUNGEON_COND_FINISH_QUEST(9),
|
||||
DUNGEON_COND_KILL_MONSTER_COUNT(11), // TODO handle count
|
||||
DUNGEON_COND_IN_TIME(13), // Missing triggers and tracking
|
||||
DUNGEON_COND_FINISH_CHALLENGE(14),
|
||||
DUNGEON_COND_END_MULTISTAGE_PLAY(15) // Missing
|
||||
;
|
||||
|
||||
@Getter private final int id;
|
||||
DungeonPassConditionType(int id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getValue() {
|
||||
return id;
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package emu.grasscutter.game.dungeons.enums;
|
||||
public enum DungeonPlayType {
|
||||
DUNGEON_PLAY_TYPE_NONE,
|
||||
DUNGEON_PLAY_TYPE_FOGGY_MAZE,
|
||||
DUNGEON_PLAY_TYPE_MIST_TRIAL,
|
||||
DUNGEON_PLAY_TYPE_TRIAL_AVATAR
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package emu.grasscutter.game.dungeons.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public enum DungeonType {
|
||||
DUNGEON_NONE(false),
|
||||
DUNGEON_PLOT(true),
|
||||
DUNGEON_FIGHT(true),
|
||||
DUNGEON_DAILY_FIGHT(false),
|
||||
DUNGEON_WEEKLY_FIGHT(true),
|
||||
DUNGEON_DISCARDED(false),
|
||||
DUNGEON_TOWER(false),
|
||||
DUNGEON_BOSS(true),
|
||||
DUNGEON_ACTIVITY(false),
|
||||
DUNGEON_EFFIGY(false),
|
||||
DUNGEON_ELEMENT_CHALLENGE(true),
|
||||
DUNGEON_THEATRE_MECHANICUS(false),
|
||||
DUNGEON_FLEUR_FAIR(false),
|
||||
DUNGEON_CHANNELLER_SLAB_LOOP(false),
|
||||
DUNGEON_CHANNELLER_SLAB_ONE_OFF(false),
|
||||
DUNGEON_BLITZ_RUSH(true),
|
||||
DUNGEON_CHESS(false),
|
||||
DUNGEON_SUMO_COMBAT(false),
|
||||
DUNGEON_ROGUELIKE(false),
|
||||
DUNGEON_HACHI(false),
|
||||
DUNGEON_POTION(false),
|
||||
DUNGEON_MINI_ELDRITCH(false),
|
||||
DUNGEON_UGC(false),
|
||||
DUNGEON_GCG(false),
|
||||
DUNGEON_CRYSTAL_LINK(false),
|
||||
DUNGEON_IRODORI_CHESS(false),
|
||||
DUNGEON_ROGUE_DIARY(false),
|
||||
DUNGEON_DREAMLAND(false),
|
||||
DUNGEON_SUMMER_V2(true),
|
||||
DUNGEON_MUQADAS_POTION(false),
|
||||
DUNGEON_INSTABLE_SPRAY(false),
|
||||
DUNGEON_WIND_FIELD(false),
|
||||
DUNGEON_BIGWORLD_MIRROR(false),
|
||||
DUNGEON_FUNGUS_FIGHTER_TRAINING(false),
|
||||
DUNGEON_FUNGUS_FIGHTER_PLOT(false),
|
||||
DUNGEON_EFFIGY_CHALLENGE_V2(false),
|
||||
DUNGEON_CHAR_AMUSEMENT(false);
|
||||
|
||||
@Getter private final boolean countsToBattlepass;
|
||||
|
||||
DungeonType(boolean countsToBattlepass){
|
||||
this.countsToBattlepass = countsToBattlepass;
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package emu.grasscutter.game.dungeons.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public enum SettleShowType {
|
||||
SETTLE_SHOW_NONE(0),
|
||||
SETTLE_SHOW_TIME_COST(1),
|
||||
SETTLE_SHOW_OPEN_CHEST_COUNT(2),
|
||||
SETTLE_SHOW_KILL_MONSTER_COUNT(3),
|
||||
SETTLE_SHOW_BLACKSCREEN(4);
|
||||
|
||||
@Getter private final int id;
|
||||
|
||||
SettleShowType(int id){
|
||||
this.id = id;
|
||||
}
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
package emu.grasscutter.game.dungeons.handlers;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonPassConfigData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
|
||||
public abstract class DungeonBaseHandler {
|
||||
|
||||
public abstract boolean execute(DungeonPassConfigData.DungeonPassCondition condition, int... params);
|
||||
public abstract boolean execute(DungeonPassData.DungeonPassCondition condition, int... params);
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
package emu.grasscutter.game.dungeons.pass_condition;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonPassConfigData;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.dungeons.DungeonValue;
|
||||
import emu.grasscutter.game.dungeons.handlers.DungeonBaseHandler;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
|
||||
@DungeonValue(DungeonPassConditionType.DUNGEON_COND_NONE)
|
||||
public class BaseCondition extends DungeonBaseHandler {
|
||||
|
||||
@Override
|
||||
public boolean execute(DungeonPassConfigData.DungeonPassCondition condition, int... params) {
|
||||
public boolean execute(DungeonPassData.DungeonPassCondition condition, int... params) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
package emu.grasscutter.game.dungeons.pass_condition;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonPassConfigData;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.dungeons.DungeonValue;
|
||||
import emu.grasscutter.game.dungeons.handlers.DungeonBaseHandler;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
|
||||
@DungeonValue(DungeonPassConditionType.DUNGEON_COND_FINISH_CHALLENGE)
|
||||
public class ConditionFinishChallenge extends DungeonBaseHandler {
|
||||
|
||||
@Override
|
||||
public boolean execute(DungeonPassConfigData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] == condition.getParam()[0] || params[1] == condition.getParam()[0];
|
||||
public boolean execute(DungeonPassData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] == condition.getParam().get(0) || params[1] == condition.getParam().get(0);
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
package emu.grasscutter.game.dungeons.pass_condition;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonPassConfigData;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.dungeons.DungeonValue;
|
||||
import emu.grasscutter.game.dungeons.handlers.DungeonBaseHandler;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
|
||||
@DungeonValue(DungeonPassConditionType.DUNGEON_COND_FINISH_QUEST)
|
||||
public class ConditionFinishQuest extends DungeonBaseHandler {
|
||||
|
||||
@Override
|
||||
public boolean execute(DungeonPassConfigData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] == condition.getParam()[0];
|
||||
public boolean execute(DungeonPassData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] == condition.getParam().get(0);
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
package emu.grasscutter.game.dungeons.pass_condition;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonPassConfigData;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.dungeons.DungeonValue;
|
||||
import emu.grasscutter.game.dungeons.handlers.DungeonBaseHandler;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
|
||||
@DungeonValue(DungeonPassConditionType.DUNGEON_COND_IN_TIME)
|
||||
public class ConditionInTime extends DungeonBaseHandler {
|
||||
|
||||
@Override
|
||||
public boolean execute(DungeonPassConfigData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] <= condition.getParam()[0];
|
||||
public boolean execute(DungeonPassData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] <= condition.getParam().get(0);
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
package emu.grasscutter.game.dungeons.pass_condition;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonPassConfigData;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.dungeons.DungeonValue;
|
||||
import emu.grasscutter.game.dungeons.handlers.DungeonBaseHandler;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
|
||||
@DungeonValue(DungeonPassConditionType.DUNGEON_COND_KILL_GROUP_MONSTER)
|
||||
public class ConditionKillGroupMonster extends DungeonBaseHandler {
|
||||
|
||||
@Override
|
||||
public boolean execute(DungeonPassConfigData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] == condition.getParam()[0];
|
||||
public boolean execute(DungeonPassData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] == condition.getParam().get(0);
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
package emu.grasscutter.game.dungeons.pass_condition;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonPassConfigData;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.dungeons.DungeonValue;
|
||||
import emu.grasscutter.game.dungeons.handlers.DungeonBaseHandler;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
|
||||
@DungeonValue(DungeonPassConditionType.DUNGEON_COND_KILL_MONSTER)
|
||||
public class ConditionKillMonster extends DungeonBaseHandler {
|
||||
|
||||
@Override
|
||||
public boolean execute(DungeonPassConfigData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] == condition.getParam()[0];
|
||||
public boolean execute(DungeonPassData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] == condition.getParam().get(0);
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
package emu.grasscutter.game.dungeons.pass_condition;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonPassConfigData;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.dungeons.DungeonValue;
|
||||
import emu.grasscutter.game.dungeons.handlers.DungeonBaseHandler;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
|
||||
@DungeonValue(DungeonPassConditionType.DUNGEON_COND_KILL_MONSTER_COUNT)
|
||||
public class ConditionKillMonsterCount extends DungeonBaseHandler {
|
||||
|
||||
@Override
|
||||
public boolean execute(DungeonPassConfigData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] >= condition.getParam()[0];
|
||||
public boolean execute(DungeonPassData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] >= condition.getParam().get(0);
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
package emu.grasscutter.game.dungeons.pass_condition;
|
||||
|
||||
import emu.grasscutter.data.excels.DungeonPassConfigData;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.dungeons.DungeonValue;
|
||||
import emu.grasscutter.game.dungeons.handlers.DungeonBaseHandler;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassData;
|
||||
|
||||
@DungeonValue(DungeonPassConditionType.DUNGEON_COND_KILL_TYPE_MONSTER)
|
||||
public class ConditionKillTypeMonster extends DungeonBaseHandler {
|
||||
|
||||
@Override
|
||||
public boolean execute(DungeonPassConfigData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] == condition.getParam()[0];
|
||||
public boolean execute(DungeonPassData.DungeonPassCondition condition, int... params) {
|
||||
return params[0] == condition.getParam().get(0);
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,7 @@ import emu.grasscutter.game.dungeons.dungeon_results.BaseDungeonResult;
|
||||
import emu.grasscutter.game.dungeons.dungeon_results.TrialAvatarDungeonResult;
|
||||
import emu.grasscutter.server.packet.send.PacketDungeonSettleNotify;
|
||||
import lombok.val;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static emu.grasscutter.game.props.ActivityType.NEW_ACTIVITY_TRIAL_AVATAR;
|
||||
import org.anime_game_servers.game_data_models.gi.data.activity.ActivityType;
|
||||
|
||||
public class TrialAvatarDungeonSettleListener implements DungeonSettleListener{
|
||||
@Override
|
||||
@ -24,7 +21,7 @@ public class TrialAvatarDungeonSettleListener implements DungeonSettleListener{
|
||||
.setDungeonStats(new DungeonEndStats(scene.getKilledMonsterCount(), time, 0, endReason))
|
||||
.setPlayer(hostPlayer)
|
||||
.setTrialCharacterIndexId(hostPlayer.getActivityManager()
|
||||
.getActivityHandlerAs(NEW_ACTIVITY_TRIAL_AVATAR, TrialAvatarActivityHandler.class)
|
||||
.getActivityHandlerAs(ActivityType.NEW_ACTIVITY_TRIAL_AVATAR, TrialAvatarActivityHandler.class)
|
||||
.map(TrialAvatarActivityHandler::getSelectedTrialAvatarIndex).orElse(0))
|
||||
.build()));
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package emu.grasscutter.game.entity;
|
||||
|
||||
import emu.grasscutter.GameConstants;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.AvatarData;
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigAbilityData;
|
||||
import emu.grasscutter.data.excels.AvatarSkillDepotData;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.inventory.EquipType;
|
||||
@ -261,7 +261,7 @@ public class EntityAvatar extends GameEntity {
|
||||
}
|
||||
|
||||
public AbilityControlBlock getAbilityControlBlock() {
|
||||
AvatarData data = this.getAvatar().getAvatarData();
|
||||
val data = this.getAvatar().getAvatarData();
|
||||
val abilityControlBlock = new AbilityControlBlock();
|
||||
val embryoId = new AtomicInteger(0);
|
||||
val embrioList = new ArrayList<AbilityEmbryo>();
|
||||
@ -269,8 +269,28 @@ public class EntityAvatar extends GameEntity {
|
||||
val abilities = data.getAbilities();
|
||||
// Add avatar abilities
|
||||
if (abilities != null) {
|
||||
embrioList.addAll(abilities.stream().map(id -> new AbilityEmbryo(embryoId.incrementAndGet(), id, GameConstants.DEFAULT_ABILITY_NAME)).toList());
|
||||
embrioList.addAll(abilities.intStream()
|
||||
.mapToObj(id -> new AbilityEmbryo(embryoId.incrementAndGet(), id, GameConstants.DEFAULT_ABILITY_NAME))
|
||||
.toList());
|
||||
}
|
||||
|
||||
// Add level entity abilities
|
||||
val sceneData = getScene().getSceneData();
|
||||
if(sceneData!=null) {
|
||||
val specifiedAvatars = sceneData.getSpecifiedAvatarList();
|
||||
if (specifiedAvatars == null || specifiedAvatars.isEmpty() || specifiedAvatars.contains(data.getAvatarId())){
|
||||
val config = GameData.getConfigLevelEntityDataMap().get(sceneData.getLevelEntityConfig());
|
||||
if(config != null && config.getMonsterAbilities() != null) {
|
||||
val configAbilitiesList = config.getAvatarAbilities().stream()
|
||||
.map(ConfigAbilityData::getAbilityName)
|
||||
.map(Utils::abilityHash)
|
||||
.map(id -> new AbilityEmbryo(embryoId.incrementAndGet(), id, GameConstants.DEFAULT_ABILITY_NAME))
|
||||
.toList();
|
||||
embrioList.addAll(configAbilitiesList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add default abilities
|
||||
embrioList.addAll(Arrays.stream(GameConstants.DEFAULT_ABILITY_HASHES).mapToObj(id -> new AbilityEmbryo(embryoId.incrementAndGet(), id, GameConstants.DEFAULT_ABILITY_NAME)).toList());
|
||||
// Add team resonances
|
||||
@ -281,7 +301,7 @@ public class EntityAvatar extends GameEntity {
|
||||
embrioList.addAll(skillDepot.getAbilities().stream().map(id -> new AbilityEmbryo(embryoId.incrementAndGet(), id, GameConstants.DEFAULT_ABILITY_NAME)).toList());
|
||||
}
|
||||
// Add equip abilities
|
||||
if (this.getAvatar().getExtraAbilityEmbryos().size() > 0) {
|
||||
if (!this.getAvatar().getExtraAbilityEmbryos().isEmpty()) {
|
||||
embrioList.addAll(this.getAvatar().getExtraAbilityEmbryos().stream().map(id -> new AbilityEmbryo(embryoId.incrementAndGet(), Utils.abilityHash(id), GameConstants.DEFAULT_ABILITY_NAME)).toList());
|
||||
}
|
||||
abilityControlBlock.setAbilityEmbryoList(embrioList);
|
||||
|
@ -9,7 +9,6 @@ import emu.grasscutter.data.excels.MonsterAffixData;
|
||||
import emu.grasscutter.data.excels.MonsterCurveData;
|
||||
import emu.grasscutter.data.excels.MonsterData;
|
||||
import emu.grasscutter.game.ability.AbilityManager;
|
||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||
import emu.grasscutter.game.entity.interfaces.StringAbilityEntity;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.*;
|
||||
@ -28,6 +27,7 @@ import org.anime_game_servers.multi_proto.gi.messages.gadget.GadgetInteractReq;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.ability.AbilitySyncStateInfo;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.entity.SceneWeaponInfo;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.scene.entity.*;
|
||||
import org.anime_game_servers.game_data_models.gi.data.dungeon.DungeonPassConditionType;
|
||||
import org.anime_game_servers.gi_lua.models.ScriptArgs;
|
||||
import org.anime_game_servers.gi_lua.models.constants.EventType;
|
||||
import org.anime_game_servers.gi_lua.models.scene.group.SceneGroup;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package emu.grasscutter.game.inventory;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
@ -21,6 +23,8 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.item.ItemParam;
|
||||
import org.anime_game_servers.game_data_models.gi.data.quest.GainItem;
|
||||
import org.anime_game_servers.game_data_models.gi.data.rewards.RewardData;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
@ -158,7 +162,7 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
||||
public void addItems(Collection<GameItem> items, ActionReason reason) {
|
||||
List<GameItem> changedItems = new ArrayList<>();
|
||||
for (var item : items) {
|
||||
if (item.getItemId() == 0) continue;
|
||||
if (item.getItemId() <= 0) continue;
|
||||
GameItem result = null;
|
||||
try {
|
||||
// putItem might throws exception
|
||||
@ -202,6 +206,45 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
||||
public void addItemParamDatas(Collection<ItemParamData> items, ActionReason reason) {
|
||||
addItems(items.stream().map(param -> new GameItem(param.getItemId(), param.getCount())).toList(), reason);
|
||||
}
|
||||
private Collection<GameItem> rewardDataToGameItems(RewardData rewardData){
|
||||
val rewards = new ArrayList<GameItem>(rewardData.getRewardItemList().size());
|
||||
rewards.addAll(rewardData.getRewardItemList().stream().filter(Objects::nonNull)
|
||||
.filter(gainItem -> gainItem.getItemId() > 0)
|
||||
.map(param -> new GameItem(param.getItemId(), param.getCount()))
|
||||
.toList());
|
||||
if(rewardData.getPlayerExp() != 0){
|
||||
rewards.add(new GameItem(102, rewardData.getPlayerExp()));
|
||||
}
|
||||
if(rewardData.getHcoin() > 0){
|
||||
rewards.add(new GameItem(201, rewardData.getHcoin()));
|
||||
}
|
||||
if (rewardData.getScoin() > 0) {
|
||||
rewards.add(new GameItem(202, rewardData.getScoin()));
|
||||
}
|
||||
if(rewardData.getCharacterExp() > 0) {
|
||||
rewards.add(new GameItem(101, rewardData.getCharacterExp()));
|
||||
}
|
||||
if (rewardData.getFriendshipExp() > 0) {
|
||||
rewards.add(new GameItem(105, rewardData.getFriendshipExp()));
|
||||
}
|
||||
if (rewardData.getResin() > 0) {
|
||||
rewards.add(new GameItem(106, rewardData.getResin()));
|
||||
}
|
||||
// TODO handle ITEM_USE_ADD_SELECT_ITEM and ITEM_USE_GRANT_SELECT_REWARD via index parameter
|
||||
return rewards;
|
||||
}
|
||||
public void addRewardData(RewardData rewardData, ActionReason reason) {
|
||||
val rewardItems = rewardDataToGameItems(rewardData);
|
||||
addItems(rewardItems, reason);
|
||||
}
|
||||
public List<GameItem> addRewardData(List<RewardData> rewardData, ActionReason reason) {
|
||||
val totalRewards = new ArrayList<GameItem>();
|
||||
for (val reward : rewardData) {
|
||||
totalRewards.addAll(rewardDataToGameItems(reward));
|
||||
}
|
||||
addItems(totalRewards, reason);
|
||||
return totalRewards;
|
||||
}
|
||||
|
||||
private synchronized GameItem putItem(GameItem item) {
|
||||
// Dont add items that dont have a valid item definition.
|
||||
@ -360,6 +403,9 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean payItem(GainItem costItem) {
|
||||
return this.payItem(costItem.getItemId(), costItem.getCount());
|
||||
}
|
||||
public boolean payItem(ItemParamData costItem) {
|
||||
return this.payItem(costItem.getId(), costItem.getCount());
|
||||
}
|
||||
@ -389,6 +435,19 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean payItems(GainItem[] costItems, ActionReason reason) {
|
||||
// Make sure player has requisite items
|
||||
for (var cost : costItems)
|
||||
if (this.getVirtualItemCount(cost.getItemId()) < (cost.getCount()))
|
||||
return false;
|
||||
// All costs are satisfied, now remove them all
|
||||
for (var cost : costItems) {
|
||||
this.payVirtualItem(cost.getItemId(), cost.getCount());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean payItems(Iterable<ItemParamData> costItems) {
|
||||
return this.payItems(costItems, 1, null);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package emu.grasscutter.game.managers;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.CityData;
|
||||
import emu.grasscutter.game.city.CityInfoData;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
import emu.grasscutter.game.player.BasePlayerManager;
|
||||
@ -11,6 +10,7 @@ import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||
import emu.grasscutter.utils.Language;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.Retcode;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.scene.entity.ChangeHpReason;
|
||||
import org.anime_game_servers.multi_proto.gi.messages.general.PropChangeReason;
|
||||
@ -20,14 +20,17 @@ import emu.grasscutter.server.packet.send.PacketSceneForceUnlockNotify;
|
||||
import lombok.val;
|
||||
import emu.grasscutter.server.packet.send.PacketLevelupCityRsp;
|
||||
|
||||
import org.anime_game_servers.game_data_models.gi.data.city.CityData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.city.CityLevelUpData;
|
||||
import org.anime_game_servers.gi_lua.models.ScriptArgs;
|
||||
import org.anime_game_servers.gi_lua.models.constants.EventType;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.*;
|
||||
|
||||
// Statue of the Seven Manager
|
||||
/*
|
||||
* Manages the Statue of the Seven and CityLevel
|
||||
*/
|
||||
public class SotSManager extends BasePlayerManager {
|
||||
|
||||
// NOTE: Spring volume balance *1 = fight prop HP *100
|
||||
@ -112,7 +115,8 @@ public class SotSManager extends BasePlayerManager {
|
||||
if (isAlive) {
|
||||
return;
|
||||
}
|
||||
logger.trace("Reviving avatar " + entity.getAvatar().getAvatarData().getName());
|
||||
val name = entity.getAvatar().getAvatarData().getBaseName();
|
||||
logger.trace("Reviving avatar {}", name);
|
||||
player.getTeamManager().reviveAvatar(entity.getAvatar());
|
||||
player.getTeamManager().healAvatar(entity.getAvatar(), 30, 0);
|
||||
});
|
||||
@ -165,7 +169,8 @@ public class SotSManager extends BasePlayerManager {
|
||||
setCurrentVolume(0);
|
||||
}
|
||||
if (needHP > 0) {
|
||||
logger.trace("Healing avatar " + entity.getAvatar().getAvatarData().getName() + " +" + needHP);
|
||||
val name = entity.getAvatar().getAvatarData().getBaseName();
|
||||
logger.trace("Healing avatar {} + {}", name, needHP);
|
||||
player.getTeamManager().healAvatar(entity.getAvatar(), 0, needHP);
|
||||
player.getSession().send(new PacketEntityFightPropChangeReasonNotify(entity, FightProperty.FIGHT_PROP_CUR_HP,
|
||||
((float) needHP / 100), List.of(3), PropChangeReason.PROP_CHANGE_STATUE_RECOVER,
|
||||
@ -200,9 +205,11 @@ public class SotSManager extends BasePlayerManager {
|
||||
}
|
||||
}
|
||||
|
||||
// City/Statue level handling
|
||||
|
||||
public CityData getCityByAreaId(int areaId) {
|
||||
return GameData.getCityDataMap().values().stream()
|
||||
.filter(city -> city.getAreaIdVec().contains(areaId))
|
||||
.filter(city -> city.getAreaIds().contains(areaId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
@ -228,62 +235,107 @@ public class SotSManager extends BasePlayerManager {
|
||||
|
||||
// search city by areaId
|
||||
var city = this.getCityByAreaId(areaId);
|
||||
if (city == null) return;
|
||||
if (city == null) return; // TODO return error to allow sending packet with error
|
||||
var cityId = city.getCityId();
|
||||
|
||||
// check data level up
|
||||
var cityInfo = this.getCityInfo(cityId);
|
||||
var nextStatuePromoteData = GameData.getStatuePromoteData(cityId, cityInfo.getLevel() + 1);
|
||||
if (nextStatuePromoteData == null) return;
|
||||
var nextLevelCrystal = nextStatuePromoteData.getCostItems()[0].getCount();
|
||||
|
||||
// delete item from inventory
|
||||
var itemNumrequired = Math.min(itemNum, nextLevelCrystal - cityInfo.getNumCrystal());
|
||||
player
|
||||
.getInventory()
|
||||
.removeItemById(nextStatuePromoteData.getCostItems()[0].getId(), itemNumrequired);
|
||||
val completedLevels = new ArrayList<CityLevelUpData>();
|
||||
var level = cityInfo.getLevel();
|
||||
var prevCrystalProgress = cityInfo.getNumCrystal();
|
||||
var itemCountLeft = itemNum;
|
||||
var crystalProgress = 0;
|
||||
while(level<10 && itemCountLeft > 0){
|
||||
val nextLevelUpData = GameData.getCityLevelUpData(cityId, level + 1);
|
||||
if(nextLevelUpData == null || nextLevelUpData.getConsumeItem() == null){
|
||||
break;
|
||||
}
|
||||
|
||||
val cost = nextLevelUpData.getConsumeItem().getCount() - prevCrystalProgress;
|
||||
|
||||
// TODO properly include already added oculi for the cost calculations
|
||||
// player might not want to level up all he can
|
||||
if(cost > itemCountLeft){
|
||||
// pay the rest the payer wanted to offer
|
||||
if(getPlayer().getInventory().payItem(nextLevelUpData.getConsumeItem().getItemId(), itemCountLeft)){
|
||||
crystalProgress = itemCountLeft + prevCrystalProgress;
|
||||
itemCountLeft = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(getPlayer().getInventory().payItem(nextLevelUpData.getConsumeItem().getItemId(), cost)){
|
||||
completedLevels.add(nextLevelUpData);
|
||||
level++;
|
||||
itemCountLeft -= cost;
|
||||
prevCrystalProgress = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update number oculi
|
||||
cityInfo.setNumCrystal(cityInfo.getNumCrystal() + itemNumrequired);
|
||||
cityInfo.setNumCrystal(crystalProgress);
|
||||
cityInfo.setLevel(level);
|
||||
|
||||
// hanble quest
|
||||
if (itemNumrequired >= 1)
|
||||
player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_CITY_LEVEL_UP, cityId, areaId);
|
||||
|
||||
// handle oculi overflow
|
||||
if (cityInfo.getNumCrystal() >= nextLevelCrystal) {
|
||||
cityInfo.setNumCrystal(cityInfo.getNumCrystal() - nextLevelCrystal);
|
||||
cityInfo.setLevel(cityInfo.getLevel() + 1);
|
||||
|
||||
// update max stamina and notify client
|
||||
player.setProperty(
|
||||
PlayerProperty.PROP_MAX_STAMINA,
|
||||
player.getProperty(PlayerProperty.PROP_MAX_STAMINA)
|
||||
+ nextStatuePromoteData.getStamina() * 100,
|
||||
true);
|
||||
|
||||
// Add items to inventory
|
||||
if (nextStatuePromoteData.getRewardIdList() != null) {
|
||||
for (var rewardId : nextStatuePromoteData.getRewardIdList()) {
|
||||
val rewardData = GameData.getRewardDataMap().get(rewardId);
|
||||
if (rewardData == null) continue;
|
||||
|
||||
player
|
||||
.getInventory()
|
||||
.addItemParamDatas(rewardData.getRewardItemList(), ActionReason.CityLevelupReward);
|
||||
completedLevels.forEach(levelData -> {
|
||||
// update player properties
|
||||
val reward = GameData.getRewardDataMap().get(levelData.getRewardId());
|
||||
if(reward != null){
|
||||
getPlayer().getInventory().addRewardData(reward, ActionReason.CityLevelupReward);
|
||||
}
|
||||
if(levelData.getActions()!=null) {
|
||||
handleLevelUpActions(levelData.getActions());
|
||||
}
|
||||
|
||||
// unlock forcescene
|
||||
player.sendPacket(new PacketSceneForceUnlockNotify(1, true));
|
||||
}
|
||||
});
|
||||
|
||||
// update data
|
||||
this.addCityInfo(cityInfo);
|
||||
|
||||
|
||||
handleLevelUpEvents(cityId, level);
|
||||
|
||||
// Packets
|
||||
player.sendPacket(
|
||||
new PacketLevelupCityRsp(
|
||||
sceneId, cityInfo.getLevel(), cityId, cityInfo.getNumCrystal(), areaId, Retcode.RET_SUCC));
|
||||
sceneId, level, cityId, crystalProgress, areaId, Retcode.RET_SUCC));
|
||||
}
|
||||
|
||||
private void handleLevelUpActions(List<CityLevelUpData.CityLevelUpAction> actions){
|
||||
actions.forEach(action -> {
|
||||
if(action.getType() == null) return;
|
||||
switch (action.getType()) {
|
||||
case WORLD_AREA_ACTION_IMPROVE_STAMINA -> {
|
||||
if (action.getParam1() == null || action.getParam1().isEmpty()) {
|
||||
break;
|
||||
}
|
||||
// update max stamina and notify client
|
||||
getPlayer().setProperty(
|
||||
PlayerProperty.PROP_MAX_STAMINA,
|
||||
getPlayer().getProperty(PlayerProperty.PROP_MAX_STAMINA)
|
||||
+ action.getParam1().get(0) * 100,
|
||||
true);
|
||||
}
|
||||
case WORLD_AREA_ACTION_UNLOCK_FORCE -> {
|
||||
if (action.getParam1() == null || action.getParam1().isEmpty()) {
|
||||
break;
|
||||
}
|
||||
// this might need to be persisted
|
||||
getPlayer().getScene().unlockForce(action.getParam1().get(0));
|
||||
}
|
||||
case WORLD_AREA_ACTION_ACTIVATE_ITEM -> {
|
||||
// TODO: implement
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handleLevelUpEvents(int cityId, int level) {
|
||||
player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_CITY_LEVEL_UP, cityId, level);
|
||||
player.getScene().getScriptManager().callEvent(new ScriptArgs(0, EventType.EVENT_CITY_LEVELUP, cityId, level));
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import org.anime_game_servers.multi_proto.gi.messages.blossom.BlossomScheduleInf
|
||||
import emu.grasscutter.scripts.ScriptSystem;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import lombok.*;
|
||||
import org.anime_game_servers.game_data_models.gi.data.city.CityData;
|
||||
import org.anime_game_servers.game_data_models.gi.data.world.WorldLevelData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -183,11 +183,12 @@ public class EnergyManager extends BasePlayerManager {
|
||||
// - Does this really count every individual hit separately?
|
||||
|
||||
// Get the avatar's weapon type.
|
||||
WeaponType weaponType = avatar.getAvatar().getAvatarData().getWeaponType();
|
||||
val weaponType = avatar.getAvatar().getAvatarData().getWeaponType();
|
||||
val weaponTypeGC = WeaponType.getTypeByName(weaponType.name());
|
||||
|
||||
// Check if we already have probability data for this avatar. If not, insert it.
|
||||
if (!this.avatarNormalProbabilities.containsKey(avatar)) {
|
||||
this.avatarNormalProbabilities.put(avatar, weaponType.getEnergyGainInitialProbability());
|
||||
this.avatarNormalProbabilities.put(avatar, weaponTypeGC.getEnergyGainInitialProbability());
|
||||
}
|
||||
|
||||
// Roll for energy.
|
||||
@ -197,11 +198,11 @@ public class EnergyManager extends BasePlayerManager {
|
||||
// If the player wins the roll, we increase the avatar's energy and reset the probability.
|
||||
if (roll < currentProbability) {
|
||||
avatar.addEnergy(1.0f, PropChangeReason.PROP_CHANGE_ABILITY, true);
|
||||
this.avatarNormalProbabilities.put(avatar, weaponType.getEnergyGainInitialProbability());
|
||||
this.avatarNormalProbabilities.put(avatar, weaponTypeGC.getEnergyGainInitialProbability());
|
||||
}
|
||||
// Otherwise, we increase the probability for the next hit.
|
||||
else {
|
||||
this.avatarNormalProbabilities.put(avatar, currentProbability + weaponType.getEnergyGainIncreaseProbability());
|
||||
this.avatarNormalProbabilities.put(avatar, currentProbability + weaponTypeGC.getEnergyGainIncreaseProbability());
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user