mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-02-04 04:32:57 +08:00
Add EntityDamageEvent
and implementations
This commit is contained in:
parent
d05b3207e5
commit
cf2832ae72
@ -15,6 +15,7 @@ import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
|
|||||||
import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState;
|
import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState;
|
||||||
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
||||||
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
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.event.entity.EntityDeathEvent;
|
||||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
@ -50,7 +51,7 @@ public abstract class GameEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getEntityType() {
|
public int getEntityType() {
|
||||||
return getId() >> 24;
|
return this.getId() >> 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
public World getWorld() {
|
public World getWorld() {
|
||||||
@ -66,7 +67,7 @@ public abstract class GameEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LifeState getLifeState() {
|
public LifeState getLifeState() {
|
||||||
return isAlive() ? LifeState.LIFE_ALIVE : LifeState.LIFE_DEAD;
|
return this.isAlive() ? LifeState.LIFE_ALIVE : LifeState.LIFE_DEAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Float> getMetaOverrideMap() {
|
public Map<String, Float> getMetaOverrideMap() {
|
||||||
@ -122,15 +123,15 @@ public abstract class GameEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addFightProperty(FightProperty prop, float value) {
|
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) {
|
public float getFightProperty(FightProperty prop) {
|
||||||
return getFightProperties().getOrDefault(prop.getId(), 0f);
|
return this.getFightProperties().getOrDefault(prop.getId(), 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAllFightPropsToEntityInfo(SceneEntityInfo.Builder entityInfo) {
|
public void addAllFightPropsToEntityInfo(SceneEntityInfo.Builder entityInfo) {
|
||||||
for (Int2FloatMap.Entry entry : getFightProperties().int2FloatEntrySet()) {
|
for (Int2FloatMap.Entry entry : this.getFightProperties().int2FloatEntrySet()) {
|
||||||
if (entry.getIntKey() == 0) {
|
if (entry.getIntKey() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -165,8 +166,8 @@ public abstract class GameEntity {
|
|||||||
|
|
||||||
protected MotionInfo getMotionInfo() {
|
protected MotionInfo getMotionInfo() {
|
||||||
MotionInfo proto = MotionInfo.newBuilder()
|
MotionInfo proto = MotionInfo.newBuilder()
|
||||||
.setPos(getPosition().toProto())
|
.setPos(this.getPosition().toProto())
|
||||||
.setRot(getRotation().toProto())
|
.setRot(this.getRotation().toProto())
|
||||||
.setSpeed(Vector.newBuilder())
|
.setSpeed(Vector.newBuilder())
|
||||||
.setState(this.getMotionState())
|
.setState(this.getMotionState())
|
||||||
.build();
|
.build();
|
||||||
@ -187,8 +188,8 @@ public abstract class GameEntity {
|
|||||||
return 0f;
|
return 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float curHp = getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
float curHp = this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
||||||
float maxHp = getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
|
float maxHp = this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
|
||||||
|
|
||||||
if (curHp >= maxHp) {
|
if (curHp >= maxHp) {
|
||||||
return 0f;
|
return 0f;
|
||||||
@ -197,37 +198,43 @@ public abstract class GameEntity {
|
|||||||
float healed = Math.min(maxHp - curHp, amount);
|
float healed = Math.min(maxHp - curHp, amount);
|
||||||
this.addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, healed);
|
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;
|
return healed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void damage(float amount) {
|
public void damage(float amount) {
|
||||||
damage(amount, 0);
|
this.damage(amount, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void damage(float amount, int killerId) {
|
public void damage(float amount, int killerId) {
|
||||||
// Sanity check
|
// Check if the entity has properties.
|
||||||
if (getFightProperties() == null) {
|
if (this.getFightProperties() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lose hp
|
// Invoke entity damage event.
|
||||||
addFightProperty(FightProperty.FIGHT_PROP_CUR_HP, -amount);
|
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
|
// Check if dead
|
||||||
boolean isDead = false;
|
boolean isDead = false;
|
||||||
if (getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) <= 0f) {
|
if (this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) <= 0f) {
|
||||||
setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 0f);
|
this.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 0f);
|
||||||
isDead = true;
|
isDead = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Packets
|
// Packets
|
||||||
this.getScene().broadcastPacket(new PacketEntityFightPropUpdateNotify(this, FightProperty.FIGHT_PROP_CUR_HP));
|
this.getScene().broadcastPacket(new PacketEntityFightPropUpdateNotify(this, FightProperty.FIGHT_PROP_CUR_HP));
|
||||||
|
|
||||||
// Check if dead
|
// Check if dead.
|
||||||
if (isDead) {
|
if (isDead) {
|
||||||
getScene().killEntity(this, killerId);
|
this.getScene().killEntity(this, killerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user