diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/GlobalRailwayManager.java b/src/main/java/com/simibubi/create/content/logistics/trains/GlobalRailwayManager.java index a484fc3ff..b4930970f 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/GlobalRailwayManager.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/GlobalRailwayManager.java @@ -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); - } } } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraph.java b/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraph.java index 2e95d4c45..378bd2934 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraph.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraph.java @@ -75,6 +75,7 @@ public class TrackGraph { public void addPoint(EdgePointType 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); - Create.RAILWAYS.sync.edgeAdded(toOther, 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 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() { diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraphPacket.java b/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraphPacket.java new file mode 100644 index 000000000..b723a5eac --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraphPacket.java @@ -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.get() + .enqueueWork(() -> handle(CreateClient.RAILWAYS, CreateClient.RAILWAYS.getOrCreateGraph(graphId))); + context.get() + .setPacketHandled(true); + } + + protected abstract void handle(GlobalRailwayManager manager, TrackGraph graph); + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraphSync.java b/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraphSync.java index c71549731..ba92b427d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraphSync.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraphSync.java @@ -1,43 +1,37 @@ 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 queuedPackets = new ArrayList<>(); + List 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)) { - AllPackets.channel.send(PacketDistributor.ALL.noArg(), packet); - } + for (TrackGraphPacket packet : queuedPackets) { + if (!packet.packetDeletesGraph && !Create.RAILWAYS.trackNetworks.containsKey(packet.graphId)) + continue; + AllPackets.channel.send(PacketDistributor.ALL.noArg(), packet); } queuedPackets.clear(); } @@ -45,21 +39,31 @@ public class TrackGraphSync { // 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 ids = pair.getFirst(); return ids.getFirst() .intValue() == nodeId @@ -69,183 +73,104 @@ public class TrackGraphSync { } public void graphSplit(TrackGraph graph, Set 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 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 key = Couple.create(node.getNetId(), node2.getNetId()); + currentPacket.addedEdges.add(Pair.of(key, edge)); + currentPacket.syncEdgeData(node, node2, edge); + }); + + if (sent++ < 1000) + continue; + + sent = 0; + 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; - if (sent++ > 1000) { sent = 0; - AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), packet); - packet = new RailGraphSyncPacket(graph.id); + 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> addedNodes; - List, TrackEdge>> addedEdges; - List removedNodes; - Map 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.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> entry : addedNodes.entrySet()) { - Integer nodeId = entry.getKey(); - Pair nodeLocation = entry.getValue(); - railGraph.loadNode(nodeLocation.getFirst(), nodeId, nodeLocation.getSecond()); - } - - for (Pair, TrackEdge> pair : addedEdges) { - Couple 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); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraphSyncPacket.java b/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraphSyncPacket.java new file mode 100644 index 000000000..4ef4e3b22 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/trains/TrackGraphSyncPacket.java @@ -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> addedNodes; + List, TrackEdge>> addedEdges; + List removedNodes; + List addedEdgePoints; + List removedEdgePoints; + Map splitSubGraphs; + Map, Pair>> 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 list = new ArrayList<>(); + Couple key = Couple.create(buffer::readInt); + Pair> 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, Pair>> entry : updatedEdgeData.entrySet()) { + entry.getKey() + .forEach(buffer::writeInt); + Pair> pair = entry.getValue(); + buffer.writeVarInt(pair.getFirst()); + List 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> entry : addedNodes.entrySet()) { + Integer nodeId = entry.getKey(); + Pair nodeLocation = entry.getValue(); + graph.loadNode(nodeLocation.getFirst(), nodeId, nodeLocation.getSecond()); + } + + for (Pair, TrackEdge> pair : addedEdges) { + Couple 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, Pair>> entry : updatedEdgeData.entrySet()) { + List idList = entry.getValue() + .getSecond(); + int groupType = entry.getValue() + .getFirst(); + + Couple 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 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 key = Couple.create(node1.getNetId(), node2.getNetId()); + List 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)); + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/TrackSavedData.java b/src/main/java/com/simibubi/create/content/logistics/trains/TrackSavedData.java index 4b7a50781..92639074b 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/TrackSavedData.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/TrackSavedData.java @@ -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 -> { diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Navigation.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Navigation.java index 51343dbde..48c2fe0c6 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Navigation.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Navigation.java @@ -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; diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java index 6fe5cf0a6..56d23c72f 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java @@ -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 diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/GlobalStation.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/GlobalStation.java index acba8b150..98596a6e5 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/GlobalStation.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/GlobalStation.java @@ -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 { @@ -26,6 +27,12 @@ public class GlobalStation extends SingleTileEdgePoint { name = nbt.getString("Name"); nearestTrain = new WeakReference(null); } + + @Override + public void read(FriendlyByteBuf buffer) { + super.read(buffer); + name = buffer.readUtf(); + } @Override public void write(CompoundTag nbt) { @@ -33,6 +40,12 @@ public class GlobalStation extends SingleTileEdgePoint { nbt.putString("Name", name); } + @Override + public void write(FriendlyByteBuf buffer) { + super.write(buffer); + buffer.writeUtf(name); + } + public boolean canApproachFrom(TrackNode side) { return isPrimary(side); } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/StationEditPacket.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/StationEditPacket.java index 270f30e37..0c632655f 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/StationEditPacket.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/StationEditPacket.java @@ -74,8 +74,11 @@ public class StationEditPacket extends TileEntityConfigurationPacket 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 extends TileEntit public void invalidateEdgePoint(CompoundTag migrationData) { this.migrationData = migrationData; - id = UUID.randomUUID(); edgePoint = null; tileEntity.sendData(); } @@ -100,14 +98,16 @@ public class TrackTargetingBehaviour extends TileEntit @SuppressWarnings("unchecked") public T createEdgePoint() { - for (TrackGraph trackGraph : Create.RAILWAYS.trackNetworks.values()) { // TODO thread breach - T point = trackGraph.getPoint(edgePointType, id); - if (point == null) - continue; - return point; - } + 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) + continue; + return point; + } - if (getWorld().isClientSide) + if (isClientSide) return null; if (!hasValidTrack()) return null; @@ -126,6 +126,10 @@ public class TrackTargetingBehaviour 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 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; diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointManager.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointManager.java index 312521f11..57c46a7a9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointManager.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointManager.java @@ -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()); } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointStorage.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointStorage.java index 95c5d3dd0..a7c8b90b5 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointStorage.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointStorage.java @@ -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 map = getMap(type); NBTHelper.iterateCompoundList(list, tag -> { TrackEdgePoint edgePoint = type.create(); - edgePoint.read(tag); + edgePoint.read(tag, false); map.put(edgePoint.getId(), edgePoint); }); } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointType.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointType.java index cd260161a..6a0f8988f 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointType.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/EdgePointType.java @@ -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 { @@ -42,5 +43,13 @@ public class EdgePointType { public ResourceLocation getId() { 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; + } } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/EdgeData.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/EdgeData.java index 64ed5d18c..4c75cfeb1 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/EdgeData.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/EdgeData.java @@ -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; diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SignalBoundary.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SignalBoundary.java index 5ba3e8047..d55cac109 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SignalBoundary.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SignalBoundary.java @@ -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); @@ -143,6 +147,15 @@ public class SignalBoundary extends TrackEdgePoint { for (int i = 1; i <= 2; i++) 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) { @@ -158,5 +171,16 @@ public class SignalBoundary extends TrackEdgePoint { if (sidesToUpdate.get(i == 1)) 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)); + } + } } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SignalEdgeGroupPacket.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SignalEdgeGroupPacket.java new file mode 100644 index 000000000..039af8094 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SignalEdgeGroupPacket.java @@ -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 ids; + boolean add; + + public SignalEdgeGroupPacket(Collection 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.get() + .enqueueWork(() -> { + Map signalEdgeGroups = CreateClient.RAILWAYS.signalEdgeGroups; + for (UUID id : ids) { + if (add) + signalEdgeGroups.put(id, new SignalEdgeGroup(id)); + else + signalEdgeGroups.remove(id); + } + }); + context.get() + .setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SignalPropagator.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SignalPropagator.java index b6cca8556..2772cd173 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SignalPropagator.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SignalPropagator.java @@ -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 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)) - notifyTrains(graph, currentEdge); + 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; } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SingleTileEdgePoint.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SingleTileEdgePoint.java index d55080d54..e26fba396 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SingleTileEdgePoint.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/SingleTileEdgePoint.java @@ -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")); } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/TrackEdgePoint.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/TrackEdgePoint.java index e14733c00..d55e39768 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/TrackEdgePoint.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/signal/TrackEdgePoint.java @@ -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() { diff --git a/src/main/java/com/simibubi/create/foundation/command/DumpRailwaysCommand.java b/src/main/java/com/simibubi/create/foundation/command/DumpRailwaysCommand.java index 88df753b2..35e0e450d 100644 --- a/src/main/java/com/simibubi/create/foundation/command/DumpRailwaysCommand.java +++ b/src/main/java/com/simibubi/create/foundation/command/DumpRailwaysCommand.java @@ -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 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) { diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index af1f83931..6cb8c94c9 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -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), ;