Refactor GameData, remove deprecated getGsonFactory

- Fix day-of-week dungeons
- AvatarSkill max level enforcement from excels
- Partial fix to bonus levels (need packet on talent update)
This commit is contained in:
AnimeGitB
2022-10-13 18:31:34 +10:30
parent bb342f9114
commit 4e75361ad4
14 changed files with 137 additions and 145 deletions

View File

@@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.*;
@@ -16,6 +17,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.ints.IntSet;
import lombok.Getter;
import lombok.experimental.Tolerate;
@@ -26,7 +28,8 @@ public class GameData {
@Getter private static final Map<String, AbilityModifierEntry> abilityModifiers = new HashMap<>();
@Getter private static final Map<String, ConfigGadget> gadgetConfigData = new HashMap<>();
@Getter private static final Map<String, OpenConfigEntry> openConfigEntries = new HashMap<>();
@Getter private static final Map<String, ScenePointEntry> scenePointEntries = new HashMap<>();
@Deprecated(forRemoval = true) @Getter private static final Map<String, ScenePointEntry> scenePointEntries = new HashMap<>();
protected static final Int2ObjectMap<ScenePointEntry> scenePointEntryMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<MainQuestData> mainQuestData = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<QuestEncryptionKey> questsKeys = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<SceneNpcBornData> npcBornData = new Int2ObjectOpenHashMap<>();
@@ -118,6 +121,8 @@ public class GameData {
@Getter private static final Map<String, ScriptSceneData> scriptSceneDataMap = new HashMap<>();
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
protected static Int2ObjectMap<IntSet> proudSkillGroupLevels = new Int2ObjectOpenHashMap<>();
protected static Int2ObjectMap<IntSet> avatarSkillLevels = new Int2ObjectOpenHashMap<>();
// Getters with wrong names, remove later
@Deprecated(forRemoval = true) public static Int2ObjectMap<CodexReliquaryData> getcodexReliquaryIdMap() {return codexReliquaryDataIdMap;}
@@ -130,7 +135,42 @@ public class GameData {
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 IntSet getAvatarSkillLevels(int avatarSkillId) {return avatarSkillLevels.get(avatarSkillId);}
public static IntSet getProudSkillGroupLevels(int proudSkillGroupId) {return proudSkillGroupLevels.get(proudSkillGroupId);}
// Multi-keyed getters
public static AvatarPromoteData getAvatarPromoteData(int promoteId, int promoteLevel) {
return avatarPromoteDataMap.get((promoteId << 8) + promoteLevel);
}
public static WeaponPromoteData getWeaponPromoteData(int promoteId, int promoteLevel) {
return weaponPromoteDataMap.get((promoteId << 8) + promoteLevel);
}
public static ReliquaryLevelData getRelicLevelData(int rankLevel, int level) {
return reliquaryLevelDataMap.get((rankLevel << 8) + level);
}
public static ScenePointEntry getScenePointEntryById(int sceneId, int pointId) {
return scenePointEntryMap.get((sceneId << 16) + pointId);
}
// Non-nullable value getters
public static int getAvatarLevelExpRequired(int level) {
return Optional.ofNullable(avatarLevelDataMap.get(level)).map(d -> d.getExp()).orElse(0);
}
public static int getAvatarFetterLevelExpRequired(int level) {
return Optional.ofNullable(avatarFetterLevelDataMap.get(level)).map(d -> d.getExp()).orElse(0);
}
public static int getRelicExpRequired(int rankLevel, int level) {
return Optional.ofNullable(getRelicLevelData(rankLevel, level)).map(d -> d.getExp()).orElse(0);
}
// Generic getter
public static Int2ObjectMap<?> getMapByResourceDef(Class<?> resourceDefinition) {
Int2ObjectMap<?> map = null;
@@ -149,24 +189,6 @@ public class GameData {
// TODO optimize
public static ScenePointEntry getScenePointEntryById(int sceneId, int pointId) {
return getScenePointEntries().get(sceneId + "_" + pointId);
}
public static int getRelicExpRequired(int rankLevel, int level) {
ReliquaryLevelData levelData = reliquaryLevelDataMap.get((rankLevel << 8) + level);
return levelData != null ? levelData.getExp() : 0;
}
public static ReliquaryLevelData getRelicLevelData(int rankLevel, int level) {
return reliquaryLevelDataMap.get((rankLevel << 8) + level);
}
public static WeaponPromoteData getWeaponPromoteData(int promoteId, int promoteLevel) {
return weaponPromoteDataMap.get((promoteId << 8) + promoteLevel);
}
public static int getWeaponExpRequired(int rankLevel, int level) {
WeaponLevelData levelData = weaponLevelDataMap.get(level);
if (levelData == null) {
@@ -179,21 +201,6 @@ public class GameData {
}
}
public static AvatarPromoteData getAvatarPromoteData(int promoteId, int promoteLevel) {
return avatarPromoteDataMap.get((promoteId << 8) + promoteLevel);
}
public static int getAvatarLevelExpRequired(int level) {
AvatarLevelData levelData = avatarLevelDataMap.get(level);
return levelData != null ? levelData.getExp() : 0;
}
public static int getAvatarFetterLevelExpRequired(int level) {
AvatarFetterLevelData levelData = avatarFetterLevelDataMap.get(level);
return levelData != null ? levelData.getExp() : 0;
}
public static Map<Integer, List<Integer>> getFetterDataEntries() {
if (fetters.isEmpty()) {
fetterDataMap.forEach((k, v) -> {

View File

@@ -1,13 +1,11 @@
package emu.grasscutter.data;
import com.google.gson.JsonElement;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.*;
import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData;
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierActionType;
import emu.grasscutter.data.common.PointData;
import emu.grasscutter.data.common.ScenePointConfig;
import emu.grasscutter.game.managers.blossom.BlossomConfig;
import emu.grasscutter.game.quest.QuestEncryptionKey;
import emu.grasscutter.game.world.SpawnDataEntry;
@@ -16,6 +14,8 @@ import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
import emu.grasscutter.scripts.SceneIndexManager;
import emu.grasscutter.utils.JsonUtils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntArraySet;
import lombok.val;
import org.reflections.Reflections;
@@ -75,6 +75,7 @@ public class ResourceLoader {
loadHomeworldDefaultSaveData();
loadNpcBornData();
loadBlossomResources();
cacheTalentLevelSets();
Grasscutter.getLogger().info(translate("messages.status.resources.finish"));
loadedAll = true;
@@ -129,6 +130,9 @@ public class ResourceLoader {
}
}
public class ScenePointConfig { // Sadly this doesn't work as a local class in loadScenePoints()
public Map<Integer, PointData> points;
}
private static void loadScenePoints() {
val pattern = Pattern.compile("scene([0-9]+)_point\\.json");
try {
@@ -136,8 +140,8 @@ public class ResourceLoader {
val matcher = pattern.matcher(path.getFileName().toString());
if (!matcher.find()) return;
int sceneId = Integer.parseInt(matcher.group(1));
ScenePointConfig config;
ScenePointConfig config;
try {
config = JsonUtils.loadToClass(path, ScenePointConfig.class);
} catch (Exception e) {
@@ -147,20 +151,18 @@ public class ResourceLoader {
if (config.points == null) return;
List<Integer> scenePoints = new ArrayList<>();
for (Map.Entry<String, JsonElement> entry : config.points.entrySet()) {
String key = entry.getKey();
String name = sceneId + "_" + key;
int id = Integer.parseInt(key);
PointData pointData = JsonUtils.decode(entry.getValue(), PointData.class);
pointData.setId(id);
val scenePoints = new IntArrayList();
config.points.forEach((pointId, pointData) -> {
val scenePoint = new ScenePointEntry(sceneId, pointData);
scenePoints.add(pointId);
pointData.setId(pointId);
GameData.getScenePointIdList().add(id);
GameData.getScenePointEntries().put(name, new ScenePointEntry(name, pointData));
scenePoints.add(id);
GameData.getScenePointIdList().add(pointId);
GameData.getScenePointEntries().put(scenePoint.getName(), scenePoint);
GameData.scenePointEntryMap.put((sceneId << 16) + pointId, scenePoint);
pointData.updateDailyDungeon();
}
});
GameData.getScenePointsPerScene().put(sceneId, scenePoints);
});
} catch (IOException e) {
@@ -169,6 +171,15 @@ public class ResourceLoader {
}
}
private static void cacheTalentLevelSets() {
GameData.getProudSkillDataMap().forEach((id, data) ->
GameData.proudSkillGroupLevels
.computeIfAbsent(data.getProudSkillGroupId(), i -> new IntArraySet())
.add(data.getLevel()));
GameData.getAvatarSkillDataMap().forEach((id, data) ->
GameData.avatarSkillLevels.put((int) id, GameData.proudSkillGroupLevels.get(data.getProudSkillGroupId())));
}
private static void loadAbilityEmbryos() {
List<AbilityEmbryoEntry> embryoList = null;

View File

@@ -1,21 +1,24 @@
package emu.grasscutter.data.binout;
import emu.grasscutter.data.common.PointData;
import lombok.Getter;
public class ScenePointEntry {
private String name;
private PointData pointData;
public ScenePointEntry(String name, PointData pointData) {
this.name = name;
this.pointData = pointData;
}
@Getter final private int sceneId;
@Getter final private PointData pointData;
public String getName() {
return name;
}
@Deprecated(forRemoval = true)
public ScenePointEntry(String name, PointData pointData) {
this.sceneId = Integer.parseInt(name.split("_")[0]);
this.pointData = pointData;
}
public PointData getPointData() {
return pointData;
public ScenePointEntry(int sceneId, PointData pointData) {
this.sceneId = sceneId;
this.pointData = pointData;
}
public String getName() {
return this.sceneId + "_" + this.pointData.getId();
}
}

View File

@@ -5,71 +5,44 @@ import com.google.gson.annotations.SerializedName;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.DailyDungeonData;
import emu.grasscutter.utils.JsonUtils;
import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter;
import lombok.Setter;
public class PointData {
private int id;
@Getter @Setter private int id;
private String $type;
private Position tranPos;
@Getter private Position tranPos;
@SerializedName(value="dungeonIds", alternate={"JHHFPGJNMIN"})
private int[] dungeonIds;
@Getter private int[] dungeonIds;
@SerializedName(value="dungeonRandomList", alternate={"OIBKFJNBLHO"})
private int[] dungeonRandomList;
@Getter private int[] dungeonRandomList;
@SerializedName(value="tranSceneId", alternate={"JHBICGBAPIH"})
private int tranSceneId;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Getter @Setter private int tranSceneId;
public String getType() {
return $type;
}
public Position getTranPos() {
return tranPos;
}
public int[] getDungeonIds() {
return dungeonIds;
}
public int[] getDungeonRandomList() {
return dungeonRandomList;
}
public int getTranSceneId() {
return tranSceneId;
}
public void setTranSceneId(int tranSceneId) {
this.tranSceneId = tranSceneId;
}
public void updateDailyDungeon() {
if (getDungeonRandomList() == null || getDungeonRandomList().length == 0) {
if (this.dungeonRandomList == null || this.dungeonRandomList.length == 0) {
return;
}
IntList newDungeons = new IntArrayList();
int day = Grasscutter.getCurrentDayOfWeek();
for (int randomId : getDungeonRandomList()) {
for (int randomId : this.dungeonRandomList) {
DailyDungeonData data = GameData.getDailyDungeonDataMap().get(randomId);
if (data != null) {
int[] addDungeons = data.getDungeonsByDay(day);
for (int d : addDungeons) {
for (int d : data.getDungeonsByDay(day)) {
newDungeons.add(d);
}
}

View File

@@ -1,15 +0,0 @@
package emu.grasscutter.data.common;
import com.google.gson.JsonObject;
public class ScenePointConfig {
public JsonObject points;
public JsonObject getPoints() {
return points;
}
public void setPoints(JsonObject Points) {
points = Points;
}
}

View File

@@ -2,11 +2,9 @@ package emu.grasscutter.data.excels;
import java.util.Calendar;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.props.SceneType;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;