2020-04-24 03:25:58 +02:00
|
|
|
package net.minestom.server.entity;
|
2019-08-10 08:44:35 +02:00
|
|
|
|
2020-07-24 02:31:10 +02:00
|
|
|
import com.extollit.gaming.ai.path.HydrazinePathFinder;
|
2021-03-09 20:51:11 +01:00
|
|
|
import net.minestom.server.attribute.Attribute;
|
2020-12-12 05:50:05 +01:00
|
|
|
import net.minestom.server.entity.ai.EntityAI;
|
2021-02-23 00:28:24 +01:00
|
|
|
import net.minestom.server.entity.ai.EntityAIGroup;
|
2020-11-29 23:14:21 +01:00
|
|
|
import net.minestom.server.entity.pathfinding.NavigableEntity;
|
2021-01-28 15:33:52 +01:00
|
|
|
import net.minestom.server.entity.pathfinding.Navigator;
|
2021-06-04 03:48:51 +02:00
|
|
|
import net.minestom.server.event.EventDispatcher;
|
2020-05-28 19:15:55 +02:00
|
|
|
import net.minestom.server.event.entity.EntityAttackEvent;
|
2020-07-24 02:31:10 +02:00
|
|
|
import net.minestom.server.instance.Instance;
|
2020-04-24 03:25:58 +02:00
|
|
|
import net.minestom.server.utils.Position;
|
2020-05-15 18:03:28 +02:00
|
|
|
import net.minestom.server.utils.time.TimeUnit;
|
2020-10-24 10:46:23 +02:00
|
|
|
import org.jetbrains.annotations.NotNull;
|
2020-10-24 11:19:54 +02:00
|
|
|
import org.jetbrains.annotations.Nullable;
|
2019-08-10 08:44:35 +02:00
|
|
|
|
2021-07-01 15:03:16 +02:00
|
|
|
import java.time.Duration;
|
2021-03-09 20:51:11 +01:00
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.UUID;
|
2021-03-25 21:36:18 +01:00
|
|
|
import java.util.concurrent.CopyOnWriteArraySet;
|
2020-08-06 11:56:43 +02:00
|
|
|
|
2021-02-23 14:10:14 +01:00
|
|
|
public class EntityCreature extends LivingEntity implements NavigableEntity, EntityAI {
|
2020-11-29 23:14:21 +01:00
|
|
|
|
2020-12-06 00:06:52 +01:00
|
|
|
private int removalAnimationDelay = 1000;
|
|
|
|
|
2021-03-25 21:36:18 +01:00
|
|
|
private final Set<EntityAIGroup> aiGroups = new CopyOnWriteArraySet<>();
|
2020-08-06 11:56:43 +02:00
|
|
|
|
2021-01-28 15:33:52 +01:00
|
|
|
private final Navigator navigator = new Navigator(this);
|
|
|
|
|
2020-08-06 11:56:43 +02:00
|
|
|
private Entity target;
|
|
|
|
|
2020-12-05 01:36:06 +01:00
|
|
|
/**
|
2021-02-25 11:56:10 +01:00
|
|
|
* Constructor which allows to specify an UUID. Only use if you know what you are doing!
|
2020-12-05 01:36:06 +01:00
|
|
|
*/
|
2021-02-25 11:56:10 +01:00
|
|
|
public EntityCreature(@NotNull EntityType entityType, @NotNull UUID uuid) {
|
|
|
|
super(entityType, uuid);
|
|
|
|
heal();
|
|
|
|
}
|
2020-05-06 22:35:32 +02:00
|
|
|
|
2021-02-25 11:56:10 +01:00
|
|
|
public EntityCreature(@NotNull EntityType entityType) {
|
|
|
|
this(entityType, UUID.randomUUID());
|
|
|
|
}
|
2020-05-06 22:35:32 +02:00
|
|
|
|
2019-08-24 20:34:01 +02:00
|
|
|
@Override
|
2020-06-01 00:51:31 +02:00
|
|
|
public void update(long time) {
|
2020-12-12 05:50:05 +01:00
|
|
|
// AI
|
|
|
|
aiTick(time);
|
2020-08-06 11:56:43 +02:00
|
|
|
|
2020-04-09 14:25:42 +02:00
|
|
|
// Path finding
|
2021-03-09 20:51:11 +01:00
|
|
|
this.navigator.tick(getAttributeValue(Attribute.MOVEMENT_SPEED));
|
2020-07-31 18:55:08 +02:00
|
|
|
|
2020-12-12 05:50:05 +01:00
|
|
|
// Fire, item pickup, ...
|
2020-07-31 18:55:08 +02:00
|
|
|
super.update(time);
|
2020-07-24 02:31:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-02-25 15:48:48 +01:00
|
|
|
public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) {
|
2021-01-28 15:33:52 +01:00
|
|
|
this.navigator.setPathFinder(new HydrazinePathFinder(navigator.getPathingEntity(), instance.getInstanceSpace()));
|
2021-02-20 09:15:08 +01:00
|
|
|
|
2021-02-25 15:48:48 +01:00
|
|
|
super.setInstance(instance, spawnPosition);
|
2020-05-26 22:53:58 +02:00
|
|
|
}
|
|
|
|
|
2019-08-24 20:34:01 +02:00
|
|
|
@Override
|
2019-08-21 16:50:52 +02:00
|
|
|
public void kill() {
|
2020-04-05 10:15:21 +02:00
|
|
|
super.kill();
|
|
|
|
|
2020-12-06 00:06:52 +01:00
|
|
|
if (removalAnimationDelay > 0) {
|
|
|
|
// Needed for proper death animation (wait for it to finish before destroying the entity)
|
2021-07-01 15:03:16 +02:00
|
|
|
scheduleRemove(Duration.of(removalAnimationDelay, TimeUnit.MILLISECOND));
|
2020-12-06 00:06:52 +01:00
|
|
|
} else {
|
|
|
|
// Instant removal without animation playback
|
|
|
|
remove();
|
|
|
|
}
|
2019-08-11 13:57:23 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 00:06:52 +01:00
|
|
|
/**
|
|
|
|
* Gets the kill animation delay before vanishing the entity.
|
|
|
|
*
|
|
|
|
* @return the removal animation delay in milliseconds, 0 if not any
|
|
|
|
*/
|
|
|
|
public int getRemovalAnimationDelay() {
|
|
|
|
return removalAnimationDelay;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Changes the removal animation delay of the entity.
|
|
|
|
* <p>
|
|
|
|
* Testing shows that 1000 is the minimum value to display the death particles.
|
|
|
|
*
|
|
|
|
* @param removalAnimationDelay the new removal animation delay in milliseconds, 0 to remove it
|
|
|
|
*/
|
|
|
|
public void setRemovalAnimationDelay(int removalAnimationDelay) {
|
|
|
|
this.removalAnimationDelay = removalAnimationDelay;
|
|
|
|
}
|
|
|
|
|
2020-12-12 05:50:05 +01:00
|
|
|
@Override
|
2021-02-23 00:28:24 +01:00
|
|
|
public Collection<EntityAIGroup> getAIGroups() {
|
2021-03-25 21:36:18 +01:00
|
|
|
return aiGroups;
|
2020-12-12 05:50:05 +01:00
|
|
|
}
|
|
|
|
|
2020-08-06 11:56:43 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Gets the entity target.
|
2020-08-06 11:56:43 +02:00
|
|
|
*
|
2021-01-03 22:42:15 +01:00
|
|
|
* @return the entity target, can be null if not any
|
2020-08-06 11:56:43 +02:00
|
|
|
*/
|
2020-10-24 11:19:54 +02:00
|
|
|
@Nullable
|
2020-08-06 11:56:43 +02:00
|
|
|
public Entity getTarget() {
|
|
|
|
return target;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-10-29 22:52:07 +01:00
|
|
|
* Changes the entity target.
|
2020-08-06 11:56:43 +02:00
|
|
|
*
|
2021-01-03 22:42:15 +01:00
|
|
|
* @param target the new entity target, null to remove
|
2020-08-06 11:56:43 +02:00
|
|
|
*/
|
2021-01-03 22:41:50 +01:00
|
|
|
public void setTarget(@Nullable Entity target) {
|
2020-08-06 11:56:43 +02:00
|
|
|
this.target = target;
|
|
|
|
}
|
|
|
|
|
2021-01-28 15:33:52 +01:00
|
|
|
@NotNull
|
|
|
|
@Override
|
|
|
|
public Navigator getNavigator() {
|
|
|
|
return navigator;
|
|
|
|
}
|
|
|
|
|
2020-05-28 19:15:55 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Calls a {@link EntityAttackEvent} with this entity as the source and {@code target} as the target.
|
2020-05-28 19:15:55 +02:00
|
|
|
*
|
2020-06-03 15:17:34 +02:00
|
|
|
* @param target the entity target
|
|
|
|
* @param swingHand true to swing the entity main hand, false otherwise
|
2020-05-28 19:15:55 +02:00
|
|
|
*/
|
2020-10-24 11:19:54 +02:00
|
|
|
public void attack(@NotNull Entity target, boolean swingHand) {
|
2020-06-03 15:17:34 +02:00
|
|
|
if (swingHand)
|
|
|
|
swingMainHand();
|
2020-05-28 19:15:55 +02:00
|
|
|
EntityAttackEvent attackEvent = new EntityAttackEvent(this, target);
|
2021-06-04 03:48:51 +02:00
|
|
|
EventDispatcher.call(attackEvent);
|
2020-05-28 19:15:55 +02:00
|
|
|
}
|
|
|
|
|
2020-06-03 15:17:34 +02:00
|
|
|
/**
|
2020-10-15 21:16:31 +02:00
|
|
|
* Calls a {@link EntityAttackEvent} with this entity as the source and {@code target} as the target.
|
2020-06-03 15:17:34 +02:00
|
|
|
* <p>
|
2020-10-15 21:16:31 +02:00
|
|
|
* This does not trigger the hand animation.
|
2020-06-03 15:17:34 +02:00
|
|
|
*
|
|
|
|
* @param target the entity target
|
|
|
|
*/
|
2020-10-24 11:19:54 +02:00
|
|
|
public void attack(@NotNull Entity target) {
|
2020-06-03 15:17:34 +02:00
|
|
|
attack(target, false);
|
|
|
|
}
|
|
|
|
|
2019-08-10 08:44:35 +02:00
|
|
|
}
|