mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-09 04:13:00 +08:00
Refactor Entity data
This commit is contained in:
parent
a30f16b0e1
commit
4d8caf5a8c
@ -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<FightProperty> 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<Integer> 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<Integer> getAffix() {
|
||||
return affix;
|
||||
}
|
||||
|
||||
public String getAi() {
|
||||
return ai;
|
||||
}
|
||||
|
||||
public int[] getEquips() {
|
||||
return equips;
|
||||
}
|
||||
|
||||
public List<HpDrops> 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<PropGrowCurve> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<GameItem> equips;
|
||||
@Transient private final Int2FloatOpenHashMap fightProp;
|
||||
@Transient @Getter private final Int2FloatOpenHashMap fightProperties;
|
||||
@Transient @Getter private final Int2FloatOpenHashMap fightPropOverrides;
|
||||
@Transient @Getter private Set<String> 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<String> 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);
|
||||
|
@ -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<AvatarStat> 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);
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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())
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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<FightProperty, CompoundProperty> 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<CompoundProperty> consumer) {
|
||||
compoundProperties.values().forEach(consumer);
|
||||
}
|
||||
|
||||
public static boolean isPercentage(FightProperty prop) {
|
||||
return !flatProps.contains(prop);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user