Skip to content
Snippets Groups Projects
Commit ac49114c authored by Melledy's avatar Melledy
Browse files

Add embryos for all skill depots for the main characters

parent fa4b768d
Branches
Tags
No related merge requests found
Showing with 214 additions and 44 deletions
...@@ -77,6 +77,7 @@ public class GameData { ...@@ -77,6 +77,7 @@ public class GameData {
private static final ArrayList<CodexReliquaryData> codexReliquaryArrayList = new ArrayList<>(); private static final ArrayList<CodexReliquaryData> codexReliquaryArrayList = new ArrayList<>();
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<WorldAreaData> worldAreaDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
...@@ -319,6 +320,10 @@ public class GameData { ...@@ -319,6 +320,10 @@ public class GameData {
public static ArrayList<CodexReliquaryData> getcodexReliquaryArrayList(){return codexReliquaryArrayList;} public static ArrayList<CodexReliquaryData> getcodexReliquaryArrayList(){return codexReliquaryArrayList;}
public static Int2ObjectMap<WorldAreaData> getWorldAreaDataMap() {
return worldAreaDataMap;
}
public static Int2ObjectMap<WorldLevelData> getWorldLevelDataMap() { public static Int2ObjectMap<WorldLevelData> getWorldLevelDataMap() {
return worldLevelDataMap; return worldLevelDataMap;
} }
......
package emu.grasscutter.data; package emu.grasscutter.data;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.danilopianini.util.FlexibleQuadTree; import org.danilopianini.util.FlexibleQuadTree;
import org.danilopianini.util.SpatialIndex; import org.danilopianini.util.SpatialIndex;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.ResourceLoader.AvatarConfig;
import emu.grasscutter.data.ResourceLoader.AvatarConfigAbility;
import emu.grasscutter.data.excels.ReliquaryAffixData; import emu.grasscutter.data.excels.ReliquaryAffixData;
import emu.grasscutter.data.excels.ReliquaryMainPropData; import emu.grasscutter.data.excels.ReliquaryMainPropData;
import emu.grasscutter.game.world.SpawnDataEntry; import emu.grasscutter.game.world.SpawnDataEntry;
...@@ -19,6 +23,7 @@ public class GameDepot { ...@@ -19,6 +23,7 @@ public class GameDepot {
private static Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicMainPropDepot = new Int2ObjectOpenHashMap<>(); private static Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicMainPropDepot = new Int2ObjectOpenHashMap<>();
private static Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot = new Int2ObjectOpenHashMap<>(); private static Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot = new Int2ObjectOpenHashMap<>();
private static Map<String, AvatarConfig> playerAbilities = new HashMap<>();
private static Int2ObjectMap<SpatialIndex<SpawnGroupEntry>> spawnLists = new Int2ObjectOpenHashMap<>(); private static Int2ObjectMap<SpatialIndex<SpawnGroupEntry>> spawnLists = new Int2ObjectOpenHashMap<>();
public static void load() { public static void load() {
...@@ -61,4 +66,12 @@ public class GameDepot { ...@@ -61,4 +66,12 @@ public class GameDepot {
public static SpatialIndex<SpawnGroupEntry> getSpawnListById(int sceneId) { public static SpatialIndex<SpawnGroupEntry> getSpawnListById(int sceneId) {
return getSpawnLists().computeIfAbsent(sceneId, id -> new FlexibleQuadTree<>()); return getSpawnLists().computeIfAbsent(sceneId, id -> new FlexibleQuadTree<>());
} }
public static Map<String, AvatarConfig> getPlayerAbilities() {
return playerAbilities;
}
public static void setPlayerAbilities(Map<String, AvatarConfig> playerAbilities) {
GameDepot.playerAbilities = playerAbilities;
}
} }
...@@ -66,37 +66,6 @@ public class ResourceLoader { ...@@ -66,37 +66,6 @@ public class ResourceLoader {
loadQuests(); loadQuests();
// Load scene points - must be done AFTER resources are loaded // Load scene points - must be done AFTER resources are loaded
loadScenePoints(); loadScenePoints();
// Custom - TODO move this somewhere else
try {
GameData.getAvatarSkillDepotDataMap().get(504).setAbilities(
new AbilityEmbryoEntry(
"",
new String[] {
"Avatar_PlayerBoy_ExtraAttack_Wind",
"Avatar_Player_UziExplode_Mix",
"Avatar_Player_UziExplode",
"Avatar_Player_UziExplode_Strike_01",
"Avatar_Player_UziExplode_Strike_02",
"Avatar_Player_WindBreathe",
"Avatar_Player_WindBreathe_CameraController"
}
));
GameData.getAvatarSkillDepotDataMap().get(704).setAbilities(
new AbilityEmbryoEntry(
"",
new String[] {
"Avatar_PlayerGirl_ExtraAttack_Wind",
"Avatar_Player_UziExplode_Mix",
"Avatar_Player_UziExplode",
"Avatar_Player_UziExplode_Strike_01",
"Avatar_Player_UziExplode_Strike_02",
"Avatar_Player_WindBreathe",
"Avatar_Player_WindBreathe_CameraController"
}
));
} catch (Exception e) {
Grasscutter.getLogger().error("Error loading abilities", e);
}
} }
public static void loadResources() { public static void loadResources() {
...@@ -244,6 +213,16 @@ public class ResourceLoader { ...@@ -244,6 +213,16 @@ public class ResourceLoader {
AbilityEmbryoEntry al = new AbilityEmbryoEntry(avatarName, config.abilities.stream().map(Object::toString).toArray(size -> new String[s])); AbilityEmbryoEntry al = new AbilityEmbryoEntry(avatarName, config.abilities.stream().map(Object::toString).toArray(size -> new String[s]));
embryoList.add(al); embryoList.add(al);
} }
File playerElementsFile = new File(Utils.toFilePath(RESOURCE("BinOutput/AbilityGroup/AbilityGroup_Other_PlayerElementAbility.json")));
if (playerElementsFile.exists()) {
try (FileReader fileReader = new FileReader(playerElementsFile)) {
GameDepot.setPlayerAbilities(Grasscutter.getGsonFactory().fromJson(fileReader, new TypeToken<Map<String, AvatarConfig>>(){}.getType()));
} catch (Exception e) {
e.printStackTrace();
}
}
} }
if (embryoList == null || embryoList.isEmpty()) { if (embryoList == null || embryoList.isEmpty()) {
...@@ -417,16 +396,17 @@ public class ResourceLoader { ...@@ -417,16 +396,17 @@ public class ResourceLoader {
// BinOutput configs // BinOutput configs
private static class AvatarConfig { public static class AvatarConfig {
@SerializedName(value="abilities", alternate={"targetAbilities"})
public ArrayList<AvatarConfigAbility> abilities; public ArrayList<AvatarConfigAbility> abilities;
}
private static class AvatarConfigAbility { public static class AvatarConfigAbility {
public String abilityName; public String abilityName;
public String toString() { public String toString() {
return abilityName; return abilityName;
} }
} }
}
private static class OpenConfig { private static class OpenConfig {
public OpenConfigData[] data; public OpenConfigData[] data;
......
...@@ -3,7 +3,10 @@ package emu.grasscutter.data.excels; ...@@ -3,7 +3,10 @@ package emu.grasscutter.data.excels;
import java.util.List; import java.util.List;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameDepot;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceLoader.AvatarConfig;
import emu.grasscutter.data.ResourceLoader.AvatarConfigAbility;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.ResourceType.LoadPriority; import emu.grasscutter.data.ResourceType.LoadPriority;
import emu.grasscutter.data.binout.AbilityEmbryoEntry; import emu.grasscutter.data.binout.AbilityEmbryoEntry;
...@@ -95,12 +98,21 @@ public class AvatarSkillDepotData extends GameResource { ...@@ -95,12 +98,21 @@ public class AvatarSkillDepotData extends GameResource {
@Override @Override
public void onLoad() { public void onLoad() {
// Set energy skill data
this.energySkillData = GameData.getAvatarSkillDataMap().get(this.energySkill); this.energySkillData = GameData.getAvatarSkillDataMap().get(this.energySkill);
if (getEnergySkillData() != null) { if (getEnergySkillData() != null) {
this.elementType = getEnergySkillData().getCostElemType(); this.elementType = getEnergySkillData().getCostElemType();
} else { } else {
this.elementType = ElementType.None; this.elementType = ElementType.None;
} }
// Set embryo abilities (if player skill depot)
if (getSkillDepotAbilityGroup() != null && getSkillDepotAbilityGroup().length() > 0) {
AvatarConfig config = GameDepot.getPlayerAbilities().get(getSkillDepotAbilityGroup());
if (config != null) {
this.setAbilities(new AbilityEmbryoEntry(getSkillDepotAbilityGroup(), config.abilities.stream().map(Object::toString).toArray(String[]::new)));
}
}
} }
public static class InherentProudSkillOpens { public static class InherentProudSkillOpens {
......
package emu.grasscutter.data.excels;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.props.ElementType;
@ResourceType(name = "WorldAreaConfigData.json")
public class WorldAreaData extends GameResource {
private int ID;
private int AreaID1;
private int AreaID2;
private int SceneID;
private ElementType elementType;
@Override
public int getId() {
return (this.AreaID2 << 16) + this.AreaID1;
}
public int getSceneID() {
return this.SceneID;
}
public ElementType getElementType() {
return this.elementType;
}
@Override
public void onLoad() {
}
}
...@@ -10,14 +10,14 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ...@@ -10,14 +10,14 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public enum ElementType { public enum ElementType {
None (0, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY), None (0, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY),
Fire (1, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY, 10101, "TeamResonance_Fire_Lv2"), Fire (1, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY, 10101, "TeamResonance_Fire_Lv2", 2),
Water (2, FightProperty.FIGHT_PROP_CUR_WATER_ENERGY, FightProperty.FIGHT_PROP_MAX_WATER_ENERGY, 10201, "TeamResonance_Water_Lv2"), Water (2, FightProperty.FIGHT_PROP_CUR_WATER_ENERGY, FightProperty.FIGHT_PROP_MAX_WATER_ENERGY, 10201, "TeamResonance_Water_Lv2", 3),
Grass (3, FightProperty.FIGHT_PROP_CUR_GRASS_ENERGY, FightProperty.FIGHT_PROP_MAX_GRASS_ENERGY), Grass (3, FightProperty.FIGHT_PROP_CUR_GRASS_ENERGY, FightProperty.FIGHT_PROP_MAX_GRASS_ENERGY),
Electric (4, FightProperty.FIGHT_PROP_CUR_ELEC_ENERGY, FightProperty.FIGHT_PROP_MAX_ELEC_ENERGY, 10401, "TeamResonance_Electric_Lv2"), Electric (4, FightProperty.FIGHT_PROP_CUR_ELEC_ENERGY, FightProperty.FIGHT_PROP_MAX_ELEC_ENERGY, 10401, "TeamResonance_Electric_Lv2", 7),
Ice (5, FightProperty.FIGHT_PROP_CUR_ICE_ENERGY, FightProperty.FIGHT_PROP_MAX_ICE_ENERGY, 10601, "TeamResonance_Ice_Lv2"), Ice (5, FightProperty.FIGHT_PROP_CUR_ICE_ENERGY, FightProperty.FIGHT_PROP_MAX_ICE_ENERGY, 10601, "TeamResonance_Ice_Lv2", 5),
Frozen (6, FightProperty.FIGHT_PROP_CUR_ICE_ENERGY, FightProperty.FIGHT_PROP_MAX_ICE_ENERGY), Frozen (6, FightProperty.FIGHT_PROP_CUR_ICE_ENERGY, FightProperty.FIGHT_PROP_MAX_ICE_ENERGY),
Wind (7, FightProperty.FIGHT_PROP_CUR_WIND_ENERGY, FightProperty.FIGHT_PROP_MAX_WIND_ENERGY, 10301, "TeamResonance_Wind_Lv2"), Wind (7, FightProperty.FIGHT_PROP_CUR_WIND_ENERGY, FightProperty.FIGHT_PROP_MAX_WIND_ENERGY, 10301, "TeamResonance_Wind_Lv2", 4),
Rock (8, FightProperty.FIGHT_PROP_CUR_ROCK_ENERGY, FightProperty.FIGHT_PROP_MAX_ROCK_ENERGY, 10701, "TeamResonance_Rock_Lv2"), Rock (8, FightProperty.FIGHT_PROP_CUR_ROCK_ENERGY, FightProperty.FIGHT_PROP_MAX_ROCK_ENERGY, 10701, "TeamResonance_Rock_Lv2", 6),
AntiFire (9, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY), AntiFire (9, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY),
Default (255, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY, 10801, "TeamResonance_AllDifferent"); Default (255, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY, 10801, "TeamResonance_AllDifferent");
...@@ -25,6 +25,7 @@ public enum ElementType { ...@@ -25,6 +25,7 @@ public enum ElementType {
private final int teamResonanceId; private final int teamResonanceId;
private final FightProperty curEnergyProp; private final FightProperty curEnergyProp;
private final FightProperty maxEnergyProp; private final FightProperty maxEnergyProp;
private int depotValue;
private final int configHash; private final int configHash;
private static final Int2ObjectMap<ElementType> map = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<ElementType> map = new Int2ObjectOpenHashMap<>();
private static final Map<String, ElementType> stringMap = new HashMap<>(); private static final Map<String, ElementType> stringMap = new HashMap<>();
...@@ -52,6 +53,11 @@ public enum ElementType { ...@@ -52,6 +53,11 @@ public enum ElementType {
} }
} }
private ElementType(int value, FightProperty curEnergyProp, FightProperty maxEnergyProp, int teamResonanceId, String configName, int depotValue) {
this(value, curEnergyProp, maxEnergyProp, teamResonanceId, configName);
this.depotValue = depotValue;
}
public int getValue() { public int getValue() {
return value; return value;
} }
...@@ -64,6 +70,10 @@ public enum ElementType { ...@@ -64,6 +70,10 @@ public enum ElementType {
return maxEnergyProp; return maxEnergyProp;
} }
public int getDepotValue() {
return depotValue;
}
public int getTeamResonanceId() { public int getTeamResonanceId() {
return teamResonanceId; return teamResonanceId;
} }
......
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.GameConstants;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.AvatarSkillDepotData;
import emu.grasscutter.data.excels.WorldAreaData;
import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarChangeElementTypeReqOuterClass.AvatarChangeElementTypeReq;
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketAbilityChangeNotify;
import emu.grasscutter.server.packet.send.PacketAvatarChangeElementTypeRsp;
import emu.grasscutter.server.packet.send.PacketAvatarFightPropNotify;
import emu.grasscutter.server.packet.send.PacketAvatarSkillDepotChangeNotify;
@Opcodes(PacketOpcodes.AvatarChangeElementTypeReq)
public class HandlerAvatarChangeElementTypeReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
AvatarChangeElementTypeReq req = AvatarChangeElementTypeReq.parseFrom(payload);
WorldAreaData area = GameData.getWorldAreaDataMap().get(req.getAreaId());
if (area == null || area.getElementType() == null || area.getElementType().getDepotValue() <= 0) {
session.send(new PacketAvatarChangeElementTypeRsp(Retcode.RET_SVR_ERROR_VALUE));
return;
}
// Get current avatar, should be one of the main characters
EntityAvatar mainCharacterEntity = session.getPlayer().getTeamManager().getCurrentAvatarEntity();
int intialSkillDepotId = 0;
if (mainCharacterEntity.getAvatar().getAvatarId() == GameConstants.MAIN_CHARACTER_MALE) {
intialSkillDepotId = 500;
} else if (mainCharacterEntity.getAvatar().getAvatarId() == GameConstants.MAIN_CHARACTER_FEMALE) {
intialSkillDepotId = 700;
} else {
session.send(new PacketAvatarChangeElementTypeRsp(Retcode.RET_SVR_ERROR_VALUE));
return;
}
intialSkillDepotId += area.getElementType().getDepotValue();
// Sanity checks for skill depots
Avatar mainCharacter = mainCharacterEntity.getAvatar();
AvatarSkillDepotData skillDepot = GameData.getAvatarSkillDepotDataMap().get(intialSkillDepotId);
if (skillDepot == null || skillDepot.getId() == mainCharacter.getSkillDepotId()) {
session.send(new PacketAvatarChangeElementTypeRsp(Retcode.RET_SVR_ERROR_VALUE));
return;
}
// Success
session.send(new PacketAvatarChangeElementTypeRsp());
// Set skill depot
mainCharacter.setSkillDepotData(skillDepot);
// Ability change packet
session.send(new PacketAvatarSkillDepotChangeNotify(mainCharacter));
session.send(new PacketAbilityChangeNotify(mainCharacterEntity));
session.send(new PacketAvatarFightPropNotify(mainCharacter));
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarChangeElementTypeRspOuterClass.AvatarChangeElementTypeRsp;
public class PacketAvatarChangeElementTypeRsp extends BasePacket {
public PacketAvatarChangeElementTypeRsp() {
super(PacketOpcodes.AvatarChangeElementTypeRsp);
}
public PacketAvatarChangeElementTypeRsp(int retcode) {
super(PacketOpcodes.AvatarChangeElementTypeRsp);
if (retcode > 0) {
AvatarChangeElementTypeRsp proto = AvatarChangeElementTypeRsp.newBuilder()
.setRetcode(retcode)
.build();
this.setData(proto);
}
}
}
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarSkillDepotChangeNotifyOuterClass.AvatarSkillDepotChangeNotify;
public class PacketAvatarSkillDepotChangeNotify extends BasePacket {
public PacketAvatarSkillDepotChangeNotify(Avatar avatar) {
super(PacketOpcodes.AvatarSkillDepotChangeNotify);
AvatarSkillDepotChangeNotify proto = AvatarSkillDepotChangeNotify.newBuilder()
.setAvatarGuid(avatar.getGuid())
.setEntityId(avatar.getEntityId())
.setSkillDepotId(avatar.getSkillDepotId())
.setCoreProudSkillLevel(avatar.getCoreProudSkillLevel())
.addAllTalentIdList(avatar.getTalentIdList())
.addAllProudSkillList(avatar.getProudSkillList())
.putAllSkillLevelMap(avatar.getSkillLevelMap())
.putAllProudSkillExtraLevelMap(avatar.getProudSkillBonusMap())
.build();
this.setData(proto);
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment