From cf2832ae72e6103f982d1a1f00d1c792eea1e1f3 Mon Sep 17 00:00:00 2001 From: KingRainbow44 Date: Thu, 4 Aug 2022 21:36:00 -0400 Subject: [PATCH] Add `EntityDamageEvent` and implementations --- .../grasscutter/game/entity/GameEntity.java | 45 +++++++++++-------- .../event/entity/EntityDamageEvent.java | 32 +++++++++++++ 2 files changed, 58 insertions(+), 19 deletions(-) create mode 100644 src/main/java/emu/grasscutter/server/event/entity/EntityDamageEvent.java diff --git a/src/main/java/emu/grasscutter/game/entity/GameEntity.java b/src/main/java/emu/grasscutter/game/entity/GameEntity.java index c0c15aaa2..c08590649 100644 --- a/src/main/java/emu/grasscutter/game/entity/GameEntity.java +++ b/src/main/java/emu/grasscutter/game/entity/GameEntity.java @@ -15,6 +15,7 @@ import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo; import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState; import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo; import emu.grasscutter.net.proto.VectorOuterClass.Vector; +import emu.grasscutter.server.event.entity.EntityDamageEvent; import emu.grasscutter.server.event.entity.EntityDeathEvent; import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify; import emu.grasscutter.utils.Position; @@ -50,7 +51,7 @@ public abstract class GameEntity { } public int getEntityType() { - return getId() >> 24; + return this.getId() >> 24; } public World getWorld() { @@ -66,7 +67,7 @@ public abstract class GameEntity { } public LifeState getLifeState() { - return isAlive() ? LifeState.LIFE_ALIVE : LifeState.LIFE_DEAD; + return this.isAlive() ? LifeState.LIFE_ALIVE : LifeState.LIFE_DEAD; } public Map getMetaOverrideMap() { @@ -122,15 +123,15 @@ public abstract class GameEntity { } public void addFightProperty(FightProperty prop, float value) { - this.getFightProperties().put(prop.getId(), getFightProperty(prop) + value); + this.getFightProperties().put(prop.getId(), this.getFightProperty(prop) + value); } public float getFightProperty(FightProperty prop) { - return getFightProperties().getOrDefault(prop.getId(), 0f); + return this.getFightProperties().getOrDefault(prop.getId(), 0f); } public void addAllFightPropsToEntityInfo(SceneEntityInfo.Builder entityInfo) { - for (Int2FloatMap.Entry entry : getFightProperties().int2FloatEntrySet()) { + for (Int2FloatMap.Entry entry : this.getFightProperties().int2FloatEntrySet()) { if (entry.getIntKey() == 0) { continue; } @@ -165,8 +166,8 @@ public abstract class GameEntity { protected MotionInfo getMotionInfo() { MotionInfo proto = MotionInfo.newBuilder() - .setPos(getPosition().toProto()) - .setRot(getRotation().toProto()) + .setPos(this.getPosition().toProto()) + .setRot(this.getRotation().toProto()) .setSpeed(Vector.newBuilder()) .setState(this.getMotionState()) .build(); @@ -187,8 +188,8 @@ public abstract class GameEntity { return 0f; } - float curHp = getFightProperty(FightProperty.FIGHT_PROP_CUR_HP); - float maxHp = getFightProperty(FightProperty.FIGHT_PROP_MAX_HP); + float curHp = this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP); + float maxHp = this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP); if (curHp >= maxHp) { return 0f; @@ -197,37 +198,43 @@ public abstract class GameEntity { float healed = Math.min(maxHp - curHp, amount); this.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, healed); - getScene().broadcastPacket(new PacketEntityFightPropUpdateNotify(this, FightProperty.FIGHT_PROP_CUR_HP)); + this.getScene().broadcastPacket(new PacketEntityFightPropUpdateNotify(this, FightProperty.FIGHT_PROP_CUR_HP)); return healed; } public void damage(float amount) { - damage(amount, 0); + this.damage(amount, 0); } public void damage(float amount, int killerId) { - // Sanity check - if (getFightProperties() == null) { + // Check if the entity has properties. + if (this.getFightProperties() == null) { return; } - // Lose hp - addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, -amount); + // Invoke entity damage event. + EntityDamageEvent event = new EntityDamageEvent(this, amount, this.getScene().getEntityById(killerId)); + event.call(); if (event.isCanceled()) { + return; // If the event is canceled, do not damage the entity. + } + + // Add negative HP to the current HP property. + this.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, -(event.getDamage())); // Check if dead boolean isDead = false; - if (getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) <= 0f) { - setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 0f); + if (this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) <= 0f) { + this.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 0f); isDead = true; } // Packets this.getScene().broadcastPacket(new PacketEntityFightPropUpdateNotify(this, FightProperty.FIGHT_PROP_CUR_HP)); - // Check if dead + // Check if dead. if (isDead) { - getScene().killEntity(this, killerId); + this.getScene().killEntity(this, killerId); } } diff --git a/src/main/java/emu/grasscutter/server/event/entity/EntityDamageEvent.java b/src/main/java/emu/grasscutter/server/event/entity/EntityDamageEvent.java new file mode 100644 index 000000000..9c5a4c033 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/event/entity/EntityDamageEvent.java @@ -0,0 +1,32 @@ +package emu.grasscutter.server.event.entity; + +import emu.grasscutter.game.entity.GameEntity; +import emu.grasscutter.server.event.Cancellable; +import emu.grasscutter.server.event.types.EntityEvent; + +import javax.annotation.Nullable; + +public final class EntityDamageEvent extends EntityEvent implements Cancellable { + private float damage; + @Nullable private final GameEntity damager; + + public EntityDamageEvent(GameEntity entity, float damage, @Nullable GameEntity damager) { + super(entity); + + this.damage = damage; + this.damager = damager; + } + + public float getDamage() { + return this.damage; + } + + public void setDamage(float damage) { + this.damage = damage; + } + + @Nullable + public GameEntity getDamager() { + return this.damager; + } +}