Files
CustomNPC-Plus/src/main/java/noppes/npcs/scripted/ScriptedActionManager.java
T

346 lines
10 KiB
Java
Raw Normal View History

package noppes.npcs.scripted;
2025-03-03 20:05:19 -05:00
import noppes.npcs.api.handler.IActionManager;
import noppes.npcs.api.handler.data.IAction;
2025-04-27 23:10:55 -04:00
import noppes.npcs.api.handler.data.IActionChain;
2025-04-28 07:41:29 +03:00
import noppes.npcs.api.handler.data.actions.IConditionalAction;
2025-04-28 03:25:01 -04:00
import noppes.npcs.controllers.data.action.Action;
import noppes.npcs.controllers.data.action.ActionChain;
import noppes.npcs.controllers.data.action.ConditionalAction;
import noppes.npcs.controllers.data.action.ParallelActionChain;
2025-04-28 07:41:29 +03:00
import java.util.*;
2025-05-19 22:07:57 -04:00
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.function.Consumer;
2025-04-26 20:52:08 -04:00
import java.util.function.Supplier;
/**
* Full-featured ActionManager:
* - delayed start, max-duration, tick-interval
* - chaining (getNext, getPrevious, scheduleAfter/Before)
* - per-action data
* - conditional actions
* - cancellation & clearing
*/
public class ScriptedActionManager implements IActionManager {
2025-04-26 20:52:08 -04:00
private boolean isWorking = false;
2025-04-28 03:05:56 -04:00
2025-05-19 22:07:57 -04:00
private final Deque<IAction> actionQueue = new ConcurrentLinkedDeque<>();
private final Deque<IAction> parallelActions = new ConcurrentLinkedDeque<>();
private final Deque<IConditionalAction> conditionalActions = new ConcurrentLinkedDeque<>();
2025-04-28 10:09:50 +03:00
@Override
public IAction create(String name) {
2025-04-28 03:25:01 -04:00
return new Action(this, name);
2025-04-28 10:09:50 +03:00
}
@Override
public IAction create(Consumer<IAction> t) {
2025-04-28 03:25:01 -04:00
return new Action(this, t);
2025-04-28 10:09:50 +03:00
}
@Override
2025-04-26 20:52:08 -04:00
public IAction create(String name, int maxDuration, int startAfterTicks, Consumer<IAction> task) {
2025-04-28 03:25:01 -04:00
return new Action(this, name, maxDuration, startAfterTicks, task);
}
2025-04-28 07:26:39 +03:00
@Override
public IAction create(String name, int delay, Consumer<IAction> t) {
2025-04-28 03:25:01 -04:00
return new Action(this, name, delay, t);
2025-04-28 07:26:39 +03:00
}
@Override
public IAction create(int delay, Consumer<IAction> t) {
2025-04-28 03:25:01 -04:00
return new Action(this, delay, t);
2025-04-28 07:26:39 +03:00
}
@Override
public IAction create(String name, Consumer<IAction> t) {
2025-04-28 03:25:01 -04:00
return new Action(this, name, t);
2025-04-28 07:26:39 +03:00
}
2025-04-28 08:17:57 +03:00
@Override
public IConditionalAction create(Supplier<Boolean> condition, Consumer<IAction> task) {
return new ConditionalAction(this, condition, task);
2025-04-28 08:17:57 +03:00
}
@Override
public IConditionalAction create(String name, Supplier<Boolean> condition, Consumer<IAction> task) {
return new ConditionalAction(this, name, condition, task);
2025-04-28 08:17:57 +03:00
}
@Override
public IConditionalAction create(Supplier<Boolean> condition, Consumer<IAction> task, Supplier<Boolean> terminateWhen) {
return new ConditionalAction(this, condition, task, terminateWhen);
2025-04-28 08:17:57 +03:00
}
@Override
public IConditionalAction create(String name, Supplier<Boolean> condition, Consumer<IAction> task, Supplier<Boolean> terminateWhen) {
return new ConditionalAction(this, name, condition, task, terminateWhen);
}
@Override
public IConditionalAction create(Supplier<Boolean> condition, Consumer<IAction> task, Supplier<Boolean> terminateWhen, Consumer<IAction> onTermination) {
return new ConditionalAction(this, condition, task, terminateWhen, onTermination);
}
@Override
public IConditionalAction create(String name, Supplier<Boolean> condition, Consumer<IAction> task, Supplier<Boolean> terminateWhen, Consumer<IAction> onTermination) {
return new ConditionalAction(this, name, condition, task, terminateWhen, onTermination);
2025-04-28 08:17:57 +03:00
}
@Override
public void start() {
isWorking = true;
}
@Override
public void stop() {
isWorking = false;
}
@Override
2025-04-28 06:47:34 +03:00
public IAction scheduleAction(IAction action) {
2025-04-26 20:52:08 -04:00
actionQueue.addLast(action);
2025-04-28 06:47:34 +03:00
return action;
}
2025-06-29 09:07:09 +03:00
@Override
2025-06-29 09:44:20 +03:00
public IAction scheduleAction(String name, Consumer<IAction> task) {
2025-06-29 09:07:09 +03:00
return scheduleAction(create(name, task));
}
@Override
public IAction scheduleAction(String name, int startAfterTicks, Consumer<IAction> task) {
return scheduleAction(create(name, startAfterTicks, task));
}
@Override
2025-04-28 06:47:34 +03:00
public IAction scheduleAction(String name, int maxDuration, int startAfterTicks, Consumer<IAction> task) {
return scheduleAction(create(name, maxDuration, startAfterTicks, task));
}
@Override
2025-04-28 06:47:34 +03:00
public IAction scheduleActionAt(int index, IAction action) {
2025-05-19 22:07:57 -04:00
int size = actionQueue.size();
if (index <= 0) {
actionQueue.addFirst(action);
} else if (index >= size) {
2025-04-26 20:52:08 -04:00
actionQueue.addLast(action);
} else {
2025-05-19 22:07:57 -04:00
List<IAction> tmp = new ArrayList<>(actionQueue);
tmp.add(index, action);
actionQueue.clear();
actionQueue.addAll(tmp);
2025-04-26 20:52:08 -04:00
}
2025-04-28 06:47:34 +03:00
return action;
}
@Override
2025-03-13 16:52:08 -04:00
public int getIndex(IAction action) {
2025-05-19 22:07:57 -04:00
int i = 0;
for (IAction a : actionQueue) {
if (a.equals(action)) return i;
i++;
}
return -1;
}
@Override
public IAction getCurrentAction() {
2025-04-26 20:52:08 -04:00
return actionQueue.peekFirst();
}
2025-06-28 19:07:37 +03:00
@Override
public IAction getAction(String name) {
for (IAction action : actionQueue) {
if (action.getName().equals(name))
return action;
}
for (IAction action : parallelActions) {
if (action.getName().equals(name))
return action;
}
for (IAction action : conditionalActions) {
if (action.getName().equals(name))
return action;
}
return null;
}
@Override
public Queue<IAction> getActionQueue() {
return actionQueue;
}
2025-06-29 09:44:20 +03:00
@Override
public boolean hasAction(String name) {
for (IAction act : actionQueue)
if (act.getName().equals(name))
return true;
return false;
}
@Override
public boolean hasAny(String name) {
if (hasAction(name))
return true;
else if (hasParallel(name))
return true;
else if (hasConditional(name))
return true;
return false;
}
2025-04-26 20:52:08 -04:00
@Override
2025-03-13 16:52:08 -04:00
public void clear() {
actionQueue.clear();
2025-04-28 03:05:56 -04:00
parallelActions.clear();
2025-04-28 08:38:30 +03:00
conditionalActions.clear();
}
2025-03-13 16:52:08 -04:00
2025-04-26 20:52:08 -04:00
@Override
public boolean cancelAction(String name) {
2025-04-28 08:36:26 +03:00
Iterator<IAction> acts = actionQueue.iterator();
while (acts.hasNext()) {
IAction act = acts.next();
2025-04-26 20:52:08 -04:00
if (act.getName().equals(name)) {
2025-04-28 08:36:26 +03:00
acts.remove();
return true;
}
}
2025-04-28 03:05:56 -04:00
Iterator<IAction> pit = parallelActions.iterator();
while (pit.hasNext()) {
if (pit.next().getName().equals(name)) {
pit.remove();
return true;
}
}
2025-04-28 08:36:26 +03:00
Iterator<IConditionalAction> cons = conditionalActions.iterator();
while (cons.hasNext()) {
IConditionalAction con = cons.next();
if (con.getName().equals(name)) {
cons.remove();
2025-04-26 20:52:08 -04:00
return true;
}
}
2025-04-26 20:52:08 -04:00
return false;
}
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// Conditionals
2025-04-26 20:52:08 -04:00
@Override
public IConditionalAction scheduleAction(String name, Supplier<Boolean> condition, Consumer<IAction> task) {
return scheduleAction(new ConditionalAction(this, name, condition, task));
2025-04-26 20:52:08 -04:00
}
@Override
public IConditionalAction scheduleAction(String name, Supplier<Boolean> condition, Consumer<IAction> task, Supplier<Boolean> terminateWhen) {
return scheduleAction(new ConditionalAction(this, name, condition, task, terminateWhen));
2025-04-28 07:41:29 +03:00
}
@Override
public IConditionalAction scheduleAction(String name, Supplier<Boolean> condition, Consumer<IAction> task, Supplier<Boolean> terminateWhen, Consumer<IAction> onTermination) {
return scheduleAction(new ConditionalAction(this, name, condition, task, terminateWhen, onTermination));
}
2025-04-28 07:41:29 +03:00
@Override
public IConditionalAction scheduleAction(IConditionalAction action) {
2025-04-28 07:41:29 +03:00
conditionalActions.add(action);
return action;
}
@Override
public List<IConditionalAction> getConditionalActions() {
2025-05-19 22:07:57 -04:00
return new ArrayList<>(conditionalActions);
}
2025-06-29 09:44:20 +03:00
@Override
public boolean hasConditional(String name) {
for (IAction act : conditionalActions)
if (act.getName().equals(name))
return true;
return false;
}
2025-04-28 03:05:56 -04:00
@Override
public IAction scheduleParallelAction(IAction action) {
parallelActions.add(action);
return action;
}
2025-04-26 20:52:08 -04:00
/**
* Call once per tick from your main loop.
*
* @param ticksExisted the global tick count, used for modulo checks.
*/
public void tick(int ticksExisted) {
if (!isWorking) return;
2025-04-28 03:05:56 -04:00
// ─── Sequential (head only) ─────────────────────────────────
2025-04-26 20:52:08 -04:00
IAction current = getCurrentAction();
2025-04-28 03:25:01 -04:00
if (current instanceof Action) {
Action cab = (Action) current;
2025-04-26 20:52:08 -04:00
cab.tick(ticksExisted);
2025-06-29 09:44:20 +03:00
if (cab.isDone()) {
cab.kill();
actionQueue.pollFirst();
}
2025-04-26 20:52:08 -04:00
}
2025-04-28 07:41:29 +03:00
2025-04-28 03:05:56 -04:00
// ─── Parallel (all) ───────────────────────────────────────
Iterator<IAction> pit = parallelActions.iterator();
while (pit.hasNext()) {
2025-04-28 03:25:01 -04:00
Action a = (Action) pit.next();
2025-04-28 03:05:56 -04:00
a.tick(ticksExisted);
2025-06-29 09:44:20 +03:00
if (a.isDone()) {
a.kill();
pit.remove();
}
2025-04-28 07:41:29 +03:00
}
2025-04-28 03:05:56 -04:00
// ─── Conditionals ─────────────────────────────────────────
Iterator<IConditionalAction> cit = conditionalActions.iterator();
while (cit.hasNext()) {
ConditionalAction con = (ConditionalAction) cit.next();
con.tick(ticksExisted);
2025-06-29 09:44:20 +03:00
if (con.isDone()) {
con.kill();
cit.remove();
}
2025-04-28 03:05:56 -04:00
}
2025-04-26 20:52:08 -04:00
}
2025-04-27 23:10:55 -04:00
@Override
public IActionChain chain() {
2025-04-28 03:25:01 -04:00
return new ActionChain(this);
2025-04-27 23:10:55 -04:00
}
2025-04-28 03:05:56 -04:00
@Override
public IActionChain parallelChain() {
2025-04-28 03:25:01 -04:00
return new ParallelActionChain(this);
2025-04-26 20:52:08 -04:00
}
2025-06-29 09:44:20 +03:00
@Override
public Queue<IAction> getParallelActions() {
return parallelActions;
}
@Override
public boolean hasParallel(String name) {
for (IAction act : parallelActions)
if (act.getName().equals(name))
return true;
return false;
}
2025-04-26 20:52:08 -04:00
}