diff --git a/src/main/java/emu/grasscutter/game/avatar/Avatar.java b/src/main/java/emu/grasscutter/game/avatar/Avatar.java index 37f696f48..f1d360250 100644 --- a/src/main/java/emu/grasscutter/game/avatar/Avatar.java +++ b/src/main/java/emu/grasscutter/game/avatar/Avatar.java @@ -8,6 +8,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.stream.Stream; import java.util.Set; 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.Int2ObjectOpenHashMap; import lombok.Getter; +import lombok.Setter; @Entity(value = "avatars", useDiscriminator = false) public class Avatar { @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 AvatarData data; - @Transient private AvatarSkillDepotData skillDepot; - @Transient private long guid; // Player unique id - private int avatarId; // Id of avatar + @Transient @Getter private AvatarData data; + @Transient @Getter private AvatarSkillDepotData skillDepot; + @Transient @Getter private long guid; // Player unique id + @Getter private int avatarId; // Id of avatar - private int level = 1; - private int exp; - private int promoteLevel; - private int satiation; // ? - private int satiationPenalty; // ? - private float currentHp; + @Getter @Setter private int level = 1; + @Getter @Setter private int exp; + @Getter @Setter private int promoteLevel; + @Getter @Setter private int satiation; // ? + @Getter @Setter private int satiationPenalty; // ? + @Getter @Setter private float currentHp; private float currentEnergy; - @Transient private final Int2ObjectMap equips; + @Transient @Getter private final Int2ObjectMap equips; @Transient private final Int2FloatOpenHashMap fightProp; @Transient @Getter private final Int2FloatOpenHashMap fightPropOverrides; - @Transient private Set extraAbilityEmbryos; + @Transient @Getter private Set extraAbilityEmbryos; private List fetters; - private Map skillLevelMap; // Talent levels + @Getter private Map skillLevelMap; // Talent levels private Map skillExtraChargeMap; // Charges - private Map proudSkillBonusMap; // Talent bonus levels (from const) - private int skillDepotId; - private int coreProudSkillLevel; // Constellation level - private Set talentIdList; // Constellation id list - private Set proudSkillList; // Character passives + @Getter private Map proudSkillBonusMap; // Talent bonus levels (from const) + @Getter private int skillDepotId; + @Getter @Setter private int coreProudSkillLevel; // Constellation level + @Getter private Set talentIdList; // Constellation id list + @Getter private Set proudSkillList; // Character passives - private int flyCloak; - private int costume; - private int bornTime; + @Getter @Setter private int flyCloak; + @Getter @Setter private int costume; + @Getter private int bornTime; - private int fetterLevel = 1; - private int fetterExp; + @Getter @Setter private int fetterLevel = 1; + @Getter @Setter private int fetterExp; - private int nameCardRewardId; - private int nameCardId; + @Getter @Setter private int nameCardRewardId; + @Getter @Setter private int nameCardId; @Deprecated // Do not use. Morhpia only! public Avatar() { @@ -139,15 +141,13 @@ public class Avatar { this.proudSkillList = new HashSet<>(); // Combat properties - for (FightProperty prop : FightProperty.values()) { - if (prop.getId() <= 0 || prop.getId() >= 3000) { - continue; - } - this.setFightProperty(prop, 0f); - } + Stream.of(FightProperty.values()) + .map(FightProperty::getId) + .filter(id -> (id > 0) && (id < 3000)) + .forEach(id -> this.setFightProperty(id, 0f)); // Skill depot - this.setSkillDepotData(getAvatarData().getSkillDepot()); + this.setSkillDepotData(data.getSkillDepot()); // Set stats this.recalcStats(); @@ -175,76 +175,12 @@ public class Avatar { this.data = data; // Used while loading this from the database } - public int getOwnerId() { - return ownerId; - } - public void setOwner(Player player) { this.owner = player; this.ownerId = player.getUid(); 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) { if (level > 80) { return 6; @@ -262,10 +198,6 @@ public class Avatar { return 0; } - public Int2ObjectMap getEquips() { - return equips; - } - public GameItem getEquipBySlot(EquipType slot) { return this.getEquips().get(slot.getValue()); } @@ -278,14 +210,6 @@ public class Avatar { return this.getEquipBySlot(EquipType.EQUIP_WEAPON); } - public int getSkillDepotId() { - return skillDepotId; - } - - public AvatarSkillDepotData getSkillDepot() { - return skillDepot; - } - protected void setSkillDepot(AvatarSkillDepotData skillDepot) { if (this.skillDepot != null) return; this.skillDepot = skillDepot; // Used while loading this from the database @@ -320,10 +244,6 @@ public class Avatar { } } - public Map getSkillLevelMap() { - return skillLevelMap; - } - public Map getSkillExtraChargeMap() { if (skillExtraChargeMap == null) { skillExtraChargeMap = new HashMap<>(); @@ -331,14 +251,6 @@ public class Avatar { return skillExtraChargeMap; } - public Map getProudSkillBonusMap() { - return proudSkillBonusMap; - } - - public Set getExtraAbilityEmbryos() { - return extraAbilityEmbryos; - } - public void setFetterList(List fetterList) { this.fetters = fetterList; } @@ -347,38 +259,6 @@ public class Avatar { 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() { if (GAME_OPTIONS.energyUsage) { this.setCurrentEnergy(this.currentEnergy); @@ -427,42 +307,6 @@ public class Avatar { return getFightProperties().getOrDefault(prop.getId(), 0f); } - public Set getTalentIdList() { - return talentIdList; - } - - public int getCoreProudSkillLevel() { - return coreProudSkillLevel; - } - - public void setCoreProudSkillLevel(int constLevel) { - this.coreProudSkillLevel = constLevel; - } - - public Set 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) { // Sanity check equip type EquipType itemEquipType = item.getItemData().getEquipType(); @@ -776,7 +620,7 @@ public class Avatar { this.getSkillExtraChargeMap().clear(); // Sanity checks - if (getData() == null || getData().getSkillDepot() == null) { + if (getData() == null || this.skillDepot == null) { return; } @@ -811,12 +655,12 @@ public class Avatar { // Check if a skill can be boosted by +3 levels int skillId = 0; - if (entry.getExtraTalentIndex() == 2 && this.getData().getSkillDepot().getSkills().size() >= 2) { + if (entry.getExtraTalentIndex() == 2 && this.skillDepot.getSkills().size() >= 2) { // E skill - skillId = this.getData().getSkillDepot().getSkills().get(1); + skillId = this.skillDepot.getSkills().get(1); } else if (entry.getExtraTalentIndex() == 9) { // Ult skill - skillId = this.getData().getSkillDepot().getEnergySkill(); + skillId = this.skillDepot.getEnergySkill(); } // Sanity check diff --git a/src/main/java/emu/grasscutter/game/player/Player.java b/src/main/java/emu/grasscutter/game/player/Player.java index 6fcad5279..03d5abb76 100644 --- a/src/main/java/emu/grasscutter/game/player/Player.java +++ b/src/main/java/emu/grasscutter/game/player/Player.java @@ -1174,6 +1174,7 @@ public class Player { this.forgingManager.sendForgeDataNotify(); this.resinManager.onPlayerLogin(); 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. diff --git a/src/main/java/emu/grasscutter/game/player/TeamManager.java b/src/main/java/emu/grasscutter/game/player/TeamManager.java index 8421b4ecf..c6f118ad8 100644 --- a/src/main/java/emu/grasscutter/game/player/TeamManager.java +++ b/src/main/java/emu/grasscutter/game/player/TeamManager.java @@ -34,25 +34,26 @@ import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify; import emu.grasscutter.server.packet.send.PacketSceneTeamUpdateNotify; import emu.grasscutter.server.packet.send.PacketSetUpAvatarTeamRsp; 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.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import lombok.Getter; +import lombok.Setter; @Entity public class TeamManager extends BasePlayerDataManager { - private Map teams; + @Getter private Map teams; private int currentTeamIndex; - private int currentCharacterIndex; + @Getter @Setter private int currentCharacterIndex; - @Transient private TeamInfo mpTeam; - @Transient private int entityId; + @Transient @Getter @Setter private TeamInfo mpTeam; + @Transient @Getter @Setter private int entityId; @Transient private final List avatars; - @Transient private final Set gadgets; - @Transient private final IntSet teamResonances; - @Transient private final IntSet teamResonancesConfig; + @Transient @Getter private final Set gadgets; + @Transient @Getter private final IntSet teamResonances; + @Transient @Getter private final IntSet teamResonancesConfig; @Transient private int useTemporarilyTeamIndex = -1; @Transient private List temporaryTeam; // Temporary Team for tower @@ -80,18 +81,6 @@ public class TeamManager extends BasePlayerDataManager { return this.getPlayer().getWorld(); } - public Map 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. * Otherwise, return -1. @@ -115,14 +104,6 @@ public class TeamManager extends BasePlayerDataManager { this.currentTeamIndex = currentTeamIndex; } - public int getCurrentCharacterIndex() { - return currentCharacterIndex; - } - - public void setCurrentCharacterIndex(int currentCharacterIndex) { - this.currentCharacterIndex = currentCharacterIndex; - } - public long getCurrentCharacterGuid() { return this.getCurrentAvatarEntity().getAvatar().getGuid(); } @@ -142,26 +123,6 @@ public class TeamManager extends BasePlayerDataManager { return this.getTeams().get(this.currentTeamIndex); } - public int getEntityId() { - return entityId; - } - - public void setEntityId(int entityId) { - this.entityId = entityId; - } - - public Set getGadgets() { - return gadgets; - } - - public IntSet getTeamResonances() { - return teamResonances; - } - - public IntSet getTeamResonancesConfig() { - return teamResonancesConfig; - } - public List getActiveTeam() { return avatars; } @@ -290,32 +251,34 @@ public class TeamManager extends BasePlayerDataManager { } private void updateTeamResonances() { - Int2IntOpenHashMap map = new Int2IntOpenHashMap(); - this.getTeamResonances().clear(); this.getTeamResonancesConfig().clear(); + // Official resonances require a full party + if (this.avatars.size() < 4) return; - for (EntityAvatar entity : this.getActiveTeam()) { - AvatarSkillDepotData skillData = entity.getAvatar().getAvatarData().getSkillDepot(); - if (skillData != null) { - map.addTo(skillData.getElementType().getValue(), 1); - } - } + // TODO: make this actually read from TeamResonanceExcelConfigData.json for the real resonances and conditions + // Currently we just hardcode these conditions, but this won't work for modded resources or future changes + var elementCounts = new Object2IntOpenHashMap(); + 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()) { - if (e.getIntValue() >= 2) { - ElementType element = ElementType.getTypeByValue(e.getIntKey()); - if (element.getTeamResonanceId() != 0) { - this.getTeamResonances().add(element.getTeamResonanceId()); - this.getTeamResonancesConfig().add(element.getConfigHash()); - } - } - } + // Dual element resonances + elementCounts.object2IntEntrySet().stream() + .filter(e -> e.getIntValue() >= 2) + .map(e -> e.getKey()) + .filter(elementType -> elementType.getTeamResonanceId() != 0) + .forEach(elementType -> { + this.teamResonances.add(elementType.getTeamResonanceId()); + this.teamResonancesConfig.add(elementType.getConfigHash()); + }); - // No resonances - if (this.getTeamResonances().size() == 0) { - this.getTeamResonances().add(ElementType.Default.getTeamResonanceId()); - this.getTeamResonancesConfig().add(ElementType.Default.getTeamResonanceId()); + // Four element resonance + if (elementCounts.size() >= 4) { + this.teamResonances.add(ElementType.Default.getTeamResonanceId()); + this.teamResonancesConfig.add(ElementType.Default.getConfigHash()); } } @@ -677,4 +640,8 @@ public class TeamManager extends BasePlayerDataManager { entity.getAvatar().save(); } } + + public void onPlayerLogin() { // Hack for now to fix resonances on login + this.updateTeamResonances(); + } }