Commit 3169e87c authored by Melledy's avatar Melledy
Browse files

Fix constellations that give an extra charge to skills

Fix #228
parent a044448a
...@@ -307,18 +307,7 @@ public class ResourceLoader { ...@@ -307,18 +307,7 @@ public class ResourceLoader {
} }
for (Entry<String, OpenConfigData[]> e : config.entrySet()) { for (Entry<String, OpenConfigData[]> e : config.entrySet()) {
List<String> abilityList = new ArrayList<>(); OpenConfigEntry entry = new OpenConfigEntry(e.getKey(), e.getValue());
int extraTalentIndex = 0;
for (OpenConfigData entry : e.getValue()) {
if (entry.$type.contains("AddAbility")) {
abilityList.add(entry.abilityName);
} else if (entry.talentIndex > 0) {
extraTalentIndex = entry.talentIndex;
}
}
OpenConfigEntry entry = new OpenConfigEntry(e.getKey(), abilityList, extraTalentIndex);
map.put(entry.getName(), entry); map.put(entry.getName(), entry);
} }
} }
...@@ -354,9 +343,11 @@ public class ResourceLoader { ...@@ -354,9 +343,11 @@ public class ResourceLoader {
public OpenConfigData[] data; public OpenConfigData[] data;
} }
private static class OpenConfigData { public static class OpenConfigData {
public String $type; public String $type;
public String abilityName; public String abilityName;
public int talentIndex; public int talentIndex;
public int skillID;
public int pointDelta;
} }
} }
package emu.grasscutter.data.custom; package emu.grasscutter.data.custom;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import emu.grasscutter.data.ResourceLoader.OpenConfigData;
public class OpenConfigEntry { public class OpenConfigEntry {
private String name; private String name;
private String[] addAbilities; private String[] addAbilities;
private int extraTalentIndex; private int extraTalentIndex;
private SkillPointModifier[] skillPointModifiers;
public OpenConfigEntry(String name, List<String> abilityList, int extraTalentIndex) { public OpenConfigEntry(String name, OpenConfigData[] data) {
this.name = name; this.name = name;
this.extraTalentIndex = extraTalentIndex;
List<String> abilityList = new ArrayList<>();
List<SkillPointModifier> modList = new ArrayList<>();
for (OpenConfigData entry : data) {
if (entry.$type.contains("AddAbility")) {
abilityList.add(entry.abilityName);
} else if (entry.talentIndex > 0) {
this.extraTalentIndex = entry.talentIndex;
} else if (entry.$type.contains("ModifySkillPoint")) {
modList.add(new SkillPointModifier(entry.skillID, entry.pointDelta));
}
}
if (abilityList.size() > 0) { if (abilityList.size() > 0) {
this.addAbilities = abilityList.toArray(new String[0]); this.addAbilities = abilityList.toArray(new String[0]);
} }
if (modList.size() > 0) {
this.skillPointModifiers = modList.toArray(new SkillPointModifier[0]);
}
} }
public String getName() { public String getName() {
...@@ -26,4 +47,26 @@ public class OpenConfigEntry { ...@@ -26,4 +47,26 @@ public class OpenConfigEntry {
public int getExtraTalentIndex() { public int getExtraTalentIndex() {
return extraTalentIndex; return extraTalentIndex;
} }
public SkillPointModifier[] getSkillPointModifiers() {
return skillPointModifiers;
}
public static class SkillPointModifier {
private int skillId;
private int delta;
public SkillPointModifier(int skillId, int delta) {
this.skillId = skillId;
this.delta = delta;
}
public int getSkillId() {
return skillId;
}
public int getDelta() {
return delta;
}
}
} }
...@@ -5,6 +5,7 @@ import java.util.HashMap; ...@@ -5,6 +5,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import org.bson.types.ObjectId; import org.bson.types.ObjectId;
...@@ -18,6 +19,7 @@ import dev.morphia.annotations.Transient; ...@@ -18,6 +19,7 @@ import dev.morphia.annotations.Transient;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.FightPropData; import emu.grasscutter.data.common.FightPropData;
import emu.grasscutter.data.custom.OpenConfigEntry; import emu.grasscutter.data.custom.OpenConfigEntry;
import emu.grasscutter.data.custom.OpenConfigEntry.SkillPointModifier;
import emu.grasscutter.data.def.AvatarData; import emu.grasscutter.data.def.AvatarData;
import emu.grasscutter.data.def.AvatarPromoteData; import emu.grasscutter.data.def.AvatarPromoteData;
import emu.grasscutter.data.def.AvatarSkillData; import emu.grasscutter.data.def.AvatarSkillData;
...@@ -46,6 +48,7 @@ import emu.grasscutter.game.props.FightProperty; ...@@ -46,6 +48,7 @@ import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo; import emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo;
import emu.grasscutter.net.proto.AvatarInfoOuterClass.AvatarInfo; import emu.grasscutter.net.proto.AvatarInfoOuterClass.AvatarInfo;
import emu.grasscutter.net.proto.AvatarSkillInfoOuterClass.AvatarSkillInfo;
import emu.grasscutter.net.proto.FetterDataOuterClass.FetterData; import emu.grasscutter.net.proto.FetterDataOuterClass.FetterData;
import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass; import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass;
import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass.ShowAvatarInfo; import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass.ShowAvatarInfo;
...@@ -83,6 +86,7 @@ public class Avatar { ...@@ -83,6 +86,7 @@ public class Avatar {
private List<Integer> fetters; private List<Integer> fetters;
private Map<Integer, Integer> skillLevelMap; // Talent levels private Map<Integer, Integer> skillLevelMap; // Talent levels
private Map<Integer, Integer> skillExtraChargeMap; // Charges
private Map<Integer, Integer> proudSkillBonusMap; // Talent bonus levels (from const) private Map<Integer, Integer> proudSkillBonusMap; // Talent bonus levels (from const)
private int skillDepotId; private int skillDepotId;
private int coreProudSkillLevel; // Constellation level private int coreProudSkillLevel; // Constellation level
...@@ -123,6 +127,7 @@ public class Avatar { ...@@ -123,6 +127,7 @@ public class Avatar {
this.flyCloak = 140001; this.flyCloak = 140001;
this.skillLevelMap = new HashMap<>(); this.skillLevelMap = new HashMap<>();
this.skillExtraChargeMap = new HashMap<>();
this.talentIdList = new HashSet<>(); this.talentIdList = new HashSet<>();
this.proudSkillList = new HashSet<>(); this.proudSkillList = new HashSet<>();
...@@ -284,6 +289,13 @@ public class Avatar { ...@@ -284,6 +289,13 @@ public class Avatar {
return skillLevelMap; return skillLevelMap;
} }
public Map<Integer, Integer> getSkillExtraChargeMap() {
if (skillExtraChargeMap == null) {
skillExtraChargeMap = new HashMap<>();
}
return skillExtraChargeMap;
}
public Map<Integer, Integer> getProudSkillBonusMap() { public Map<Integer, Integer> getProudSkillBonusMap() {
return proudSkillBonusMap; return proudSkillBonusMap;
} }
...@@ -676,9 +688,10 @@ public class Avatar { ...@@ -676,9 +688,10 @@ public class Avatar {
} }
} }
public void recalcProudSkillBonusMap() { public void recalcConstellations() {
// Clear first // Clear first
this.getProudSkillBonusMap().clear(); this.getProudSkillBonusMap().clear();
this.getSkillExtraChargeMap().clear();
// Sanity checks // Sanity checks
if (getData() == null || getData().getSkillDepot() == null) { if (getData() == null || getData().getSkillDepot() == null) {
...@@ -699,6 +712,21 @@ public class Avatar { ...@@ -699,6 +712,21 @@ public class Avatar {
continue; continue;
} }
// Check if we can add charges to a skill
if (entry.getSkillPointModifiers() != null) {
for (SkillPointModifier mod : entry.getSkillPointModifiers()) {
AvatarSkillData skillData = GameData.getAvatarSkillDataMap().get(mod.getSkillId());
if (skillData == null) continue;
int charges = skillData.getMaxChargeNum() + mod.getDelta();
this.getSkillExtraChargeMap().put(mod.getSkillId(), charges);
}
continue;
}
// Check if a skill can be boosted by +3 levels
int skillId = 0; int skillId = 0;
if (entry.getExtraTalentIndex() == 2 && this.getData().getSkillDepot().getSkills().size() >= 2) { if (entry.getExtraTalentIndex() == 2 && this.getData().getSkillDepot().getSkills().size() >= 2) {
...@@ -788,6 +816,10 @@ public class Avatar { ...@@ -788,6 +816,10 @@ public class Avatar {
.setWearingFlycloakId(this.getFlyCloak()) .setWearingFlycloakId(this.getFlyCloak())
.setCostumeId(this.getCostume()); .setCostumeId(this.getCostume());
for (Entry<Integer, Integer> entry : this.getSkillExtraChargeMap().entrySet()) {
avatarInfo.putSkillMap(entry.getKey(), AvatarSkillInfo.newBuilder().setMaxChargeCount(entry.getValue()).build());
}
for (GameItem item : this.getEquips().values()) { for (GameItem item : this.getEquips().values()) {
avatarInfo.addEquipGuidList(item.getGuid()); avatarInfo.addEquipGuidList(item.getGuid());
} }
......
...@@ -148,7 +148,7 @@ public class AvatarStorage implements Iterable<Avatar> { ...@@ -148,7 +148,7 @@ public class AvatarStorage implements Iterable<Avatar> {
avatar.setOwner(getPlayer()); avatar.setOwner(getPlayer());
// Force recalc of const boosted skills // Force recalc of const boosted skills
avatar.recalcProudSkillBonusMap(); avatar.recalcConstellations();
// Add to avatar storage // Add to avatar storage
this.avatars.put(avatar.getAvatarId(), avatar); this.avatars.put(avatar.getAvatarId(), avatar);
......
...@@ -8,6 +8,7 @@ import java.util.stream.Collectors; ...@@ -8,6 +8,7 @@ import java.util.stream.Collectors;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.ItemParamData; import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.data.custom.OpenConfigEntry; import emu.grasscutter.data.custom.OpenConfigEntry;
import emu.grasscutter.data.custom.OpenConfigEntry.SkillPointModifier;
import emu.grasscutter.data.def.AvatarPromoteData; import emu.grasscutter.data.def.AvatarPromoteData;
import emu.grasscutter.data.def.AvatarSkillData; import emu.grasscutter.data.def.AvatarSkillData;
import emu.grasscutter.data.def.AvatarSkillDepotData; import emu.grasscutter.data.def.AvatarSkillDepotData;
...@@ -835,9 +836,22 @@ public class InventoryManager { ...@@ -835,9 +836,22 @@ public class InventoryManager {
// Proud skill bonus map (Extra skills) // Proud skill bonus map (Extra skills)
OpenConfigEntry entry = GameData.getOpenConfigEntries().get(talentData.getOpenConfig()); OpenConfigEntry entry = GameData.getOpenConfigEntries().get(talentData.getOpenConfig());
if (entry != null && entry.getExtraTalentIndex() > 0) { if (entry != null) {
avatar.recalcProudSkillBonusMap(); if (entry.getExtraTalentIndex() > 0) {
// Check if new constellation adds +3 to a skill level
avatar.recalcConstellations();
// Packet
player.sendPacket(new PacketProudSkillExtraLevelNotify(avatar, entry.getExtraTalentIndex())); player.sendPacket(new PacketProudSkillExtraLevelNotify(avatar, entry.getExtraTalentIndex()));
} else if (entry.getSkillPointModifiers() != null) {
// Check if new constellation adds skill charges
avatar.recalcConstellations();
// Packet
for (SkillPointModifier mod : entry.getSkillPointModifiers()) {
player.sendPacket(
new PacketAvatarSkillMaxChargeCountNotify(avatar, mod.getSkillId(), avatar.getSkillExtraChargeMap().getOrDefault(mod.getSkillId(), 0))
);
}
}
} }
// Recalc + save avatar // Recalc + save avatar
......
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.AvatarSkillMaxChargeCountNotifyOuterClass.AvatarSkillMaxChargeCountNotify;
public class PacketAvatarSkillMaxChargeCountNotify extends BasePacket {
public PacketAvatarSkillMaxChargeCountNotify(Avatar avatar, int skillId, int maxCharges) {
super(PacketOpcodes.AvatarSkillMaxChargeCountNotify);
AvatarSkillMaxChargeCountNotify proto = AvatarSkillMaxChargeCountNotify.newBuilder()
.setAvatarGuid(avatar.getGuid())
.setSkillId(skillId)
.setMaxChargeCount(maxCharges)
.build();
this.setData(proto);
}
}
Markdown is supported
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