Remove erroneous references to excel skilldata instead of avatar skilldata

Refactor team resonances and correct login behaviour and less-than-full-party behaviour
This commit is contained in:
AnimeGitB 2022-08-11 13:11:33 +09:30
parent b4a2fe37e3
commit 02deeb2852
3 changed files with 75 additions and 263 deletions

View File

@ -8,6 +8,7 @@ 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.Map.Entry;
import java.util.stream.Stream;
import java.util.Set; import java.util.Set;
import org.bson.types.ObjectId; import org.bson.types.ObjectId;
@ -64,50 +65,51 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
@Entity(value = "avatars", useDiscriminator = false) @Entity(value = "avatars", useDiscriminator = false)
public class Avatar { public class Avatar {
@Id private ObjectId id; @Id private ObjectId id;
@Indexed private int ownerId; // Id of player that this avatar belongs to @Indexed @Getter private int ownerId; // Id of player that this avatar belongs to
@Transient private Player owner; @Transient private Player owner;
@Transient private AvatarData data; @Transient @Getter private AvatarData data;
@Transient private AvatarSkillDepotData skillDepot; @Transient @Getter private AvatarSkillDepotData skillDepot;
@Transient private long guid; // Player unique id @Transient @Getter private long guid; // Player unique id
private int avatarId; // Id of avatar @Getter private int avatarId; // Id of avatar
private int level = 1; @Getter @Setter private int level = 1;
private int exp; @Getter @Setter private int exp;
private int promoteLevel; @Getter @Setter private int promoteLevel;
private int satiation; // ? @Getter @Setter private int satiation; // ?
private int satiationPenalty; // ? @Getter @Setter private int satiationPenalty; // ?
private float currentHp; @Getter @Setter private float currentHp;
private float currentEnergy; private float currentEnergy;
@Transient private final Int2ObjectMap<GameItem> equips; @Transient @Getter private final Int2ObjectMap<GameItem> equips;
@Transient private final Int2FloatOpenHashMap fightProp; @Transient private final Int2FloatOpenHashMap fightProp;
@Transient @Getter private final Int2FloatOpenHashMap fightPropOverrides; @Transient @Getter private final Int2FloatOpenHashMap fightPropOverrides;
@Transient private Set<String> extraAbilityEmbryos; @Transient @Getter private Set<String> extraAbilityEmbryos;
private List<Integer> fetters; private List<Integer> fetters;
private Map<Integer, Integer> skillLevelMap; // Talent levels @Getter private Map<Integer, Integer> skillLevelMap; // Talent levels
private Map<Integer, Integer> skillExtraChargeMap; // Charges private Map<Integer, Integer> skillExtraChargeMap; // Charges
private Map<Integer, Integer> proudSkillBonusMap; // Talent bonus levels (from const) @Getter private Map<Integer, Integer> proudSkillBonusMap; // Talent bonus levels (from const)
private int skillDepotId; @Getter private int skillDepotId;
private int coreProudSkillLevel; // Constellation level @Getter @Setter private int coreProudSkillLevel; // Constellation level
private Set<Integer> talentIdList; // Constellation id list @Getter private Set<Integer> talentIdList; // Constellation id list
private Set<Integer> proudSkillList; // Character passives @Getter private Set<Integer> proudSkillList; // Character passives
private int flyCloak; @Getter @Setter private int flyCloak;
private int costume; @Getter @Setter private int costume;
private int bornTime; @Getter private int bornTime;
private int fetterLevel = 1; @Getter @Setter private int fetterLevel = 1;
private int fetterExp; @Getter @Setter private int fetterExp;
private int nameCardRewardId; @Getter @Setter private int nameCardRewardId;
private int nameCardId; @Getter @Setter private int nameCardId;
@Deprecated // Do not use. Morhpia only! @Deprecated // Do not use. Morhpia only!
public Avatar() { public Avatar() {
@ -139,15 +141,13 @@ public class Avatar {
this.proudSkillList = new HashSet<>(); this.proudSkillList = new HashSet<>();
// Combat properties // Combat properties
for (FightProperty prop : FightProperty.values()) { Stream.of(FightProperty.values())
if (prop.getId() <= 0 || prop.getId() >= 3000) { .map(FightProperty::getId)
continue; .filter(id -> (id > 0) && (id < 3000))
} .forEach(id -> this.setFightProperty(id, 0f));
this.setFightProperty(prop, 0f);
}
// Skill depot // Skill depot
this.setSkillDepotData(getAvatarData().getSkillDepot()); this.setSkillDepotData(data.getSkillDepot());
// Set stats // Set stats
this.recalcStats(); this.recalcStats();
@ -175,76 +175,12 @@ public class Avatar {
this.data = data; // Used while loading this from the database this.data = data; // Used while loading this from the database
} }
public int getOwnerId() {
return ownerId;
}
public void setOwner(Player player) { public void setOwner(Player player) {
this.owner = player; this.owner = player;
this.ownerId = player.getUid(); this.ownerId = player.getUid();
this.guid = player.getNextGameGuid(); this.guid = player.getNextGameGuid();
} }
public int getSatiation() {
return satiation;
}
public void setSatiation(int satiation) {
this.satiation = satiation;
}
public int getNameCardRewardId() {
return nameCardRewardId;
}
public void setNameCardRewardId(int nameCardRewardId) {
this.nameCardRewardId = nameCardRewardId;
}
public int getSatiationPenalty() {
return satiationPenalty;
}
public void setSatiationPenalty(int satiationPenalty) {
this.satiationPenalty = satiationPenalty;
}
public AvatarData getData() {
return data;
}
public long getGuid() {
return guid;
}
public int getAvatarId() {
return avatarId;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public int getExp() {
return exp;
}
public void setExp(int exp) {
this.exp = exp;
}
public int getPromoteLevel() {
return promoteLevel;
}
public void setPromoteLevel(int promoteLevel) {
this.promoteLevel = promoteLevel;
}
static public int getMinPromoteLevel(int level) { static public int getMinPromoteLevel(int level) {
if (level > 80) { if (level > 80) {
return 6; return 6;
@ -262,10 +198,6 @@ public class Avatar {
return 0; return 0;
} }
public Int2ObjectMap<GameItem> getEquips() {
return equips;
}
public GameItem getEquipBySlot(EquipType slot) { public GameItem getEquipBySlot(EquipType slot) {
return this.getEquips().get(slot.getValue()); return this.getEquips().get(slot.getValue());
} }
@ -278,14 +210,6 @@ public class Avatar {
return this.getEquipBySlot(EquipType.EQUIP_WEAPON); return this.getEquipBySlot(EquipType.EQUIP_WEAPON);
} }
public int getSkillDepotId() {
return skillDepotId;
}
public AvatarSkillDepotData getSkillDepot() {
return skillDepot;
}
protected void setSkillDepot(AvatarSkillDepotData skillDepot) { protected void setSkillDepot(AvatarSkillDepotData skillDepot) {
if (this.skillDepot != null) return; if (this.skillDepot != null) return;
this.skillDepot = skillDepot; // Used while loading this from the database this.skillDepot = skillDepot; // Used while loading this from the database
@ -320,10 +244,6 @@ public class Avatar {
} }
} }
public Map<Integer, Integer> getSkillLevelMap() {
return skillLevelMap;
}
public Map<Integer, Integer> getSkillExtraChargeMap() { public Map<Integer, Integer> getSkillExtraChargeMap() {
if (skillExtraChargeMap == null) { if (skillExtraChargeMap == null) {
skillExtraChargeMap = new HashMap<>(); skillExtraChargeMap = new HashMap<>();
@ -331,14 +251,6 @@ public class Avatar {
return skillExtraChargeMap; return skillExtraChargeMap;
} }
public Map<Integer, Integer> getProudSkillBonusMap() {
return proudSkillBonusMap;
}
public Set<String> getExtraAbilityEmbryos() {
return extraAbilityEmbryos;
}
public void setFetterList(List<Integer> fetterList) { public void setFetterList(List<Integer> fetterList) {
this.fetters = fetterList; this.fetters = fetterList;
} }
@ -347,38 +259,6 @@ public class Avatar {
return fetters; return fetters;
} }
public int getFetterLevel() {
return fetterLevel;
}
public void setFetterLevel(int fetterLevel) {
this.fetterLevel = fetterLevel;
}
public int getFetterExp() {
return fetterExp;
}
public void setFetterExp(int fetterExp) {
this.fetterExp = fetterExp;
}
public int getNameCardId() {
return nameCardId;
}
public void setNameCardId(int nameCardId) {
this.nameCardId = nameCardId;
}
public float getCurrentHp() {
return currentHp;
}
public void setCurrentHp(float currentHp) {
this.currentHp = currentHp;
}
public void setCurrentEnergy() { public void setCurrentEnergy() {
if (GAME_OPTIONS.energyUsage) { if (GAME_OPTIONS.energyUsage) {
this.setCurrentEnergy(this.currentEnergy); this.setCurrentEnergy(this.currentEnergy);
@ -427,42 +307,6 @@ public class Avatar {
return getFightProperties().getOrDefault(prop.getId(), 0f); return getFightProperties().getOrDefault(prop.getId(), 0f);
} }
public Set<Integer> getTalentIdList() {
return talentIdList;
}
public int getCoreProudSkillLevel() {
return coreProudSkillLevel;
}
public void setCoreProudSkillLevel(int constLevel) {
this.coreProudSkillLevel = constLevel;
}
public Set<Integer> getProudSkillList() {
return proudSkillList;
}
public int getFlyCloak() {
return flyCloak;
}
public void setFlyCloak(int flyCloak) {
this.flyCloak = flyCloak;
}
public int getCostume() {
return costume;
}
public void setCostume(int costume) {
this.costume = costume;
}
public int getBornTime() {
return bornTime;
}
public boolean equipItem(GameItem item, boolean shouldRecalc) { public boolean equipItem(GameItem item, boolean shouldRecalc) {
// Sanity check equip type // Sanity check equip type
EquipType itemEquipType = item.getItemData().getEquipType(); EquipType itemEquipType = item.getItemData().getEquipType();
@ -776,7 +620,7 @@ public class Avatar {
this.getSkillExtraChargeMap().clear(); this.getSkillExtraChargeMap().clear();
// Sanity checks // Sanity checks
if (getData() == null || getData().getSkillDepot() == null) { if (getData() == null || this.skillDepot == null) {
return; return;
} }
@ -811,12 +655,12 @@ public class Avatar {
// Check if a skill can be boosted by +3 levels // 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.skillDepot.getSkills().size() >= 2) {
// E skill // E skill
skillId = this.getData().getSkillDepot().getSkills().get(1); skillId = this.skillDepot.getSkills().get(1);
} else if (entry.getExtraTalentIndex() == 9) { } else if (entry.getExtraTalentIndex() == 9) {
// Ult skill // Ult skill
skillId = this.getData().getSkillDepot().getEnergySkill(); skillId = this.skillDepot.getEnergySkill();
} }
// Sanity check // Sanity check

View File

@ -1174,6 +1174,7 @@ public class Player {
this.forgingManager.sendForgeDataNotify(); this.forgingManager.sendForgeDataNotify();
this.resinManager.onPlayerLogin(); this.resinManager.onPlayerLogin();
this.cookingManager.sendCookDataNofity(); this.cookingManager.sendCookDataNofity();
this.teamManager.onPlayerLogin();
getTodayMoonCard(); // The timer works at 0:0, some users log in after that, use this method to check if they have received a reward today or not. If not, send the reward. getTodayMoonCard(); // The timer works at 0:0, some users log in after that, use this method to check if they have received a reward today or not. If not, send the reward.

View File

@ -34,25 +34,26 @@ import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify;
import emu.grasscutter.server.packet.send.PacketSceneTeamUpdateNotify; import emu.grasscutter.server.packet.send.PacketSceneTeamUpdateNotify;
import emu.grasscutter.server.packet.send.PacketSetUpAvatarTeamRsp; import emu.grasscutter.server.packet.send.PacketSetUpAvatarTeamRsp;
import emu.grasscutter.server.packet.send.PacketWorldPlayerDieNotify; import emu.grasscutter.server.packet.send.PacketWorldPlayerDieNotify;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import lombok.Getter;
import lombok.Setter;
@Entity @Entity
public class TeamManager extends BasePlayerDataManager { public class TeamManager extends BasePlayerDataManager {
private Map<Integer, TeamInfo> teams; @Getter private Map<Integer, TeamInfo> teams;
private int currentTeamIndex; private int currentTeamIndex;
private int currentCharacterIndex; @Getter @Setter private int currentCharacterIndex;
@Transient private TeamInfo mpTeam; @Transient @Getter @Setter private TeamInfo mpTeam;
@Transient private int entityId; @Transient @Getter @Setter private int entityId;
@Transient private final List<EntityAvatar> avatars; @Transient private final List<EntityAvatar> avatars;
@Transient private final Set<EntityBaseGadget> gadgets; @Transient @Getter private final Set<EntityBaseGadget> gadgets;
@Transient private final IntSet teamResonances; @Transient @Getter private final IntSet teamResonances;
@Transient private final IntSet teamResonancesConfig; @Transient @Getter private final IntSet teamResonancesConfig;
@Transient private int useTemporarilyTeamIndex = -1; @Transient private int useTemporarilyTeamIndex = -1;
@Transient private List<TeamInfo> temporaryTeam; // Temporary Team for tower @Transient private List<TeamInfo> temporaryTeam; // Temporary Team for tower
@ -80,18 +81,6 @@ public class TeamManager extends BasePlayerDataManager {
return this.getPlayer().getWorld(); return this.getPlayer().getWorld();
} }
public Map<Integer, TeamInfo> getTeams() {
return this.teams;
}
public TeamInfo getMpTeam() {
return mpTeam;
}
public void setMpTeam(TeamInfo mpTeam) {
this.mpTeam = mpTeam;
}
/** /**
* Search through all teams and if the team matches, return that index. * Search through all teams and if the team matches, return that index.
* Otherwise, return -1. * Otherwise, return -1.
@ -115,14 +104,6 @@ public class TeamManager extends BasePlayerDataManager {
this.currentTeamIndex = currentTeamIndex; this.currentTeamIndex = currentTeamIndex;
} }
public int getCurrentCharacterIndex() {
return currentCharacterIndex;
}
public void setCurrentCharacterIndex(int currentCharacterIndex) {
this.currentCharacterIndex = currentCharacterIndex;
}
public long getCurrentCharacterGuid() { public long getCurrentCharacterGuid() {
return this.getCurrentAvatarEntity().getAvatar().getGuid(); return this.getCurrentAvatarEntity().getAvatar().getGuid();
} }
@ -142,26 +123,6 @@ public class TeamManager extends BasePlayerDataManager {
return this.getTeams().get(this.currentTeamIndex); return this.getTeams().get(this.currentTeamIndex);
} }
public int getEntityId() {
return entityId;
}
public void setEntityId(int entityId) {
this.entityId = entityId;
}
public Set<EntityBaseGadget> getGadgets() {
return gadgets;
}
public IntSet getTeamResonances() {
return teamResonances;
}
public IntSet getTeamResonancesConfig() {
return teamResonancesConfig;
}
public List<EntityAvatar> getActiveTeam() { public List<EntityAvatar> getActiveTeam() {
return avatars; return avatars;
} }
@ -290,32 +251,34 @@ public class TeamManager extends BasePlayerDataManager {
} }
private void updateTeamResonances() { private void updateTeamResonances() {
Int2IntOpenHashMap map = new Int2IntOpenHashMap();
this.getTeamResonances().clear(); this.getTeamResonances().clear();
this.getTeamResonancesConfig().clear(); this.getTeamResonancesConfig().clear();
// Official resonances require a full party
if (this.avatars.size() < 4) return;
for (EntityAvatar entity : this.getActiveTeam()) { // TODO: make this actually read from TeamResonanceExcelConfigData.json for the real resonances and conditions
AvatarSkillDepotData skillData = entity.getAvatar().getAvatarData().getSkillDepot(); // Currently we just hardcode these conditions, but this won't work for modded resources or future changes
if (skillData != null) { var elementCounts = new Object2IntOpenHashMap<ElementType>();
map.addTo(skillData.getElementType().getValue(), 1); this.getActiveTeam().stream()
} .map(EntityAvatar::getAvatar).filter(Objects::nonNull)
} .map(Avatar::getSkillDepot).filter(Objects::nonNull)
.map(AvatarSkillDepotData::getElementType).filter(Objects::nonNull)
.forEach(elementType -> elementCounts.addTo(elementType, 1));
for (Int2IntMap.Entry e : map.int2IntEntrySet()) { // Dual element resonances
if (e.getIntValue() >= 2) { elementCounts.object2IntEntrySet().stream()
ElementType element = ElementType.getTypeByValue(e.getIntKey()); .filter(e -> e.getIntValue() >= 2)
if (element.getTeamResonanceId() != 0) { .map(e -> e.getKey())
this.getTeamResonances().add(element.getTeamResonanceId()); .filter(elementType -> elementType.getTeamResonanceId() != 0)
this.getTeamResonancesConfig().add(element.getConfigHash()); .forEach(elementType -> {
} this.teamResonances.add(elementType.getTeamResonanceId());
} this.teamResonancesConfig.add(elementType.getConfigHash());
} });
// No resonances // Four element resonance
if (this.getTeamResonances().size() == 0) { if (elementCounts.size() >= 4) {
this.getTeamResonances().add(ElementType.Default.getTeamResonanceId()); this.teamResonances.add(ElementType.Default.getTeamResonanceId());
this.getTeamResonancesConfig().add(ElementType.Default.getTeamResonanceId()); this.teamResonancesConfig.add(ElementType.Default.getConfigHash());
} }
} }
@ -677,4 +640,8 @@ public class TeamManager extends BasePlayerDataManager {
entity.getAvatar().save(); entity.getAvatar().save();
} }
} }
public void onPlayerLogin() { // Hack for now to fix resonances on login
this.updateTeamResonances();
}
} }