diff --git a/src/main/java/emu/grasscutter/data/excels/MonsterData.java b/src/main/java/emu/grasscutter/data/excels/MonsterData.java index 758937fda..de31c3381 100644 --- a/src/main/java/emu/grasscutter/data/excels/MonsterData.java +++ b/src/main/java/emu/grasscutter/data/excels/MonsterData.java @@ -1,19 +1,28 @@ package emu.grasscutter.data.excels; import java.util.List; +import java.util.Set; + +import com.google.gson.annotations.SerializedName; import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameResource; import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType.LoadPriority; import emu.grasscutter.data.common.PropGrowCurve; +import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.MonsterType; +import lombok.Getter; @ResourceType(name = "MonsterExcelConfigData.json", loadPriority = LoadPriority.LOW) +@Getter public class MonsterData extends GameResource { - private int id; - - private String monsterName; + static public Set definedFightProperties = Set.of(FightProperty.FIGHT_PROP_BASE_HP, FightProperty.FIGHT_PROP_BASE_ATTACK, FightProperty.FIGHT_PROP_BASE_DEFENSE, FightProperty.FIGHT_PROP_PHYSICAL_SUB_HURT, FightProperty.FIGHT_PROP_FIRE_SUB_HURT, FightProperty.FIGHT_PROP_ELEC_SUB_HURT, FightProperty.FIGHT_PROP_WATER_SUB_HURT, FightProperty.FIGHT_PROP_GRASS_SUB_HURT, FightProperty.FIGHT_PROP_WIND_SUB_HURT, FightProperty.FIGHT_PROP_ROCK_SUB_HURT, FightProperty.FIGHT_PROP_ICE_SUB_HURT); + + @Getter(onMethod = @__(@Override)) + private int id; + + private String monsterName; private MonsterType type; private String serverScript; private List affix; @@ -28,9 +37,14 @@ public class MonsterData extends GameResource { private int describeId; private int combatBGMLevel; private int entityBudgetLevel; - private float hpBase; - private float attackBase; - private float defenseBase; + + @SerializedName("hpBase") + private float baseHp; + @SerializedName("attackBase") + private float baseAttack; + @SerializedName("defenseBase") + private float baseDefense; + private float fireSubHurt; private float elecSubHurt; private float grassSubHurt; @@ -46,127 +60,23 @@ public class MonsterData extends GameResource { // Transient private int weaponId; private MonsterDescribeData describeData; - - @Override - public int getId() { - return this.id; - } - - public String getMonsterName() { - return monsterName; - } - public MonsterType getType() { - return type; - } - - public String getServerScript() { - return serverScript; - } - - public List getAffix() { - return affix; - } - - public String getAi() { - return ai; - } - - public int[] getEquips() { - return equips; - } - - public List getHpDrops() { - return hpDrops; - } - - public int getKillDropId() { - return killDropId; - } - - public String getExcludeWeathers() { - return excludeWeathers; - } - - public int getFeatureTagGroupID() { - return featureTagGroupID; - } - - public int getMpPropID() { - return mpPropID; - } - - public String getSkin() { - return skin; - } - - public int getDescribeId() { - return describeId; - } - - public int getCombatBGMLevel() { - return combatBGMLevel; - } - - public int getEntityBudgetLevel() { - return entityBudgetLevel; - } - - public float getBaseHp() { - return hpBase; - } - - public float getBaseAttack() { - return attackBase; - } - - public float getBaseDefense() { - return defenseBase; - } - - public float getElecSubHurt() { - return elecSubHurt; - } - - public float getGrassSubHurt() { - return grassSubHurt; - } - - public float getWaterSubHurt() { - return waterSubHurt; - } - - public float getWindSubHurt() { - return windSubHurt; - } - - public float getIceSubHurt() { - return iceSubHurt; - } - - public float getPhysicalSubHurt() { - return physicalSubHurt; - } - - public List getPropGrowCurves() { - return propGrowCurves; - } - - public long getNameTextMapHash() { - return nameTextMapHash; - } - - public int getCampID() { - return campID; - } - - public MonsterDescribeData getDescribeData() { - return describeData; - } - - public int getWeaponId() { - return weaponId; - } + public float getFightProperty(FightProperty prop) { + return switch (prop) { + case FIGHT_PROP_BASE_HP -> this.baseHp; + case FIGHT_PROP_BASE_ATTACK -> this.baseAttack; + case FIGHT_PROP_BASE_DEFENSE -> this.baseDefense; + case FIGHT_PROP_PHYSICAL_SUB_HURT -> this.physicalSubHurt; + case FIGHT_PROP_FIRE_SUB_HURT -> this.fireSubHurt; + case FIGHT_PROP_ELEC_SUB_HURT -> this.elecSubHurt; + case FIGHT_PROP_WATER_SUB_HURT -> this.waterSubHurt; + case FIGHT_PROP_GRASS_SUB_HURT -> this.grassSubHurt; + case FIGHT_PROP_WIND_SUB_HURT -> this.windSubHurt; + case FIGHT_PROP_ROCK_SUB_HURT -> this.rockSubHurt; + case FIGHT_PROP_ICE_SUB_HURT -> this.iceSubHurt; + default -> 0f; + }; + } @Override public void onLoad() { @@ -185,16 +95,10 @@ public class MonsterData extends GameResource { } } } - - public class HpDrops { - private int DropId; - private int HpPercent; - public int getDropId(){ - return this.DropId; - } - public int getHpPercent(){ - return this.HpPercent; - } - } + @Getter + public class HpDrops { + private int DropId; + private int HpPercent; + } } diff --git a/src/main/java/emu/grasscutter/game/avatar/Avatar.java b/src/main/java/emu/grasscutter/game/avatar/Avatar.java index 4286a9a5d..adb3dc759 100644 --- a/src/main/java/emu/grasscutter/game/avatar/Avatar.java +++ b/src/main/java/emu/grasscutter/game/avatar/Avatar.java @@ -58,6 +58,7 @@ import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass.ShowAvatarInfo; import emu.grasscutter.net.proto.ShowEquipOuterClass.ShowEquip; import emu.grasscutter.server.packet.send.*; import emu.grasscutter.utils.ProtoHelper; +import it.unimi.dsi.fastutil.ints.Int2FloatMap; import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2IntArrayMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; @@ -89,7 +90,7 @@ public class Avatar { private float currentEnergy; @Transient @Getter private final Int2ObjectMap equips; - @Transient private final Int2FloatOpenHashMap fightProp; + @Transient @Getter private final Int2FloatOpenHashMap fightProperties; @Transient @Getter private final Int2FloatOpenHashMap fightPropOverrides; @Transient @Getter private Set extraAbilityEmbryos; @@ -115,7 +116,7 @@ public class Avatar { @Deprecated // Do not use. Morhpia only! public Avatar() { this.equips = new Int2ObjectOpenHashMap<>(); - this.fightProp = new Int2FloatOpenHashMap(); + this.fightProperties = new Int2FloatOpenHashMap(); this.fightPropOverrides = new Int2FloatOpenHashMap(); this.extraAbilityEmbryos = new HashSet<>(); this.fetters = new ArrayList<>(); // TODO Move to avatar @@ -276,10 +277,6 @@ public class Avatar { } } - public Int2FloatOpenHashMap getFightProperties() { - return fightProp; - } - public void setFightProperty(FightProperty prop, float value) { this.getFightProperties().put(prop.getId(), value); } @@ -399,9 +396,9 @@ public class Avatar { public void recalcStats(boolean forceSendAbilityChange) { // Setup - AvatarData data = this.getAvatarData(); - AvatarPromoteData promoteData = GameData.getAvatarPromoteData(data.getAvatarPromoteId(), this.getPromoteLevel()); - Int2IntOpenHashMap setMap = new Int2IntOpenHashMap(); + var data = this.getAvatarData(); + var promoteData = GameData.getAvatarPromoteData(data.getAvatarPromoteId(), this.getPromoteLevel()); + var setMap = new Int2IntOpenHashMap(); // Extra ability embryos Set prevExtraAbilityEmbryos = this.getExtraAbilityEmbryos(); @@ -579,21 +576,11 @@ public class Avatar { // Add any skill strings from this constellation // Set % stats - this.setFightProperty( - FightProperty.FIGHT_PROP_MAX_HP, - (getFightProperty(FightProperty.FIGHT_PROP_BASE_HP) * (1f + getFightProperty(FightProperty.FIGHT_PROP_HP_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_HP) - ); - this.setFightProperty( - FightProperty.FIGHT_PROP_CUR_ATTACK, - (getFightProperty(FightProperty.FIGHT_PROP_BASE_ATTACK) * (1f + getFightProperty(FightProperty.FIGHT_PROP_ATTACK_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_ATTACK) - ); - this.setFightProperty( - FightProperty.FIGHT_PROP_CUR_DEFENSE, - (getFightProperty(FightProperty.FIGHT_PROP_BASE_DEFENSE) * (1f + getFightProperty(FightProperty.FIGHT_PROP_DEFENSE_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_DEFENSE) - ); + FightProperty.forEachCompoundProperty(c -> this.setFightProperty(c.getResult(), + this.getFightProperty(c.getFlat()) + (this.getFightProperty(c.getBase()) * (1f + this.getFightProperty(c.getPercent()))))); // Reapply all overrides - this.fightProp.putAll(this.fightPropOverrides); + this.fightProperties.putAll(this.fightPropOverrides); // Set current hp this.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * hpPercent); diff --git a/src/main/java/emu/grasscutter/game/avatar/AvatarStat.java b/src/main/java/emu/grasscutter/game/avatar/AvatarStat.java deleted file mode 100644 index fc20d00d3..000000000 --- a/src/main/java/emu/grasscutter/game/avatar/AvatarStat.java +++ /dev/null @@ -1,124 +0,0 @@ -package emu.grasscutter.game.avatar; - -import java.util.stream.Stream; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; - -public enum AvatarStat { - FIGHT_PROP_NONE(0), - FIGHT_PROP_BASE_HP(1), - FIGHT_PROP_HP(2), - FIGHT_PROP_HP_PERCENT(3), - FIGHT_PROP_BASE_ATTACK(4), - FIGHT_PROP_ATTACK(5), - FIGHT_PROP_ATTACK_PERCENT(6), - FIGHT_PROP_BASE_DEFENSE(7), - FIGHT_PROP_DEFENSE(8), - FIGHT_PROP_DEFENSE_PERCENT(9), - FIGHT_PROP_BASE_SPEED(10), - FIGHT_PROP_SPEED_PERCENT(11), - FIGHT_PROP_HP_MP_PERCENT(12), - FIGHT_PROP_ATTACK_MP_PERCENT(13), - FIGHT_PROP_CRITICAL(20), - FIGHT_PROP_ANTI_CRITICAL(21), - FIGHT_PROP_CRITICAL_HURT(22), - FIGHT_PROP_CHARGE_EFFICIENCY(23), - FIGHT_PROP_ADD_HURT(24), - FIGHT_PROP_SUB_HURT(25), - FIGHT_PROP_HEAL_ADD(26), - FIGHT_PROP_HEALED_ADD(27), - FIGHT_PROP_ELEMENT_MASTERY(28), - FIGHT_PROP_PHYSICAL_SUB_HURT(29), - FIGHT_PROP_PHYSICAL_ADD_HURT(30), - FIGHT_PROP_DEFENCE_IGNORE_RATIO(31), - FIGHT_PROP_DEFENCE_IGNORE_DELTA(32), - FIGHT_PROP_FIRE_ADD_HURT(40), - FIGHT_PROP_ELEC_ADD_HURT(41), - FIGHT_PROP_WATER_ADD_HURT(42), - FIGHT_PROP_GRASS_ADD_HURT(43), - FIGHT_PROP_WIND_ADD_HURT(44), - FIGHT_PROP_ROCK_ADD_HURT(45), - FIGHT_PROP_ICE_ADD_HURT(46), - FIGHT_PROP_HIT_HEAD_ADD_HURT(47), - FIGHT_PROP_FIRE_SUB_HURT(50), - FIGHT_PROP_ELEC_SUB_HURT(51), - FIGHT_PROP_WATER_SUB_HURT(52), - FIGHT_PROP_GRASS_SUB_HURT(53), - FIGHT_PROP_WIND_SUB_HURT(54), - FIGHT_PROP_ROCK_SUB_HURT(55), - FIGHT_PROP_ICE_SUB_HURT(56), - FIGHT_PROP_EFFECT_HIT(60), - FIGHT_PROP_EFFECT_RESIST(61), - FIGHT_PROP_FREEZE_RESIST(62), - FIGHT_PROP_TORPOR_RESIST(63), - FIGHT_PROP_DIZZY_RESIST(64), - FIGHT_PROP_FREEZE_SHORTEN(65), - FIGHT_PROP_TORPOR_SHORTEN(66), - FIGHT_PROP_DIZZY_SHORTEN(67), - FIGHT_PROP_MAX_FIRE_ENERGY(70), - FIGHT_PROP_MAX_ELEC_ENERGY(71), - FIGHT_PROP_MAX_WATER_ENERGY(72), - FIGHT_PROP_MAX_GRASS_ENERGY(73), - FIGHT_PROP_MAX_WIND_ENERGY(74), - FIGHT_PROP_MAX_ICE_ENERGY(75), - FIGHT_PROP_MAX_ROCK_ENERGY(76), - FIGHT_PROP_SKILL_CD_MINUS_RATIO(80), - FIGHT_PROP_SHIELD_COST_MINUS_RATIO(81), - FIGHT_PROP_CUR_FIRE_ENERGY(1000), - FIGHT_PROP_CUR_ELEC_ENERGY(1001), - FIGHT_PROP_CUR_WATER_ENERGY(1002), - FIGHT_PROP_CUR_GRASS_ENERGY(1003), - FIGHT_PROP_CUR_WIND_ENERGY(1004), - FIGHT_PROP_CUR_ICE_ENERGY(1005), - FIGHT_PROP_CUR_ROCK_ENERGY(1006), - FIGHT_PROP_CUR_HP(1010), - FIGHT_PROP_MAX_HP(2000), - FIGHT_PROP_CUR_ATTACK(2001), - FIGHT_PROP_CUR_DEFENSE(2002), - FIGHT_PROP_CUR_SPEED(2003), - FIGHT_PROP_NONEXTRA_ATTACK(3000), - FIGHT_PROP_NONEXTRA_DEFENSE(3001), - FIGHT_PROP_NONEXTRA_CRITICAL(3002), - FIGHT_PROP_NONEXTRA_ANTI_CRITICAL(3003), - FIGHT_PROP_NONEXTRA_CRITICAL_HURT(3004), - FIGHT_PROP_NONEXTRA_CHARGE_EFFICIENCY(3005), - FIGHT_PROP_NONEXTRA_ELEMENT_MASTERY(3006), - FIGHT_PROP_NONEXTRA_PHYSICAL_SUB_HURT(3007), - FIGHT_PROP_NONEXTRA_FIRE_ADD_HURT(3008), - FIGHT_PROP_NONEXTRA_ELEC_ADD_HURT(3009), - FIGHT_PROP_NONEXTRA_WATER_ADD_HURT(3010), - FIGHT_PROP_NONEXTRA_GRASS_ADD_HURT(3011), - FIGHT_PROP_NONEXTRA_WIND_ADD_HURT(3012), - FIGHT_PROP_NONEXTRA_ROCK_ADD_HURT(3013), - FIGHT_PROP_NONEXTRA_ICE_ADD_HURT(3014), - FIGHT_PROP_NONEXTRA_FIRE_SUB_HURT(3015), - FIGHT_PROP_NONEXTRA_ELEC_SUB_HURT(3016), - FIGHT_PROP_NONEXTRA_WATER_SUB_HURT(3017), - FIGHT_PROP_NONEXTRA_GRASS_SUB_HURT(3018), - FIGHT_PROP_NONEXTRA_WIND_SUB_HURT(3019), - FIGHT_PROP_NONEXTRA_ROCK_SUB_HURT(3020), - FIGHT_PROP_NONEXTRA_ICE_SUB_HURT(3021), - FIGHT_PROP_NONEXTRA_SKILL_CD_MINUS_RATIO(3022), - FIGHT_PROP_NONEXTRA_SHIELD_COST_MINUS_RATIO(3023), - FIGHT_PROP_NONEXTRA_PHYSICAL_ADD_HURT(3024); - - private final int id; - private static final Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); - - static { - Stream.of(values()).forEach(e -> map.put(e.getId(), e)); - } - - private AvatarStat(int id) { - this.id = id; - } - - public int getId() { - return id; - } - - public static AvatarStat getStatById(int value) { - return map.getOrDefault(value, FIGHT_PROP_NONE); - } -} diff --git a/src/main/java/emu/grasscutter/game/entity/EntityAvatar.java b/src/main/java/emu/grasscutter/game/entity/EntityAvatar.java index 8bce738fa..ef8ca5dcf 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityAvatar.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityAvatar.java @@ -21,7 +21,6 @@ import emu.grasscutter.net.proto.ChangeHpReasonOuterClass.ChangeHpReason; import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo; import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData; import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo; -import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair; import emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType; import emu.grasscutter.net.proto.PropChangeReasonOuterClass.PropChangeReason; import emu.grasscutter.net.proto.PropPairOuterClass.PropPair; @@ -38,20 +37,25 @@ import emu.grasscutter.utils.Position; import emu.grasscutter.utils.ProtoHelper; import emu.grasscutter.utils.Utils; import it.unimi.dsi.fastutil.ints.Int2FloatMap; -import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; +import lombok.Getter; import lombok.val; public class EntityAvatar extends GameEntity { - private final Avatar avatar; + @Getter private final Avatar avatar; - private PlayerDieType killedType; - private int killedBy; + @Getter private PlayerDieType killedType; + @Getter private int killedBy; + + public EntityAvatar(Avatar avatar) { + this(null, avatar); + } public EntityAvatar(Scene scene, Avatar avatar) { super(scene); this.avatar = avatar; this.avatar.setCurrentEnergy(); - this.id = getScene().getWorld().getNextEntityId(EntityIdType.AVATAR); + if (scene != null) + this.id = getScene().getWorld().getNextEntityId(EntityIdType.AVATAR); GameItem weapon = this.getAvatar().getWeapon(); if (weapon != null) { @@ -59,47 +63,20 @@ public class EntityAvatar extends GameEntity { } } - public EntityAvatar(Avatar avatar) { - super(null); - this.avatar = avatar; - this.avatar.setCurrentEnergy(); - } - - public Player getPlayer() { - return avatar.getPlayer(); - } + public Player getPlayer() {return this.avatar.getPlayer();} @Override - public Position getPosition() { - return getPlayer().getPosition(); - } + public Position getPosition() {return getPlayer().getPosition();} @Override - public Position getRotation() { - return getPlayer().getRotation(); - } - - public Avatar getAvatar() { - return avatar; - } - - public int getKilledBy() { - return killedBy; - } - - public PlayerDieType getKilledType() { - return killedType; - } + public Position getRotation() {return getPlayer().getRotation();} @Override public boolean isAlive() { return this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) > 0f; } - @Override - public Int2FloatOpenHashMap getFightProperties() { - return getAvatar().getFightProperties(); - } + @Override public Int2FloatMap getFightProperties() {return getAvatar().getFightProperties();} public int getWeaponEntityId() { if (getAvatar().getWeapon() != null) { @@ -145,11 +122,8 @@ public class EntityAvatar extends GameEntity { public void clearEnergy(ChangeEnergyReason reason) { // Fight props. - FightProperty curEnergyProp = this.getAvatar().getSkillDepot().getElementType().getCurEnergyProp(); - FightProperty maxEnergyProp = this.getAvatar().getSkillDepot().getElementType().getMaxEnergyProp(); - - // Get max energy. - float maxEnergy = this.avatar.getFightProperty(maxEnergyProp); + val curEnergyProp = this.getAvatar().getSkillDepot().getElementType().getCurEnergyProp(); + float curEnergy = this.getFightProperty(curEnergyProp); // Set energy to zero. this.avatar.setCurrentEnergy(curEnergyProp, 0); @@ -158,7 +132,7 @@ public class EntityAvatar extends GameEntity { this.getScene().broadcastPacket(new PacketEntityFightPropUpdateNotify(this, curEnergyProp)); if (reason == ChangeEnergyReason.CHANGE_ENERGY_REASON_SKILL_START) { - this.getScene().broadcastPacket(new PacketEntityFightPropChangeReasonNotify(this, curEnergyProp, -maxEnergy, reason)); + this.getScene().broadcastPacket(new PacketEntityFightPropChangeReasonNotify(this, curEnergyProp, -curEnergy, reason)); } } @@ -167,18 +141,16 @@ public class EntityAvatar extends GameEntity { } public void addEnergy(float amount, PropChangeReason reason, boolean isFlat) { // Get current and maximum energy for this avatar. - FightProperty curEnergyProp = this.getAvatar().getSkillDepot().getElementType().getCurEnergyProp(); - FightProperty maxEnergyProp = this.getAvatar().getSkillDepot().getElementType().getMaxEnergyProp(); + val elementType = this.getAvatar().getSkillDepot().getElementType(); + val curEnergyProp = elementType.getCurEnergyProp(); + val maxEnergyProp = elementType.getMaxEnergyProp(); float curEnergy = this.getFightProperty(curEnergyProp); float maxEnergy = this.getFightProperty(maxEnergyProp); - // Get energy recharge. - float energyRecharge = this.getFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY); - // Scale amount by energy recharge, if the amount is not flat. if (!isFlat) { - amount *= energyRecharge; + amount *= this.getFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY); } // Determine the new energy value. diff --git a/src/main/java/emu/grasscutter/game/entity/EntityBaseGadget.java b/src/main/java/emu/grasscutter/game/entity/EntityBaseGadget.java index 6004c983d..b2370449a 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityBaseGadget.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityBaseGadget.java @@ -3,11 +3,23 @@ package emu.grasscutter.game.entity; import emu.grasscutter.data.binout.ConfigGadget; import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.world.Scene; +import emu.grasscutter.utils.Position; +import lombok.Getter; public abstract class EntityBaseGadget extends GameEntity { + @Getter(onMethod = @__(@Override)) + protected final Position position; + @Getter(onMethod = @__(@Override)) + protected final Position rotation; public EntityBaseGadget(Scene scene) { + this(scene, null, null); + } + + public EntityBaseGadget(Scene scene, Position position, Position rotation) { super(scene); + this.position = position != null ? position.clone() : new Position(); + this.rotation = rotation != null ? rotation.clone() : new Position(); } public abstract int getGadgetId(); diff --git a/src/main/java/emu/grasscutter/game/entity/EntityClientGadget.java b/src/main/java/emu/grasscutter/game/entity/EntityClientGadget.java index 34fcf918d..ef376bd4f 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityClientGadget.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityClientGadget.java @@ -19,30 +19,28 @@ import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo; import emu.grasscutter.net.proto.VectorOuterClass.Vector; import emu.grasscutter.utils.Position; import emu.grasscutter.utils.ProtoHelper; -import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2FloatMap; +import lombok.Getter; public class EntityClientGadget extends EntityBaseGadget { - private final Player owner; + @Getter private final Player owner; - private final Position pos; - private final Position rot; + @Getter(onMethod = @__(@Override)) + private int gadgetId; - private int configId; - private int campId; - private int campType; - private int ownerEntityId; - private int targetEntityId; - private boolean asyncLoad; + @Getter private int campId; + @Getter private int campType; + @Getter private int ownerEntityId; + @Getter private int targetEntityId; + @Getter private boolean asyncLoad; - private int originalOwnerEntityId; + @Getter private int originalOwnerEntityId; public EntityClientGadget(Scene scene, Player player, EvtCreateGadgetNotify notify) { - super(scene); + super(scene, new Position(notify.getInitPos()), new Position(notify.getInitEulerAngles())); this.owner = player; this.id = notify.getEntityId(); - this.pos = new Position(notify.getInitPos()); - this.rot = new Position(notify.getInitEulerAngles()); - this.configId = notify.getConfigId(); + this.gadgetId = notify.getConfigId(); this.campId = notify.getCampId(); this.campType = notify.getCampType(); this.ownerEntityId = notify.getPropOwnerEntityId(); @@ -58,61 +56,12 @@ public class EntityClientGadget extends EntityBaseGadget { } } - @Override - public int getGadgetId() { - return configId; - } - - public Player getOwner() { - return owner; - } - - public int getCampId() { - return campId; - } - - public int getCampType() { - return campType; - } - - public int getOwnerEntityId() { - return ownerEntityId; - } - - public int getTargetEntityId() { - return targetEntityId; - } - - public boolean isAsyncLoad() { - return this.asyncLoad; - } - - public int getOriginalOwnerEntityId() { - return this.originalOwnerEntityId; - } - @Override public void onDeath(int killerId) { super.onDeath(killerId); // Invoke super class's onDeath() method. } - @Override - public Int2FloatOpenHashMap getFightProperties() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Position getPosition() { - // TODO Auto-generated method stub - return this.pos; - } - - @Override - public Position getRotation() { - // TODO Auto-generated method stub - return this.rot; - } + @Override public Int2FloatMap getFightProperties() {return null;} @Override public SceneEntityInfo toProto() { diff --git a/src/main/java/emu/grasscutter/game/entity/EntityGadget.java b/src/main/java/emu/grasscutter/game/entity/EntityGadget.java index a7996b6d8..0689214db 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityGadget.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityGadget.java @@ -6,8 +6,6 @@ import emu.grasscutter.data.excels.GadgetData; import emu.grasscutter.game.entity.gadget.*; import emu.grasscutter.game.player.Player; import emu.grasscutter.game.props.EntityIdType; -import emu.grasscutter.game.props.EntityType; -import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.world.Scene; import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo; @@ -29,77 +27,47 @@ import emu.grasscutter.scripts.data.ScriptArgs; import emu.grasscutter.server.packet.send.PacketGadgetStateNotify; import emu.grasscutter.utils.Position; import emu.grasscutter.utils.ProtoHelper; +import it.unimi.dsi.fastutil.ints.Int2FloatMap; import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; import lombok.Getter; +import lombok.Setter; import lombok.ToString; +import java.util.Optional; + import javax.annotation.Nullable; @ToString(callSuper = true) public class EntityGadget extends EntityBaseGadget { - private final GadgetData data; - private final Position pos; - private final Position rot; + @Getter private final GadgetData gadgetData; + @Getter(onMethod = @__(@Override)) @Setter private int gadgetId; - private int state; - private int pointType; - private GadgetContent content; - private Int2FloatOpenHashMap fightProp; - private SceneGadget metaGadget; + @Getter @Setter private int state; + @Getter @Setter private int pointType; + @Getter private GadgetContent content; + @Getter(onMethod = @__(@Override), lazy = true) + private final Int2FloatMap fightProperties = new Int2FloatOpenHashMap(); + @Getter @Setter private SceneGadget metaGadget; @Nullable @Getter private ConfigGadget configGadget; - public EntityGadget(Scene scene, int gadgetId, Position pos, Position rot) { - super(scene); - this.data = GameData.getGadgetDataMap().get(gadgetId); - if (data!=null && data.getJsonName()!=null) { - this.configGadget = GameData.getGadgetConfigData().get(data.getJsonName()); - } - this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET); - this.gadgetId = gadgetId; - this.pos = pos.clone(); - this.rot = rot != null ? rot.clone() : new Position(); - fillFightProps(configGadget); + public EntityGadget(Scene scene, int gadgetId, Position pos) { + this(scene, gadgetId, pos, null, null); } - public EntityGadget(Scene scene, int gadgetId, Position pos) { - this(scene, gadgetId, pos, new Position()); + public EntityGadget(Scene scene, int gadgetId, Position pos, Position rot) { + this(scene, gadgetId, pos, rot, null); } public EntityGadget(Scene scene, int gadgetId, Position pos, Position rot, GadgetContent content) { - this(scene, gadgetId, pos, rot); - this.content = content; - } - - public GadgetData getGadgetData() { - return data; - } - - @Override - public Position getPosition() { - return this.pos; - } - - @Override - public Position getRotation() { - return this.rot; - } - - public int getGadgetId() { - return gadgetId; - } - - public void setGadgetId(int gadgetId) { + super(scene, pos, rot); + this.gadgetData = GameData.getGadgetDataMap().get(gadgetId); + this.configGadget = Optional.ofNullable(this.gadgetData).map(GadgetData::getJsonName).map(GameData.getGadgetConfigData()::get).orElse(null); + this.id = this.getScene().getWorld().getNextEntityId(EntityIdType.GADGET); this.gadgetId = gadgetId; - } - - public int getState() { - return state; - } - - public void setState(int state) { - this.state = state; + this.content = content; + fillFightProps(configGadget); } public void updateState(int state) { @@ -108,39 +76,18 @@ public class EntityGadget extends EntityBaseGadget { getScene().getScriptManager().callEvent(EventType.EVENT_GADGET_STATE_CHANGE, new ScriptArgs(state, this.getConfigId())); } - public int getPointType() { - return pointType; - } - - public void setPointType(int pointType) { - this.pointType = pointType; - } - - public GadgetContent getContent() { - return content; - } - - @Deprecated // Dont use! + @Deprecated(forRemoval = true) // Dont use! public void setContent(GadgetContent content) { this.content = this.content == null ? content : this.content; } - public SceneGadget getMetaGadget() { - return metaGadget; - } - - public void setMetaGadget(SceneGadget metaGadget) { - this.metaGadget = metaGadget; - } - // TODO refactor public void buildContent() { - if (getContent() != null || getGadgetData() == null || getGadgetData().getType() == null) { + if (this.getContent() != null || this.getGadgetData() == null || this.getGadgetData().getType() == null) { return; } - EntityType type = getGadgetData().getType(); - GadgetContent content = switch (type) { + this.content = switch (this.getGadgetData().getType()) { case GatherPoint -> new GadgetGatherPoint(this); case GatherObject -> new GadgetGatherObject(this); case Worktop -> new GadgetWorktop(this); @@ -149,14 +96,6 @@ public class EntityGadget extends EntityBaseGadget { case Gadget -> new GadgetObject(this); default -> null; }; - - this.content = content; - } - - @Override - public Int2FloatOpenHashMap getFightProperties() { - if (this.fightProp == null) this.fightProp = new Int2FloatOpenHashMap(); - return this.fightProp; } @Override @@ -216,7 +155,7 @@ public class EntityGadget extends EntityBaseGadget { entityInfo.addPropList(pair); // We do not use the getter to null check because the getter will create a fight prop map if it is null - if (this.fightProp != null) { + if (this.fightProperties != null) { addAllFightPropsToEntityInfo(entityInfo); } diff --git a/src/main/java/emu/grasscutter/game/entity/EntityItem.java b/src/main/java/emu/grasscutter/game/entity/EntityItem.java index c4befb408..cd3d81d60 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityItem.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityItem.java @@ -25,57 +25,33 @@ import emu.grasscutter.net.proto.VectorOuterClass.Vector; import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp; import emu.grasscutter.utils.Position; import emu.grasscutter.utils.ProtoHelper; -import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2FloatMap; +import lombok.Getter; public class EntityItem extends EntityBaseGadget { - private final Position pos; - private final Position rot; - - private final GameItem item; - private final long guid; - - private final boolean share; + @Getter private final GameItem item; + @Getter private final long guid; + @Getter private final boolean share; public EntityItem(Scene scene, Player player, ItemData itemData, Position pos, int count) { - super(scene); - this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET); - this.pos = new Position(pos); - this.rot = new Position(); - this.guid = player == null ? scene.getWorld().getHost().getNextGameGuid() : player.getNextGameGuid(); - this.item = new GameItem(itemData, count); - this.share = true; + this(scene, player, itemData, pos, count, true); } // In official game, some drop items are shared to all players, and some other items are independent to all players // For example, if you killed a monster in MP mode, all players could get drops but rarity and number of them are different // but if you broke regional mine, when someone picked up the drop then it disappeared public EntityItem(Scene scene, Player player, ItemData itemData, Position pos, int count, boolean share) { - super(scene); + super(scene, pos, null); this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET); - this.pos = new Position(pos); - this.rot = new Position(); this.guid = player == null ? scene.getWorld().getHost().getNextGameGuid() : player.getNextGameGuid(); this.item = new GameItem(itemData, count); this.share = share; } - @Override - public int getId() { - return this.id; - } - - private GameItem getItem() { - return this.item; - } - public ItemData getItemData() { return this.getItem().getItemData(); } - public long getGuid() { - return guid; - } - public int getCount() { return this.getItem().getCount(); } @@ -85,24 +61,7 @@ public class EntityItem extends EntityBaseGadget { return this.getItemData().getGadgetId(); } - @Override - public Position getPosition() { - return this.pos; - } - - @Override - public Position getRotation() { - return this.rot; - } - - @Override - public Int2FloatOpenHashMap getFightProperties() { - return null; - } - - public boolean isShare() { - return share; - } + @Override public Int2FloatMap getFightProperties() {return null;} @Override public void onInteract(Player player, GadgetInteractReq interactReq) { diff --git a/src/main/java/emu/grasscutter/game/entity/EntityMonster.java b/src/main/java/emu/grasscutter/game/entity/EntityMonster.java index 31e4b8630..19727b119 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityMonster.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityMonster.java @@ -1,14 +1,12 @@ package emu.grasscutter.game.entity; -import emu.grasscutter.Grasscutter; +import java.util.Optional; + import emu.grasscutter.data.GameData; -import emu.grasscutter.data.common.ItemParamData; import emu.grasscutter.data.common.PropGrowCurve; import emu.grasscutter.data.excels.EnvAnimalGatherConfigData; -import emu.grasscutter.data.excels.ItemData; import emu.grasscutter.data.excels.MonsterCurveData; import emu.grasscutter.data.excels.MonsterData; -import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.player.Player; import emu.grasscutter.game.props.ActionReason; import emu.grasscutter.game.props.EntityIdType; @@ -16,13 +14,11 @@ import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.props.WatcherTriggerType; import emu.grasscutter.game.world.Scene; -import emu.grasscutter.net.proto.VisionTypeOuterClass; import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo; import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair; import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo; import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData; import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo; -import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair; import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq; import emu.grasscutter.net.proto.MonsterBornTypeOuterClass.MonsterBornType; import emu.grasscutter.net.proto.PropPairOuterClass.PropPair; @@ -35,31 +31,32 @@ import emu.grasscutter.scripts.constants.EventType; import emu.grasscutter.scripts.data.ScriptArgs; import emu.grasscutter.utils.Position; import emu.grasscutter.utils.ProtoHelper; -import it.unimi.dsi.fastutil.ints.Int2FloatMap; import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; import lombok.Getter; import lombok.Setter; public class EntityMonster extends GameEntity { - private final MonsterData monsterData; - private final Int2FloatOpenHashMap fightProp; + @Getter private final MonsterData monsterData; + @Getter(onMethod = @__(@Override)) + private final Int2FloatOpenHashMap fightProperties; - private final Position pos; - private final Position rot; - private final Position bornPos; - private final int level; + @Getter(onMethod = @__(@Override)) + private final Position position; + @Getter(onMethod = @__(@Override)) + private final Position rotation; + @Getter private final Position bornPos; + @Getter private final int level; private int weaponEntityId; - private int poseId; - @Getter @Setter - private int aiId=-1; + @Getter @Setter private int poseId; + @Getter @Setter private int aiId = -1; public EntityMonster(Scene scene, MonsterData monsterData, Position pos, int level) { super(scene); this.id = getWorld().getNextEntityId(EntityIdType.MONSTER); this.monsterData = monsterData; - this.fightProp = new Int2FloatOpenHashMap(); - this.pos = new Position(pos); - this.rot = new Position(); + this.fightProperties = new Int2FloatOpenHashMap(); + this.position = new Position(pos); + this.rotation = new Position(); this.bornPos = getPosition().clone(); this.level = level; @@ -71,59 +68,19 @@ public class EntityMonster extends GameEntity { this.recalcStats(); } - @Override - public int getId() { - return this.id; - } - - public MonsterData getMonsterData() { - return monsterData; - } - public int getMonsterWeaponId() { - return getMonsterData().getWeaponId(); + return this.getMonsterData().getWeaponId(); } private int getMonsterId() { return this.getMonsterData().getId(); } - public int getLevel() { - return level; - } - - @Override - public Position getPosition() { - return this.pos; - } - - @Override - public Position getRotation() { - return this.rot; - } - - public Position getBornPos() { - return bornPos; - } - - @Override - public Int2FloatOpenHashMap getFightProperties() { - return fightProp; - } - @Override public boolean isAlive() { return this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) > 0f; } - public int getPoseId() { - return poseId; - } - - public void setPoseId(int poseId) { - this.poseId = poseId; - } - @Override public void onInteract(Player player, GadgetInteractReq interactReq) { EnvAnimalGatherConfigData gatherData = GameData.getEnvAnimalGatherConfigDataMap().get(this.getMonsterData().getId()); @@ -163,27 +120,24 @@ public class EntityMonster extends GameEntity { @Override public void onDeath(int killerId) { super.onDeath(killerId); // Invoke super class's onDeath() method. + var scene = this.getScene(); + var challenge = Optional.ofNullable(scene.getChallenge()); + var scriptManager = scene.getScriptManager(); + + Optional.ofNullable(this.getSpawnEntry()).ifPresent(scene.getDeadSpawnedEntities()::add); - if (this.getSpawnEntry() != null) { - this.getScene().getDeadSpawnedEntities().add(getSpawnEntry()); - } // first set the challenge data - if (getScene().getChallenge() != null) { - getScene().getChallenge().onMonsterDeath(this); - } - if (getScene().getScriptManager().isInit() && this.getGroupId() > 0) { - if (getScene().getScriptManager().getScriptMonsterSpawnService() != null) { - getScene().getScriptManager().getScriptMonsterSpawnService().onMonsterDead(this); - } + challenge.ifPresent(c -> c.onMonsterDeath(this)); + + if (scriptManager.isInit() && this.getGroupId() > 0) { + Optional.ofNullable(scriptManager.getScriptMonsterSpawnService()).ifPresent(s -> s.onMonsterDead(this)); + // prevent spawn monster after success - if (getScene().getChallenge() != null && getScene().getChallenge().inProgress()) { - getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, new ScriptArgs().setParam1(this.getConfigId())); - }else if (getScene().getChallenge() == null) { - getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, new ScriptArgs().setParam1(this.getConfigId())); - } + if (challenge.map(c -> c.inProgress()).orElse(true)) + scriptManager.callEvent(EventType.EVENT_ANY_MONSTER_DIE, new ScriptArgs().setParam1(this.getConfigId())); } // Battle Pass trigger - getScene().getPlayers().forEach(p -> p.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_MONSTER_DIE, this.getMonsterId(), 1)); + scene.getPlayers().forEach(p -> p.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_MONSTER_DIE, this.getMonsterId(), 1)); } public void recalcStats() { @@ -197,18 +151,7 @@ public class EntityMonster extends GameEntity { this.getFightProperties().clear(); // Base stats - this.setFightProperty(FightProperty.FIGHT_PROP_BASE_HP, data.getBaseHp()); - this.setFightProperty(FightProperty.FIGHT_PROP_BASE_ATTACK, data.getBaseAttack()); - this.setFightProperty(FightProperty.FIGHT_PROP_BASE_DEFENSE, data.getBaseDefense()); - - this.setFightProperty(FightProperty.FIGHT_PROP_PHYSICAL_SUB_HURT, data.getPhysicalSubHurt()); - this.setFightProperty(FightProperty.FIGHT_PROP_FIRE_SUB_HURT, .1f); - this.setFightProperty(FightProperty.FIGHT_PROP_ELEC_SUB_HURT, data.getElecSubHurt()); - this.setFightProperty(FightProperty.FIGHT_PROP_WATER_SUB_HURT, data.getWaterSubHurt()); - this.setFightProperty(FightProperty.FIGHT_PROP_GRASS_SUB_HURT, data.getGrassSubHurt()); - this.setFightProperty(FightProperty.FIGHT_PROP_WIND_SUB_HURT, data.getWindSubHurt()); - this.setFightProperty(FightProperty.FIGHT_PROP_ROCK_SUB_HURT, .1f); - this.setFightProperty(FightProperty.FIGHT_PROP_ICE_SUB_HURT, data.getIceSubHurt()); + MonsterData.definedFightProperties.forEach(prop -> this.setFightProperty(prop, data.getFightProperty(prop))); // Level curve MonsterCurveData curve = GameData.getMonsterCurveDataMap().get(this.getLevel()); @@ -220,18 +163,8 @@ public class EntityMonster extends GameEntity { } // Set % stats - this.setFightProperty( - FightProperty.FIGHT_PROP_MAX_HP, - (getFightProperty(FightProperty.FIGHT_PROP_BASE_HP) * (1f + getFightProperty(FightProperty.FIGHT_PROP_HP_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_HP) - ); - this.setFightProperty( - FightProperty.FIGHT_PROP_CUR_ATTACK, - (getFightProperty(FightProperty.FIGHT_PROP_BASE_ATTACK) * (1f + getFightProperty(FightProperty.FIGHT_PROP_ATTACK_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_ATTACK) - ); - this.setFightProperty( - FightProperty.FIGHT_PROP_CUR_DEFENSE, - (getFightProperty(FightProperty.FIGHT_PROP_BASE_DEFENSE) * (1f + getFightProperty(FightProperty.FIGHT_PROP_DEFENSE_PERCENT))) + getFightProperty(FightProperty.FIGHT_PROP_DEFENSE) - ); + FightProperty.forEachCompoundProperty(c -> this.setFightProperty(c.getResult(), + this.getFightProperty(c.getFlat()) + (this.getFightProperty(c.getBase()) * (1f + this.getFightProperty(c.getPercent()))))); // Set current hp this.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * hpPercent); @@ -239,14 +172,14 @@ public class EntityMonster extends GameEntity { @Override public SceneEntityInfo toProto() { - EntityAuthorityInfo authority = EntityAuthorityInfo.newBuilder() + var authority = EntityAuthorityInfo.newBuilder() .setAbilityInfo(AbilitySyncStateInfo.newBuilder()) .setRendererChangedInfo(EntityRendererChangedInfo.newBuilder()) .setAiInfo(SceneEntityAiInfo.newBuilder().setIsAiOpen(true).setBornPos(this.getBornPos().toProto())) .setBornPos(this.getBornPos().toProto()) .build(); - SceneEntityInfo.Builder entityInfo = SceneEntityInfo.newBuilder() + var entityInfo = SceneEntityInfo.newBuilder() .setEntityId(getId()) .setEntityType(ProtEntityType.PROT_ENTITY_TYPE_MONSTER) .setMotionInfo(this.getMotionInfo()) @@ -257,13 +190,12 @@ public class EntityMonster extends GameEntity { this.addAllFightPropsToEntityInfo(entityInfo); - PropPair pair = PropPair.newBuilder() - .setType(PlayerProperty.PROP_LEVEL.getId()) - .setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, getLevel())) - .build(); - entityInfo.addPropList(pair); + entityInfo.addPropList(PropPair.newBuilder() + .setType(PlayerProperty.PROP_LEVEL.getId()) + .setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, getLevel())) + .build()); - SceneMonsterInfo.Builder monsterInfo = SceneMonsterInfo.newBuilder() + var monsterInfo = SceneMonsterInfo.newBuilder() .setMonsterId(getMonsterId()) .setGroupId(this.getGroupId()) .setConfigId(this.getConfigId()) diff --git a/src/main/java/emu/grasscutter/game/entity/EntityNPC.java b/src/main/java/emu/grasscutter/game/entity/EntityNPC.java index 6d1fead52..4a26f251c 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityNPC.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityNPC.java @@ -5,14 +5,16 @@ import emu.grasscutter.game.world.Scene; import emu.grasscutter.net.proto.*; import emu.grasscutter.scripts.data.SceneNPC; import emu.grasscutter.utils.Position; -import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2FloatMap; +import lombok.Getter; public class EntityNPC extends GameEntity{ - + @Getter(onMethod = @__(@Override)) private final Position position; + @Getter(onMethod = @__(@Override)) private final Position rotation; private final SceneNPC metaNpc; - private final int suiteId; + @Getter private final int suiteId; public EntityNPC(Scene scene, SceneNPC metaNPC, int blockId, int suiteId) { super(scene); @@ -27,24 +29,7 @@ public class EntityNPC extends GameEntity{ } - @Override - public Int2FloatOpenHashMap getFightProperties() { - return null; - } - - @Override - public Position getPosition() { - return position; - } - - @Override - public Position getRotation() { - return rotation; - } - - public int getSuiteId() { - return suiteId; - } + @Override public Int2FloatMap getFightProperties() {return null;} @Override public SceneEntityInfoOuterClass.SceneEntityInfo toProto() { diff --git a/src/main/java/emu/grasscutter/game/entity/EntityRegion.java b/src/main/java/emu/grasscutter/game/entity/EntityRegion.java index 32fac1343..fef33ac86 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityRegion.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityRegion.java @@ -5,7 +5,7 @@ import emu.grasscutter.game.world.Scene; import emu.grasscutter.net.proto.SceneEntityInfoOuterClass; import emu.grasscutter.scripts.data.SceneRegion; import emu.grasscutter.utils.Position; -import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2FloatMap; import lombok.Getter; import java.util.Set; @@ -57,20 +57,11 @@ public class EntityRegion extends GameEntity{ } public boolean entityLeave() {return this.entityLeave;} public void resetEntityLeave() {this.entityLeave = false;} - @Override - public Int2FloatOpenHashMap getFightProperties() { - return null; - } + @Override public Int2FloatMap getFightProperties() {return null;} - @Override - public Position getPosition() { - return position; - } + @Override public Position getPosition() {return position;} - @Override - public Position getRotation() { - return null; - } + @Override public Position getRotation() {return null;} @Override public SceneEntityInfoOuterClass.SceneEntityInfo toProto() { diff --git a/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java b/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java index 462a0d402..7bb4f0dae 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityVehicle.java @@ -12,7 +12,6 @@ import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncState import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair; import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo; import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo; -import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair; import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo; import emu.grasscutter.net.proto.PropPairOuterClass.PropPair; import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType; @@ -36,10 +35,8 @@ import java.util.List; public class EntityVehicle extends EntityBaseGadget { @Getter private final Player owner; - private final Int2FloatMap fightProp; - - private final Position pos; - private final Position rot; + @Getter(onMethod = @__(@Override)) + private final Int2FloatMap fightProperties; @Getter private final int pointId; @Getter private final int gadgetId; @@ -49,12 +46,10 @@ public class EntityVehicle extends EntityBaseGadget { @Nullable @Getter private ConfigGadget configGadget; public EntityVehicle(Scene scene, Player player, int gadgetId, int pointId, Position pos, Position rot) { - super(scene); + super(scene, pos, rot); this.owner = player; this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET); - this.fightProp = new Int2FloatOpenHashMap(); - this.pos = new Position(pos); - this.rot = new Position(rot); + this.fightProperties = new Int2FloatOpenHashMap(); this.gadgetId = gadgetId; this.pointId = pointId; this.curStamina = 240; // might be in configGadget.GCALKECLLLP.JBAKBEFIMBN.ANBMPHPOALP @@ -74,19 +69,6 @@ public class EntityVehicle extends EntityBaseGadget { this.addFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, 0); } - @Override - public Int2FloatMap getFightProperties() { - return fightProp; - } - - @Override - public Position getPosition() { return this.pos; } - - @Override - public Position getRotation() { - return this.rot; - } - @Override public SceneEntityInfo toProto() { diff --git a/src/main/java/emu/grasscutter/game/entity/GameEntity.java b/src/main/java/emu/grasscutter/game/entity/GameEntity.java index 220edcb47..aed62ef35 100644 --- a/src/main/java/emu/grasscutter/game/entity/GameEntity.java +++ b/src/main/java/emu/grasscutter/game/entity/GameEntity.java @@ -33,7 +33,7 @@ public abstract class GameEntity { @Getter @Setter private int configId; @Getter @Setter private int groupId; - private MotionState moveState; + @Getter @Setter private MotionState motionState; @Getter @Setter private int lastMoveSceneTimeMs; @Getter @Setter private int lastMoveReliableSeq; @@ -45,7 +45,7 @@ public abstract class GameEntity { public GameEntity(Scene scene) { this.scene = scene; - this.moveState = MotionState.MOTION_STATE_NONE; + this.motionState = MotionState.MOTION_STATE_NONE; } public int getEntityType() { @@ -84,14 +84,6 @@ public abstract class GameEntity { public abstract Position getRotation(); - public MotionState getMotionState() { - return moveState; - } - - public void setMotionState(MotionState moveState) { - this.moveState = moveState; - } - public void setFightProperty(FightProperty prop, float value) { this.getFightProperties().put(prop.getId(), value); } diff --git a/src/main/java/emu/grasscutter/game/entity/platform/EntityPlatform.java b/src/main/java/emu/grasscutter/game/entity/platform/EntityPlatform.java index 3ec85c35e..cc946d685 100644 --- a/src/main/java/emu/grasscutter/game/entity/platform/EntityPlatform.java +++ b/src/main/java/emu/grasscutter/game/entity/platform/EntityPlatform.java @@ -20,12 +20,12 @@ import javax.annotation.Nullable; public class EntityPlatform extends EntityBaseGadget { @Getter private final Player owner; + @Getter(onMethod = @__(@Override)) private final int gadgetId; @Getter private final EntityClientGadget gadget; - private final Int2FloatMap fightProp; - private final Position pos; - private final Position rot; + @Getter(onMethod = @__(@Override)) + private final Int2FloatMap fightProperties; @Nullable @Getter private ConfigGadget configGadget; @@ -39,13 +39,11 @@ public class EntityPlatform extends EntityBaseGadget { private boolean isActive; public EntityPlatform(EntityClientGadget gadget, Scene scene, Player player, int gadgetId, Position pos, Position rot, MovingPlatformTypeOuterClass.MovingPlatformType movingPlatformType) { - super(scene); + super(scene, pos, rot); this.gadget = gadget; this.owner = player; this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET); - this.fightProp = new Int2FloatOpenHashMap(); - this.pos = new Position(pos); - this.rot = new Position(rot); + this.fightProperties = new Int2FloatOpenHashMap(); this.movingPlatformType = movingPlatformType; this.gadgetId = gadgetId; GadgetData data = GameData.getGadgetDataMap().get(gadgetId); @@ -56,26 +54,6 @@ public class EntityPlatform extends EntityBaseGadget { fillFightProps(configGadget); } - @Override - public int getGadgetId() { - return gadgetId; - } - - @Override - public Int2FloatMap getFightProperties() { - return fightProp; - } - - @Override - public Position getPosition() { - return pos; - } - - @Override - public Position getRotation() { - return rot; - } - @Override public SceneEntityInfoOuterClass.SceneEntityInfo toProto() { var platform = PlatformInfoOuterClass.PlatformInfo.newBuilder() diff --git a/src/main/java/emu/grasscutter/game/props/FightProperty.java b/src/main/java/emu/grasscutter/game/props/FightProperty.java index a51ecdbad..599b15640 100644 --- a/src/main/java/emu/grasscutter/game/props/FightProperty.java +++ b/src/main/java/emu/grasscutter/game/props/FightProperty.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Consumer; import static java.util.Map.entry; @@ -12,6 +13,7 @@ import java.util.stream.Stream; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import lombok.Getter; public enum FightProperty { FIGHT_PROP_NONE(0), @@ -195,8 +197,37 @@ public enum FightProperty { FIGHT_PROP_BASE_HP, FIGHT_PROP_HP, FIGHT_PROP_BASE_ATTACK, FIGHT_PROP_ATTACK, FIGHT_PROP_BASE_DEFENSE, FIGHT_PROP_DEFENSE, FIGHT_PROP_HEALED_ADD, FIGHT_PROP_CUR_FIRE_ENERGY, FIGHT_PROP_CUR_ELEC_ENERGY, FIGHT_PROP_CUR_WATER_ENERGY, FIGHT_PROP_CUR_GRASS_ENERGY, FIGHT_PROP_CUR_WIND_ENERGY, FIGHT_PROP_CUR_ICE_ENERGY, - FIGHT_PROP_CUR_ROCK_ENERGY, FIGHT_PROP_CUR_HP, FIGHT_PROP_MAX_HP, FIGHT_PROP_CUR_ATTACK, FIGHT_PROP_CUR_DEFENSE); - + FIGHT_PROP_CUR_ROCK_ENERGY, FIGHT_PROP_CUR_HP, FIGHT_PROP_MAX_HP, FIGHT_PROP_CUR_ATTACK, FIGHT_PROP_CUR_DEFENSE); + + @Getter + public static class CompoundProperty { + private FightProperty result; + private FightProperty base; + private FightProperty percent; + private FightProperty flat; + + public CompoundProperty(FightProperty result, FightProperty base, FightProperty percent, FightProperty flat) { + this.result = result; + this.base = base; + this.percent = percent; + this.flat = flat; + } + } + + private static Map compoundProperties = Map.ofEntries( + entry(FIGHT_PROP_MAX_HP, new CompoundProperty(FIGHT_PROP_MAX_HP, FIGHT_PROP_BASE_HP, FIGHT_PROP_HP_PERCENT, FIGHT_PROP_HP)), + entry(FIGHT_PROP_CUR_ATTACK, new CompoundProperty(FIGHT_PROP_CUR_ATTACK, FIGHT_PROP_BASE_ATTACK, FIGHT_PROP_ATTACK_PERCENT, FIGHT_PROP_ATTACK)), + entry(FIGHT_PROP_CUR_DEFENSE, new CompoundProperty(FIGHT_PROP_CUR_DEFENSE, FIGHT_PROP_BASE_DEFENSE, FIGHT_PROP_DEFENSE_PERCENT, FIGHT_PROP_DEFENSE)) + ); + + public static CompoundProperty getCompoundProperty(FightProperty result) { + return compoundProperties.get(result); + } + + public static void forEachCompoundProperty(Consumer consumer) { + compoundProperties.values().forEach(consumer); + } + public static boolean isPercentage(FightProperty prop) { return !flatProps.contains(prop); }