From 6a421336df64c04355e603d5b676de0720e4a73c Mon Sep 17 00:00:00 2001 From: KingRainbow44 Date: Sun, 13 Aug 2023 19:01:08 -0400 Subject: [PATCH] Implement time axis --- .../scripts/SceneScriptManager.java | 40 ++++++++++++--- .../grasscutter/scripts/SceneTimeAxis.java | 50 +++++++++++++++++++ .../emu/grasscutter/scripts/ScriptLib.java | 25 +++++++--- 3 files changed, 102 insertions(+), 13 deletions(-) create mode 100644 src/main/java/emu/grasscutter/scripts/SceneTimeAxis.java diff --git a/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java b/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java index c9f470930..1eee758b7 100644 --- a/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java +++ b/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java @@ -1,7 +1,5 @@ package emu.grasscutter.scripts; -import static emu.grasscutter.scripts.constants.EventType.EVENT_TIMER_EVENT; - import com.github.davidmoten.rtreemulti.RTree; import com.github.davidmoten.rtreemulti.geometry.Geometry; import emu.grasscutter.Grasscutter; @@ -21,17 +19,20 @@ import emu.grasscutter.server.packet.send.PacketGroupSuiteNotify; import emu.grasscutter.utils.*; import io.netty.util.concurrent.FastThreadLocalThread; import it.unimi.dsi.fastutil.ints.*; +import kotlin.Pair; +import lombok.val; +import org.luaj.vm2.*; +import org.luaj.vm2.lib.jse.CoerceJavaToLua; + +import javax.annotation.*; import java.io.*; import java.nio.file.Files; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; -import javax.annotation.*; -import kotlin.Pair; -import lombok.val; -import org.luaj.vm2.*; -import org.luaj.vm2.lib.jse.CoerceJavaToLua; + +import static emu.grasscutter.scripts.constants.EventType.EVENT_TIMER_EVENT; public class SceneScriptManager { private final Scene scene; @@ -39,6 +40,9 @@ public class SceneScriptManager { private SceneMeta meta; private boolean isInit; + private final Map timeAxis + = new ConcurrentHashMap<>(); + /** current triggers controlled by RefreshGroup */ private final Map> currentTriggers; @@ -1198,6 +1202,28 @@ public class SceneScriptManager { }); } + /** + * Registers a new time axis for this scene. + * Starts the time axis after. + * + * @param timeAxis The time axis. + */ + public void initTimeAxis(SceneTimeAxis timeAxis) { + this.timeAxis.put(timeAxis.getIdentifier(), timeAxis); + } + + /** + * Terminates a time axis. + * + * @param identifier The identifier of the time axis. + */ + public void stopTimeAxis(String identifier) { + var timeAxis = this.timeAxis.get(identifier); + if (timeAxis != null) { + timeAxis.stop(); + } + } + public void onDestroy() { activeGroupTimers.forEach( (gid, times) -> diff --git a/src/main/java/emu/grasscutter/scripts/SceneTimeAxis.java b/src/main/java/emu/grasscutter/scripts/SceneTimeAxis.java new file mode 100644 index 000000000..971068e4a --- /dev/null +++ b/src/main/java/emu/grasscutter/scripts/SceneTimeAxis.java @@ -0,0 +1,50 @@ +package emu.grasscutter.scripts; + +import emu.grasscutter.scripts.constants.EventType; +import emu.grasscutter.scripts.data.ScriptArgs; +import lombok.*; + +import java.util.*; + +@Getter +@RequiredArgsConstructor +public final class SceneTimeAxis { + private final Timer timer = new Timer(); + + private final SceneScriptManager handle; + private final int groupId; + + private final String identifier; + private final int delay; + private final boolean loop; + + /** + * Schedules the task to run. + */ + public void start() { + if (this.loop) { + this.timer.scheduleAtFixedRate( + new Task(), this.delay, this.delay); + } else { + this.timer.schedule(new Task(), this.delay); + } + } + + /** + * Terminates a repeating task. + */ + public void stop() { + this.timer.cancel(); + } + + final class Task extends TimerTask { + @Override + public void run() { + // Invoke script event. + SceneTimeAxis.this.handle.callEvent(new ScriptArgs( + SceneTimeAxis.this.groupId, + EventType.EVENT_TIME_AXIS_PASS + ).setEventSource(SceneTimeAxis.this.identifier)); + } + } +} diff --git a/src/main/java/emu/grasscutter/scripts/ScriptLib.java b/src/main/java/emu/grasscutter/scripts/ScriptLib.java index d55ebf7a1..3321dd9bf 100644 --- a/src/main/java/emu/grasscutter/scripts/ScriptLib.java +++ b/src/main/java/emu/grasscutter/scripts/ScriptLib.java @@ -956,14 +956,27 @@ public class ScriptLib { return 0; } - public int InitTimeAxis(String var1, int[] var2, boolean var3){ - logger.warn("[LUA] Call unimplemented InitTimeAxis with {} {} {}", var1, var2, var3); - //TODO implement var1 == name? var2 == delay? var3 == should loop? + public int InitTimeAxis(String identifier, int[] delays, boolean shouldLoop) { + if (this.getCurrentGroup().isEmpty()) { + logger.warn("[LUA] Call InitTimeAxis without a group"); + return 0; + } + + var scriptManager = this.getSceneScriptManager(); + var group = this.getCurrentGroup().get(); + + // Create a new time axis instance. + scriptManager.initTimeAxis(new SceneTimeAxis( + scriptManager, group.id, + identifier, delays[0], shouldLoop + )); + return 0; } - public int EndTimeAxis(String var1){ - logger.warn("[LUA] Call unimplemented EndTimeAxis with {}", var1); - //TODO implement var1 == name? + + public int EndTimeAxis(String identifier) { + this.getSceneScriptManager().stopTimeAxis(identifier); + return 0; }