mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-01 13:01:32 +01:00
Added LastEntityDamagerTarget & LivingEntity#getLastDamageType
This commit is contained in:
parent
dcf6bc2082
commit
7b5c6dfc44
@ -77,6 +77,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
|
||||
protected UUID uuid;
|
||||
private boolean isActive; // False if entity has only been instanced without being added somewhere
|
||||
private boolean removed;
|
||||
private boolean shouldRemove;
|
||||
private long scheduledRemoveTime;
|
||||
private EntityType entityType;
|
||||
@ -1116,12 +1117,22 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
* WARNING: this do not trigger the {@link EntityDeathEvent} event
|
||||
*/
|
||||
public void remove() {
|
||||
this.removed = true;
|
||||
this.shouldRemove = true;
|
||||
entityById.remove(id);
|
||||
if (instance != null)
|
||||
instance.removeEntity(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if this entity has been removed
|
||||
*
|
||||
* @return true if this entity is removed
|
||||
*/
|
||||
public boolean isRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger {@link #remove()} after the specified time
|
||||
*
|
||||
|
@ -27,6 +27,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
protected boolean isDead;
|
||||
|
||||
private float health;
|
||||
private DamageType lastDamageType;
|
||||
|
||||
// Bounding box used for items' pickup (see LivingEntity#setBoundingBox)
|
||||
protected BoundingBox expandedBoundingBox;
|
||||
@ -244,7 +245,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
|
||||
// Additional hearts support
|
||||
if (this instanceof Player) {
|
||||
Player player = (Player) this;
|
||||
final Player player = (Player) this;
|
||||
final float additionalHearts = player.getAdditionalHearts();
|
||||
if (additionalHearts > 0) {
|
||||
if (damage > additionalHearts) {
|
||||
@ -257,6 +258,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// Set the final entity health
|
||||
setHealth(getHealth() - damage);
|
||||
|
||||
// play damage sound
|
||||
@ -273,6 +275,9 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
SoundEffectPacket damageSoundPacket = SoundEffectPacket.create(soundCategory, sound, getPosition().getX(), getPosition().getY(), getPosition().getZ(), 1.0f, 1.0f);
|
||||
sendPacketToViewersAndSelf(damageSoundPacket);
|
||||
}
|
||||
|
||||
// Set the last damage type since the event is not cancelled
|
||||
this.lastDamageType = entityDamageEvent.getDamageType();
|
||||
});
|
||||
|
||||
return !entityDamageEvent.isCancelled();
|
||||
@ -312,6 +317,15 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
sendMetadataIndex(8); // Health metadata index
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last damage type of this entity
|
||||
*
|
||||
* @return the last damage type, null if not any
|
||||
*/
|
||||
public DamageType getLastDamageType() {
|
||||
return lastDamageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity max health from {@link #getAttributeValue(Attribute)} {@link Attribute#MAX_HEALTH}
|
||||
*
|
||||
|
@ -3,10 +3,15 @@ package net.minestom.server.entity.ai.goal;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.EntityCreature;
|
||||
import net.minestom.server.entity.ai.GoalSelector;
|
||||
import net.minestom.server.entity.ai.TargetSelector;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.time.CooldownUtils;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
|
||||
/**
|
||||
* Attack the entity's target ({@link EntityCreature#getTarget()}) OR the closest entity
|
||||
* which can be targeted with the entity {@link TargetSelector}
|
||||
*/
|
||||
public class MeleeAttackGoal extends GoalSelector {
|
||||
|
||||
private long lastHit;
|
||||
@ -26,20 +31,21 @@ public class MeleeAttackGoal extends GoalSelector {
|
||||
|
||||
@Override
|
||||
public boolean shouldStart() {
|
||||
return entityCreature.getTarget() != null;
|
||||
return getTarget() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
final Position targetPosition = entityCreature.getTarget().getPosition();
|
||||
final Position targetPosition = getTarget().getPosition();
|
||||
entityCreature.setPathTo(targetPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(long time) {
|
||||
final Entity target = entityCreature.getTarget();
|
||||
final Entity target = getTarget();
|
||||
if (target != null) {
|
||||
|
||||
// Attack the target entity
|
||||
if (entityCreature.getBoundingBox().intersect(target)) {
|
||||
if (!CooldownUtils.hasCooldown(time, lastHit, timeUnit, delay)) {
|
||||
entityCreature.attack(target, true);
|
||||
@ -48,6 +54,7 @@ public class MeleeAttackGoal extends GoalSelector {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move toward the target entity
|
||||
final Position pathPosition = entityCreature.getPathPosition();
|
||||
final Position targetPosition = target.getPosition();
|
||||
if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) {
|
||||
@ -63,6 +70,18 @@ public class MeleeAttackGoal extends GoalSelector {
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
// Stop following the target
|
||||
entityCreature.setPathTo(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link EntityCreature#getTarget()} or
|
||||
* the entity target selectors to get the correct target
|
||||
*
|
||||
* @return the target of the entity
|
||||
*/
|
||||
private Entity getTarget() {
|
||||
final Entity target = entityCreature.getTarget();
|
||||
return target == null ? findTarget() : target;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,9 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Target the closest entity
|
||||
*/
|
||||
public class ClosestEntityTarget extends TargetSelector {
|
||||
|
||||
private float range;
|
||||
@ -37,11 +40,13 @@ public class ClosestEntityTarget extends TargetSelector {
|
||||
for (Chunk chunk : chunks) {
|
||||
final Set<Entity> entities = instance.getChunkEntities(chunk);
|
||||
|
||||
if (!(entities instanceof LivingEntity))
|
||||
continue;
|
||||
|
||||
for (Entity ent : entities) {
|
||||
|
||||
// Only target living entities
|
||||
if (!(ent instanceof LivingEntity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't target itself
|
||||
if (ent.equals(entityCreature)) {
|
||||
continue;
|
||||
@ -56,12 +61,13 @@ public class ClosestEntityTarget extends TargetSelector {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!correct) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check distance
|
||||
final float d = getEntityCreature().getDistance(ent);
|
||||
final float d = entityCreature.getDistance(ent);
|
||||
if ((entity == null || d < distance) && d < range) {
|
||||
entity = ent;
|
||||
distance = d;
|
||||
|
@ -0,0 +1,41 @@
|
||||
package net.minestom.server.entity.ai.target;
|
||||
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.EntityCreature;
|
||||
import net.minestom.server.entity.ai.TargetSelector;
|
||||
import net.minestom.server.entity.damage.DamageType;
|
||||
import net.minestom.server.entity.damage.EntityDamage;
|
||||
|
||||
/**
|
||||
* Target the last damager of this entity
|
||||
*/
|
||||
public class LastEntityDamagerTarget extends TargetSelector {
|
||||
|
||||
private float range;
|
||||
|
||||
public LastEntityDamagerTarget(EntityCreature entityCreature, float range) {
|
||||
super(entityCreature);
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity findTarget() {
|
||||
final DamageType damageType = entityCreature.getLastDamageType();
|
||||
|
||||
if (!(damageType instanceof EntityDamage)) {
|
||||
// No damager recorded, return null
|
||||
return null;
|
||||
}
|
||||
|
||||
final EntityDamage entityDamage = (EntityDamage) damageType;
|
||||
final Entity entity = entityDamage.getSource();
|
||||
|
||||
if (entity.isRemoved()) {
|
||||
// Entity not valid
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check range
|
||||
return entityCreature.getDistance(entity) < range ? entity : null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user