refactor: fix nullable params

This commit is contained in:
Breno A. 2024-06-09 10:26:58 -03:00
parent 3b68645330
commit d4ce7aac08
4 changed files with 279 additions and 384 deletions

View File

@ -231,6 +231,10 @@ public class Achievements {
}); });
var a = this.getAchievement(i); var a = this.getAchievement(i);
if(a == null) {
Grasscutter.getLogger().warn("null returned while getting achievement!");
return;
}
a.setStatus(Status.STATUS_REWARD_TAKEN); a.setStatus(Status.STATUS_REWARD_TAKEN);
this.save(); this.save();
this.sendUpdatePacket(a); this.sendUpdatePacket(a);

View File

@ -25,7 +25,7 @@ public class AllActivityConditionBuilder {
private Map<ActivityConditions, ActivityConditionBaseHandler> initActivityConditions() { private Map<ActivityConditions, ActivityConditionBaseHandler> initActivityConditions() {
Reflections reflector = Grasscutter.reflector; Reflections reflector = Grasscutter.reflector;
return reflector.getTypesAnnotatedWith(ActivityCondition.class).stream() return reflector.getTypesAnnotatedWith(ActivityCondition.class).stream()
.map(this::newInstance) .map(this::newInstance).filter(Objects::nonNull)
.map(h -> new AbstractMap.SimpleEntry<>(extractActionType(h), h)) .map(h -> new AbstractMap.SimpleEntry<>(extractActionType(h), h))
.collect( .collect(
Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)); Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));

View File

@ -1,25 +1,37 @@
package emu.grasscutter.game.avatar; package emu.grasscutter.game.avatar;
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
import dev.morphia.annotations.*; import dev.morphia.annotations.*;
import emu.grasscutter.GameConstants; import emu.grasscutter.GameConstants;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.OpenConfigEntry; import emu.grasscutter.data.binout.OpenConfigEntry;
import emu.grasscutter.data.binout.OpenConfigEntry.SkillPointModifier; import emu.grasscutter.data.binout.OpenConfigEntry.SkillPointModifier;
import emu.grasscutter.data.common.FightPropData; import emu.grasscutter.data.common.FightPropData;
import emu.grasscutter.data.excels.*; import emu.grasscutter.data.excels.EquipAffixData;
import emu.grasscutter.data.excels.ItemData.WeaponProperty; import emu.grasscutter.data.excels.ItemData.WeaponProperty;
import emu.grasscutter.data.excels.avatar.*; import emu.grasscutter.data.excels.ProudSkillData;
import emu.grasscutter.data.excels.avatar.AvatarData;
import emu.grasscutter.data.excels.avatar.AvatarSkillData;
import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData;
import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData.InherentProudSkillOpens; import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData.InherentProudSkillOpens;
import emu.grasscutter.data.excels.reliquary.*; import emu.grasscutter.data.excels.avatar.AvatarTalentData;
import emu.grasscutter.data.excels.reliquary.ReliquaryAffixData;
import emu.grasscutter.data.excels.reliquary.ReliquaryLevelData;
import emu.grasscutter.data.excels.reliquary.ReliquaryMainPropData;
import emu.grasscutter.data.excels.reliquary.ReliquarySetData;
import emu.grasscutter.data.excels.trial.TrialAvatarTemplateData; import emu.grasscutter.data.excels.trial.TrialAvatarTemplateData;
import emu.grasscutter.data.excels.weapon.*; import emu.grasscutter.data.excels.weapon.WeaponCurveData;
import emu.grasscutter.data.excels.weapon.WeaponPromoteData;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.entity.*; import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.inventory.*; import emu.grasscutter.game.entity.EntityWeapon;
import emu.grasscutter.game.inventory.EquipType;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.*; import emu.grasscutter.game.props.ElementType;
import emu.grasscutter.game.props.FetterState;
import emu.grasscutter.game.props.FightProperty;
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.AvatarSkillInfoOuterClass.AvatarSkillInfo;
@ -32,68 +44,130 @@ import emu.grasscutter.net.proto.TrialAvatarInfoOuterClass.TrialAvatarInfo;
import emu.grasscutter.server.packet.send.*; import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.utils.helpers.ProtoHelper; import emu.grasscutter.utils.helpers.ProtoHelper;
import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.ints.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.val;
import org.bson.types.ObjectId;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*; import java.util.*;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.annotation.*;
import lombok.*; import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
import org.bson.types.ObjectId;
@Entity(value = "avatars", useDiscriminator = false) @Entity(value = "avatars", useDiscriminator = false)
public class Avatar { public class Avatar {
@Transient @Getter private final Int2ObjectMap<GameItem> equips; @Transient
@Transient @Getter private final Int2FloatOpenHashMap fightProperties; @Getter
@Transient @Getter private final Int2FloatOpenHashMap fightPropOverrides; private final Int2ObjectMap<GameItem> equips;
@Id private ObjectId id; @Transient
@Indexed @Getter private int ownerId; // Id of player that this avatar belongs to @Getter
@Transient private Player owner; private final Int2FloatOpenHashMap fightProperties;
@Transient @Getter private AvatarData avatarData; @Transient
@Nullable @Transient @Getter private AvatarSkillDepotData skillDepot; @Getter
@Transient @Getter private long guid; // Player unique id private final Int2FloatOpenHashMap fightPropOverrides;
@Getter private int avatarId; // Id of avatar @Id
@Getter @Setter private int level = 1; private ObjectId id;
@Getter @Setter private int exp; @Indexed
@Getter @Setter private int promoteLevel; @Getter
@Getter @Setter private int satiation; // Fullness private int ownerId; // Id of player that this avatar belongs to
@Getter @Setter private int satiationPenalty; // When eating too much @Transient
@Getter @Setter private float currentHp; private Player owner;
@Transient
@Getter
private AvatarData avatarData;
@Nullable
@Transient
@Getter
private AvatarSkillDepotData skillDepot;
@Transient
@Getter
private long guid; // Player unique id
@Getter
private int avatarId; // Id of avatar
@Getter
@Setter
private int level = 1;
@Getter
@Setter
private int exp;
@Getter
@Setter
private int promoteLevel;
@Getter
@Setter
private int satiation; // Fullness
@Getter
@Setter
private int satiationPenalty; // When eating too much
@Getter
@Setter
private float currentHp;
private float currentEnergy; private float currentEnergy;
@Transient @Getter private Set<String> extraAbilityEmbryos; @Transient
@Getter
private Set<String> extraAbilityEmbryos;
private List<Integer> fetters; private List<Integer> fetters;
private final Map<Integer, Integer> skillLevelMap = new Int2IntArrayMap(7); // Talent levels private final Map<Integer, Integer> skillLevelMap = new Int2IntArrayMap(7); // Talent levels
@Transient @Getter @Transient
@Getter
private final Map<Integer, Integer> skillExtraChargeMap = new Int2IntArrayMap(2); // Charges private final Map<Integer, Integer> skillExtraChargeMap = new Int2IntArrayMap(2); // Charges
@Transient @Transient
private final Map<Integer, Integer> proudSkillBonusMap = private final Map<Integer, Integer> proudSkillBonusMap = new Int2IntArrayMap(2); // Talent bonus levels (from const)
new Int2IntArrayMap(2); // Talent bonus levels (from const)
@Getter private int skillDepotId; @Getter
private int skillDepotId;
private Set<Integer> talentIdList; // Constellation id list private Set<Integer> talentIdList; // Constellation id list
@Getter private Set<Integer> proudSkillList; // Character passives @Getter
private Set<Integer> proudSkillList; // Character passives
@Getter @Setter private int flyCloak; @Getter
@Getter @Setter private int costume; @Setter
@Getter private int bornTime; private int flyCloak;
@Getter
@Setter
private int costume;
@Getter
private int bornTime;
@Getter @Setter private int fetterLevel = 1; @Getter
@Getter @Setter private int fetterExp; @Setter
private int fetterLevel = 1;
@Getter
@Setter
private int fetterExp;
@Getter @Setter private int nameCardRewardId; @Getter
@Getter @Setter private int nameCardId; @Setter
private int nameCardRewardId;
@Getter
@Setter
private int nameCardId;
// trial avatar property // trial avatar property
@Getter @Setter private int trialAvatarId = 0; @Getter
@Setter
private int trialAvatarId = 0;
// cannot store to db if grant reason is not integer // cannot store to db if grant reason is not integer
@Getter @Setter @Getter
@Setter
private int grantReason = TrialAvatarGrantRecord.GrantReason.GRANT_REASON_INVALID.getNumber(); private int grantReason = TrialAvatarGrantRecord.GrantReason.GRANT_REASON_INVALID.getNumber();
@Getter @Setter private int fromParentQuestId = 0; @Getter
@Setter
private int fromParentQuestId = 0;
// so far no outer class or prop value has information of this, but from packet: // so far no outer class or prop value has information of this, but from packet:
// 1 = normal, 2 = trial avatar // 1 = normal, 2 = trial avatar
@Transient @Getter @Setter private int avatarType = Type.NORMAL.getNumber(); @Transient
@Getter
@Setter
private int avatarType = Type.NORMAL.getNumber();
@Deprecated // Do not use. Morhpia only! @Deprecated // Do not use. Morhpia only!
public Avatar() { public Avatar() {
@ -123,16 +197,11 @@ public class Avatar {
this.proudSkillList = new HashSet<>(); this.proudSkillList = new HashSet<>();
// Combat properties // Combat properties
Stream.of(FightProperty.values()) Stream.of(FightProperty.values()).map(FightProperty::getId).filter(id -> (id > 0) && (id < 3000)).forEach(id -> this.setFightProperty(id, 0f));
.map(FightProperty::getId)
.filter(id -> (id > 0) && (id < 3000))
.forEach(id -> this.setFightProperty(id, 0f));
this.setSkillDepotData( this.setSkillDepotData(switch (this.getAvatarId()) {
switch (this.getAvatarId()) {
case GameConstants.MAIN_CHARACTER_MALE -> GameData.getAvatarSkillDepotDataMap().get(501); case GameConstants.MAIN_CHARACTER_MALE -> GameData.getAvatarSkillDepotDataMap().get(501);
case GameConstants.MAIN_CHARACTER_FEMALE -> GameData.getAvatarSkillDepotDataMap() case GameConstants.MAIN_CHARACTER_FEMALE -> GameData.getAvatarSkillDepotDataMap().get(701);
.get(701);
default -> data.getSkillDepot(); default -> data.getSkillDepot();
}); });
@ -166,8 +235,7 @@ public class Avatar {
* @return True if the avatar is a main character. * @return True if the avatar is a main character.
*/ */
public boolean isMainCharacter() { public boolean isMainCharacter() {
return List.of(GameConstants.MAIN_CHARACTER_MALE, GameConstants.MAIN_CHARACTER_FEMALE) return List.of(GameConstants.MAIN_CHARACTER_MALE, GameConstants.MAIN_CHARACTER_FEMALE).contains(this.getAvatarId());
.contains(this.getAvatarId());
} }
public Player getPlayer() { public Player getPlayer() {
@ -229,7 +297,8 @@ public class Avatar {
/** /**
* @return The avatar's equipped weapon. * @return The avatar's equipped weapon.
*/ */
@Nullable public GameItem getWeapon() { @Nullable
public GameItem getWeapon() {
return this.getEquipBySlot(EquipType.EQUIP_WEAPON); return this.getEquipBySlot(EquipType.EQUIP_WEAPON);
} }
@ -266,17 +335,10 @@ public class Avatar {
this.skillDepotId = skillDepot.getId(); this.skillDepotId = skillDepot.getId();
this.skillDepot = skillDepot; this.skillDepot = skillDepot;
// Add any missing skills // Add any missing skills
this.skillDepot this.skillDepot.getSkillsAndEnergySkill().forEach(skillId -> this.skillLevelMap.putIfAbsent(skillId, 1));
.getSkillsAndEnergySkill()
.forEach(skillId -> this.skillLevelMap.putIfAbsent(skillId, 1));
// Add proud skills // Add proud skills
this.proudSkillList.clear(); this.proudSkillList.clear();
skillDepot.getInherentProudSkillOpens().stream() skillDepot.getInherentProudSkillOpens().stream().filter(openData -> openData.getProudSkillGroupId() > 0).filter(openData -> openData.getNeedAvatarPromoteLevel() <= this.getPromoteLevel()).mapToInt(openData -> (openData.getProudSkillGroupId() * 100) + 1).filter(proudSkillId -> GameData.getProudSkillDataMap().containsKey(proudSkillId)).forEach(proudSkillId -> this.proudSkillList.add(proudSkillId));
.filter(openData -> openData.getProudSkillGroupId() > 0)
.filter(openData -> openData.getNeedAvatarPromoteLevel() <= this.getPromoteLevel())
.mapToInt(openData -> (openData.getProudSkillGroupId() * 100) + 1)
.filter(proudSkillId -> GameData.getProudSkillDataMap().containsKey(proudSkillId))
.forEach(proudSkillId -> this.proudSkillList.add(proudSkillId));
this.recalcStats(); this.recalcStats();
if (notify) { if (notify) {
@ -348,8 +410,7 @@ public class Avatar {
ElementType element = depot.getElementType(); ElementType element = depot.getElementType();
var maxEnergy = depot.getEnergySkillData().getCostElemVal(); var maxEnergy = depot.getEnergySkillData().getCostElemVal();
this.setFightProperty(element.getMaxEnergyProp(), maxEnergy); this.setFightProperty(element.getMaxEnergyProp(), maxEnergy);
this.setFightProperty( this.setFightProperty(element.getCurEnergyProp(), GAME_OPTIONS.energyUsage ? currentEnergy : maxEnergy);
element.getCurEnergyProp(), GAME_OPTIONS.energyUsage ? currentEnergy : maxEnergy);
} }
} }
@ -377,13 +438,10 @@ public class Avatar {
return getFightProperties().getOrDefault(prop.getId(), 0f); return getFightProperties().getOrDefault(prop.getId(), 0f);
} }
public Map<Integer, Integer> public Map<Integer, Integer> getSkillLevelMap() { // Returns a copy of the skill levels for the current skillDepot.
getSkillLevelMap() { // Returns a copy of the skill levels for the current skillDepot.
var map = new Int2IntOpenHashMap(); var map = new Int2IntOpenHashMap();
this.skillDepot if (this.skillDepot == null) return map;
.getSkillsAndEnergySkill() this.skillDepot.getSkillsAndEnergySkill().forEach(skillId -> map.put(skillId, this.skillLevelMap.putIfAbsent(skillId, 1).intValue()));
.forEach(
skillId -> map.put(skillId, this.skillLevelMap.putIfAbsent(skillId, 1).intValue()));
return map; return map;
} }
@ -391,10 +449,8 @@ public class Avatar {
// levels. // levels.
public Map<Integer, Integer> getProudSkillBonusMap() { public Map<Integer, Integer> getProudSkillBonusMap() {
var map = new Int2IntArrayMap(); var map = new Int2IntArrayMap();
this.skillDepot if (this.skillDepot == null) return map;
.getSkillsAndEnergySkill() this.skillDepot.getSkillsAndEnergySkill().forEach(skillId -> {
.forEach(
skillId -> {
val skillData = GameData.getAvatarSkillDataMap().get(skillId); val skillData = GameData.getAvatarSkillDataMap().get(skillId);
if (skillData == null) return; if (skillData == null) return;
int proudSkillGroupId = skillData.getProudSkillGroupId(); int proudSkillGroupId = skillData.getProudSkillGroupId();
@ -439,9 +495,7 @@ public class Avatar {
if (otherAvatar != null) { if (otherAvatar != null) {
// Unequip other avatar's item // Unequip other avatar's item
if (otherAvatar.unequipItem(item.getItemData().getEquipType())) { if (otherAvatar.unequipItem(item.getItemData().getEquipType())) {
getPlayer() getPlayer().sendPacket(new PacketAvatarEquipChangeNotify(otherAvatar, item.getItemData().getEquipType()));
.sendPacket(
new PacketAvatarEquipChangeNotify(otherAvatar, item.getItemData().getEquipType()));
} }
// Swap with other avatar // Swap with other avatar
if (getEquips().containsKey(itemEquipType.getValue())) { if (getEquips().containsKey(itemEquipType.getValue())) {
@ -459,14 +513,9 @@ public class Avatar {
this.getEquips().put(itemEquipType.getValue(), item); this.getEquips().put(itemEquipType.getValue(), item);
if (itemEquipType == EquipType.EQUIP_WEAPON && getPlayer().getWorld() != null) { if (itemEquipType == EquipType.EQUIP_WEAPON && getPlayer().getWorld() != null) {
if (!(item.getWeaponEntity() != null if (!(item.getWeaponEntity() != null && item.getWeaponEntity().getScene() == getPlayer().getScene())) {
&& item.getWeaponEntity().getScene() == getPlayer().getScene())) { item.setWeaponEntity(new EntityWeapon(this.getPlayer().getScene(), item.getItemData().getGadgetId()));
item.setWeaponEntity( this.getPlayer().getScene().getWeaponEntities().put(item.getWeaponEntity().getId(), item.getWeaponEntity());
new EntityWeapon(this.getPlayer().getScene(), item.getItemData().getGadgetId()));
this.getPlayer()
.getScene()
.getWeaponEntities()
.put(item.getWeaponEntity().getId(), item.getWeaponEntity());
} }
// item.setWeaponEntityId(this.getPlayer().getWorld().getNextEntityId(EntityIdType.WEAPON)); // item.setWeaponEntityId(this.getPlayer().getWorld().getNextEntityId(EntityIdType.WEAPON));
} }
@ -504,8 +553,7 @@ public class Avatar {
public void recalcStats(boolean forceSendAbilityChange) { public void recalcStats(boolean forceSendAbilityChange) {
// Setup // Setup
var data = this.getAvatarData(); var data = this.getAvatarData();
var promoteData = var promoteData = GameData.getAvatarPromoteData(data.getAvatarPromoteId(), this.getPromoteLevel());
GameData.getAvatarPromoteData(data.getAvatarPromoteId(), this.getPromoteLevel());
var setMap = new Int2IntOpenHashMap(); var setMap = new Int2IntOpenHashMap();
// Extra ability embryos // Extra ability embryos
@ -518,27 +566,18 @@ public class Avatar {
this.setNameCardId(data.getNameCardId()); this.setNameCardId(data.getNameCardId());
// Get hp percent, set to 100% if none // Get hp percent, set to 100% if none
float hpPercent = float hpPercent = this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) <= 0 ? 1f : this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) / this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) <= 0
? 1f
: this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP)
/ this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
// Store current energy value for later // Store current energy value for later
float currentEnergy = float currentEnergy = (this.getSkillDepot() != null) ? this.getFightProperty(this.getSkillDepot().getElementType().getCurEnergyProp()) : 0f;
(this.getSkillDepot() != null)
? this.getFightProperty(this.getSkillDepot().getElementType().getCurEnergyProp())
: 0f;
// Clear properties // Clear properties
this.getFightProperties().clear(); this.getFightProperties().clear();
// Base stats // Base stats
this.setFightProperty(FightProperty.FIGHT_PROP_BASE_HP, data.getBaseHp(this.getLevel())); this.setFightProperty(FightProperty.FIGHT_PROP_BASE_HP, data.getBaseHp(this.getLevel()));
this.setFightProperty( this.setFightProperty(FightProperty.FIGHT_PROP_BASE_ATTACK, data.getBaseAttack(this.getLevel()));
FightProperty.FIGHT_PROP_BASE_ATTACK, data.getBaseAttack(this.getLevel())); this.setFightProperty(FightProperty.FIGHT_PROP_BASE_DEFENSE, data.getBaseDefense(this.getLevel()));
this.setFightProperty(
FightProperty.FIGHT_PROP_BASE_DEFENSE, data.getBaseDefense(this.getLevel()));
this.setFightProperty(FightProperty.FIGHT_PROP_CRITICAL, data.getBaseCritical()); this.setFightProperty(FightProperty.FIGHT_PROP_CRITICAL, data.getBaseCritical());
this.setFightProperty(FightProperty.FIGHT_PROP_CRITICAL_HURT, data.getBaseCriticalHurt()); this.setFightProperty(FightProperty.FIGHT_PROP_CRITICAL_HURT, data.getBaseCriticalHurt());
this.setFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, 1f); this.setFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, 1f);
@ -560,14 +599,11 @@ public class Avatar {
continue; continue;
} }
// Artifact main stat // Artifact main stat
ReliquaryMainPropData mainPropData = ReliquaryMainPropData mainPropData = GameData.getReliquaryMainPropDataMap().get(equip.getMainPropId());
GameData.getReliquaryMainPropDataMap().get(equip.getMainPropId());
if (mainPropData != null) { if (mainPropData != null) {
ReliquaryLevelData levelData = ReliquaryLevelData levelData = GameData.getRelicLevelData(equip.getItemData().getRankLevel(), equip.getLevel());
GameData.getRelicLevelData(equip.getItemData().getRankLevel(), equip.getLevel());
if (levelData != null) { if (levelData != null) {
this.addFightProperty( this.addFightProperty(mainPropData.getFightProp(), levelData.getPropValue(mainPropData.getFightProp()));
mainPropData.getFightProp(), levelData.getPropValue(mainPropData.getFightProp()));
} }
} }
// Artifact sub stats // Artifact sub stats
@ -584,8 +620,7 @@ public class Avatar {
} }
// Set stuff // Set stuff
setMap.forEach( setMap.forEach((setId, amount) -> {
(setId, amount) -> {
ReliquarySetData setData = GameData.getReliquarySetDataMap().get((int) setId); ReliquarySetData setData = GameData.getReliquarySetDataMap().get((int) setId);
if (setData == null) return; if (setData == null) return;
@ -618,15 +653,11 @@ public class Avatar {
WeaponCurveData curveData = GameData.getWeaponCurveDataMap().get(weapon.getLevel()); WeaponCurveData curveData = GameData.getWeaponCurveDataMap().get(weapon.getLevel());
if (curveData != null) { if (curveData != null) {
for (WeaponProperty weaponProperty : weapon.getItemData().getWeaponProperties()) { for (WeaponProperty weaponProperty : weapon.getItemData().getWeaponProperties()) {
this.addFightProperty( this.addFightProperty(weaponProperty.getPropType(), weaponProperty.getInitValue() * curveData.getMultByProp(weaponProperty.getType()));
weaponProperty.getPropType(),
weaponProperty.getInitValue() * curveData.getMultByProp(weaponProperty.getType()));
} }
} }
// Weapon promotion stats // Weapon promotion stats
WeaponPromoteData wepPromoteData = WeaponPromoteData wepPromoteData = GameData.getWeaponPromoteData(weapon.getItemData().getWeaponPromoteId(), weapon.getPromoteLevel());
GameData.getWeaponPromoteData(
weapon.getItemData().getWeaponPromoteId(), weapon.getPromoteLevel());
if (wepPromoteData != null) { if (wepPromoteData != null) {
for (FightPropData prop : wepPromoteData.getAddProps()) { for (FightPropData prop : wepPromoteData.getAddProps()) {
if (prop.getValue() == 0f || prop.getProp() == null) { if (prop.getValue() == 0f || prop.getProp() == null) {
@ -661,8 +692,7 @@ public class Avatar {
} }
// Add proud skills and unlock them if needed // Add proud skills and unlock them if needed
AvatarSkillDepotData skillDepot = AvatarSkillDepotData skillDepot = GameData.getAvatarSkillDepotDataMap().get(this.getSkillDepotId());
GameData.getAvatarSkillDepotDataMap().get(this.getSkillDepotId());
this.getProudSkillList().clear(); this.getProudSkillList().clear();
if (skillDepot != null) { if (skillDepot != null) {
for (InherentProudSkillOpens openData : skillDepot.getInherentProudSkillOpens()) { for (InherentProudSkillOpens openData : skillDepot.getInherentProudSkillOpens()) {
@ -695,31 +725,17 @@ public class Avatar {
} }
// Constellations // Constellations
this.getTalentIdList() this.getTalentIdList().intStream().mapToObj(GameData.getAvatarTalentDataMap()::get).filter(Objects::nonNull).map(AvatarTalentData::getOpenConfig).filter(Objects::nonNull).forEach(this::addToExtraAbilityEmbryos);
.intStream()
.mapToObj(GameData.getAvatarTalentDataMap()::get)
.filter(Objects::nonNull)
.map(AvatarTalentData::getOpenConfig)
.filter(Objects::nonNull)
.forEach(this::addToExtraAbilityEmbryos);
// Add any skill strings from this constellation // Add any skill strings from this constellation
// Set % stats // Set % stats
FightProperty.forEachCompoundProperty( FightProperty.forEachCompoundProperty(c -> this.setFightProperty(c.getResult(), this.getFightProperty(c.getFlat()) + (this.getFightProperty(c.getBase()) * (1f + this.getFightProperty(c.getPercent())))));
c ->
this.setFightProperty(
c.getResult(),
this.getFightProperty(c.getFlat())
+ (this.getFightProperty(c.getBase())
* (1f + this.getFightProperty(c.getPercent())))));
// Reapply all overrides // Reapply all overrides
this.fightProperties.putAll(this.fightPropOverrides); this.fightProperties.putAll(this.fightPropOverrides);
// Set current hp // Set current hp
this.setFightProperty( this.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * hpPercent);
FightProperty.FIGHT_PROP_CUR_HP,
this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * hpPercent);
// Packet // Packet
if (getPlayer() != null && getPlayer().hasSentLoginPackets()) { if (getPlayer() != null && getPlayer().hasSentLoginPackets()) {
@ -727,9 +743,7 @@ public class Avatar {
getPlayer().sendPacket(new PacketAvatarFightPropNotify(this)); getPlayer().sendPacket(new PacketAvatarFightPropNotify(this));
// Update client abilities // Update client abilities
EntityAvatar entity = this.getAsEntity(); EntityAvatar entity = this.getAsEntity();
if (entity != null if (entity != null && (!this.getExtraAbilityEmbryos().equals(prevExtraAbilityEmbryos) || forceSendAbilityChange)) {
&& (!this.getExtraAbilityEmbryos().equals(prevExtraAbilityEmbryos)
|| forceSendAbilityChange)) {
getPlayer().sendPacket(new PacketAbilityChangeNotify(entity)); getPlayer().sendPacket(new PacketAbilityChangeNotify(entity));
} }
} }
@ -767,19 +781,12 @@ public class Avatar {
// Check if new constellation adds +3 to a skill level // Check if new constellation adds +3 to a skill level
if (this.calcConstellationExtraLevels(entry) && notifyClient) { if (this.calcConstellationExtraLevels(entry) && notifyClient) {
// Packet // Packet
this.getPlayer() this.getPlayer().sendPacket(new PacketProudSkillExtraLevelNotify(this, entry.getExtraTalentIndex()));
.sendPacket(new PacketProudSkillExtraLevelNotify(this, entry.getExtraTalentIndex()));
} }
// Check if new constellation adds skill charges // Check if new constellation adds skill charges
if (this.calcConstellationExtraCharges(entry) && notifyClient) { if (this.calcConstellationExtraCharges(entry) && notifyClient) {
// Packet // Packet
Stream.of(entry.getSkillPointModifiers()) Stream.of(entry.getSkillPointModifiers()).mapToInt(SkillPointModifier::getSkillId).forEach(skillId -> this.getPlayer().sendPacket(new PacketAvatarSkillMaxChargeCountNotify(this, skillId, this.getSkillExtraChargeMap().getOrDefault(skillId, 0))));
.mapToInt(SkillPointModifier::getSkillId)
.forEach(
skillId -> this.getPlayer()
.sendPacket(
new PacketAvatarSkillMaxChargeCountNotify(
this, skillId, this.getSkillExtraChargeMap().getOrDefault(skillId, 0))));
} }
} }
@ -793,16 +800,7 @@ public class Avatar {
return; return;
} }
this.getTalentIdList() this.getTalentIdList().intStream().mapToObj(GameData.getAvatarTalentDataMap()::get).filter(Objects::nonNull).map(AvatarTalentData::getOpenConfig).filter(Objects::nonNull).filter(openConfig -> !openConfig.isEmpty()).map(GameData.getOpenConfigEntries()::get).filter(Objects::nonNull).forEach(e -> this.calcConstellation(e, false));
.intStream()
.mapToObj(GameData.getAvatarTalentDataMap()::get)
.filter(Objects::nonNull)
.map(AvatarTalentData::getOpenConfig)
.filter(Objects::nonNull)
.filter(openConfig -> !openConfig.isEmpty())
.map(GameData.getOpenConfigEntries()::get)
.filter(Objects::nonNull)
.forEach(e -> this.calcConstellation(e, false));
} }
private boolean calcConstellationExtraCharges(OpenConfigEntry entry) { private boolean calcConstellationExtraCharges(OpenConfigEntry entry) {
@ -822,15 +820,12 @@ public class Avatar {
} }
private boolean calcConstellationExtraLevels(OpenConfigEntry entry) { private boolean calcConstellationExtraLevels(OpenConfigEntry entry) {
int skillId = if(this.skillDepot == null) return false;
switch (entry.getExtraTalentIndex()) { int skillId = switch (entry.getExtraTalentIndex()) {
case 9 -> this.skillDepot.getEnergySkill(); // Ult skill case 9 -> this.skillDepot.getEnergySkill(); // Ult skill
case 2 -> (this.skillDepot.getSkills().size() >= 2) case 2 -> (this.skillDepot.getSkills().size() >= 2) ? this.skillDepot.getSkills().get(1) : 0; // E skill
? this.skillDepot.getSkills().get(1) case 1 ->
: 0; // E skill (!this.skillDepot.getSkills().isEmpty()) ? this.skillDepot.getSkills().get(0) : 0; // Normal Attack (Liney)
case 1 -> (!this.skillDepot.getSkills().isEmpty())
? this.skillDepot.getSkills().get(0)
: 0; // Normal Attack (Liney)
default -> 0; default -> 0;
}; };
// Sanity check // Sanity check
@ -851,8 +846,7 @@ public class Avatar {
} }
private int addProudSkillLevelBonus(int proudSkillGroupId, int bonus) { private int addProudSkillLevelBonus(int proudSkillGroupId, int bonus) {
return this.proudSkillBonusMap.compute( return this.proudSkillBonusMap.compute(proudSkillGroupId, (k, v) -> (v == null) ? bonus : v + bonus);
proudSkillGroupId, (k, v) -> (v == null) ? bonus : v + bonus);
} }
public boolean upgradeSkill(int skillId) { public boolean upgradeSkill(int skillId) {
@ -883,9 +877,7 @@ public class Avatar {
if (level < 0 || level > 15) return false; if (level < 0 || level > 15) return false;
var validLevels = GameData.getAvatarSkillLevels(skillId); var validLevels = GameData.getAvatarSkillLevels(skillId);
if (validLevels != null && !validLevels.contains(level)) return false; if (validLevels != null && !validLevels.contains(level)) return false;
int oldLevel = int oldLevel = this.skillLevelMap.getOrDefault(skillId, 0); // just taking the return value of put would have null concerns
this.skillLevelMap.getOrDefault(
skillId, 0); // just taking the return value of put would have null concerns
this.skillLevelMap.put(skillId, level); this.skillLevelMap.put(skillId, level);
this.save(); this.save();
@ -904,7 +896,7 @@ public class Avatar {
public boolean unlockConstellation(boolean skipPayment) { public boolean unlockConstellation(boolean skipPayment) {
int currentTalentLevel = this.getCoreProudSkillLevel(); int currentTalentLevel = this.getCoreProudSkillLevel();
if (currentTalentLevel < 0) return false; if (currentTalentLevel < 0 || this.skillDepot == null) return false;
int talentId = this.skillDepot.getTalents().get(currentTalentLevel); int talentId = this.skillDepot.getTalents().get(currentTalentLevel);
return this.unlockConstellation(talentId, skipPayment); return this.unlockConstellation(talentId, skipPayment);
} }
@ -920,9 +912,7 @@ public class Avatar {
var player = this.getPlayer(); var player = this.getPlayer();
// Pay constellation item if possible // Pay constellation item if possible
if (!skipPayment if (!skipPayment && (player != null) && !player.getInventory().payItem(talentData.getMainCostItemId(), 1)) {
&& (player != null)
&& !player.getInventory().payItem(talentData.getMainCostItemId(), 1)) {
return false; return false;
} }
@ -953,8 +943,7 @@ public class Avatar {
this.save(); this.save();
return; return;
} }
this.talentIdList.removeAll( this.talentIdList.removeAll(this.getTalentIdList()); // Only remove constellations from active depot
this.getTalentIdList()); // Only remove constellations from active depot
for (int i = 0; i < level; i++) this.unlockConstellation(true); for (int i = 0; i < level; i++) this.unlockConstellation(true);
this.recalcStats(); this.recalcStats();
this.save(); this.save();
@ -963,12 +952,7 @@ public class Avatar {
public boolean sendSkillExtraChargeMap() { public boolean sendSkillExtraChargeMap() {
val map = this.getSkillExtraChargeMap(); val map = this.getSkillExtraChargeMap();
if (map.isEmpty()) return false; if (map.isEmpty()) return false;
this.getPlayer() this.getPlayer().sendPacket(new PacketAvatarSkillInfoNotify(this.guid, new Int2IntArrayMap(map))); // TODO: Remove this allocation when updating interfaces to FastUtils
.sendPacket(
new PacketAvatarSkillInfoNotify(
this.guid,
new Int2IntArrayMap(
map))); // TODO: Remove this allocation when updating interfaces to FastUtils
// later // later
return true; return true;
} }
@ -1000,12 +984,7 @@ public class Avatar {
} }
if (this.fetters != null) { if (this.fetters != null) {
this.fetters.forEach( this.fetters.forEach(fetterId -> avatarFetter.addFetterList(FetterData.newBuilder().setFetterId(fetterId).setFetterState(FetterState.FINISH.getValue())));
fetterId ->
avatarFetter.addFetterList(
FetterData.newBuilder()
.setFetterId(fetterId)
.setFetterState(FetterState.FINISH.getValue())));
} }
int cardId = this.getNameCardId(); int cardId = this.getNameCardId();
@ -1014,100 +993,40 @@ public class Avatar {
avatarFetter.addRewardedFetterLevelList(10); avatarFetter.addRewardedFetterLevelList(10);
} }
AvatarInfo.Builder avatarInfo = AvatarInfo.Builder avatarInfo = AvatarInfo.newBuilder().setAvatarId(this.getAvatarId()).setGuid(this.getGuid()).setLifeState(1).addAllTalentIdList(this.getTalentIdList()).putAllFightPropMap(this.getFightProperties()).setSkillDepotId(this.getSkillDepotId()).setCoreProudSkillLevel(this.getCoreProudSkillLevel()).putAllSkillLevelMap(this.getSkillLevelMap()).addAllInherentProudSkillList(this.getProudSkillList()).putAllProudSkillExtraLevelMap(this.getProudSkillBonusMap()).setAvatarType(this.getAvatarType()).setBornTime(this.getBornTime()).setFetterInfo(avatarFetter).setWearingFlycloakId(this.getFlyCloak()).setCostumeId(this.getCostume());
AvatarInfo.newBuilder()
.setAvatarId(this.getAvatarId())
.setGuid(this.getGuid())
.setLifeState(1)
.addAllTalentIdList(this.getTalentIdList())
.putAllFightPropMap(this.getFightProperties())
.setSkillDepotId(this.getSkillDepotId())
.setCoreProudSkillLevel(this.getCoreProudSkillLevel())
.putAllSkillLevelMap(this.getSkillLevelMap())
.addAllInherentProudSkillList(this.getProudSkillList())
.putAllProudSkillExtraLevelMap(this.getProudSkillBonusMap())
.setAvatarType(this.getAvatarType())
.setBornTime(this.getBornTime())
.setFetterInfo(avatarFetter)
.setWearingFlycloakId(this.getFlyCloak())
.setCostumeId(this.getCostume());
this.getSkillExtraChargeMap() this.getSkillExtraChargeMap().forEach((skillId, count) -> avatarInfo.putSkillMap(skillId, AvatarSkillInfo.newBuilder().setMaxChargeCount(count).build()));
.forEach(
(skillId, count) ->
avatarInfo.putSkillMap(
skillId, AvatarSkillInfo.newBuilder().setMaxChargeCount(count).build()));
this.getEquips().forEach((k, item) -> avatarInfo.addEquipGuidList(item.getGuid())); this.getEquips().forEach((k, item) -> avatarInfo.addEquipGuidList(item.getGuid()));
avatarInfo.putPropMap( avatarInfo.putPropMap(PlayerProperty.PROP_LEVEL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, this.getLevel()));
PlayerProperty.PROP_LEVEL.getId(), avatarInfo.putPropMap(PlayerProperty.PROP_EXP.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_EXP, this.getExp()));
ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, this.getLevel())); avatarInfo.putPropMap(PlayerProperty.PROP_BREAK_LEVEL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_BREAK_LEVEL, this.getPromoteLevel()));
avatarInfo.putPropMap( avatarInfo.putPropMap(PlayerProperty.PROP_SATIATION_VAL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_VAL, this.getSatiation()));
PlayerProperty.PROP_EXP.getId(), avatarInfo.putPropMap(PlayerProperty.PROP_SATIATION_PENALTY_TIME.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_PENALTY_TIME, this.getSatiationPenalty()));
ProtoHelper.newPropValue(PlayerProperty.PROP_EXP, this.getExp()));
avatarInfo.putPropMap(
PlayerProperty.PROP_BREAK_LEVEL.getId(),
ProtoHelper.newPropValue(PlayerProperty.PROP_BREAK_LEVEL, this.getPromoteLevel()));
avatarInfo.putPropMap(
PlayerProperty.PROP_SATIATION_VAL.getId(),
ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_VAL, this.getSatiation()));
avatarInfo.putPropMap(
PlayerProperty.PROP_SATIATION_PENALTY_TIME.getId(),
ProtoHelper.newPropValue(
PlayerProperty.PROP_SATIATION_PENALTY_TIME, this.getSatiationPenalty()));
return avatarInfo.build(); return avatarInfo.build();
} }
// used only in character showcase // used only in character showcase
public ShowAvatarInfo toShowAvatarInfoProto() { public ShowAvatarInfo toShowAvatarInfoProto() {
AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder().setExpLevel(this.getFetterLevel());
AvatarFetterInfo.newBuilder().setExpLevel(this.getFetterLevel());
ShowAvatarInfo.Builder showAvatarInfo = ShowAvatarInfo.Builder showAvatarInfo = ShowAvatarInfoOuterClass.ShowAvatarInfo.newBuilder().setAvatarId(avatarId).addAllTalentIdList(this.getTalentIdList()).putAllFightPropMap(this.getFightProperties()).setSkillDepotId(this.getSkillDepotId()).setCoreProudSkillLevel(this.getCoreProudSkillLevel()).addAllInherentProudSkillList(this.getProudSkillList()).putAllSkillLevelMap(this.getSkillLevelMap()).putAllProudSkillExtraLevelMap(this.getProudSkillBonusMap()).setFetterInfo(avatarFetter).setCostumeId(this.getCostume());
ShowAvatarInfoOuterClass.ShowAvatarInfo.newBuilder()
.setAvatarId(avatarId)
.addAllTalentIdList(this.getTalentIdList())
.putAllFightPropMap(this.getFightProperties())
.setSkillDepotId(this.getSkillDepotId())
.setCoreProudSkillLevel(this.getCoreProudSkillLevel())
.addAllInherentProudSkillList(this.getProudSkillList())
.putAllSkillLevelMap(this.getSkillLevelMap())
.putAllProudSkillExtraLevelMap(this.getProudSkillBonusMap())
.setFetterInfo(avatarFetter)
.setCostumeId(this.getCostume());
showAvatarInfo.putPropMap( showAvatarInfo.putPropMap(PlayerProperty.PROP_LEVEL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, this.getLevel()));
PlayerProperty.PROP_LEVEL.getId(), showAvatarInfo.putPropMap(PlayerProperty.PROP_EXP.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_EXP, this.getExp()));
ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, this.getLevel())); showAvatarInfo.putPropMap(PlayerProperty.PROP_BREAK_LEVEL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_BREAK_LEVEL, this.getPromoteLevel()));
showAvatarInfo.putPropMap( showAvatarInfo.putPropMap(PlayerProperty.PROP_SATIATION_VAL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_VAL, this.getSatiation()));
PlayerProperty.PROP_EXP.getId(), showAvatarInfo.putPropMap(PlayerProperty.PROP_SATIATION_PENALTY_TIME.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_PENALTY_TIME, this.getSatiationPenalty()));
ProtoHelper.newPropValue(PlayerProperty.PROP_EXP, this.getExp()));
showAvatarInfo.putPropMap(
PlayerProperty.PROP_BREAK_LEVEL.getId(),
ProtoHelper.newPropValue(PlayerProperty.PROP_BREAK_LEVEL, this.getPromoteLevel()));
showAvatarInfo.putPropMap(
PlayerProperty.PROP_SATIATION_VAL.getId(),
ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_VAL, this.getSatiation()));
showAvatarInfo.putPropMap(
PlayerProperty.PROP_SATIATION_PENALTY_TIME.getId(),
ProtoHelper.newPropValue(
PlayerProperty.PROP_SATIATION_PENALTY_TIME, this.getSatiationPenalty()));
int maxStamina = this.getPlayer().getProperty(PlayerProperty.PROP_MAX_STAMINA); int maxStamina = this.getPlayer().getProperty(PlayerProperty.PROP_MAX_STAMINA);
showAvatarInfo.putPropMap( showAvatarInfo.putPropMap(PlayerProperty.PROP_MAX_STAMINA.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_MAX_STAMINA, maxStamina));
PlayerProperty.PROP_MAX_STAMINA.getId(),
ProtoHelper.newPropValue(PlayerProperty.PROP_MAX_STAMINA, maxStamina));
for (GameItem item : this.getEquips().values()) { for (GameItem item : this.getEquips().values()) {
if (item.getItemType() == ItemType.ITEM_RELIQUARY) { if (item.getItemType() == ItemType.ITEM_RELIQUARY) {
showAvatarInfo.addEquipList( showAvatarInfo.addEquipList(ShowEquip.newBuilder().setItemId(item.getItemId()).setReliquary(item.toReliquaryProto()));
ShowEquip.newBuilder()
.setItemId(item.getItemId())
.setReliquary(item.toReliquaryProto()));
} else if (item.getItemType() == ItemType.ITEM_WEAPON) { } else if (item.getItemType() == ItemType.ITEM_WEAPON) {
showAvatarInfo.addEquipList( showAvatarInfo.addEquipList(ShowEquip.newBuilder().setItemId(item.getItemId()).setWeapon(item.toWeaponProto()));
ShowEquip.newBuilder().setItemId(item.getItemId()).setWeapon(item.toWeaponProto()));
} }
} }
@ -1122,8 +1041,7 @@ public class Avatar {
* @param grantReason The reason for granting the avatar. * @param grantReason The reason for granting the avatar.
* @param questId The ID of the quest that granted the avatar. * @param questId The ID of the quest that granted the avatar.
*/ */
public void setTrialAvatarInfo( public void setTrialAvatarInfo(int level, int avatarId, TrialAvatarGrantRecord.GrantReason grantReason, int questId) {
int level, int avatarId, TrialAvatarGrantRecord.GrantReason grantReason, int questId) {
this.setLevel(level); this.setLevel(level);
this.setPromoteLevel(getMinPromoteLevel(level)); this.setPromoteLevel(getMinPromoteLevel(level));
this.setTrialAvatarId(avatarId); this.setTrialAvatarId(avatarId);
@ -1140,10 +1058,7 @@ public class Avatar {
* @return The avatar's template. * @return The avatar's template.
*/ */
private int getTrialTemplate() { private int getTrialTemplate() {
return this.getLevel() <= 9 return this.getLevel() <= 9 ? 1 : (int) (Math.floor(this.getLevel() / 10f) * 10); // round trial level to fit template levels
? 1
: (int)
(Math.floor(this.getLevel() / 10f) * 10); // round trial level to fit template levels
} }
/** /**
@ -1165,11 +1080,11 @@ public class Avatar {
return trialData.getCoreProudSkillLevel(); // enhanced version of weapon return trialData.getCoreProudSkillLevel(); // enhanced version of weapon
} }
/** Applies the correct skill level for the trial avatar. */ /**
* Applies the correct skill level for the trial avatar.
*/
public void applyTrialSkillLevels() { public void applyTrialSkillLevels() {
this.getSkillLevelMap() this.getSkillLevelMap().keySet().forEach(skill -> this.setSkillLevel(skill, this.getTrialSkillLevel()));
.keySet()
.forEach(skill -> this.setSkillLevel(skill, this.getTrialSkillLevel()));
} }
/** /**
@ -1181,9 +1096,7 @@ public class Avatar {
if (GameData.getTrialAvatarDataMap().get(this.getTrialAvatarId()) == null) if (GameData.getTrialAvatarDataMap().get(this.getTrialAvatarId()) == null)
return this.getAvatarData().getInitialWeapon(); return this.getAvatarData().getInitialWeapon();
return GameData.getItemDataMap().get(this.getAvatarData().getInitialWeapon() + 100) == null return GameData.getItemDataMap().get(this.getAvatarData().getInitialWeapon() + 100) == null ? getAvatarData().getInitialWeapon() : getAvatarData().getInitialWeapon() + 100; // enhanced version of weapon
? getAvatarData().getInitialWeapon()
: getAvatarData().getInitialWeapon() + 100; // enhanced version of weapon
} }
// Use custom data. // Use custom data.
@ -1191,9 +1104,7 @@ public class Avatar {
if (trialData == null) return 0; if (trialData == null) return 0;
var trialCustomParams = trialData.getTrialAvatarParamList(); var trialCustomParams = trialData.getTrialAvatarParamList();
return trialCustomParams.size() < 2 return trialCustomParams.size() < 2 ? getAvatarData().getInitialWeapon() : Integer.parseInt(trialCustomParams.get(1).split(";")[0]);
? getAvatarData().getInitialWeapon()
: Integer.parseInt(trialCustomParams.get(1).split(";")[0]);
} }
/** /**
@ -1204,8 +1115,7 @@ public class Avatar {
if (GameData.getTrialAvatarCustomData().isEmpty()) { if (GameData.getTrialAvatarCustomData().isEmpty()) {
int trialAvatarTemplateLevel = getTrialTemplate(); int trialAvatarTemplateLevel = getTrialTemplate();
TrialAvatarTemplateData templateData = TrialAvatarTemplateData templateData = GameData.getTrialAvatarTemplateDataMap().get(trialAvatarTemplateLevel);
GameData.getTrialAvatarTemplateDataMap().get(trialAvatarTemplateLevel);
return templateData == null ? List.of() : templateData.getTrialReliquaryList(); return templateData == null ? List.of() : templateData.getTrialReliquaryList();
} }
@ -1213,14 +1123,13 @@ public class Avatar {
var trialData = GameData.getTrialAvatarCustomData().get(this.getTrialAvatarId()); var trialData = GameData.getTrialAvatarCustomData().get(this.getTrialAvatarId());
if (trialData == null) return List.of(); if (trialData == null) return List.of();
var trialCustomParams = var trialCustomParams = GameData.getTrialAvatarCustomData().get(getTrialAvatarId()).getTrialAvatarParamList();
GameData.getTrialAvatarCustomData().get(getTrialAvatarId()).getTrialAvatarParamList(); return trialCustomParams.size() < 3 ? List.of() : Stream.of(trialCustomParams.get(2).split(";")).map(Integer::parseInt).toList();
return trialCustomParams.size() < 3
? List.of()
: Stream.of(trialCustomParams.get(2).split(";")).map(Integer::parseInt).toList();
} }
/** Applies the correct items for the trial avatar. */ /**
* Applies the correct items for the trial avatar.
*/
public void applyTrialItems() { public void applyTrialItems() {
// Use an enhanced version of the weapon if available. // Use an enhanced version of the weapon if available.
var weapon = new GameItem(this.getTrialWeaponId()); var weapon = new GameItem(this.getTrialWeaponId());
@ -1230,9 +1139,7 @@ public class Avatar {
this.getEquips().put(weapon.getEquipSlot(), weapon); this.getEquips().put(weapon.getEquipSlot(), weapon);
// Add artifacts for the trial avatar. // Add artifacts for the trial avatar.
this.getTrialReliquary() this.getTrialReliquary().forEach(id -> {
.forEach(
id -> {
var reliquaryData = GameData.getTrialReliquaryDataMap().get((int) id); var reliquaryData = GameData.getTrialReliquaryDataMap().get((int) id);
if (reliquaryData == null) return; if (reliquaryData == null) return;
@ -1245,35 +1152,26 @@ public class Avatar {
// Add costume if avatar has a costume. // Add costume if avatar has a costume.
if (GAME_OPTIONS.trialCostumes) { if (GAME_OPTIONS.trialCostumes) {
GameData.getAvatarCostumeDataItemIdMap() GameData.getAvatarCostumeDataItemIdMap().values().forEach(costumeData -> {
.values()
.forEach(
costumeData -> {
if (costumeData.getCharacterId() != this.getAvatarId()) return; if (costumeData.getCharacterId() != this.getAvatarId()) return;
this.setCostume(costumeData.getId()); this.setCostume(costumeData.getId());
}); });
} }
} }
/** Equips the items applied from {@link Avatar#applyTrialItems()}. */ /**
* Equips the items applied from {@link Avatar#applyTrialItems()}.
*/
public void equipTrialItems() { public void equipTrialItems() {
var player = this.getPlayer(); var player = this.getPlayer();
this.getEquips() this.getEquips().values().forEach(item -> {
.values()
.forEach(
item -> {
item.setEquipCharacter(this.getAvatarId()); item.setEquipCharacter(this.getAvatarId());
item.setOwner(player); item.setOwner(player);
if (item.getItemData().getEquipType() == EquipType.EQUIP_WEAPON) { if (item.getItemData().getEquipType() == EquipType.EQUIP_WEAPON) {
if (!(item.getWeaponEntity() != null if (!(item.getWeaponEntity() != null && item.getWeaponEntity().getScene() == player.getScene())) {
&& item.getWeaponEntity().getScene() == player.getScene())) { item.setWeaponEntity(new EntityWeapon(player.getScene(), item.getItemData().getGadgetId()));
item.setWeaponEntity( player.getScene().getWeaponEntities().put(item.getWeaponEntity().getId(), item.getWeaponEntity());
new EntityWeapon(player.getScene(), item.getItemData().getGadgetId()));
player
.getScene()
.getWeaponEntities()
.put(item.getWeaponEntity().getId(), item.getWeaponEntity());
} }
player.sendPacket(new PacketAvatarEquipChangeNotify(this, item)); player.sendPacket(new PacketAvatarEquipChangeNotify(this, item));
@ -1287,26 +1185,20 @@ public class Avatar {
* @return The trial info protocol buffer. * @return The trial info protocol buffer.
*/ */
public TrialAvatarInfo toTrialInfo() { public TrialAvatarInfo toTrialInfo() {
var trialAvatar = var trialAvatar = TrialAvatarInfo.newBuilder().setTrialAvatarId(this.getTrialAvatarId()).setGrantRecord(TrialAvatarGrantRecord.newBuilder().setGrantReason(this.getGrantReason()).setFromParentQuestId(this.getFromParentQuestId()));
TrialAvatarInfo.newBuilder()
.setTrialAvatarId(this.getTrialAvatarId())
.setGrantRecord(
TrialAvatarGrantRecord.newBuilder()
.setGrantReason(this.getGrantReason())
.setFromParentQuestId(this.getFromParentQuestId()));
// Check if the avatar is a trial avatar. // Check if the avatar is a trial avatar.
if (this.getTrialAvatarId() > 0) { if (this.getTrialAvatarId() > 0) {
// Add the artifacts and weapons for the avatar. // Add the artifacts and weapons for the avatar.
trialAvatar.addAllTrialEquipList( trialAvatar.addAllTrialEquipList(this.getEquips().values().stream().map(GameItem::toProto).toList());
this.getEquips().values().stream().map(GameItem::toProto).toList());
} }
return trialAvatar.build(); return trialAvatar.build();
} }
@PostLoad @PostLoad
private void onLoad() {} private void onLoad() {
}
@PrePersist @PrePersist
private void prePersist() { private void prePersist() {
@ -1316,8 +1208,7 @@ public class Avatar {
@AllArgsConstructor @AllArgsConstructor
@Getter @Getter
enum Type { enum Type {
NORMAL(1), NORMAL(1), TRIAL(2);
TRIAL(2);
final int number; final int number;
} }

View File

@ -347,7 +347,7 @@ public final class Language {
return Files.getLastModifiedTime(path).toMillis(); return Files.getLastModifiedTime(path).toMillis();
} catch (Exception ignored) { } catch (Exception ignored) {
Grasscutter.getLogger() Grasscutter.getLogger()
.debug("Exception while checking modified time: ", path); .debug("Exception while checking modified time: {}", path);
return Long.MAX_VALUE; // Don't use cache, something has gone wrong return Long.MAX_VALUE; // Don't use cache, something has gone wrong
} }
}) })