mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 16:37:45 +00:00
Merge branch 'dev' of https://github.com/KAMKEEL/CustomNPC-Plus into dev
This commit is contained in:
commit
8296a008d4
9 files changed
+365
-23
No files matched your search
@@ -496,7 +496,7 @@ public class ScriptPlayerEventHandler {
|
||||
|
||||
EntityPlayer player = (EntityPlayer) event.entityLiving;
|
||||
PlayerData playerData = PlayerData.get(player);
|
||||
playerData.actionManager.clear();
|
||||
// playerData.actionManager.clear();
|
||||
}
|
||||
|
||||
if (event.source.getEntity() instanceof EntityPlayerMP) {
|
||||
|
||||
@@ -11,13 +11,22 @@ import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import noppes.npcs.client.AnalyticsTracking;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.scripted.NpcAPI;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public class ServerTickHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerTick(TickEvent.WorldTickEvent event) {
|
||||
public void onServerTick(TickEvent.ServerTickEvent event) {
|
||||
if (event.phase == Phase.END) {
|
||||
NpcAPI.actionManager.tick(MinecraftServer.getServer().getTickCounter());
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onWorldTick(TickEvent.WorldTickEvent event) {
|
||||
if (event.phase == Phase.START) {
|
||||
NPCSpawning.findChunksForSpawning((WorldServer) event.world);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package noppes.npcs.controllers.data.action;
|
||||
|
||||
import noppes.npcs.api.handler.data.IAction;
|
||||
import noppes.npcs.scripted.CustomNPCsException;
|
||||
import noppes.npcs.scripted.ScriptedActionManager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Action implements IAction {
|
||||
protected final ScriptedActionManager manager;
|
||||
@@ -16,8 +18,10 @@ public class Action implements IAction {
|
||||
protected int maxDuration = -1;
|
||||
protected int updateEveryXTick = 5;
|
||||
protected Consumer<IAction> task;
|
||||
private boolean done;
|
||||
private final Map<String, Object> dataStore = new HashMap<>();
|
||||
protected boolean done;
|
||||
protected final Map<String, Object> dataStore = new HashMap<>();
|
||||
protected boolean isThreaded;
|
||||
protected ActionThread threaded;
|
||||
|
||||
public Action(ScriptedActionManager manager, String name) {
|
||||
this.manager = manager;
|
||||
@@ -68,13 +72,17 @@ public class Action implements IAction {
|
||||
return;
|
||||
}
|
||||
if (ticksExisted % updateEveryXTick == 0 && task != null) {
|
||||
try {
|
||||
task.accept(this);
|
||||
count++;
|
||||
} catch (Throwable t) {
|
||||
System.err.println("Scripted action '" + name + "' threw an exception:");
|
||||
t.printStackTrace();
|
||||
markDone();
|
||||
if (isThreaded)
|
||||
threaded.run();
|
||||
else {
|
||||
try {
|
||||
task.accept(this);
|
||||
count++;
|
||||
} catch (Throwable t) {
|
||||
System.err.println("Scripted action '" + name + "' threw an exception:");
|
||||
t.printStackTrace();
|
||||
markDone();
|
||||
}
|
||||
}
|
||||
}
|
||||
duration++;
|
||||
@@ -107,7 +115,7 @@ public class Action implements IAction {
|
||||
|
||||
@Override
|
||||
public IAction setMaxDuration(int x) {
|
||||
this.maxDuration = x;
|
||||
this.maxDuration = Math.max(-1, x);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -121,6 +129,11 @@ public class Action implements IAction {
|
||||
return done;
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
if (threaded != null)
|
||||
threaded.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(String key) {
|
||||
return dataStore.get(key);
|
||||
@@ -150,7 +163,7 @@ public class Action implements IAction {
|
||||
|
||||
@Override
|
||||
public IAction setUpdateEveryXTick(int x) {
|
||||
this.updateEveryXTick = x;
|
||||
this.updateEveryXTick = Math.max(1, x);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -161,7 +174,67 @@ public class Action implements IAction {
|
||||
|
||||
@Override
|
||||
public IAction pauseFor(int ticks) {
|
||||
this.startAfterTicks = ticks;
|
||||
if (isThreaded)
|
||||
threaded.pauseFor(ticks);
|
||||
else
|
||||
this.startAfterTicks = ticks;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction pauseFor(long millis) {
|
||||
if (isThreaded) {
|
||||
threaded.pauseFor(millis);
|
||||
return this;
|
||||
}
|
||||
|
||||
return pauseFor((int) (millis / 50));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
if (isThreaded)
|
||||
threaded.pause();
|
||||
else
|
||||
throw new CustomNPCsException("Must threadify() IAction before pausing!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseUntil(Supplier<Boolean> until) {
|
||||
if (isThreaded)
|
||||
threaded.pauseUntil(until);
|
||||
else
|
||||
throw new CustomNPCsException("Must threadify() IAction before pausing!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume() {
|
||||
if (isThreaded)
|
||||
threaded.resume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
if (isThreaded)
|
||||
return threaded.isPaused();
|
||||
|
||||
return startAfterTicks > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction threadify() {
|
||||
if (!isThreaded) {
|
||||
isThreaded = true;
|
||||
threaded = new ActionThread(this);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction start() {
|
||||
manager.start();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -191,6 +264,32 @@ public class Action implements IAction {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction parallel(IAction after) {
|
||||
return manager.scheduleParallelAction(after);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction parallel(Consumer<IAction> task) {
|
||||
return manager.scheduleParallelAction(manager.create(task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction parallel(int delay, Consumer<IAction> task) {
|
||||
return manager.scheduleParallelAction(manager.create(delay, task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction parallel(String name, Consumer<IAction> task) {
|
||||
return manager.scheduleParallelAction(manager.create(name, task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction parallel(String name, int startAfterTicks, Consumer<IAction> task) {
|
||||
return manager.scheduleParallelAction(manager.create(name, startAfterTicks, task));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IAction after(IAction after) {
|
||||
int idx = manager.getIndex(this);
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
package noppes.npcs.controllers.data.action;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ActionThread {
|
||||
private final Action action;
|
||||
|
||||
private final Object lock = new Object();
|
||||
private Thread thread;
|
||||
ExecutorService executor;
|
||||
private Future<?> currentExecution;
|
||||
private volatile boolean threadPaused, threadSleeping;
|
||||
|
||||
private Supplier<Boolean> pauseUntil;
|
||||
|
||||
public ActionThread(Action action) {
|
||||
this.action = action;
|
||||
|
||||
executor = Executors.newSingleThreadExecutor(r -> {
|
||||
thread = new Thread(r);
|
||||
thread.setName(String.format("ActionThread (%s)", action.getName()));
|
||||
return thread;
|
||||
});
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (isThreadRunning())
|
||||
currentExecution.cancel(true);
|
||||
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
public void pauseFor(long millis) {
|
||||
if (isPaused() || !inActionThread())
|
||||
return;
|
||||
|
||||
try {
|
||||
threadSleeping = true;
|
||||
Thread.sleep(millis);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} finally {
|
||||
threadSleeping = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void pauseFor(int ticks) {
|
||||
pauseFor(ticks * 50L);
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if (!inActionThread() || isPaused())
|
||||
return;
|
||||
|
||||
threadPaused = true;
|
||||
synchronized (lock) {
|
||||
while (threadPaused) {
|
||||
try {
|
||||
lock.wait(); // Wait until notified
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void pauseUntil(Supplier<Boolean> until) {
|
||||
this.pauseUntil = until;
|
||||
pause();
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
synchronized (lock) {
|
||||
if (threadPaused) {
|
||||
threadPaused = false;
|
||||
lock.notify();
|
||||
}
|
||||
|
||||
if (threadSleeping && currentExecution != null)
|
||||
currentExecution.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean inActionThread() {
|
||||
return Thread.currentThread() == thread;
|
||||
}
|
||||
|
||||
public boolean isPaused() {
|
||||
return threadPaused || threadSleeping;
|
||||
}
|
||||
|
||||
public boolean isThreadRunning() {
|
||||
return currentExecution != null && !currentExecution.isDone();
|
||||
}
|
||||
|
||||
|
||||
protected void run() {
|
||||
if (threadPaused && pauseUntil != null && pauseUntil.get())
|
||||
resume();
|
||||
|
||||
if (isThreadRunning())
|
||||
return;
|
||||
|
||||
currentExecution = executor.submit(() -> {
|
||||
try {
|
||||
action.task.accept(action);
|
||||
action.count++;
|
||||
} catch (Throwable t) {
|
||||
System.err.println("Scripted threaded action '" + action.name + "' threw an exception:");
|
||||
t.printStackTrace();
|
||||
action.markDone();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1168,7 +1168,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti
|
||||
setHealth(getMaxHealth());
|
||||
dataWatcher.updateObject(14, 0); // animation Normal
|
||||
dataWatcher.updateObject(15, 0);
|
||||
actionManager.clear();
|
||||
// actionManager.clear();
|
||||
combatHandler.reset();
|
||||
this.setAttackTarget(null);
|
||||
this.setRevengeTarget(null);
|
||||
|
||||
@@ -79,6 +79,7 @@ public class NpcAPI extends AbstractNpcAPI {
|
||||
private static final CacheHashMap<ItemStack, CacheHashMap.CachedObject<ScriptItemStack>> scriptItemCache = new CacheHashMap<>(60 * 1000);
|
||||
public static final HashMap<String, Object> engineObjects = new HashMap<>();
|
||||
public static final EventBus EVENT_BUS = new EventBus();
|
||||
public static final ScriptedActionManager actionManager = new ScriptedActionManager();
|
||||
private static AbstractNpcAPI instance = null;
|
||||
|
||||
private final static String API_USER_AGENT = "CNPC+API";
|
||||
@@ -559,6 +560,10 @@ public class NpcAPI extends AbstractNpcAPI {
|
||||
return container instanceof ContainerNpcInterface ? ContainerNpcInterface.getOrCreateIContainer((ContainerNpcInterface) container) : new ScriptContainer(container);
|
||||
}
|
||||
|
||||
public IActionManager getActionManager() {
|
||||
return actionManager;
|
||||
}
|
||||
|
||||
private void checkWorld() {
|
||||
if (CustomNpcs.getServer() == null || CustomNpcs.getServer().isServerStopped()) {
|
||||
throw new CustomNPCsException("No world is loaded right now");
|
||||
|
||||
@@ -40,8 +40,8 @@ public class ScriptedActionManager implements IActionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction create(String name, int maxDuration, int startAfterTicks, Consumer<IAction> task) {
|
||||
return new Action(this, name, maxDuration, startAfterTicks, task);
|
||||
public IAction create(String name, int maxDuration, int delay, Consumer<IAction> task) {
|
||||
return new Action(this, name, maxDuration, delay, task);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,8 +106,27 @@ public class ScriptedActionManager implements IActionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction scheduleAction(String name, int maxDuration, int startAfterTicks, Consumer<IAction> task) {
|
||||
return scheduleAction(create(name, maxDuration, startAfterTicks, task));
|
||||
public IAction scheduleAction(Consumer<IAction> task) {
|
||||
return scheduleAction(create(task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction scheduleAction(int delay, Consumer<IAction> task) {
|
||||
return scheduleAction(create(delay, task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction scheduleAction(String name, Consumer<IAction> task) {
|
||||
return scheduleAction(create(name, task));
|
||||
}
|
||||
@Override
|
||||
public IAction scheduleAction(String name, int delay, Consumer<IAction> task) {
|
||||
return scheduleAction(create(name, delay, task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction scheduleAction(String name, int maxDuration, int delay, Consumer<IAction> task) {
|
||||
return scheduleAction(create(name, maxDuration, delay, task));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -141,11 +160,51 @@ public class ScriptedActionManager implements IActionManager {
|
||||
return actionQueue.peekFirst();
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
actionQueue.clear();
|
||||
@@ -213,11 +272,33 @@ public class ScriptedActionManager implements IActionManager {
|
||||
return new ArrayList<>(conditionalActions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasConditional(String name) {
|
||||
for (IAction act : conditionalActions)
|
||||
if (act.getName().equals(name))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction scheduleParallelAction(IAction action) {
|
||||
parallelActions.add(action);
|
||||
return action;
|
||||
}
|
||||
@Override
|
||||
public IAction scheduleParallelAction(String name, Consumer<IAction> task) {
|
||||
return scheduleParallelAction(create(name, task));
|
||||
}
|
||||
@Override
|
||||
public IAction scheduleParallelAction(String name, int delay, Consumer<IAction> task) {
|
||||
return scheduleParallelAction(create(name, delay, task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAction scheduleParallelAction(String name, int maxDuration, int delay, Consumer<IAction> task) {
|
||||
return scheduleParallelAction(create(name, maxDuration, delay, task));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -233,7 +314,10 @@ public class ScriptedActionManager implements IActionManager {
|
||||
if (current instanceof Action) {
|
||||
Action cab = (Action) current;
|
||||
cab.tick(ticksExisted);
|
||||
if (cab.isDone()) actionQueue.pollFirst();
|
||||
if (cab.isDone()) {
|
||||
cab.kill();
|
||||
actionQueue.pollFirst();
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Parallel (all) ───────────────────────────────────────
|
||||
@@ -241,7 +325,10 @@ public class ScriptedActionManager implements IActionManager {
|
||||
while (pit.hasNext()) {
|
||||
Action a = (Action) pit.next();
|
||||
a.tick(ticksExisted);
|
||||
if (a.isDone()) pit.remove();
|
||||
if (a.isDone()) {
|
||||
a.kill();
|
||||
pit.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Conditionals ─────────────────────────────────────────
|
||||
@@ -249,7 +336,10 @@ public class ScriptedActionManager implements IActionManager {
|
||||
while (cit.hasNext()) {
|
||||
ConditionalAction con = (ConditionalAction) cit.next();
|
||||
con.tick(ticksExisted);
|
||||
if (con.isDone()) cit.remove();
|
||||
if (con.isDone()) {
|
||||
con.kill();
|
||||
cit.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,4 +352,18 @@ public class ScriptedActionManager implements IActionManager {
|
||||
public IActionChain parallelChain() {
|
||||
return new ParallelActionChain(this);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import noppes.npcs.api.*;
|
||||
import noppes.npcs.api.entity.IEntity;
|
||||
import noppes.npcs.api.entity.IPlayer;
|
||||
import noppes.npcs.api.gui.ICustomGui;
|
||||
import noppes.npcs.api.handler.IActionManager;
|
||||
import noppes.npcs.api.handler.IOverlayHandler;
|
||||
import noppes.npcs.api.handler.data.*;
|
||||
import noppes.npcs.api.item.IItemStack;
|
||||
@@ -846,4 +847,9 @@ public class ScriptPlayer<T extends EntityPlayerMP> extends ScriptLivingBase<T>
|
||||
public IPlayerAttributes getAttributes() {
|
||||
return AttributeController.getTracker(this.player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IActionManager getActionManager() {
|
||||
return data.actionManager;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user