mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-27 23:47:38 +01:00
Catching up
- Fixed client-side trains not animating their wheels properly - Client-side stations now receive information about a trains' orientation and whether it can be disassembled - Server-safe train relocation - Fixed client trains not catching up with received location when graph id changes - Coupling renderer now entirely client-side - Fixed Coupling render artefacts whenever a carriage drives out of the view frustum - Fixed train information interpolated too quickly when a train has multiple carriage entities
This commit is contained in:
parent
9629cb84eb
commit
fa47939428
12 changed files with 184 additions and 37 deletions
|
@ -38,7 +38,7 @@ public class Carriage {
|
|||
|
||||
CompoundTag serialisedEntity;
|
||||
WeakReference<CarriageContraptionEntity> 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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<Train> trains = Create.RAILWAYS.trains.values(); // TODO: thread breach
|
||||
Collection<Train> 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))
|
||||
|
|
|
@ -28,6 +28,7 @@ public class CarriageSyncData {
|
|||
|
||||
public Vector<Pair<Couple<Integer>, 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)
|
||||
|
|
|
@ -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 -> {
|
||||
|
|
|
@ -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) {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<CarriageContraptionEntity> 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<Component> 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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in a new issue