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
This commit is contained in:
simibubi 2023-11-01 20:22:29 +01:00
parent 77ba1e8bf6
commit d6708cef3b
5 changed files with 34 additions and 25 deletions

View file

@ -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)

View file

@ -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<TrackNode, TrackEdge> connectionsFromInitial = graph.getConnectionsFrom(initialNode1);
if (connectionsFromInitial == null)
return -1;
TrackEdge initialEdge = connectionsFromInitial.get(initialNode2);
if (initialEdge == null)
return -1; // graph changed

View file

@ -601,7 +601,7 @@ public class Train {
Vec3 start = (speed < 0 ? trailingPoint : leadingPoint).getPosition(graph);
Vec3 end = (speed < 0 ? leadingPoint : trailingPoint).getPosition(graph);
Pair<Train, Vec3> collision = findCollidingTrain(level, start, end, this, dimension);
Pair<Train, Vec3> collision = findCollidingTrain(level, start, end, dimension);
if (collision == null)
return;
@ -617,13 +617,16 @@ public class Train {
train.crash();
}
public static Pair<Train, Vec3> findCollidingTrain(Level level, Vec3 start, Vec3 end, Train ignore,
ResourceKey<Level> dimension) {
for (Train train : Create.RAILWAYS.sided(level).trains.values()) {
if (train == ignore)
public Pair<Train, Vec3> findCollidingTrain(Level level, Vec3 start, Vec3 end, ResourceKey<Level> 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;

View file

@ -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)

View file

@ -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<Boolean> values = blockEntities.get(primary)
.values();
for (Boolean b : values)
if (b)
return true;
return false;
}
private SignalState resolveSignalChain(TrackGraph graph, boolean side) {