Files
CustomNPC-Plus/src/main/java/noppes/npcs/controllers/data/action/Action.java
T

506 lines
13 KiB
Java
Raw Normal View History

2025-04-28 03:25:01 -04:00
package noppes.npcs.controllers.data.action;
import noppes.npcs.api.handler.data.IAction;
2025-06-30 07:15:34 +03:00
import noppes.npcs.api.handler.data.actions.IConditionalAction;
import noppes.npcs.controllers.ScriptContainer;
import noppes.npcs.scripted.CustomNPCsException;
import org.apache.commons.lang3.exception.ExceptionUtils;
2025-04-28 03:25:01 -04:00
import java.util.Deque;
2025-04-28 03:25:01 -04:00
import java.util.HashMap;
import java.util.LinkedList;
2025-04-28 03:25:01 -04:00
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
2025-04-28 03:25:01 -04:00
public class Action implements IAction {
protected final ActionManager manager;
protected boolean isScheduled;
2025-04-28 03:25:01 -04:00
protected final String name;
protected int startAfterTicks;
protected int count, maxCount = -1;
protected int duration, maxDuration = -1;
2025-04-28 03:25:01 -04:00
protected int updateEveryXTick = 5;
protected Consumer<IAction> task;
2025-06-28 09:30:21 +03:00
protected boolean done;
protected final Map<String, Object> dataStore = new HashMap<>();
protected boolean isThreaded;
2025-06-29 20:59:43 +03:00
protected ActionThread actionThread;
protected ScriptContainer reportTo;
public Action(ActionManager manager, String name) {
2025-04-28 03:25:01 -04:00
this.manager = manager;
this.name = name;
if (ScriptContainer.Current != null)
reportTo = ScriptContainer.Current;
2025-04-28 03:25:01 -04:00
}
public Action(ActionManager manager, Consumer<IAction> task) {
2025-04-28 03:25:01 -04:00
this(manager, task.toString(), task);
}
public Action(ActionManager manager, String name, Consumer<IAction> task) {
this(manager, name);
this.task = task;
2025-04-28 03:25:01 -04:00
}
public Action(ActionManager manager, int startAfterTicks, Consumer<IAction> task) {
2025-04-28 03:25:01 -04:00
this(manager, task);
this.startAfterTicks = startAfterTicks;
}
public Action(ActionManager manager, String name, int startAfterTicks, Consumer<IAction> task) {
this(manager, name, task);
this.startAfterTicks = startAfterTicks;
}
public Action(ActionManager manager, int maxDuration, int startAfterTicks, Consumer<IAction> task) {
2025-06-30 07:15:34 +03:00
this(manager, startAfterTicks, task);
this.maxDuration = maxDuration;
}
public Action(ActionManager manager, String name, int maxDuration, int startAfterTicks, Consumer<IAction> task) {
this(manager, name, startAfterTicks, task);
this.maxDuration = maxDuration;
}
2025-04-28 03:25:01 -04:00
@Override
public IAction setTask(Consumer<IAction> task) {
this.task = task;
return this;
}
public void tick(int ticksExisted) {
if (done) return;
if (startAfterTicks > 0) {
startAfterTicks--;
return;
}
if (maxDuration > -1 && duration >= maxDuration || maxCount == 0) {
2025-04-28 03:25:01 -04:00
markDone();
return;
}
if (ticksExisted % updateEveryXTick == 0 && task != null) {
2025-06-28 09:30:21 +03:00
if (isThreaded)
2025-06-29 21:56:15 +03:00
actionThread.execute("task", this::executeTask);
2025-06-29 21:06:15 +03:00
else
executeTask();
}
if (maxCount > -1 && count >= maxCount) {
markDone();
return;
}
2025-06-29 21:06:15 +03:00
duration++;
}
protected void executeTask() {
try {
task.accept(this);
count++;
} catch (Throwable t) {
String err = "IAction '" + name + "' threw an exception:";
if (reportTo != null)
reportTo.appendConsole(err + "\n" + ExceptionUtils.getStackTrace(t));
System.err.println(err);
2025-06-29 21:06:15 +03:00
t.printStackTrace();
markDone();
2025-04-28 03:25:01 -04:00
}
}
2025-04-28 10:42:47 +03:00
@Override
public ActionManager getManager() {
2025-04-28 10:42:47 +03:00
return manager;
}
@Override
public boolean isScheduled() {
return isScheduled;
}
2025-04-28 03:25:01 -04:00
@Override
public int getCount() {
return count;
}
@Override
public int getDuration() {
return duration;
}
@Override
public String getName() {
return name;
}
@Override
public int getMaxDuration() {
return maxDuration;
}
@Override
public IAction setMaxDuration(int x) {
2025-06-29 09:07:09 +03:00
this.maxDuration = Math.max(-1, x);
2025-04-28 03:25:01 -04:00
return this;
}
@Override
public int getMaxCount() {
return maxCount;
}
@Override
public IAction times(int x) {
this.maxCount = Math.max(-1, x);
return this;
}
@Override
public IAction once() {
this.maxCount = 1;
return this;
}
2025-04-28 03:25:01 -04:00
@Override
public void markDone() {
done = true;
}
@Override
public boolean isDone() {
return done;
}
2025-06-30 08:59:51 +03:00
@Override
2025-06-29 09:44:20 +03:00
public void kill() {
2025-06-29 20:59:43 +03:00
if (actionThread != null)
actionThread.stop();
2025-06-30 08:59:51 +03:00
dataStore.clear();
isScheduled = false;
2025-06-30 08:59:51 +03:00
done = true;
2025-06-29 09:44:20 +03:00
}
2025-04-28 03:25:01 -04:00
@Override
public Object getData(String key) {
return dataStore.get(key);
}
@Override
2025-05-30 04:07:56 +03:00
public IAction setData(String key, Object v) {
2025-04-28 03:25:01 -04:00
dataStore.put(key, v);
return this;
}
@Override
public IAction removeData(String key) {
dataStore.remove(key);
return this;
}
2025-05-30 04:07:56 +03:00
@Override
public boolean hasData(String key) {
return dataStore.containsKey(key);
}
2025-04-28 03:25:01 -04:00
@Override
public int getUpdateEvery() {
2025-04-28 03:25:01 -04:00
return updateEveryXTick;
}
@Override
public IAction updateEvery(int x) {
2025-06-29 09:07:09 +03:00
this.updateEveryXTick = Math.max(1, x);
2025-04-28 03:25:01 -04:00
return this;
}
@Override
public int getStartAfterTicks() {
return startAfterTicks;
}
@Override
public IAction pauseFor(int ticks) {
2025-06-28 09:30:21 +03:00
if (isThreaded)
2025-06-29 20:59:43 +03:00
actionThread.pauseFor(ticks);
else
this.startAfterTicks = ticks;
2025-06-28 09:30:21 +03:00
2025-04-28 03:25:01 -04:00
return this;
}
2025-06-28 09:30:21 +03:00
@Override
public IAction pauseFor(long millis) {
if (isThreaded) {
2025-06-29 20:59:43 +03:00
actionThread.pauseFor(millis);
return this;
}
2025-06-28 09:30:21 +03:00
return pauseFor((int) (millis / 50));
}
@Override
public void pause() {
if (isThreaded)
2025-06-29 20:59:43 +03:00
actionThread.pause();
else
throw new CustomNPCsException("Must threadify() IAction before pausing!");
}
@Override
public void pauseUntil(Function<IAction, Boolean> until) {
if (isThreaded)
2025-06-29 20:59:43 +03:00
actionThread.pauseUntil(until);
else
throw new CustomNPCsException("Must threadify() IAction before pausing!");
}
@Override
public void resume() {
if (isThreaded)
2025-06-29 20:59:43 +03:00
actionThread.resume();
}
2025-06-28 09:30:21 +03:00
@Override
public boolean isPaused() {
if (isThreaded)
2025-06-29 20:59:43 +03:00
return actionThread.isPaused();
2025-06-28 09:30:21 +03:00
return startAfterTicks > 0;
}
@Override
public IAction threadify() {
if (!isThreaded) {
isThreaded = true;
2025-06-29 20:59:43 +03:00
actionThread = new ActionThread(this);
}
return this;
2025-06-28 09:30:21 +03:00
}
2025-06-29 09:07:09 +03:00
@Override
public IAction start() {
manager.start();
return this;
}
2025-04-28 03:25:01 -04:00
@Override
public IAction getNext() {
2025-05-19 22:07:57 -04:00
boolean seenMe = false;
for (IAction a : manager.getActionQueue()) {
if (seenMe) {
return a;
}
if (a == this) {
seenMe = true;
}
}
return null;
2025-04-28 03:25:01 -04:00
}
@Override
public IAction getPrevious() {
2025-05-19 22:07:57 -04:00
IAction prev = null;
for (IAction a : manager.getActionQueue()) {
if (a == this) {
return prev;
}
prev = a;
}
return null;
2025-04-28 03:25:01 -04:00
}
protected Action unscheduledBefore, unscheduledAfter;
protected LinkedList<Action> allUnscheduledBefore() {
Action before = unscheduledBefore;
LinkedList<Action> befores = new LinkedList<>();
while (before != null) {
befores.addFirst(before);
before = before.unscheduledBefore;
}
return befores;
}
protected void scheduleAllBefore(Deque<IAction> actionQueue) {
allUnscheduledBefore().forEach((bef) -> {
if (bef.unscheduledAfter != null)
bef.unscheduledAfter.unscheduledBefore = null;
bef.unscheduledAfter = null;
actionQueue.addLast(bef);
bef.isScheduled = true;
});
}
protected LinkedList<Action> allUnscheduledAfter() {
Action after = unscheduledAfter;
LinkedList<Action> afters = new LinkedList<>();
while (after != null) {
afters.add(after);
after = after.unscheduledAfter;
}
return afters;
}
protected void scheduleAllAfter(Deque<IAction> actionQueue) {
allUnscheduledAfter().forEach((aft) -> {
if (aft.unscheduledBefore != null)
aft.unscheduledBefore.unscheduledAfter = null;
aft.unscheduledBefore = null;
actionQueue.addLast(aft);
aft.isScheduled = true;
});
}
2025-04-28 03:25:01 -04:00
@Override
public IAction after(IAction after) {
int idx = manager.getIndex(this);
if (idx >= 0)
manager.scheduleActionAt(idx + 1, after);
else {
Action aft = (Action) after;
unscheduledAfter = aft;
aft.unscheduledBefore = this;
}
2025-04-28 03:25:01 -04:00
return after;
}
@Override
public IAction after(String name, int maxDuration, int delay, Consumer<IAction> t) {
return after(manager.create(name, maxDuration, delay, t));
}
@Override
public IAction after(String name, int delay, Consumer<IAction> t) {
return after(manager.create(name, delay, t));
}
@Override
public IAction after(int delay, Consumer<IAction> t) {
return after(manager.create(delay, t));
}
@Override
public IAction after(String name, Consumer<IAction> t) {
return after(manager.create(name, t));
}
@Override
public IAction after(Consumer<IAction> t) {
return after(manager.create(t));
}
@Override
public IAction before(IAction before) {
int idx = manager.getIndex(this);
if (idx >= 0)
manager.scheduleActionAt(Math.max(0, idx), before);
else {
Action bef = (Action) before;
unscheduledBefore = bef;
bef.unscheduledAfter = this;
}
2025-04-28 03:25:01 -04:00
return before;
}
@Override
public IAction before(String name, int maxDuration, int delay, Consumer<IAction> t) {
return before(manager.create(name, maxDuration, delay, t));
}
@Override
public IAction before(String name, int delay, Consumer<IAction> t) {
return before(manager.create(name, delay, t));
}
@Override
public IAction before(int delay, Consumer<IAction> t) {
return before(manager.create(delay, t));
}
@Override
public IAction before(String name, Consumer<IAction> t) {
return before(manager.create(name, t));
}
@Override
public IAction before(Consumer<IAction> t) {
return before(manager.create(t));
}
2025-06-30 07:15:34 +03:00
@Override
public IConditionalAction conditional(IConditionalAction after) {
2025-06-30 09:28:31 +03:00
return manager.schedule(after);
2025-06-30 07:15:34 +03:00
}
@Override
public IConditionalAction conditional(Function<IAction, Boolean> condition, Consumer<IAction> task) {
2025-06-30 07:15:34 +03:00
return conditional(manager.create(condition, task));
}
@Override
public IConditionalAction conditional(String name, Function<IAction, Boolean> condition, Consumer<IAction> task) {
2025-06-30 07:15:34 +03:00
return conditional(manager.create(name, condition, task));
}
@Override
public IConditionalAction conditional(Function<IAction, Boolean> condition, Consumer<IAction> task, Function<IAction, Boolean> terminateWhen) {
2025-06-30 07:15:34 +03:00
return conditional(manager.create(condition, task, terminateWhen));
}
@Override
public IConditionalAction conditional(String name, Function<IAction, Boolean> condition, Consumer<IAction> task, Function<IAction, Boolean> terminateWhen) {
2025-06-30 07:15:34 +03:00
return conditional(manager.create(name, condition, task, terminateWhen));
}
@Override
public IConditionalAction conditional(Function<IAction, Boolean> condition, Consumer<IAction> task, Function<IAction, Boolean> terminateWhen, Consumer<IAction> onTermination) {
2025-06-30 07:15:34 +03:00
return conditional(manager.create(condition, task, terminateWhen, onTermination));
}
@Override
public IConditionalAction conditional(String name, Function<IAction, Boolean> condition, Consumer<IAction> task, Function<IAction, Boolean> terminateWhen, Consumer<IAction> onTermination) {
2025-06-30 07:15:34 +03:00
return conditional(manager.create(name, condition, task, terminateWhen, onTermination));
}
@Override
public IAction parallel(IAction after) {
2025-06-30 09:28:31 +03:00
return manager.scheduleParallel(after);
2025-06-30 07:15:34 +03:00
}
@Override
public IAction parallel(Consumer<IAction> task) {
return parallel(manager.create(task));
}
@Override
public IAction parallel(int delay, Consumer<IAction> task) {
return parallel(manager.create(delay, task));
}
@Override
public IAction parallel(String name, Consumer<IAction> task) {
return parallel(manager.create(name, task));
}
@Override
public IAction parallel(String name, int startAfterTicks, Consumer<IAction> task) {
return parallel(manager.create(name, startAfterTicks, task));
}
@Override
public IAction parallel(String name, int maxDuration, int delay, Consumer<IAction> t) {
return parallel(manager.create(name, maxDuration, delay, t));
}
2025-04-28 03:25:01 -04:00
}