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.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<GameItem> equips;
@Transient @Getter private final Int2ObjectMap<GameItem> equips;
@Transient private final Int2FloatOpenHashMap fightProp;
@Transient @Getter private final Int2FloatOpenHashMap fightPropOverrides;
@Transient private Set<String> extraAbilityEmbryos;
@Transient @Getter private Set<String> extraAbilityEmbryos;
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> proudSkillBonusMap; // Talent bonus levels (from const)
private int skillDepotId;
private int coreProudSkillLevel; // Constellation level
private Set<Integer> talentIdList; // Constellation id list
private Set<Integer> proudSkillList; // Character passives
@Getter private Map<Integer, Integer> proudSkillBonusMap; // Talent bonus levels (from const)
@Getter private int skillDepotId;
@Getter @Setter private int coreProudSkillLevel; // Constellation level
@Getter private Set<Integer> talentIdList; // Constellation id list
@Getter private Set<Integer> 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<GameItem> 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<Integer, Integer> getSkillLevelMap() {
return skillLevelMap;
}
public Map<Integer, Integer> getSkillExtraChargeMap() {
if (skillExtraChargeMap == null) {
skillExtraChargeMap = new HashMap<>();
@ -331,14 +251,6 @@ public class Avatar {
return skillExtraChargeMap;
}
public Map<Integer, Integer> getProudSkillBonusMap() {
return proudSkillBonusMap;
}
public Set<String> getExtraAbilityEmbryos() {
return extraAbilityEmbryos;
}
public void setFetterList(List<Integer> 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<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) {
// 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

View File

@ -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.

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.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<Integer, TeamInfo> teams;
@Getter private Map<Integer, TeamInfo> 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<EntityAvatar> avatars;
@Transient private final Set<EntityBaseGadget> gadgets;
@Transient private final IntSet teamResonances;
@Transient private final IntSet teamResonancesConfig;
@Transient @Getter private final Set<EntityBaseGadget> gadgets;
@Transient @Getter private final IntSet teamResonances;
@Transient @Getter private final IntSet teamResonancesConfig;
@Transient private int useTemporarilyTeamIndex = -1;
@Transient private List<TeamInfo> temporaryTeam; // Temporary Team for tower
@ -80,18 +81,6 @@ public class TeamManager extends BasePlayerDataManager {
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.
* 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<EntityBaseGadget> getGadgets() {
return gadgets;
}
public IntSet getTeamResonances() {
return teamResonances;
}
public IntSet getTeamResonancesConfig() {
return teamResonancesConfig;
}
public List<EntityAvatar> 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<ElementType>();
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();
}
}