From c10f01f92383caced55cdf000eb000d8470564bf Mon Sep 17 00:00:00 2001 From: zbx1425 Date: Sun, 30 Jul 2023 23:41:41 +0800 Subject: [PATCH] Add getRelativeStation --- .../render/scripting/GraphicsTexture.java | 4 + .../render/scripting/RenderTrainScripted.java | 5 +- .../render/scripting/TrainExtra.java | 115 ++++++++++++++++++ .../render/scripting/TrainScriptContext.java | 25 +++- .../scripting/TrainTypeScriptContext.java | 4 +- 5 files changed, 146 insertions(+), 7 deletions(-) create mode 100644 common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainExtra.java diff --git a/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/GraphicsTexture.java b/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/GraphicsTexture.java index 6267a995..a17da105 100644 --- a/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/GraphicsTexture.java +++ b/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/GraphicsTexture.java @@ -22,7 +22,11 @@ public class GraphicsTexture { private final BufferedImage bufferedImage; public final Graphics2D graphics; + public final int width, height; + public GraphicsTexture(int width, int height) { + this.width = width; + this.height = height; dynamicTexture = new DynamicTexture(new NativeImage(width, height, false)); identifier = new ResourceLocation(Main.MOD_ID, String.format("dynamic/graphics/%s", UUID.randomUUID())); Minecraft.getInstance().execute(() -> { diff --git a/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/RenderTrainScripted.java b/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/RenderTrainScripted.java index 16d1124c..857b8bf6 100644 --- a/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/RenderTrainScripted.java +++ b/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/RenderTrainScripted.java @@ -4,6 +4,7 @@ import cn.zbx1425.mtrsteamloco.render.RenderUtil; import cn.zbx1425.sowcer.math.Matrix4f; import cn.zbx1425.sowcer.math.PoseStackUtil; +import mtr.client.ClientData; import mtr.data.TrainClient; import mtr.render.TrainRendererBase; import net.minecraft.client.renderer.LightTexture; @@ -32,7 +33,6 @@ private RenderTrainScripted(RenderTrainScripted base, TrainClient trainClient) { @Override public TrainRendererBase createTrainInstance(TrainClient trainClient) { RenderTrainScripted result = new RenderTrainScripted(this, trainClient); - result.trainScripting.callCreate(typeScripting); return result; } @@ -55,7 +55,10 @@ public void renderCar(int carIndex, double x, double y, double z, float yaw, flo } matrices.popPose(); + trainScripting.trainExtraWriting.doorLeftOpen[carIndex] = doorLeftOpen; + trainScripting.trainExtraWriting.doorRightOpen[carIndex] = doorRightOpen; if (carIndex == train.trainCars - 1) { + trainScripting.extraFinished(); trainScripting.tryCallRender(typeScripting); } } diff --git a/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainExtra.java b/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainExtra.java new file mode 100644 index 00000000..956c9ac2 --- /dev/null +++ b/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainExtra.java @@ -0,0 +1,115 @@ +package cn.zbx1425.mtrsteamloco.render.scripting; + +import cn.zbx1425.mtrsteamloco.Main; +import cn.zbx1425.mtrsteamloco.mixin.TrainAccessor; +import mtr.client.ClientData; +import mtr.data.DataCache; +import mtr.data.Route; +import mtr.data.Station; +import mtr.data.TrainClient; +import mtr.path.PathData; + +import java.util.*; + +public class TrainExtra { + + public boolean[] doorLeftOpen; + public boolean[] doorRightOpen; + + private final TrainClient train; + private StationIndexMap trainStations; + private List mapValidForPath; + + public TrainExtra(TrainClient train) { + doorLeftOpen = new boolean[train.trainCars]; + doorRightOpen = new boolean[train.trainCars]; + this.train = train; + } + + public void reset() { + if (mapValidForPath == null || !mapValidForPath.equals(train.path)) { + if (train.getRouteIds().size() > 0) { + trainStations = getTrainStations(); + mapValidForPath = train.path; + } + } + } + + private StationIndexMap getTrainStations() { + List routeIds = train.getRouteIds(); + DataCache dataCache = ClientData.DATA_CACHE; + if (routeIds.size() == 0) return null; + StationIndexMap result = new StationIndexMap(); + int sum = 0; + int processingPathIndex = 0; + for(int i = 0; i < routeIds.size(); ++i) { + Route thisRoute = dataCache.routeIdMap.get(routeIds.get(i)); + Route nextRoute = i < routeIds.size() - 1 && !(dataCache.routeIdMap.get(routeIds.get(i + 1))).isHidden ? dataCache.routeIdMap.get(routeIds.get(i + 1)) : null; + Station lastStation = ClientData.DATA_CACHE.platformIdToStation.get(thisRoute.getLastPlatformId()); + if (thisRoute != null) { + int routeBeginOffset = sum; + sum += thisRoute.platformIds.size(); + if (!thisRoute.platformIds.isEmpty() && nextRoute != null && !nextRoute.platformIds.isEmpty() && thisRoute.getLastPlatformId() == nextRoute.getFirstPlatformId()) { + --sum; + } + + while (processingPathIndex < train.path.size() + && train.path.get(processingPathIndex).stopIndex - 1 < sum) { + if (train.path.get(processingPathIndex).dwellTime <= 0) { + processingPathIndex++; + continue; + } + int difference = train.path.get(processingPathIndex).stopIndex - 1 - routeBeginOffset; + Station thisStation = dataCache.platformIdToStation.get((thisRoute.platformIds.get(difference)).platformId); + String customDestination = thisRoute.getDestination(difference); + double distance = ((TrainAccessor)train).getDistances().get(processingPathIndex); + result.put(processingPathIndex, new StationInfo(thisRoute, thisStation, lastStation, customDestination != null ? customDestination : lastStation.name, distance)); + processingPathIndex++; + } + } + } + return result; + } + + public StationInfo getRelativeStation(int offset, boolean allowDifferentLine) { + int headIndex = train.getIndex(0, train.spacing, true); + if (trainStations == null) return null; + Map.Entry ceilEntry = trainStations.idLookup.ceilingEntry(headIndex); + if (ceilEntry == null) return null; + int queryIndex = ceilEntry.getValue() + offset; + if (queryIndex < 0 || queryIndex > trainStations.stations.size() - 1 + || (!allowDifferentLine && !Objects.equals(trainStations.stations.get(queryIndex).route.id, trainStations.stations.get(ceilEntry.getValue()).route.id))) { + return null; + } else { + return trainStations.stations.get(queryIndex); + } + } + + private static class StationIndexMap { + + private final TreeMap idLookup = new TreeMap<>(); + private final ArrayList stations = new ArrayList<>(); + + public void put(int index, StationInfo stationInfo) { + stations.add(stationInfo); + idLookup.put(index, stations.size() - 1); + } + } + + public static class StationInfo { + + public Route route; + public Station station; + public Station destinationStation; + public String destinationName; + public double distance; + + public StationInfo(Route route, Station station, Station destinationStation, String destinationName, double distance) { + this.route = route; + this.station = station; + this.destinationStation = destinationStation; + this.destinationName = destinationName; + this.distance = distance; + } + } +} diff --git a/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainScriptContext.java b/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainScriptContext.java index f55e3bfd..48f48385 100644 --- a/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainScriptContext.java +++ b/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainScriptContext.java @@ -14,22 +14,30 @@ public class TrainScriptContext { public Future scriptStatus; public TrainClient train; + public TrainExtra trainExtra; + protected TrainExtra trainExtraWriting; + public TrainDrawCalls scriptResult; private TrainDrawCalls scriptResultWriting; public Scriptable state; + private boolean created = false; + public TrainScriptContext(TrainClient train) { scriptResult = new TrainDrawCalls(train.trainCars); scriptResultWriting = new TrainDrawCalls(train.trainCars); + trainExtra = new TrainExtra(train); + trainExtraWriting = new TrainExtra(train); this.train = train; } - public void callCreate(TrainTypeScriptContext jsContext) { - scriptStatus = jsContext.callCreateTrain(this); - } - public void tryCallRender(TrainTypeScriptContext jsContext) { + if (!created) { + scriptStatus = jsContext.callCreateTrain(this); + created = true; + return; + } if (scriptStatus == null || scriptStatus.isDone()) { scriptStatus = jsContext.callRenderTrain(this); } @@ -44,6 +52,15 @@ public void scriptFinished() { } } + public void extraFinished() { + synchronized (this) { + TrainExtra temp = trainExtraWriting; + trainExtraWriting = trainExtra; + trainExtra = temp; + trainExtraWriting.reset(); + } + } + public void drawCarModel(int carIndex, ModelCluster model, Matrices poseStack) { scriptResultWriting.enqueueCar(carIndex, model, poseStack == null ? Matrix4f.IDENTITY : poseStack.last()); } diff --git a/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainTypeScriptContext.java b/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainTypeScriptContext.java index 1fdfe6f2..e47994da 100644 --- a/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainTypeScriptContext.java +++ b/common/src/main/java/cn/zbx1425/mtrsteamloco/render/scripting/TrainTypeScriptContext.java @@ -56,7 +56,7 @@ public Future callCreateTrain(TrainScriptContext trainCtx) { try { Object createFunction = scope.get("createTrain", scope); if (createFunction instanceof Function && createFunction != Scriptable.NOT_FOUND) { - Object[] functionParam = { trainCtx, trainCtx.train, trainCtx.state }; + Object[] functionParam = { trainCtx }; ((Function)createFunction).call(rhinoCtx, scope, scope, functionParam); } } catch (Exception ex) { @@ -75,7 +75,7 @@ public Future callRenderTrain(TrainScriptContext trainCtx) { try { Object renderFunction = scope.get("renderTrain", scope); if (renderFunction instanceof Function && renderFunction != Scriptable.NOT_FOUND) { - Object[] functionParam = { trainCtx, trainCtx.train, trainCtx.state }; + Object[] functionParam = { trainCtx }; ((Function)renderFunction).call(rhinoCtx, scope, scope, functionParam); } trainCtx.scriptFinished();