diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java index c960dafc2..1677e278b 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java @@ -38,7 +38,7 @@ public class Carriage { CompoundTag serialisedEntity; WeakReference entity; - + // client public boolean pointsInitialised; @@ -63,8 +63,6 @@ public class Carriage { public void setContraption(Level level, CarriageContraption contraption) { CarriageContraptionEntity entity = CarriageContraptionEntity.create(level, contraption); - entity.setInitialOrientation(contraption.getAssemblyDirection() - .getClockWise()); entity.setCarriage(this); contraption.startMoving(level); serialisedEntity = entity.serializeNBT(); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java index 1c1ef056c..a0b61f8e8 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java @@ -51,7 +51,7 @@ public class CarriageBogey { if (carriage.train.derailed) yRot += derailAngle; - wheelAngle.setValue((wheelAngle.getValue() - angleDiff * Math.signum(carriage.train.speed)) % 360); + wheelAngle.setValue((wheelAngle.getValue() - angleDiff) % 360); pitch.setValue(xRot); yaw.setValue(-yRot); } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntity.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntity.java index d3adce1e9..d84f6ab22 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntity.java @@ -1,5 +1,6 @@ package com.simibubi.create.content.logistics.trains.entity; +import java.lang.ref.WeakReference; import java.util.Collection; import java.util.Optional; import java.util.UUID; @@ -29,6 +30,7 @@ import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; @@ -114,7 +116,8 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { CarriageContraptionEntity entity = new CarriageContraptionEntity(AllEntityTypes.CARRIAGE_CONTRAPTION.get(), world); entity.setContraption(contraption); - entity.setInitialOrientation(contraption.getAssemblyDirection()); + entity.setInitialOrientation(contraption.getAssemblyDirection() + .getClockWise()); entity.startAtInitialYaw(); return entity; } @@ -129,6 +132,8 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { if (train == null || train.carriages.size() <= carriageIndex) return; carriage = train.carriages.get(carriageIndex); + if (carriage != null) + carriage.entity = new WeakReference<>(this); updateTrackGraph(); } else discard(); @@ -170,7 +175,9 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { carriage.alignEntity(this); - double distanceTo = position().distanceTo(new Vec3(xo, yo, zo)); + Vec3 diff = position().subtract(xo, yo, zo); + Vec3 relativeDiff = VecHelper.rotate(diff, yaw, Axis.Y); + double distanceTo = diff.length() * Math.signum(-relativeDiff.x); carriage.bogeys.getFirst() .updateAngles(distanceTo); @@ -410,6 +417,7 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { public void setGraph(@Nullable UUID graphId) { entityData.set(TRACK_GRAPH, Optional.ofNullable(graphId)); + prevPosInvalid = true; } } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java index d3757bdf8..4ccb4d538 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java @@ -18,6 +18,11 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer @Override public boolean shouldRender(CarriageContraptionEntity entity, Frustum clippingHelper, double cameraX, double cameraY, double cameraZ) { + Carriage carriage = entity.getCarriage(); + if (carriage != null) + for (CarriageBogey bogey : carriage.bogeys) + if (bogey != null) + bogey.leadingCouplingAnchor = bogey.trailingCouplingAnchor = null; if (!super.shouldRender(entity, clippingHelper, cameraX, cameraY, cameraZ)) return false; return entity.validForRender; diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageCouplingRenderer.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageCouplingRenderer.java index 14ab0feeb..50a6ddce0 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageCouplingRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageCouplingRenderer.java @@ -6,7 +6,7 @@ import java.util.List; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.simibubi.create.AllBlockPartials; -import com.simibubi.create.Create; +import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -26,7 +26,7 @@ import net.minecraft.world.phys.Vec3; public class CarriageCouplingRenderer { public static void renderAll(PoseStack ms, MultiBufferSource buffer) { - Collection trains = Create.RAILWAYS.trains.values(); // TODO: thread breach + Collection trains = CreateClient.RAILWAYS.trains.values(); VertexConsumer vb = buffer.getBuffer(RenderType.solid()); BlockState air = Blocks.AIR.defaultBlockState(); float partialTicks = AnimationTickHolder.getPartialTicks(); @@ -51,7 +51,7 @@ public class CarriageCouplingRenderer { CarriageBogey bogey2 = carriage2.leadingBogey(); Vec3 anchor = bogey1.trailingCouplingAnchor; Vec3 anchor2 = bogey2.leadingCouplingAnchor; - + if (anchor == null || anchor2 == null) continue; if (!anchor.closerThan(camera, 64)) diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageSyncData.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageSyncData.java index 551399f58..e9cd00dc8 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageSyncData.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageSyncData.java @@ -28,6 +28,7 @@ public class CarriageSyncData { public Vector, Float>> wheelLocations; public float distanceToDestination; + public boolean leadingCarriage; // For Client interpolation private TravellingPoint[] pointsToApproach; @@ -39,6 +40,7 @@ public class CarriageSyncData { pointDistanceSnapshot = new float[4]; pointsToApproach = new TravellingPoint[4]; destinationDistanceSnapshot = 0; + leadingCarriage = false; for (int i = 0; i < 4; i++) { wheelLocations.add(null); pointsToApproach[i] = new TravellingPoint(); @@ -50,6 +52,7 @@ public class CarriageSyncData { for (int i = 0; i < 4; i++) data.wheelLocations.set(i, wheelLocations.get(i)); data.distanceToDestination = distanceToDestination; + data.leadingCarriage = leadingCarriage; return data; } @@ -63,6 +66,7 @@ public class CarriageSyncData { buffer.writeFloat(pair.getSecond()); } buffer.writeFloat(distanceToDestination); + buffer.writeBoolean(leadingCarriage); } public void read(FriendlyByteBuf buffer) { @@ -72,6 +76,7 @@ public class CarriageSyncData { wheelLocations.set(i, Pair.of(Couple.create(buffer::readInt), buffer.readFloat())); } distanceToDestination = buffer.readFloat(); + leadingCarriage = buffer.readBoolean(); } public void update(CarriageContraptionEntity entity, Carriage carriage) { @@ -79,6 +84,8 @@ public class CarriageSyncData { if (graph == null) return; + leadingCarriage = entity.carriageIndex == (carriage.train.speed >= 0 ? 0 : carriage.train.carriages.size() - 1); + for (boolean first : Iterate.trueAndFalse) { if (!first && !carriage.isOnTwoBogeys()) break; @@ -154,6 +161,9 @@ public class CarriageSyncData { return; } + if (!leadingCarriage) + return; + destinationDistanceSnapshot = (float) (distanceToDestination - carriage.train.navigation.distanceToDestination); } @@ -209,6 +219,9 @@ public class CarriageSyncData { TrackEdge initialEdge = graph.getConnectionsFrom(initialNode1) .get(initialNode2); + if (initialEdge == null) + return -1; // graph changed + TrackNode targetNode1 = forward ? target.node1 : target.node2; TrackNode targetNode2 = forward ? target.node2 : target.node1; TrackEdge targetEdge = graph.getConnectionsFrom(targetNode1) 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 87e42af45..45abfc08f 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 @@ -374,15 +374,8 @@ public class Train { } public boolean disassemble(Direction assemblyDirection, BlockPos pos) { - for (Carriage carriage : carriages) { - CarriageContraptionEntity entity = carriage.entity.get(); - if (entity == null) - return false; - if (!Mth.equal(entity.pitch, 0)) - return false; - if (!Mth.equal(((entity.yaw % 90) + 360) % 90, 0)) - return false; - } + if (!canDisassemble()) + return false; int offset = 1; boolean backwards = currentlyBackwards; @@ -412,6 +405,19 @@ public class Train { return true; } + public boolean canDisassemble() { + for (Carriage carriage : carriages) { + CarriageContraptionEntity entity = carriage.entity.get(); + if (entity == null) + return false; + if (!Mth.equal(entity.pitch, 0)) + return false; + if (!Mth.equal(((entity.yaw % 90) + 360) % 90, 0)) + return false; + } + return true; + } + public boolean isTravellingOn(TrackNode node) { MutableBoolean affected = new MutableBoolean(false); forEachTravellingPoint(tp -> { diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainRelocationPacket.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainRelocationPacket.java new file mode 100644 index 000000000..939efdf1d --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainRelocationPacket.java @@ -0,0 +1,93 @@ +package com.simibubi.create.content.logistics.trains.entity; + +import java.util.UUID; +import java.util.function.Supplier; + +import com.simibubi.create.Create; +import com.simibubi.create.foundation.networking.SimplePacketBase; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.network.NetworkEvent.Context; + +public class TrainRelocationPacket extends SimplePacketBase { + + UUID trainId; + BlockPos pos; + Vec3 lookAngle; + int entityId; + + public TrainRelocationPacket(FriendlyByteBuf buffer) { + trainId = buffer.readUUID(); + pos = buffer.readBlockPos(); + lookAngle = VecHelper.read(buffer); + entityId = buffer.readInt(); + } + + public TrainRelocationPacket(UUID trainId, BlockPos pos, Vec3 lookAngle, int entityId) { + this.trainId = trainId; + this.pos = pos; + this.lookAngle = lookAngle; + this.entityId = entityId; + } + + @Override + public void write(FriendlyByteBuf buffer) { + buffer.writeUUID(trainId); + buffer.writeBlockPos(pos); + VecHelper.write(lookAngle, buffer); + buffer.writeInt(entityId); + } + + @Override + public void handle(Supplier context) { + Context ctx = context.get(); + ctx.enqueueWork(() -> { + ServerPlayer sender = ctx.getSender(); + Train train = Create.RAILWAYS.trains.get(trainId); + Entity entity = sender.level.getEntity(entityId); + + String messagePrefix = sender.getName() + .getString() + " could not relocate Train "; + + if (train == null || !(entity instanceof CarriageContraptionEntity cce)) { + Create.LOGGER.warn(messagePrefix + train.id.toString() + .substring(0, 5) + ": not present on server"); + return; + } + + if (!train.id.equals(cce.trainId)) + return; + + if (!sender.position() + .closerThan(Vec3.atCenterOf(pos), 26)) { + Create.LOGGER.warn(messagePrefix + train.name.getString() + ": player too far from clicked pos"); + return; + } + if (!sender.position() + .closerThan(cce.position(), 26 + cce.getBoundingBox() + .getXsize() / 2)) { + Create.LOGGER.warn(messagePrefix + train.name.getString() + ": player too far from carriage entity"); + return; + } + + if (TrainRelocator.relocate(train, sender.level, pos, lookAngle, false)) { + sender.displayClientMessage(Lang.translate("train.relocate.success") + .withStyle(ChatFormatting.GREEN), true); + train.syncTrackGraphChanges(); + return; + } + + Create.LOGGER.warn(messagePrefix + train.name.getString() + ": relocation failed server-side"); + + }); + ctx.setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainRelocator.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainRelocator.java index cd52a6233..a6af96f21 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainRelocator.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainRelocator.java @@ -12,6 +12,7 @@ import org.apache.commons.lang3.mutable.MutableBoolean; import com.simibubi.create.AllItems; import com.simibubi.create.Create; +import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandlerClient; import com.simibubi.create.content.logistics.trains.GraphLocation; import com.simibubi.create.content.logistics.trains.ITrackBlock; @@ -23,6 +24,7 @@ import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ISign import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection; import com.simibubi.create.foundation.item.TooltipHelper; +import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Pair; @@ -33,7 +35,7 @@ import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction.AxisDirection; import net.minecraft.network.chat.Component; -import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.state.BlockState; @@ -41,6 +43,8 @@ import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.InputEvent.ClickInputEvent; public class TrainRelocator { @@ -48,10 +52,12 @@ public class TrainRelocator { static WeakReference hoveredEntity = new WeakReference<>(null); static UUID relocatingTrain; static Vec3 relocatingOrigin; + static int relocatingEntityId; static BlockPos lastHoveredPos; static Boolean lastHoveredResult; + @OnlyIn(Dist.CLIENT) public static void onClicked(ClickInputEvent event) { if (relocatingTrain == null) return; @@ -75,18 +81,16 @@ public class TrainRelocator { return; Train relocating = getRelocating(mc.level); if (relocating != null) { - Boolean relocate = relocateClient(relocating, false); // TODO send packet - if (relocate != null && relocate.booleanValue()) { + Boolean relocate = relocateClient(relocating, false); + if (relocate != null && relocate.booleanValue()) relocatingTrain = null; - player.displayClientMessage(Lang.translate("train.relocate.success") - .withStyle(ChatFormatting.GREEN), true); - } if (relocate != null) event.setCanceled(true); } } @Nullable + @OnlyIn(Dist.CLIENT) public static Boolean relocateClient(Train relocating, boolean simulate) { Minecraft mc = Minecraft.getInstance(); HitResult hitResult = mc.hitResult; @@ -103,12 +107,16 @@ public class TrainRelocator { BlockState blockState = mc.level.getBlockState(blockPos); if (!(blockState.getBlock()instanceof ITrackBlock track)) return lastHoveredResult = null; - return lastHoveredResult = relocate(relocating, mc.player, blockPos, simulate); + + Vec3 lookAngle = mc.player.getLookAngle(); + boolean result = relocate(relocating, mc.level, blockPos, lookAngle, true); + if (!simulate && result) + AllPackets.channel + .sendToServer(new TrainRelocationPacket(relocatingTrain, blockPos, lookAngle, relocatingEntityId)); + return lastHoveredResult = result; } - public static boolean relocate(Train train, Player player, BlockPos pos, boolean simulate) { - Vec3 lookAngle = player.getLookAngle(); - Level level = player.getLevel(); + public static boolean relocate(Train train, Level level, BlockPos pos, Vec3 lookAngle, boolean simulate) { BlockState blockState = level.getBlockState(pos); if (!(blockState.getBlock()instanceof ITrackBlock track)) return false; @@ -179,6 +187,7 @@ public class TrainRelocator { return true; } + @OnlyIn(Dist.CLIENT) public static void clientTick() { Minecraft mc = Minecraft.getInstance(); LocalPlayer player = mc.player; @@ -197,7 +206,10 @@ public class TrainRelocator { return; } - if (Math.abs(relocating.speed) > 1 / 1024d) { + Entity entity = mc.level.getEntity(relocatingEntityId); + if (entity instanceof AbstractContraptionEntity ce && Math.abs(ce.getPosition(0) + .subtract(ce.getPosition(1)) + .lengthSqr()) > 1 / 1024d) { player.displayClientMessage(Lang.translate("train.cannot_relocate_moving") .withStyle(ChatFormatting.RED), true); relocatingTrain = null; @@ -252,16 +264,19 @@ public class TrainRelocator { } } + @OnlyIn(Dist.CLIENT) public static boolean carriageWrenched(Vec3 vec3, CarriageContraptionEntity entity) { Train train = getTrainFromEntity(entity); if (train != null && !train.heldForAssembly) { relocatingOrigin = vec3; relocatingTrain = train.id; + relocatingEntityId = entity.getId(); return true; } return false; } + @OnlyIn(Dist.CLIENT) public static boolean addToTooltip(List tooltip, boolean shiftKeyDown) { Train train = getTrainFromEntity(hoveredEntity.get()); if (train != null && train.derailed) { @@ -271,6 +286,7 @@ public class TrainRelocator { return false; } + @OnlyIn(Dist.CLIENT) private static Train getRelocating(LevelAccessor level) { return relocatingTrain == null ? null : Create.RAILWAYS.sided(level).trains.get(relocatingTrain); } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationScreen.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationScreen.java index 0c47f767b..6fcb1ff85 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationScreen.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationScreen.java @@ -175,7 +175,7 @@ public class StationScreen extends AbstractStationScreen { } boolean trainAtStation = trainPresent(); - disassembleTrainButton.active = trainAtStation; // TODO te.canAssemble + disassembleTrainButton.active = trainAtStation && te.trainCanDisassemble; openScheduleButton.active = train.runtime.getSchedule() != null; float f = trainAtStation ? 0 : (float) (train.navigation.distanceToDestination / 30f); @@ -221,7 +221,7 @@ public class StationScreen extends AbstractStationScreen { offset += icon.render(TrainIconType.FLIPPED_ENGINE, ms, x + offset, y + 20) + 1; continue; } - Carriage carriage = carriages.get(train.currentlyBackwards ? carriages.size() - i - 1 : i); + Carriage carriage = carriages.get(te.trainBackwards ? carriages.size() - i - 1 : i); offset += icon.render(carriage.bogeySpacing, ms, x + offset, y + 20) + 1; } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java index 5b9a1b8df..062933e6d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java @@ -62,6 +62,8 @@ public class StationTileEntity extends SmartTileEntity { // for display UUID imminentTrain; boolean trainPresent; + boolean trainBackwards; + boolean trainCanDisassemble; public StationTileEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); @@ -88,11 +90,15 @@ public class StationTileEntity extends SmartTileEntity { if (!tag.contains("ImminentTrain")) { imminentTrain = null; trainPresent = false; + trainCanDisassemble = false; + trainBackwards = false; return; } imminentTrain = tag.getUUID("ImminentTrain"); trainPresent = tag.getBoolean("TrainPresent"); + trainCanDisassemble = tag.getBoolean("TrainCanDisassemble"); + trainBackwards = tag.getBoolean("TrainBackwards"); } @Override @@ -103,15 +109,13 @@ public class StationTileEntity extends SmartTileEntity { if (!clientPacket) return; - GlobalStation station = getStation(); - if (station == null) - return; - Train imminentTrain = station.getImminentTrain(); if (imminentTrain == null) return; - tag.putUUID("ImminentTrain", imminentTrain.id); - tag.putBoolean("TrainPresent", imminentTrain.getCurrentStation() == station); + tag.putUUID("ImminentTrain", imminentTrain); + tag.putBoolean("TrainPresent", trainPresent); + tag.putBoolean("TrainCanDisassemble", trainCanDisassemble); + tag.putBoolean("TrainBackwards", trainBackwards); } @Nullable @@ -156,6 +160,8 @@ public class StationTileEntity extends SmartTileEntity { if (this.trainPresent != trainPresent || !Objects.equals(imminentID, this.imminentTrain)) { this.imminentTrain = imminentID; this.trainPresent = trainPresent; + this.trainCanDisassemble = trainPresent && imminentTrain.canDisassemble(); + this.trainBackwards = imminentTrain != null && imminentTrain.currentlyBackwards; sendData(); } } 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 4753fa1f4..be53b64bb 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -45,6 +45,7 @@ import com.simibubi.create.content.logistics.packet.FunnelFlapPacket; import com.simibubi.create.content.logistics.packet.TunnelFlapPacket; import com.simibubi.create.content.logistics.trains.TrackGraphSyncPacket; import com.simibubi.create.content.logistics.trains.entity.TrainPacket; +import com.simibubi.create.content.logistics.trains.entity.TrainRelocationPacket; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalEdgeGroupPacket; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationEditPacket; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.TrainEditPacket; @@ -113,6 +114,7 @@ public enum AllPackets { CONFIGURE_SCHEDULE(ScheduleEditPacket.class, ScheduleEditPacket::new, PLAY_TO_SERVER), CONFIGURE_STATION(StationEditPacket.class, StationEditPacket::new, PLAY_TO_SERVER), C_CONFIGURE_TRAIN(TrainEditPacket.class, TrainEditPacket::new, PLAY_TO_SERVER), + RELOCATE_TRAIN(TrainRelocationPacket.class, TrainRelocationPacket::new, PLAY_TO_SERVER), // Server to Client SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),