fixed gadget hp properties and invincibility handling (#1773)

* fixed gadget hp properties and invincibility handling

* Allow killing of hp locked entities, if the damage is higher then the hp

Co-authored-by: hartie95 <mail@hartie95.de>
This commit is contained in:
Alexander Hartmann
2022-09-15 04:26:20 +02:00
committed by GitHub
parent 21ff749dca
commit 08fdcf6ed4
7 changed files with 111 additions and 10 deletions

View File

@@ -1,21 +1,20 @@
package emu.grasscutter.game.entity;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.ConfigGadget;
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.LifeState;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.game.world.SpawnDataEntry;
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.MotionInfoOuterClass.MotionInfo;
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
@@ -24,18 +23,18 @@ import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo;
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.data.SceneGadget;
import emu.grasscutter.scripts.data.ScriptArgs;
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
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.ToString;
import javax.annotation.Nullable;
@ToString(callSuper = true)
public class EntityGadget extends EntityBaseGadget {
private final GadgetData data;
@@ -48,14 +47,20 @@ public class EntityGadget extends EntityBaseGadget {
private GadgetContent content;
private Int2FloatOpenHashMap fightProp;
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();
}
public EntityGadget(Scene scene, int gadgetId, Position pos) {
@@ -67,6 +72,22 @@ public class EntityGadget extends EntityBaseGadget {
this.content = content;
}
private void fillFightProps() {
if (configGadget == null || configGadget.getCombat() == null) {
return;
}
var combatData = configGadget.getCombat();
var combatProperties = combatData.getProperty();
var targetHp = combatProperties.getHP();
setFightProperty(FightProperty.FIGHT_PROP_MAX_HP, targetHp);
if (combatProperties.isInvincible()) {
targetHp = Float.POSITIVE_INFINITY;
}
setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, targetHp);
setLockHP(combatProperties.isLockHP());
}
public GadgetData getGadgetData() {
return data;
}

View File

@@ -37,6 +37,8 @@ public abstract class GameEntity {
@Getter @Setter private int lastMoveSceneTimeMs;
@Getter @Setter private int lastMoveReliableSeq;
@Getter @Setter private boolean lockHP;
// Abilities
private Object2FloatMap<String> metaOverrideMap;
private Int2ObjectMap<String> metaModifiers;
@@ -106,6 +108,10 @@ public abstract class GameEntity {
return this.getFightProperties().getOrDefault(prop.getId(), 0f);
}
public boolean hasFightProperty(FightProperty prop) {
return this.getFightProperties().containsKey(prop.getId());
}
public void addAllFightPropsToEntityInfo(SceneEntityInfo.Builder entityInfo) {
for (Int2FloatMap.Entry entry : this.getFightProperties().int2FloatEntrySet()) {
if (entry.getIntKey() == 0) {
@@ -153,7 +159,7 @@ public abstract class GameEntity {
public void damage(float amount, int killerId) {
// Check if the entity has properties.
if (this.getFightProperties() == null) {
if (this.getFightProperties() == null || !hasFightProperty(FightProperty.FIGHT_PROP_CUR_HP)) {
return;
}
@@ -164,9 +170,10 @@ public abstract class GameEntity {
return; // If the event is canceled, do not damage the entity.
}
if (getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) != Float.POSITIVE_INFINITY) {
// Add negative HP to the current HP property.
this.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, -(event.getDamage()));
float curHp = getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
if (curHp != Float.POSITIVE_INFINITY && !lockHP || lockHP && curHp <= event.getDamage()) {
// Add negative HP to the current HP property.
this.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, -(event.getDamage()));
}
// Check if dead