From d6708cef3b558d97a9e3450067d43474f2838d7f Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Wed, 1 Nov 2023 20:22:29 +0100 Subject: [PATCH] Collide on sight - Trains check their distance before running full collision tests - Trains can no longer collide when on separate track networks - Micro-optimised some streams and map value iterators --- .../content/trains/GlobalRailwayManager.java | 11 +++++------ .../trains/entity/CarriageSyncData.java | 9 ++++++--- .../create/content/trains/entity/Train.java | 19 +++++++++++++------ .../content/trains/entity/TrainRelocator.java | 4 ++-- .../content/trains/signal/SignalBoundary.java | 16 ++++++++-------- 5 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/trains/GlobalRailwayManager.java b/src/main/java/com/simibubi/create/content/trains/GlobalRailwayManager.java index b20f8b9f7..73d9d244a 100644 --- a/src/main/java/com/simibubi/create/content/trains/GlobalRailwayManager.java +++ b/src/main/java/com/simibubi/create/content/trains/GlobalRailwayManager.java @@ -188,20 +188,19 @@ public class GlobalRailwayManager { if (level.dimension() != Level.OVERWORLD) return; - for (SignalEdgeGroup group : signalEdgeGroups.values()) { + signalEdgeGroups.forEach((id, group) -> { group.trains.clear(); group.reserved = null; - } + }); - for (TrackGraph graph : trackNetworks.values()) { + trackNetworks.forEach((id, graph) -> { graph.tickPoints(true); graph.resolveIntersectingEdgeGroups(level); - } + }); tickTrains(level); - for (TrackGraph graph : trackNetworks.values()) - graph.tickPoints(false); + trackNetworks.forEach((id, graph) -> graph.tickPoints(false)); GlobalTrainDisplayData.updateTick = level.getGameTime() % 100 == 0; if (GlobalTrainDisplayData.updateTick) diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageSyncData.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageSyncData.java index 70ac8d235..83dcd85be 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageSyncData.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageSyncData.java @@ -304,9 +304,12 @@ public class CarriageSyncData { TrackNode initialNode1 = forward ? current.node1 : current.node2; TrackNode initialNode2 = forward ? current.node2 : current.node1; - TrackEdge initialEdge = graph.getConnectionsFrom(initialNode1) - .get(initialNode2); - + + Map connectionsFromInitial = graph.getConnectionsFrom(initialNode1); + if (connectionsFromInitial == null) + return -1; + + TrackEdge initialEdge = connectionsFromInitial.get(initialNode2); if (initialEdge == null) return -1; // graph changed diff --git a/src/main/java/com/simibubi/create/content/trains/entity/Train.java b/src/main/java/com/simibubi/create/content/trains/entity/Train.java index ee73a2d89..3d539192a 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/Train.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/Train.java @@ -601,7 +601,7 @@ public class Train { Vec3 start = (speed < 0 ? trailingPoint : leadingPoint).getPosition(graph); Vec3 end = (speed < 0 ? leadingPoint : trailingPoint).getPosition(graph); - Pair collision = findCollidingTrain(level, start, end, this, dimension); + Pair collision = findCollidingTrain(level, start, end, dimension); if (collision == null) return; @@ -617,13 +617,16 @@ public class Train { train.crash(); } - public static Pair findCollidingTrain(Level level, Vec3 start, Vec3 end, Train ignore, - ResourceKey dimension) { - for (Train train : Create.RAILWAYS.sided(level).trains.values()) { - if (train == ignore) + public Pair findCollidingTrain(Level level, Vec3 start, Vec3 end, ResourceKey dimension) { + Vec3 diff = end.subtract(start); + double maxDistanceSqr = Math.pow(AllConfigs.server().trains.maxAssemblyLength.get(), 2.0); + + Trains: for (Train train : Create.RAILWAYS.sided(level).trains.values()) { + if (train == this) + continue; + if (train.graph != null && train.graph != graph) continue; - Vec3 diff = end.subtract(start); Vec3 lastPoint = null; for (Carriage otherCarriage : train.carriages) { @@ -643,6 +646,10 @@ public class Train { Vec3 start2 = otherLeading.getPosition(train.graph); Vec3 end2 = otherTrailing.getPosition(train.graph); + + if (Math.min(start2.distanceToSqr(start), end2.distanceToSqr(start)) > maxDistanceSqr) + continue Trains; + if (betweenBits) { end2 = start2; start2 = lastPoint; diff --git a/src/main/java/com/simibubi/create/content/trains/entity/TrainRelocator.java b/src/main/java/com/simibubi/create/content/trains/entity/TrainRelocator.java index ee806f9f9..94caf1327 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/TrainRelocator.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/TrainRelocator.java @@ -223,8 +223,8 @@ public class TrainRelocator { Vec3 vec1 = recordedVecs.get(i); Vec3 vec2 = recordedVecs.get(i + 1); boolean blocking = i >= blockingIndex.intValue() - 1; - boolean collided = !blocked.booleanValue() - && Train.findCollidingTrain(level, vec1, vec2, train, level.dimension()) != null; + boolean collided = + !blocked.booleanValue() && train.findCollidingTrain(level, vec1, vec2, level.dimension()) != null; if (level.isClientSide && simulate) toVisualise.add(vec2); if (collided || blocking) diff --git a/src/main/java/com/simibubi/create/content/trains/signal/SignalBoundary.java b/src/main/java/com/simibubi/create/content/trains/signal/SignalBoundary.java index 327b525c2..c61263078 100644 --- a/src/main/java/com/simibubi/create/content/trains/signal/SignalBoundary.java +++ b/src/main/java/com/simibubi/create/content/trains/signal/SignalBoundary.java @@ -1,5 +1,6 @@ package com.simibubi.create.content.trains.signal; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -187,10 +188,7 @@ public class SignalBoundary extends TrackEdgePoint { if (set.isEmpty()) continue; - boolean forcedRed = set.values() - .stream() - .anyMatch(Boolean::booleanValue); - + boolean forcedRed = isForcedRed(current); UUID group = groups.get(current); if (Objects.equal(group, groups.get(!current))) { cachedStates.set(current, SignalState.INVALID); @@ -214,10 +212,12 @@ public class SignalBoundary extends TrackEdgePoint { } public boolean isForcedRed(boolean primary) { - return blockEntities.get(primary) - .values() - .stream() - .anyMatch(Boolean::booleanValue); + Collection values = blockEntities.get(primary) + .values(); + for (Boolean b : values) + if (b) + return true; + return false; } private SignalState resolveSignalChain(TrackGraph graph, boolean side) {