mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-18 07:53:07 +01:00
The Client is always right
- Fixed edge points getting wiped near where two graphs just merged - Fixed edge points not migrating to modified edges properly - Graph edge points are now synched by netcode (signals, stations) - Fixed incorrect stopping position when approaching station manually while the train is still moving backwards - Fixed single-group edges not being deserialised correctly - Edge data is now synched by netcode - Signal edge groups are now synched by netcode - Signal block indication can now get necessary information client-side
This commit is contained in:
parent
3362e6a05e
commit
3c64ada850
23 changed files with 592 additions and 245 deletions
|
@ -46,6 +46,7 @@ public class GlobalRailwayManager {
|
|||
loadTrackData(serverPlayer.getServer());
|
||||
trackNetworks.values()
|
||||
.forEach(g -> sync.sendFullGraphTo(g, serverPlayer));
|
||||
sync.sendEdgeGroups(signalEdgeGroups.keySet(), serverPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,21 +151,21 @@ public class GlobalRailwayManager {
|
|||
for (Train train : trains.values())
|
||||
train.tick(level);
|
||||
|
||||
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_H)) {
|
||||
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_H) && AllKeys.altDown())
|
||||
trackNetworks.values()
|
||||
.forEach(TrackGraph::debugViewSignalData);
|
||||
}
|
||||
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_J) && AllKeys.altDown()) {
|
||||
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_J) && AllKeys.altDown())
|
||||
trackNetworks.values()
|
||||
.forEach(TrackGraph::debugViewNodes);
|
||||
}
|
||||
}
|
||||
|
||||
public void clientTick() {
|
||||
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_J) && !AllKeys.altDown()) {
|
||||
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_H) && !AllKeys.altDown())
|
||||
trackNetworks.values()
|
||||
.forEach(TrackGraph::debugViewSignalData);
|
||||
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_J) && !AllKeys.altDown())
|
||||
trackNetworks.values()
|
||||
.forEach(TrackGraph::debugViewNodes);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ public class TrackGraph {
|
|||
public <T extends TrackEdgePoint> void addPoint(EdgePointType<T> type, T point) {
|
||||
edgePoints.put(type, point);
|
||||
EdgePointManager.onEdgePointAdded(this, point, type);
|
||||
Create.RAILWAYS.sync.pointAdded(this, point);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
|
@ -91,6 +92,7 @@ public class TrackGraph {
|
|||
if (removed == null)
|
||||
return null;
|
||||
EdgePointManager.onEdgePointRemoved(this, removed, type);
|
||||
Create.RAILWAYS.sync.pointRemoved(this, removed);
|
||||
markDirty();
|
||||
return removed;
|
||||
}
|
||||
|
@ -197,12 +199,13 @@ public class TrackGraph {
|
|||
TrackNode n2 = toOther.locateNode(node2.location);
|
||||
if (n1 == null || n2 == null)
|
||||
return;
|
||||
toOther.putConnection(n1, n2, edge);
|
||||
if (toOther.putConnection(n1, n2, edge)) {
|
||||
Create.RAILWAYS.sync.edgeAdded(toOther, n1, n2, edge);
|
||||
Create.RAILWAYS.sync.edgeDataChanged(toOther, n1, n2, edge);
|
||||
}
|
||||
}));
|
||||
|
||||
edgePoints.transferAll(toOther.edgePoints);
|
||||
|
||||
edgePoints.transferAll(toOther, toOther.edgePoints);
|
||||
nodes.clear();
|
||||
connectionsByNode.clear();
|
||||
|
||||
|
@ -325,9 +328,13 @@ public class TrackGraph {
|
|||
map2.remove(node1);
|
||||
}
|
||||
|
||||
public void putConnection(TrackNode node1, TrackNode node2, TrackEdge edge) {
|
||||
connectionsByNode.computeIfAbsent(node1, n -> new IdentityHashMap<>())
|
||||
.put(node2, edge);
|
||||
public boolean putConnection(TrackNode node1, TrackNode node2, TrackEdge edge) {
|
||||
Map<TrackNode, TrackEdge> connections = connectionsByNode.computeIfAbsent(node1, n -> new IdentityHashMap<>());
|
||||
if (connections.containsKey(node2) && connections.get(node2)
|
||||
.getEdgeData()
|
||||
.hasPoints())
|
||||
return false;
|
||||
return connections.put(node2, edge) == null;
|
||||
}
|
||||
|
||||
public void markDirty() {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package com.simibubi.create.content.logistics.trains;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
|
||||
import net.minecraftforge.network.NetworkEvent.Context;
|
||||
|
||||
public abstract class TrackGraphPacket extends SimplePacketBase {
|
||||
|
||||
public UUID graphId;
|
||||
public boolean packetDeletesGraph;
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get()
|
||||
.enqueueWork(() -> handle(CreateClient.RAILWAYS, CreateClient.RAILWAYS.getOrCreateGraph(graphId)));
|
||||
context.get()
|
||||
.setPacketHandled(true);
|
||||
}
|
||||
|
||||
protected abstract void handle(GlobalRailwayManager manager, TrackGraph graph);
|
||||
|
||||
}
|
|
@ -1,65 +1,69 @@
|
|||
package com.simibubi.create.content.logistics.trains;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
|
||||
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroupPacket;
|
||||
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.Pair;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.network.NetworkEvent.Context;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
|
||||
public class TrackGraphSync {
|
||||
|
||||
List<RailGraphSyncPacket> queuedPackets = new ArrayList<>();
|
||||
List<TrackGraphPacket> queuedPackets = new ArrayList<>();
|
||||
|
||||
public void serverTick() {
|
||||
finish();
|
||||
flushGraphPacket(null);
|
||||
if (queuedPackets.isEmpty())
|
||||
return;
|
||||
for (RailGraphSyncPacket packet : queuedPackets) {
|
||||
if (packet.delete || Create.RAILWAYS.trackNetworks.containsKey(packet.graphId)) {
|
||||
for (TrackGraphPacket packet : queuedPackets) {
|
||||
if (!packet.packetDeletesGraph && !Create.RAILWAYS.trackNetworks.containsKey(packet.graphId))
|
||||
continue;
|
||||
AllPackets.channel.send(PacketDistributor.ALL.noArg(), packet);
|
||||
}
|
||||
}
|
||||
queuedPackets.clear();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public void nodeAdded(TrackGraph graph, TrackNode node) {
|
||||
flushPacket(graph.id);
|
||||
currentPacket.addedNodes.put(node.getNetId(), Pair.of(node.getLocation(), node.getNormal()));
|
||||
flushGraphPacket(graph.id);
|
||||
currentGraphSyncPacket.addedNodes.put(node.getNetId(), Pair.of(node.getLocation(), node.getNormal()));
|
||||
}
|
||||
|
||||
public void edgeAdded(TrackGraph graph, TrackNode node1, TrackNode node2, TrackEdge edge) {
|
||||
flushPacket(graph.id);
|
||||
currentPacket.addedEdges.add(Pair.of(Couple.create(node1.getNetId(), node2.getNetId()), edge));
|
||||
flushGraphPacket(graph.id);
|
||||
currentGraphSyncPacket.addedEdges.add(Pair.of(Couple.create(node1.getNetId(), node2.getNetId()), edge));
|
||||
}
|
||||
|
||||
public void pointAdded(TrackGraph graph, TrackEdgePoint point) {
|
||||
flushGraphPacket(graph.id);
|
||||
currentGraphSyncPacket.addedEdgePoints.add(point);
|
||||
}
|
||||
|
||||
public void pointRemoved(TrackGraph graph, TrackEdgePoint point) {
|
||||
flushGraphPacket(graph.id);
|
||||
currentGraphSyncPacket.removedEdgePoints.add(point.getId());
|
||||
}
|
||||
|
||||
public void nodeRemoved(TrackGraph graph, TrackNode node) {
|
||||
flushPacket(graph.id);
|
||||
flushGraphPacket(graph.id);
|
||||
int nodeId = node.getNetId();
|
||||
if (currentPacket.addedNodes.remove(nodeId) == null)
|
||||
currentPacket.removedNodes.add(nodeId);
|
||||
currentPacket.addedEdges.removeIf(pair -> {
|
||||
if (currentGraphSyncPacket.addedNodes.remove(nodeId) == null)
|
||||
currentGraphSyncPacket.removedNodes.add(nodeId);
|
||||
currentGraphSyncPacket.addedEdges.removeIf(pair -> {
|
||||
Couple<Integer> ids = pair.getFirst();
|
||||
return ids.getFirst()
|
||||
.intValue() == nodeId
|
||||
|
@ -69,183 +73,104 @@ public class TrackGraphSync {
|
|||
}
|
||||
|
||||
public void graphSplit(TrackGraph graph, Set<TrackGraph> additional) {
|
||||
flushPacket(graph.id);
|
||||
additional.forEach(rg -> currentPacket.splitSubGraphs.put(rg.nodesById.keySet()
|
||||
flushGraphPacket(graph.id);
|
||||
additional.forEach(rg -> currentGraphSyncPacket.splitSubGraphs.put(rg.nodesById.keySet()
|
||||
.stream()
|
||||
.findFirst()
|
||||
.get(), rg.id));
|
||||
}
|
||||
|
||||
public void graphRemoved(TrackGraph graph) {
|
||||
flushPacket(graph.id);
|
||||
currentPacket.delete = true;
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
flushPacket(null);
|
||||
flushGraphPacket(graph.id);
|
||||
currentGraphSyncPacket.packetDeletesGraph = true;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public void sendEdgeGroups(Collection<UUID> ids, ServerPlayer player) {
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), new SignalEdgeGroupPacket(ids, true));
|
||||
}
|
||||
|
||||
public void edgeGroupCreated(UUID id) {
|
||||
AllPackets.channel.send(PacketDistributor.ALL.noArg(), new SignalEdgeGroupPacket(ImmutableList.of(id), true));
|
||||
}
|
||||
|
||||
public void edgeGroupRemoved(UUID id) {
|
||||
AllPackets.channel.send(PacketDistributor.ALL.noArg(), new SignalEdgeGroupPacket(ImmutableList.of(id), false));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public void edgeDataChanged(TrackGraph graph, TrackNode node1, TrackNode node2, TrackEdge edge) {
|
||||
flushGraphPacket(graph.id);
|
||||
currentGraphSyncPacket.syncEdgeData(node1, node2, edge);
|
||||
}
|
||||
|
||||
public void edgeDataChanged(TrackGraph graph, TrackNode node1, TrackNode node2, TrackEdge edge, TrackEdge edge2) {
|
||||
flushGraphPacket(graph.id);
|
||||
currentGraphSyncPacket.syncEdgeData(node1, node2, edge);
|
||||
currentGraphSyncPacket.syncEdgeData(node2, node1, edge2);
|
||||
}
|
||||
|
||||
public void sendFullGraphTo(TrackGraph graph, ServerPlayer player) {
|
||||
RailGraphSyncPacket packet = new RailGraphSyncPacket(graph.id);
|
||||
TrackGraphSyncPacket packet = new TrackGraphSyncPacket(graph.id);
|
||||
int sent = 0;
|
||||
|
||||
for (TrackNode node : graph.nodes.values()) {
|
||||
RailGraphSyncPacket currentPacket = packet;
|
||||
TrackGraphSyncPacket currentPacket = packet;
|
||||
currentPacket.addedNodes.put(node.getNetId(), Pair.of(node.getLocation(), node.getNormal()));
|
||||
if (!graph.connectionsByNode.containsKey(node))
|
||||
continue;
|
||||
graph.connectionsByNode.get(node)
|
||||
.forEach((node2, edge) -> currentPacket.addedEdges
|
||||
.add(Pair.of(Couple.create(node.getNetId(), node2.getNetId()), edge)));
|
||||
.forEach((node2, edge) -> {
|
||||
Couple<Integer> key = Couple.create(node.getNetId(), node2.getNetId());
|
||||
currentPacket.addedEdges.add(Pair.of(key, edge));
|
||||
currentPacket.syncEdgeData(node, node2, edge);
|
||||
});
|
||||
|
||||
if (sent++ < 1000)
|
||||
continue;
|
||||
|
||||
if (sent++ > 1000) {
|
||||
sent = 0;
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), packet);
|
||||
packet = new RailGraphSyncPacket(graph.id);
|
||||
packet = flushAndCreateNew(graph, player, packet);
|
||||
}
|
||||
|
||||
for (EdgePointType<?> type : EdgePointType.TYPES.values()) {
|
||||
for (TrackEdgePoint point : graph.getPoints(type)) {
|
||||
packet.addedEdgePoints.add(point);
|
||||
|
||||
if (sent++ < 1000)
|
||||
continue;
|
||||
|
||||
sent = 0;
|
||||
packet = flushAndCreateNew(graph, player, packet);
|
||||
}
|
||||
}
|
||||
|
||||
if (sent > 0)
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), packet);
|
||||
flushAndCreateNew(graph, player, packet);
|
||||
}
|
||||
|
||||
private RailGraphSyncPacket currentPacket;
|
||||
private TrackGraphSyncPacket flushAndCreateNew(TrackGraph graph, ServerPlayer player, TrackGraphSyncPacket packet) {
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), packet);
|
||||
packet = new TrackGraphSyncPacket(graph.id);
|
||||
return packet;
|
||||
}
|
||||
|
||||
private void flushPacket(@Nullable UUID graphId) {
|
||||
if (currentPacket != null) {
|
||||
if (currentPacket.graphId.equals(graphId))
|
||||
//
|
||||
|
||||
private TrackGraphSyncPacket currentGraphSyncPacket;
|
||||
|
||||
private void flushGraphPacket(@Nullable UUID graphId) {
|
||||
if (currentGraphSyncPacket != null) {
|
||||
if (currentGraphSyncPacket.graphId.equals(graphId))
|
||||
return;
|
||||
queuedPackets.add(currentPacket);
|
||||
currentPacket = null;
|
||||
queuedPackets.add(currentGraphSyncPacket);
|
||||
currentGraphSyncPacket = null;
|
||||
}
|
||||
|
||||
if (graphId != null)
|
||||
currentPacket = new RailGraphSyncPacket(graphId);
|
||||
}
|
||||
|
||||
public static class RailGraphSyncPacket extends SimplePacketBase {
|
||||
|
||||
UUID graphId;
|
||||
Map<Integer, Pair<TrackNodeLocation, Vec3>> addedNodes;
|
||||
List<Pair<Couple<Integer>, TrackEdge>> addedEdges;
|
||||
List<Integer> removedNodes;
|
||||
Map<Integer, UUID> splitSubGraphs;
|
||||
boolean delete;
|
||||
|
||||
public RailGraphSyncPacket(UUID graphId) {
|
||||
this.graphId = graphId;
|
||||
addedNodes = new HashMap<>();
|
||||
addedEdges = new ArrayList<>();
|
||||
removedNodes = new ArrayList<>();
|
||||
splitSubGraphs = new HashMap<>();
|
||||
delete = false;
|
||||
}
|
||||
|
||||
public RailGraphSyncPacket(FriendlyByteBuf buffer) {
|
||||
int size;
|
||||
|
||||
graphId = buffer.readUUID();
|
||||
delete = buffer.readBoolean();
|
||||
|
||||
if (delete)
|
||||
return;
|
||||
|
||||
addedNodes = new HashMap<>();
|
||||
addedEdges = new ArrayList<>();
|
||||
removedNodes = new ArrayList<>();
|
||||
splitSubGraphs = new HashMap<>();
|
||||
|
||||
size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
removedNodes.add(buffer.readVarInt());
|
||||
|
||||
size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
addedNodes.put(buffer.readVarInt(),
|
||||
Pair.of(TrackNodeLocation.fromPackedPos(buffer.readBlockPos()), VecHelper.read(buffer)));
|
||||
|
||||
size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
addedEdges.add(Pair.of(Couple.create(buffer::readVarInt), TrackEdge.read(buffer)));
|
||||
|
||||
size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
splitSubGraphs.put(buffer.readVarInt(), buffer.readUUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buffer) {
|
||||
|
||||
buffer.writeUUID(graphId);
|
||||
buffer.writeBoolean(delete);
|
||||
if (delete)
|
||||
return;
|
||||
|
||||
buffer.writeVarInt(removedNodes.size());
|
||||
removedNodes.forEach(buffer::writeVarInt);
|
||||
|
||||
buffer.writeVarInt(addedNodes.size());
|
||||
addedNodes.forEach((node, loc) -> {
|
||||
buffer.writeVarInt(node);
|
||||
buffer.writeBlockPos(new BlockPos(loc.getFirst()));
|
||||
VecHelper.write(loc.getSecond(), buffer);
|
||||
});
|
||||
|
||||
buffer.writeVarInt(addedEdges.size());
|
||||
addedEdges.forEach(pair -> {
|
||||
pair.getFirst()
|
||||
.forEach(buffer::writeVarInt);
|
||||
pair.getSecond()
|
||||
.write(buffer);
|
||||
});
|
||||
|
||||
buffer.writeVarInt(splitSubGraphs.size());
|
||||
splitSubGraphs.forEach((node, uuid) -> {
|
||||
buffer.writeVarInt(node);
|
||||
buffer.writeUUID(uuid);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get()
|
||||
.enqueueWork(() -> {
|
||||
GlobalRailwayManager manager = CreateClient.RAILWAYS;
|
||||
TrackGraph railGraph = manager.getOrCreateGraph(graphId);
|
||||
|
||||
if (delete) {
|
||||
manager.removeGraph(railGraph);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int nodeId : removedNodes) {
|
||||
TrackNode node = railGraph.getNode(nodeId);
|
||||
if (node != null)
|
||||
railGraph.removeNode(null, node.getLocation());
|
||||
}
|
||||
|
||||
for (Entry<Integer, Pair<TrackNodeLocation, Vec3>> entry : addedNodes.entrySet()) {
|
||||
Integer nodeId = entry.getKey();
|
||||
Pair<TrackNodeLocation, Vec3> nodeLocation = entry.getValue();
|
||||
railGraph.loadNode(nodeLocation.getFirst(), nodeId, nodeLocation.getSecond());
|
||||
}
|
||||
|
||||
for (Pair<Couple<Integer>, TrackEdge> pair : addedEdges) {
|
||||
Couple<TrackNode> nodes = pair.getFirst()
|
||||
.map(railGraph::getNode);
|
||||
if (nodes.getFirst() != null && nodes.getSecond() != null)
|
||||
railGraph.putConnection(nodes.getFirst(), nodes.getSecond(), pair.getSecond());
|
||||
}
|
||||
|
||||
if (!splitSubGraphs.isEmpty())
|
||||
railGraph.findDisconnectedGraphs(splitSubGraphs)
|
||||
.forEach(manager::putGraph);
|
||||
|
||||
});
|
||||
context.get()
|
||||
.setPacketHandled(true);
|
||||
}
|
||||
|
||||
currentGraphSyncPacket = new TrackGraphSyncPacket(graphId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
package com.simibubi.create.content.logistics.trains;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
|
||||
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData;
|
||||
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.Pair;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class TrackGraphSyncPacket extends TrackGraphPacket {
|
||||
|
||||
Map<Integer, Pair<TrackNodeLocation, Vec3>> addedNodes;
|
||||
List<Pair<Couple<Integer>, TrackEdge>> addedEdges;
|
||||
List<Integer> removedNodes;
|
||||
List<TrackEdgePoint> addedEdgePoints;
|
||||
List<UUID> removedEdgePoints;
|
||||
Map<Integer, UUID> splitSubGraphs;
|
||||
Map<Couple<Integer>, Pair<Integer, List<UUID>>> updatedEdgeData;
|
||||
|
||||
static final int NULL_GROUP = 0, PASSIVE_GROUP = 1, GROUP = 2;
|
||||
|
||||
public TrackGraphSyncPacket(UUID graphId) {
|
||||
this.graphId = graphId;
|
||||
addedNodes = new HashMap<>();
|
||||
addedEdges = new ArrayList<>();
|
||||
removedNodes = new ArrayList<>();
|
||||
addedEdgePoints = new ArrayList<>();
|
||||
removedEdgePoints = new ArrayList<>();
|
||||
updatedEdgeData = new HashMap<>();
|
||||
splitSubGraphs = new HashMap<>();
|
||||
packetDeletesGraph = false;
|
||||
}
|
||||
|
||||
public TrackGraphSyncPacket(FriendlyByteBuf buffer) {
|
||||
int size;
|
||||
|
||||
graphId = buffer.readUUID();
|
||||
packetDeletesGraph = buffer.readBoolean();
|
||||
|
||||
if (packetDeletesGraph)
|
||||
return;
|
||||
|
||||
addedNodes = new HashMap<>();
|
||||
addedEdges = new ArrayList<>();
|
||||
addedEdgePoints = new ArrayList<>();
|
||||
removedEdgePoints = new ArrayList<>();
|
||||
removedNodes = new ArrayList<>();
|
||||
splitSubGraphs = new HashMap<>();
|
||||
updatedEdgeData = new HashMap<>();
|
||||
|
||||
size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
removedNodes.add(buffer.readVarInt());
|
||||
|
||||
size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
addedNodes.put(buffer.readVarInt(),
|
||||
Pair.of(TrackNodeLocation.fromPackedPos(buffer.readBlockPos()), VecHelper.read(buffer)));
|
||||
|
||||
size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
addedEdges.add(Pair.of(Couple.create(buffer::readVarInt), TrackEdge.read(buffer)));
|
||||
|
||||
size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
addedEdgePoints.add(EdgePointType.read(buffer));
|
||||
|
||||
size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
removedEdgePoints.add(buffer.readUUID());
|
||||
|
||||
size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++) {
|
||||
ArrayList<UUID> list = new ArrayList<>();
|
||||
Couple<Integer> key = Couple.create(buffer::readInt);
|
||||
Pair<Integer, List<UUID>> entry = Pair.of(buffer.readVarInt(), list);
|
||||
int size2 = buffer.readVarInt();
|
||||
for (int j = 0; j < size2; j++)
|
||||
list.add(buffer.readUUID());
|
||||
updatedEdgeData.put(key, entry);
|
||||
}
|
||||
|
||||
size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
splitSubGraphs.put(buffer.readVarInt(), buffer.readUUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buffer) {
|
||||
|
||||
buffer.writeUUID(graphId);
|
||||
buffer.writeBoolean(packetDeletesGraph);
|
||||
if (packetDeletesGraph)
|
||||
return;
|
||||
|
||||
buffer.writeVarInt(removedNodes.size());
|
||||
removedNodes.forEach(buffer::writeVarInt);
|
||||
|
||||
buffer.writeVarInt(addedNodes.size());
|
||||
addedNodes.forEach((node, loc) -> {
|
||||
buffer.writeVarInt(node);
|
||||
buffer.writeBlockPos(new BlockPos(loc.getFirst()));
|
||||
VecHelper.write(loc.getSecond(), buffer);
|
||||
});
|
||||
|
||||
buffer.writeVarInt(addedEdges.size());
|
||||
addedEdges.forEach(pair -> {
|
||||
pair.getFirst()
|
||||
.forEach(buffer::writeVarInt);
|
||||
pair.getSecond()
|
||||
.write(buffer);
|
||||
});
|
||||
|
||||
buffer.writeVarInt(addedEdgePoints.size());
|
||||
addedEdgePoints.forEach(ep -> ep.write(buffer));
|
||||
|
||||
buffer.writeVarInt(removedEdgePoints.size());
|
||||
removedEdgePoints.forEach(buffer::writeUUID);
|
||||
|
||||
buffer.writeVarInt(updatedEdgeData.size());
|
||||
for (Entry<Couple<Integer>, Pair<Integer, List<UUID>>> entry : updatedEdgeData.entrySet()) {
|
||||
entry.getKey()
|
||||
.forEach(buffer::writeInt);
|
||||
Pair<Integer, List<UUID>> pair = entry.getValue();
|
||||
buffer.writeVarInt(pair.getFirst());
|
||||
List<UUID> list = pair.getSecond();
|
||||
buffer.writeVarInt(list.size());
|
||||
list.forEach(buffer::writeUUID);
|
||||
}
|
||||
|
||||
buffer.writeVarInt(splitSubGraphs.size());
|
||||
splitSubGraphs.forEach((node, uuid) -> {
|
||||
buffer.writeVarInt(node);
|
||||
buffer.writeUUID(uuid);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handle(GlobalRailwayManager manager, TrackGraph graph) {
|
||||
if (packetDeletesGraph) {
|
||||
manager.removeGraph(graph);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int nodeId : removedNodes) {
|
||||
TrackNode node = graph.getNode(nodeId);
|
||||
if (node != null)
|
||||
graph.removeNode(null, node.getLocation());
|
||||
}
|
||||
|
||||
for (Entry<Integer, Pair<TrackNodeLocation, Vec3>> entry : addedNodes.entrySet()) {
|
||||
Integer nodeId = entry.getKey();
|
||||
Pair<TrackNodeLocation, Vec3> nodeLocation = entry.getValue();
|
||||
graph.loadNode(nodeLocation.getFirst(), nodeId, nodeLocation.getSecond());
|
||||
}
|
||||
|
||||
for (Pair<Couple<Integer>, TrackEdge> pair : addedEdges) {
|
||||
Couple<TrackNode> nodes = pair.getFirst()
|
||||
.map(graph::getNode);
|
||||
if (nodes.getFirst() != null && nodes.getSecond() != null)
|
||||
graph.putConnection(nodes.getFirst(), nodes.getSecond(), pair.getSecond());
|
||||
}
|
||||
|
||||
for (TrackEdgePoint edgePoint : addedEdgePoints)
|
||||
graph.edgePoints.put(edgePoint.getType(), edgePoint);
|
||||
|
||||
for (UUID uuid : removedEdgePoints)
|
||||
for (EdgePointType<?> type : EdgePointType.TYPES.values())
|
||||
graph.edgePoints.remove(type, uuid);
|
||||
|
||||
handleEdgeData(manager, graph);
|
||||
|
||||
if (!splitSubGraphs.isEmpty())
|
||||
graph.findDisconnectedGraphs(splitSubGraphs)
|
||||
.forEach(manager::putGraph);
|
||||
}
|
||||
|
||||
protected void handleEdgeData(GlobalRailwayManager manager, TrackGraph graph) {
|
||||
for (Entry<Couple<Integer>, Pair<Integer, List<UUID>>> entry : updatedEdgeData.entrySet()) {
|
||||
List<UUID> idList = entry.getValue()
|
||||
.getSecond();
|
||||
int groupType = entry.getValue()
|
||||
.getFirst();
|
||||
|
||||
Couple<TrackNode> nodes = entry.getKey()
|
||||
.map(graph::getNode);
|
||||
if (nodes.either(Objects::isNull))
|
||||
continue;
|
||||
TrackEdge edge = graph.getConnectionsFrom(nodes.getFirst())
|
||||
.get(nodes.getSecond());
|
||||
if (edge == null)
|
||||
continue;
|
||||
|
||||
EdgeData edgeData = new EdgeData();
|
||||
if (groupType == NULL_GROUP)
|
||||
edgeData.singleSignalGroup = null;
|
||||
else if (groupType == PASSIVE_GROUP)
|
||||
edgeData.singleSignalGroup = EdgeData.passiveGroup;
|
||||
else
|
||||
edgeData.singleSignalGroup = idList.get(0);
|
||||
|
||||
List<TrackEdgePoint> points = edgeData.getPoints();
|
||||
edge.edgeData = edgeData;
|
||||
|
||||
for (int i = groupType == GROUP ? 1 : 0; i < idList.size(); i++) {
|
||||
UUID uuid = idList.get(i);
|
||||
for (EdgePointType<?> type : EdgePointType.TYPES.values()) {
|
||||
TrackEdgePoint point = graph.edgePoints.get(type, uuid);
|
||||
if (point == null)
|
||||
continue;
|
||||
points.add(point);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void syncEdgeData(TrackNode node1, TrackNode node2, TrackEdge edge) {
|
||||
Couple<Integer> key = Couple.create(node1.getNetId(), node2.getNetId());
|
||||
List<UUID> list = new ArrayList<>();
|
||||
EdgeData edgeData = edge.getEdgeData();
|
||||
int groupType = edgeData.hasSignalBoundaries() ? NULL_GROUP
|
||||
: EdgeData.passiveGroup.equals(edgeData.singleSignalGroup) ? PASSIVE_GROUP : GROUP;
|
||||
if (groupType == GROUP)
|
||||
list.add(edgeData.singleSignalGroup);
|
||||
for (TrackEdgePoint point : edgeData.getPoints())
|
||||
list.add(point.getId());
|
||||
updatedEdgeData.put(key, Pair.of(groupType, list));
|
||||
}
|
||||
|
||||
}
|
|
@ -27,7 +27,7 @@ public class TrackSavedData extends SavedData {
|
|||
}
|
||||
|
||||
private static TrackSavedData load(CompoundTag nbt) {
|
||||
TrackSavedData sd = new TrackSavedData();
|
||||
TrackSavedData sd = new TrackSavedData();//TODO load trains before everything else
|
||||
sd.trackNetworks = new HashMap<>();
|
||||
sd.signalEdgeGroups = new HashMap<>();
|
||||
NBTHelper.iterateCompoundList(nbt.getList("RailGraphs", Tag.TAG_COMPOUND), c -> {
|
||||
|
|
|
@ -94,11 +94,6 @@ public class Navigation {
|
|||
if (waitingForSignal == null)
|
||||
distanceToSignal = Double.MAX_VALUE;
|
||||
|
||||
if (train.getCurrentStation() != null) {
|
||||
int i = 0;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (distanceToSignal > 1 / 16f) {
|
||||
signalScout.node1 = leadingPoint.node1;
|
||||
signalScout.node2 = leadingPoint.node2;
|
||||
|
|
|
@ -241,10 +241,11 @@ public class Train {
|
|||
if (navigation.destination != null) {
|
||||
boolean recalculate = navigation.distanceToDestination % 100 > 20;
|
||||
boolean imminentRecalculate = navigation.distanceToDestination > 5;
|
||||
navigation.distanceToDestination -= Math.abs(distance);
|
||||
double toSubstract = navigation.destinationBehindTrain ? -distance : distance;
|
||||
navigation.distanceToDestination -= toSubstract;
|
||||
boolean signalMode = navigation.waitingForSignal != null;
|
||||
if (signalMode) {
|
||||
navigation.distanceToSignal -= Math.abs(distance);
|
||||
navigation.distanceToSignal -= toSubstract;
|
||||
recalculate = navigation.distanceToSignal % 100 > 20;
|
||||
}
|
||||
if (recalculate && (signalMode ? navigation.distanceToSignal : navigation.distanceToDestination) % 100 <= 20
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.simibubi.create.content.logistics.trains.entity.Train;
|
|||
import com.simibubi.create.content.logistics.trains.management.signal.SingleTileEdgePoint;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
|
||||
public class GlobalStation extends SingleTileEdgePoint {
|
||||
|
||||
|
@ -27,12 +28,24 @@ public class GlobalStation extends SingleTileEdgePoint {
|
|||
nearestTrain = new WeakReference<Train>(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(FriendlyByteBuf buffer) {
|
||||
super.read(buffer);
|
||||
name = buffer.readUtf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag nbt) {
|
||||
super.write(nbt);
|
||||
nbt.putString("Name", name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buffer) {
|
||||
super.write(buffer);
|
||||
buffer.writeUtf(name);
|
||||
}
|
||||
|
||||
public boolean canApproachFrom(TrackNode side) {
|
||||
return isPrimary(side);
|
||||
}
|
||||
|
|
|
@ -74,8 +74,11 @@ public class StationEditPacket extends TileEntityConfigurationPacket<StationTile
|
|||
|
||||
if (!name.isBlank()) {
|
||||
GlobalStation station = te.getStation();
|
||||
if (station != null)
|
||||
GraphLocation graphLocation = te.edgePoint.determineGraphLocation();
|
||||
if (station != null && graphLocation != null) {
|
||||
station.name = name;
|
||||
Create.RAILWAYS.sync.pointAdded(graphLocation.graph, station);
|
||||
}
|
||||
Create.RAILWAYS.markTracksDirty();
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,8 @@ public class StationScreen extends AbstractStationScreen {
|
|||
int trainIconWidth = getTrainIconWidth(imminentTrain);
|
||||
int targetPos = background.width / 2 - trainIconWidth / 2;
|
||||
float f = (float) (imminentTrain.navigation.distanceToDestination / 15f);
|
||||
if (imminentTrain.currentStation.equals(station.getId()))
|
||||
f = 0;
|
||||
trainPosition.startWithValue(targetPos - (targetPos + 5) * f);
|
||||
}
|
||||
return;
|
||||
|
@ -167,15 +169,16 @@ public class StationScreen extends AbstractStationScreen {
|
|||
return;
|
||||
}
|
||||
|
||||
if (train.navigation.destination != station && train.getCurrentStation() != station) {
|
||||
boolean trainAtStation = train.currentStation != null && train.currentStation.equals(station.getId());
|
||||
if (train.navigation.destination != station && !trainAtStation) {
|
||||
leavingAnimation = 80;
|
||||
return;
|
||||
}
|
||||
|
||||
disassembleTrainButton.active = train.getCurrentStation() == station; // TODO te.canAssemble
|
||||
disassembleTrainButton.active = trainAtStation; // TODO te.canAssemble
|
||||
openScheduleButton.active = train.runtime.schedule != null;
|
||||
|
||||
float f = (float) (train.navigation.distanceToDestination / 30f);
|
||||
float f = trainAtStation ? 0 : (float) (train.navigation.distanceToDestination / 30f);
|
||||
trainPosition.setValue(targetPos - (targetPos + trainIconWidth) * f);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,13 +68,12 @@ public class TrackTargetingBehaviour<T extends TrackEdgePoint> extends TileEntit
|
|||
|
||||
@Override
|
||||
public void read(CompoundTag nbt, boolean clientPacket) {
|
||||
UUID prevId = id;
|
||||
id = nbt.getUUID("Id");
|
||||
targetTrack = NbtUtils.readBlockPos(nbt.getCompound("TargetTrack"));
|
||||
targetDirection = nbt.getBoolean("TargetDirection") ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE;
|
||||
if (nbt.contains("Migrate"))
|
||||
migrationData = nbt.getCompound("Migrate");
|
||||
if (clientPacket && !prevId.equals(id))
|
||||
if (clientPacket)
|
||||
edgePoint = null;
|
||||
super.read(nbt, clientPacket);
|
||||
}
|
||||
|
@ -86,7 +85,6 @@ public class TrackTargetingBehaviour<T extends TrackEdgePoint> extends TileEntit
|
|||
|
||||
public void invalidateEdgePoint(CompoundTag migrationData) {
|
||||
this.migrationData = migrationData;
|
||||
id = UUID.randomUUID();
|
||||
edgePoint = null;
|
||||
tileEntity.sendData();
|
||||
}
|
||||
|
@ -100,6 +98,8 @@ public class TrackTargetingBehaviour<T extends TrackEdgePoint> extends TileEntit
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T createEdgePoint() {
|
||||
boolean isClientSide = getWorld().isClientSide;
|
||||
if (migrationData == null || isClientSide)
|
||||
for (TrackGraph trackGraph : Create.RAILWAYS.trackNetworks.values()) { // TODO thread breach
|
||||
T point = trackGraph.getPoint(edgePointType, id);
|
||||
if (point == null)
|
||||
|
@ -107,7 +107,7 @@ public class TrackTargetingBehaviour<T extends TrackEdgePoint> extends TileEntit
|
|||
return point;
|
||||
}
|
||||
|
||||
if (getWorld().isClientSide)
|
||||
if (isClientSide)
|
||||
return null;
|
||||
if (!hasValidTrack())
|
||||
return null;
|
||||
|
@ -126,6 +126,10 @@ public class TrackTargetingBehaviour<T extends TrackEdgePoint> extends TileEntit
|
|||
if (edge == null)
|
||||
return null;
|
||||
|
||||
double length = edge.getLength(node1, node2);
|
||||
CompoundTag data = migrationData;
|
||||
migrationData = null;
|
||||
|
||||
EdgeData signalData = edge.getEdgeData();
|
||||
if (signalData.hasPoints()) {
|
||||
for (EdgePointType<?> otherType : EdgePointType.TYPES.values()) {
|
||||
|
@ -147,19 +151,13 @@ public class TrackTargetingBehaviour<T extends TrackEdgePoint> extends TileEntit
|
|||
}
|
||||
|
||||
T point = edgePointType.create();
|
||||
boolean reverseEdge = front || point instanceof SingleTileEdgePoint;
|
||||
|
||||
if (data != null)
|
||||
point.read(data, true);
|
||||
|
||||
point.setId(id);
|
||||
|
||||
if (point instanceof SingleTileEdgePoint step) {
|
||||
point.setLocation(loc.edge, loc.position);
|
||||
if (migrationData != null) {
|
||||
step.read(migrationData, true);
|
||||
migrationData = null;
|
||||
tileEntity.setChanged();
|
||||
}
|
||||
} else
|
||||
point.setLocation(front ? loc.edge : loc.edge.swap(),
|
||||
front ? loc.position : edge.getLength(node1, node2) - loc.position);
|
||||
|
||||
point.setLocation(reverseEdge ? loc.edge : loc.edge.swap(), reverseEdge ? loc.position : length - loc.position);
|
||||
point.tileAdded(getPos(), front);
|
||||
loc.graph.addPoint(edgePointType, point);
|
||||
return point;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.content.logistics.trains.management.edgePoint;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.logistics.trains.TrackEdge;
|
||||
import com.simibubi.create.content.logistics.trains.TrackGraph;
|
||||
import com.simibubi.create.content.logistics.trains.TrackNode;
|
||||
|
@ -22,6 +23,7 @@ public class EdgePointManager {
|
|||
TrackEdge startEdge = startEdges.get(front);
|
||||
startEdge.getEdgeData()
|
||||
.addPoint(node1, node2, startEdge, point);
|
||||
Create.RAILWAYS.sync.edgeDataChanged(graph, node1, node2, startEdge);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,8 +34,11 @@ public class EdgePointManager {
|
|||
startNodes.forEachWithParams((l1, l2) -> {
|
||||
TrackEdge trackEdge = graph.getConnectionsFrom(l1)
|
||||
.get(l2);
|
||||
if (trackEdge == null)
|
||||
return;
|
||||
trackEdge.getEdgeData()
|
||||
.removePoint(l1, l2, trackEdge, point);
|
||||
Create.RAILWAYS.sync.edgeDataChanged(graph, l1, l2, trackEdge);
|
||||
}, startNodes.swap());
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.logistics.trains.TrackGraph;
|
||||
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
|
@ -54,9 +55,13 @@ public class EdgePointStorage {
|
|||
.forEach(p -> p.tick(graph)));
|
||||
}
|
||||
|
||||
public void transferAll(EdgePointStorage other) {
|
||||
pointsByType.forEach((type, map) -> other.getMap(type)
|
||||
.putAll(map));
|
||||
public void transferAll(TrackGraph target, EdgePointStorage other) {
|
||||
pointsByType.forEach((type, map) -> {
|
||||
other.getMap(type)
|
||||
.putAll(map);
|
||||
map.values()
|
||||
.forEach(ep -> Create.RAILWAYS.sync.pointAdded(target, ep));
|
||||
});
|
||||
pointsByType.clear();
|
||||
}
|
||||
|
||||
|
@ -83,7 +88,7 @@ public class EdgePointStorage {
|
|||
Map<UUID, TrackEdgePoint> map = getMap(type);
|
||||
NBTHelper.iterateCompoundList(list, tag -> {
|
||||
TrackEdgePoint edgePoint = type.create();
|
||||
edgePoint.read(tag);
|
||||
edgePoint.read(tag, false);
|
||||
map.put(edgePoint.getId(), edgePoint);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.simibubi.create.content.logistics.trains.management.GlobalStation;
|
|||
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary;
|
||||
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class EdgePointType<T extends TrackEdgePoint> {
|
||||
|
@ -43,4 +44,12 @@ public class EdgePointType<T extends TrackEdgePoint> {
|
|||
return id;
|
||||
}
|
||||
|
||||
public static TrackEdgePoint read(FriendlyByteBuf buffer) {
|
||||
ResourceLocation type = buffer.readResourceLocation();
|
||||
EdgePointType<?> edgePointType = TYPES.get(type);
|
||||
TrackEdgePoint point = edgePointType.create();
|
||||
point.read(buffer);
|
||||
return point;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ public class EdgeData {
|
|||
public static EdgeData read(CompoundTag nbt, TrackGraph graph) {
|
||||
EdgeData data = new EdgeData();
|
||||
if (nbt.contains("SignalGroup"))
|
||||
data.singleSignalGroup = nbt.getUUID("Group");
|
||||
data.singleSignalGroup = nbt.getUUID("SignalGroup");
|
||||
else if (!nbt.contains("PassiveGroup"))
|
||||
data.singleSignalGroup = null;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import net.minecraft.core.BlockPos;
|
|||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
|
||||
public class SignalBoundary extends TrackEdgePoint {
|
||||
|
@ -124,8 +125,11 @@ public class SignalBoundary extends TrackEdgePoint {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundTag nbt) {
|
||||
super.read(nbt);
|
||||
public void read(CompoundTag nbt, boolean migration) {
|
||||
super.read(nbt, migration);
|
||||
|
||||
if (migration)
|
||||
return;
|
||||
|
||||
sidesToUpdate = Couple.create(true, true);
|
||||
signals = Couple.create(HashSet::new);
|
||||
|
@ -144,6 +148,15 @@ public class SignalBoundary extends TrackEdgePoint {
|
|||
sidesToUpdate.set(i == 1, nbt.contains("Update" + i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(FriendlyByteBuf buffer) {
|
||||
super.read(buffer);
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
if (buffer.readBoolean())
|
||||
groups.set(i == 1, buffer.readUUID());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag nbt) {
|
||||
super.write(nbt);
|
||||
|
@ -159,4 +172,15 @@ public class SignalBoundary extends TrackEdgePoint {
|
|||
nbt.putBoolean("Update" + i, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buffer) {
|
||||
super.write(buffer);
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
boolean hasGroup = groups.get(i == 1) != null;
|
||||
buffer.writeBoolean(hasGroup);
|
||||
if (hasGroup)
|
||||
buffer.writeUUID(groups.get(i == 1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package com.simibubi.create.content.logistics.trains.management.signal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraftforge.network.NetworkEvent.Context;
|
||||
|
||||
public class SignalEdgeGroupPacket extends SimplePacketBase {
|
||||
|
||||
Collection<UUID> ids;
|
||||
boolean add;
|
||||
|
||||
public SignalEdgeGroupPacket(Collection<UUID> ids, boolean add) {
|
||||
this.ids = ids;
|
||||
this.add = add;
|
||||
}
|
||||
|
||||
public SignalEdgeGroupPacket(FriendlyByteBuf buffer) {
|
||||
ids = new ArrayList<>();
|
||||
add = buffer.readBoolean();
|
||||
int size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++)
|
||||
ids.add(buffer.readUUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buffer) {
|
||||
buffer.writeBoolean(add);
|
||||
buffer.writeVarInt(ids.size());
|
||||
ids.forEach(buffer::writeUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get()
|
||||
.enqueueWork(() -> {
|
||||
Map<UUID, SignalEdgeGroup> signalEdgeGroups = CreateClient.RAILWAYS.signalEdgeGroups;
|
||||
for (UUID id : ids) {
|
||||
if (add)
|
||||
signalEdgeGroups.put(id, new SignalEdgeGroup(id));
|
||||
else
|
||||
signalEdgeGroups.remove(id);
|
||||
}
|
||||
});
|
||||
context.get()
|
||||
.setPacketHandled(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -13,6 +13,7 @@ import com.google.common.base.Predicates;
|
|||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.logistics.trains.TrackEdge;
|
||||
import com.simibubi.create.content.logistics.trains.TrackGraph;
|
||||
import com.simibubi.create.content.logistics.trains.TrackGraphSync;
|
||||
import com.simibubi.create.content.logistics.trains.TrackNode;
|
||||
import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Train;
|
||||
|
@ -28,7 +29,9 @@ public class SignalPropagator {
|
|||
for (boolean front : Iterate.trueAndFalse) {
|
||||
if (signal.sidesToUpdate.get(front))
|
||||
continue;
|
||||
Create.RAILWAYS.signalEdgeGroups.remove(signal.groups.get(front));
|
||||
UUID id = signal.groups.get(front);
|
||||
if (Create.RAILWAYS.signalEdgeGroups.remove(id) != null)
|
||||
Create.RAILWAYS.sync.edgeGroupRemoved(id);
|
||||
walkSignals(graph, signal, front, pair -> {
|
||||
TrackNode node1 = pair.getFirst();
|
||||
SignalBoundary boundary = pair.getSecond();
|
||||
|
@ -51,23 +54,30 @@ public class SignalPropagator {
|
|||
|
||||
public static void propagateSignalGroup(TrackGraph graph, SignalBoundary signal, boolean front) {
|
||||
Map<UUID, SignalEdgeGroup> globalGroups = Create.RAILWAYS.signalEdgeGroups;
|
||||
TrackGraphSync sync = Create.RAILWAYS.sync;
|
||||
|
||||
SignalEdgeGroup group = new SignalEdgeGroup(UUID.randomUUID());
|
||||
UUID groupId = group.id;
|
||||
globalGroups.put(groupId, group);
|
||||
sync.edgeGroupCreated(groupId);
|
||||
signal.groups.set(front, groupId);
|
||||
sync.pointAdded(graph, signal);
|
||||
|
||||
walkSignals(graph, signal, front, pair -> {
|
||||
TrackNode node1 = pair.getFirst();
|
||||
SignalBoundary boundary = pair.getSecond();
|
||||
UUID currentGroup = boundary.getGroup(node1);
|
||||
if (currentGroup != null)
|
||||
globalGroups.remove(currentGroup);
|
||||
if (globalGroups.remove(currentGroup) != null)
|
||||
sync.edgeGroupRemoved(currentGroup);
|
||||
boundary.setGroup(node1, groupId);
|
||||
sync.pointAdded(graph, boundary);
|
||||
return true;
|
||||
|
||||
}, signalData -> {
|
||||
if (signalData.singleSignalGroup != null)
|
||||
globalGroups.remove(signalData.singleSignalGroup);
|
||||
if (globalGroups.remove(signalData.singleSignalGroup) != null)
|
||||
sync.edgeGroupRemoved(signalData.singleSignalGroup);
|
||||
signalData.singleSignalGroup = groupId;
|
||||
return true;
|
||||
|
||||
|
@ -85,16 +95,19 @@ public class SignalPropagator {
|
|||
TrackNode node1 = startNodes.get(front);
|
||||
TrackNode node2 = startNodes.get(!front);
|
||||
TrackEdge startEdge = startEdges.get(front);
|
||||
TrackEdge oppositeEdge = startEdges.get(!front);
|
||||
|
||||
if (startEdge == null)
|
||||
return;
|
||||
|
||||
Create.RAILWAYS.sync.edgeDataChanged(graph, node1, node2, startEdge, oppositeEdge);
|
||||
|
||||
// Check for signal on the same edge
|
||||
SignalBoundary immediateBoundary = startEdge.getEdgeData()
|
||||
.next(EdgePointType.SIGNAL, node1, node2, startEdge, signal.getLocationOn(node1, node2, startEdge));
|
||||
if (immediateBoundary != null) {
|
||||
if (boundaryCallback.test(Pair.of(node1, immediateBoundary)))
|
||||
notifyTrains(graph, startEdge, startEdges.get(!front));
|
||||
notifyTrains(graph, startEdge, oppositeEdge);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -134,16 +147,20 @@ public class SignalPropagator {
|
|||
|
||||
// no boundary- update group of edge
|
||||
if (!signalData.hasSignalBoundaries()) {
|
||||
if (nonBoundaryCallback.test(signalData))
|
||||
if (!nonBoundaryCallback.test(signalData))
|
||||
continue;
|
||||
notifyTrains(graph, currentEdge);
|
||||
Create.RAILWAYS.sync.edgeDataChanged(graph, currentNode, nextNode, edge, oppositeEdge);
|
||||
continue;
|
||||
}
|
||||
|
||||
// other/own boundary found
|
||||
SignalBoundary nextBoundary =
|
||||
signalData.next(EdgePointType.SIGNAL, currentNode, nextNode, currentEdge, 0);
|
||||
if (boundaryCallback.test(Pair.of(currentNode, nextBoundary)))
|
||||
if (boundaryCallback.test(Pair.of(currentNode, nextBoundary))) {
|
||||
notifyTrains(graph, edge, oppositeEdge);
|
||||
Create.RAILWAYS.sync.edgeDataChanged(graph, currentNode, nextNode, edge, oppositeEdge);
|
||||
}
|
||||
continue EdgeWalk;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,15 +34,10 @@ public abstract class SingleTileEdgePoint extends TrackEdgePoint {
|
|||
}
|
||||
|
||||
@Override
|
||||
public final void read(CompoundTag nbt) {
|
||||
read(nbt, false);
|
||||
}
|
||||
|
||||
public void read(CompoundTag nbt, boolean migration) {
|
||||
super.read(nbt, migration);
|
||||
if (migration)
|
||||
return;
|
||||
|
||||
super.read(nbt);
|
||||
tilePos = NbtUtils.readBlockPos(nbt.getCompound("TilePos"));
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import net.minecraft.core.BlockPos;
|
|||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
|
||||
public abstract class TrackEdgePoint {
|
||||
|
@ -82,19 +83,35 @@ public abstract class TrackEdgePoint {
|
|||
.equals(node1.getLocation());
|
||||
}
|
||||
|
||||
public void read(CompoundTag nbt) {
|
||||
public void read(CompoundTag nbt, boolean migration) {
|
||||
if (migration)
|
||||
return;
|
||||
|
||||
id = nbt.getUUID("Id");
|
||||
position = nbt.getDouble("Position");
|
||||
edgeLocation = Couple.deserializeEach(nbt.getList("Edge", Tag.TAG_COMPOUND),
|
||||
tag -> TrackNodeLocation.fromPackedPos(NbtUtils.readBlockPos(tag)));
|
||||
}
|
||||
|
||||
public void read(FriendlyByteBuf buffer) {
|
||||
id = buffer.readUUID();
|
||||
edgeLocation = Couple.create(() -> TrackNodeLocation.fromPackedPos(buffer.readBlockPos()));
|
||||
position = buffer.readDouble();
|
||||
}
|
||||
|
||||
public void write(CompoundTag nbt) {
|
||||
nbt.putUUID("Id", id);
|
||||
nbt.putDouble("Position", position);
|
||||
nbt.put("Edge", edgeLocation.serializeEach(loc -> NbtUtils.writeBlockPos(new BlockPos(loc))));
|
||||
}
|
||||
|
||||
public void write(FriendlyByteBuf buffer) {
|
||||
buffer.writeResourceLocation(type.getId());
|
||||
buffer.writeUUID(id);
|
||||
edgeLocation.forEach(loc -> buffer.writeBlockPos(new BlockPos(loc)));
|
||||
buffer.writeDouble(position);
|
||||
}
|
||||
|
||||
public void tick(TrackGraph graph) {}
|
||||
|
||||
protected void removeFromAllGraphs() {
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.UUID;
|
|||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.logistics.trains.GlobalRailwayManager;
|
||||
import com.simibubi.create.content.logistics.trains.TrackGraph;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Train;
|
||||
|
@ -40,7 +40,7 @@ public class DumpRailwaysCommand {
|
|||
}
|
||||
|
||||
static void fillReport(ServerLevel level, BiConsumer<String, Integer> chat) {
|
||||
GlobalRailwayManager railways = Create.RAILWAYS;
|
||||
GlobalRailwayManager railways = CreateClient.RAILWAYS;
|
||||
int white = ChatFormatting.WHITE.getColor();
|
||||
int blue = 0xD3DEDC;
|
||||
int darkBlue = 0x92A9BD;
|
||||
|
@ -68,6 +68,8 @@ public class DumpRailwaysCommand {
|
|||
chat.accept(" -> " + signals.size() + " registered Signals", blue);
|
||||
for (GlobalStation globalStation : graph.getPoints(EdgePointType.STATION)) {
|
||||
BlockPos pos = globalStation.getTilePos();
|
||||
if (pos == null)
|
||||
pos = BlockPos.ZERO;
|
||||
chat.accept(" -> " + globalStation.name + " (" + globalStation.id.toString()
|
||||
.substring(0, 5) + ") [" + pos.getX() + "," + pos.getY() + "," + pos.getZ() + "]", darkBlue);
|
||||
if (globalStation.getPresentTrain() != null) {
|
||||
|
|
|
@ -43,10 +43,11 @@ import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket;
|
|||
import com.simibubi.create.content.logistics.packet.ConfigureStockswitchPacket;
|
||||
import com.simibubi.create.content.logistics.packet.FunnelFlapPacket;
|
||||
import com.simibubi.create.content.logistics.packet.TunnelFlapPacket;
|
||||
import com.simibubi.create.content.logistics.trains.TrackGraphSync.RailGraphSyncPacket;
|
||||
import com.simibubi.create.content.logistics.trains.TrackGraphSyncPacket;
|
||||
import com.simibubi.create.content.logistics.trains.management.StationEditPacket;
|
||||
import com.simibubi.create.content.logistics.trains.management.TrainEditPacket;
|
||||
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEditPacket;
|
||||
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroupPacket;
|
||||
import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket;
|
||||
import com.simibubi.create.content.schematics.packet.InstantSchematicPacket;
|
||||
import com.simibubi.create.content.schematics.packet.SchematicPlacePacket;
|
||||
|
@ -132,7 +133,8 @@ public enum AllPackets {
|
|||
SOUL_PULSE(SoulPulseEffectPacket.class, SoulPulseEffectPacket::new, PLAY_TO_CLIENT),
|
||||
PERSISTENT_DATA(ISyncPersistentData.PersistentDataPacket.class, ISyncPersistentData.PersistentDataPacket::new, PLAY_TO_CLIENT),
|
||||
SYNC_POTATO_PROJECTILE_TYPES(PotatoProjectileTypeManager.SyncPacket.class, PotatoProjectileTypeManager.SyncPacket::new, PLAY_TO_CLIENT),
|
||||
SYNC_RAIL_GRAPH(RailGraphSyncPacket.class, RailGraphSyncPacket::new, PLAY_TO_CLIENT),
|
||||
SYNC_RAIL_GRAPH(TrackGraphSyncPacket.class, TrackGraphSyncPacket::new, PLAY_TO_CLIENT),
|
||||
SYNC_EDGE_GROUP(SignalEdgeGroupPacket.class, SignalEdgeGroupPacket::new, PLAY_TO_CLIENT),
|
||||
REMOVE_TE(RemoveTileEntityPacket.class, RemoveTileEntityPacket::new, PLAY_TO_CLIENT),
|
||||
|
||||
;
|
||||
|
|
Loading…
Reference in a new issue