blob: 66bf602e283ed3112f0f9612050322c76826215f [file] [log] [blame] [raw]
package net.glowstone.entity.ai;
import java.util.concurrent.ThreadLocalRandom;
import lombok.Getter;
import net.glowstone.entity.GlowLivingEntity;
import org.jetbrains.annotations.NonNls;
public abstract class EntityTask implements Comparable<EntityTask> {
/**
* The name of this EntityTask. Must be unique to each EntityTask implementation.
*
* @return the name of this EntityTask.
*/
@Getter
@NonNls
private final String name;
/**
* Whether this task is currently being executed.
*
* @return true if this task is being executed, false otherwise.
*/
@Getter
private boolean executing = false;
private int duration = 0;
/**
* Whether this task is paused.
*
* @return whether this task is paused.
*/
@Getter
private boolean paused = false;
public EntityTask(@NonNls String name) {
this.name = name;
}
@Override
public int compareTo(EntityTask other) {
return 0; // TODO: AI task priority
}
/**
* Advances this task by a tick on the given entity.
*
* @param entity the entity to run on
*/
public final void pulse(GlowLivingEntity entity) {
if (paused || entity.isDead() || !entity.hasAI()) {
return;
}
if (isInstant()) {
execute(entity);
return;
}
if (executing && duration > 0) {
duration--;
execute(entity);
return;
}
if (executing && duration == 0) {
executing = false;
end(entity);
return;
}
if (!executing && shouldStart(entity)) {
duration = getDurationMin() == getDurationMax() ? getDurationMin()
: ThreadLocalRandom.current().nextInt(getDurationMax() - getDurationMin())
+ getDurationMin();
executing = true;
start(entity);
}
}
/**
* Resets the progress of this task for this entity.
*
* @param entity the entity in question.
*/
public void reset(GlowLivingEntity entity) {
end(entity);
duration = 0;
executing = false;
}
/**
* Resumes the previously paused task for this entity.
*
* @param entity the entity in question.
*/
public final void resume(GlowLivingEntity entity) {
if (!isPaused()) {
return;
}
paused = false;
}
/**
* Pauses this task for this entity.
*
* @param entity the entity in question.
*/
public final void pause(GlowLivingEntity entity) {
if (isPaused()) {
return;
}
reset(entity);
paused = true;
}
/**
* The minimum duration of this task. This value is ignored if this task is instant.
*
* @return the minimum duration of this task, in ticks.
*/
public abstract int getDurationMin();
/**
* The maximum duration of this task. This value is ignored if this task is instant.
*
* @return the maximum duration of this task, in ticks.
*/
public abstract int getDurationMax();
/**
* Whether the task should begin executing for this entity.
*
* @param entity the entity in question.
* @return true if the task should start, false otherwise.
*/
public abstract boolean shouldStart(GlowLivingEntity entity);
/**
* Invoked when this task is about to start for this entity.
*
* @param entity the entity in question.
*/
public abstract void start(GlowLivingEntity entity);
/**
* Invoked when this task is being ended for this entity.
*
* @param entity the entity in question.
*/
public abstract void end(GlowLivingEntity entity);
/**
* Invoked each tick when this task is being executed for this entity.
*
* @param entity the entity in question.
*/
public abstract void execute(GlowLivingEntity entity);
/**
* Whether this task is instant. An "instant" task will be executed every tick while the entity
* is alive.
*
* @return the entity in question.
*/
public abstract boolean isInstant();
}