mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-28 16:06:48 +01:00
TCP Handbrake
- Manual Train Controls now use network packets - Carriages now properly re-introduce their passengers when entering ticking chunks - Fixed approach station prompt no longer appearing - Fixed players shunted to 0,0 when seated while train assembles - Fixed relocator not using client-side graph when testing validity - Fixed entity data not synched properly from dedicated servers - Fixed controls storing state in behaviour class - Fixed carriages not serialising conductor seat data correctly
This commit is contained in:
parent
fa47939428
commit
ed6712fd0b
20 changed files with 417 additions and 139 deletions
|
@ -6,8 +6,11 @@ import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.apache.commons.lang3.mutable.MutableInt;
|
import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
import org.apache.commons.lang3.tuple.MutablePair;
|
import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
|
|
||||||
|
@ -21,6 +24,7 @@ import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.content.contraptions.components.actors.SeatBlock;
|
import com.simibubi.create.content.contraptions.components.actors.SeatBlock;
|
||||||
import com.simibubi.create.content.contraptions.components.actors.SeatEntity;
|
import com.simibubi.create.content.contraptions.components.actors.SeatEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
|
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsStopControllingPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.MountedContraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.MountedContraption;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionSeatMappingPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionSeatMappingPacket;
|
||||||
import com.simibubi.create.foundation.collision.Matrix3d;
|
import com.simibubi.create.foundation.collision.Matrix3d;
|
||||||
|
@ -39,6 +43,7 @@ import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
@ -63,6 +68,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
|
|
||||||
private static final EntityDataAccessor<Boolean> STALLED =
|
private static final EntityDataAccessor<Boolean> STALLED =
|
||||||
SynchedEntityData.defineId(AbstractContraptionEntity.class, EntityDataSerializers.BOOLEAN);
|
SynchedEntityData.defineId(AbstractContraptionEntity.class, EntityDataSerializers.BOOLEAN);
|
||||||
|
private static final EntityDataAccessor<Optional<UUID>> CONTROLLED_BY =
|
||||||
|
SynchedEntityData.defineId(AbstractContraptionEntity.class, EntityDataSerializers.OPTIONAL_UUID);
|
||||||
|
|
||||||
public final Map<Entity, MutableInt> collidingEntities;
|
public final Map<Entity, MutableInt> collidingEntities;
|
||||||
|
|
||||||
|
@ -178,6 +185,14 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
return getName();
|
return getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<UUID> getControllingPlayer() {
|
||||||
|
return entityData.get(CONTROLLED_BY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setControllingPlayer(@Nullable UUID playerId) {
|
||||||
|
entityData.set(CONTROLLED_BY, Optional.ofNullable(playerId));
|
||||||
|
}
|
||||||
|
|
||||||
public boolean startControlling(BlockPos controlsLocalPos, Player player) {
|
public boolean startControlling(BlockPos controlsLocalPos, Player player) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +201,13 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopControlling(BlockPos controlsLocalPos) {}
|
public void stopControlling(BlockPos controlsLocalPos) {
|
||||||
|
getControllingPlayer().map(level::getPlayerByUUID)
|
||||||
|
.map(p -> (p instanceof ServerPlayer) ? ((ServerPlayer) p) : null)
|
||||||
|
.ifPresent(p -> AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> p),
|
||||||
|
new ControlsStopControllingPacket()));
|
||||||
|
setControllingPlayer(null);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean handlePlayerInteraction(Player player, BlockPos localPos, Direction side,
|
public boolean handlePlayerInteraction(Player player, BlockPos localPos, Direction side,
|
||||||
InteractionHand interactionHand) {
|
InteractionHand interactionHand) {
|
||||||
|
@ -403,6 +424,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
@Override
|
@Override
|
||||||
protected void defineSynchedData() {
|
protected void defineSynchedData() {
|
||||||
this.entityData.define(STALLED, false);
|
this.entityData.define(STALLED, false);
|
||||||
|
this.entityData.define(CONTROLLED_BY, Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -113,8 +113,7 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getInitialYaw() {
|
public float getInitialYaw() {
|
||||||
return (isInitialOrientationPresent() ? entityData.get(INITIAL_ORIENTATION) : Direction.SOUTH)
|
return (isInitialOrientationPresent() ? entityData.get(INITIAL_ORIENTATION) : Direction.SOUTH).toYRot();
|
||||||
.toYRot();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -177,8 +176,7 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity {
|
||||||
super.writeAdditional(compound, spawnPacket);
|
super.writeAdditional(compound, spawnPacket);
|
||||||
|
|
||||||
if (motionBeforeStall != null)
|
if (motionBeforeStall != null)
|
||||||
compound.put("CachedMotion",
|
compound.put("CachedMotion", newDoubleList(motionBeforeStall.x, motionBeforeStall.y, motionBeforeStall.z));
|
||||||
newDoubleList(motionBeforeStall.x, motionBeforeStall.y, motionBeforeStall.z));
|
|
||||||
|
|
||||||
Direction optional = entityData.get(INITIAL_ORIENTATION);
|
Direction optional = entityData.get(INITIAL_ORIENTATION);
|
||||||
if (optional.getAxis()
|
if (optional.getAxis()
|
||||||
|
@ -200,7 +198,7 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity {
|
||||||
@Override
|
@Override
|
||||||
public void onSyncedDataUpdated(EntityDataAccessor<?> key) {
|
public void onSyncedDataUpdated(EntityDataAccessor<?> key) {
|
||||||
super.onSyncedDataUpdated(key);
|
super.onSyncedDataUpdated(key);
|
||||||
if (key == INITIAL_ORIENTATION && isInitialOrientationPresent() && !manuallyPlaced)
|
if (INITIAL_ORIENTATION.equals(key) && isInitialOrientationPresent() && !manuallyPlaced)
|
||||||
startAtInitialYaw();
|
startAtInitialYaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,19 +5,14 @@ import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.InputConstants;
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
||||||
|
import com.simibubi.create.foundation.networking.AllPackets;
|
||||||
import com.simibubi.create.foundation.utility.ControlsUtil;
|
import com.simibubi.create.foundation.utility.ControlsUtil;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
|
||||||
|
|
||||||
import net.minecraft.client.KeyMapping;
|
import net.minecraft.client.KeyMapping;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.player.LocalPlayer;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
|
|
||||||
public class ControlsHandler {
|
public class ControlsHandler {
|
||||||
|
|
||||||
|
@ -29,33 +24,28 @@ public class ControlsHandler {
|
||||||
static WeakReference<AbstractContraptionEntity> entityRef = new WeakReference<>(null);
|
static WeakReference<AbstractContraptionEntity> entityRef = new WeakReference<>(null);
|
||||||
static BlockPos controlsPos;
|
static BlockPos controlsPos;
|
||||||
|
|
||||||
public static void controllerClicked(AbstractContraptionEntity entity, BlockPos controllerLocalPos, Player player) {
|
public static void startControlling(AbstractContraptionEntity entity, BlockPos controllerLocalPos) {
|
||||||
AbstractContraptionEntity prevEntity = entityRef.get();
|
|
||||||
if (prevEntity != null) {
|
|
||||||
stopControlling();
|
|
||||||
if (prevEntity == entity)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!entity.startControlling(controllerLocalPos, player))
|
|
||||||
return;
|
|
||||||
entityRef = new WeakReference<AbstractContraptionEntity>(entity);
|
entityRef = new WeakReference<AbstractContraptionEntity>(entity);
|
||||||
controlsPos = controllerLocalPos;
|
controlsPos = controllerLocalPos;
|
||||||
|
|
||||||
Minecraft.getInstance().player.displayClientMessage(
|
Minecraft.getInstance().player.displayClientMessage(
|
||||||
Lang.translate("contraption.controls.start_controlling", entity.getContraptionName()), true);
|
Lang.translate("contraption.controls.start_controlling", entity.getContraptionName()), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void stopControlling() {
|
public static void stopControlling() {
|
||||||
AbstractContraptionEntity abstractContraptionEntity = entityRef.get();
|
|
||||||
if (abstractContraptionEntity != null)
|
|
||||||
abstractContraptionEntity.stopControlling(controlsPos);
|
|
||||||
ControlsUtil.getControls()
|
ControlsUtil.getControls()
|
||||||
.forEach(kb -> kb.setDown(ControlsUtil.isActuallyPressed(kb)));
|
.forEach(kb -> kb.setDown(ControlsUtil.isActuallyPressed(kb)));
|
||||||
|
AbstractContraptionEntity abstractContraptionEntity = entityRef.get();
|
||||||
|
|
||||||
|
if (!currentlyPressed.isEmpty() && abstractContraptionEntity != null)
|
||||||
|
AllPackets.channel.sendToServer(
|
||||||
|
new ControlsInputPacket(currentlyPressed, false, abstractContraptionEntity.getId(), controlsPos));
|
||||||
|
|
||||||
packetCooldown = 0;
|
packetCooldown = 0;
|
||||||
entityRef = new WeakReference<>(null);
|
entityRef = new WeakReference<>(null);
|
||||||
controlsPos = null;
|
controlsPos = null;
|
||||||
// if (!currentlyPressed.isEmpty())
|
|
||||||
// AllPackets.channel.sendToServer(new LinkedControllerInputPacket(currentlyPressed, false));
|
|
||||||
currentlyPressed.clear();
|
currentlyPressed.clear();
|
||||||
|
|
||||||
Minecraft.getInstance().player.displayClientMessage(Lang.translate("contraption.controls.stop_controlling"),
|
Minecraft.getInstance().player.displayClientMessage(Lang.translate("contraption.controls.stop_controlling"),
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
@ -67,24 +57,6 @@ public class ControlsHandler {
|
||||||
if (packetCooldown > 0)
|
if (packetCooldown > 0)
|
||||||
packetCooldown--;
|
packetCooldown--;
|
||||||
|
|
||||||
Minecraft mc = Minecraft.getInstance();
|
|
||||||
LocalPlayer player = mc.player;
|
|
||||||
|
|
||||||
if (player.isSpectator()) {
|
|
||||||
stopControlling();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (InputConstants.isKeyDown(mc.getWindow()
|
|
||||||
.getWindow(), GLFW.GLFW_KEY_ESCAPE)) {
|
|
||||||
stopControlling();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!entity.toGlobalVector(VecHelper.getCenterOf(controlsPos), 1)
|
|
||||||
.closerThan(player.position(), 10)) {
|
|
||||||
stopControlling();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<KeyMapping> controls = ControlsUtil.getControls();
|
Vector<KeyMapping> controls = ControlsUtil.getControls();
|
||||||
Collection<Integer> pressedKeys = new HashSet<>();
|
Collection<Integer> pressedKeys = new HashSet<>();
|
||||||
for (int i = 0; i < controls.size(); i++) {
|
for (int i = 0; i < controls.size(); i++) {
|
||||||
|
@ -99,34 +71,24 @@ public class ControlsHandler {
|
||||||
|
|
||||||
// Released Keys
|
// Released Keys
|
||||||
if (!releasedKeys.isEmpty()) {
|
if (!releasedKeys.isEmpty()) {
|
||||||
// AllPackets.channel.sendToServer(new LinkedControllerInputPacket(releasedKeys, false, lecternPos));
|
AllPackets.channel.sendToServer(new ControlsInputPacket(releasedKeys, false, entity.getId(), controlsPos));
|
||||||
// AllSoundEvents.CONTROLLER_CLICK.playAt(player.level, player.blockPosition(), 1f, .5f, true);
|
// AllSoundEvents.CONTROLLER_CLICK.playAt(player.level, player.blockPosition(), 1f, .5f, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Newly Pressed Keys
|
// Newly Pressed Keys
|
||||||
if (!newKeys.isEmpty()) {
|
if (!newKeys.isEmpty()) {
|
||||||
if (newKeys.contains(Integer.valueOf(5))) {
|
AllPackets.channel.sendToServer(new ControlsInputPacket(newKeys, true, entity.getId(), controlsPos));
|
||||||
stopControlling();
|
packetCooldown = PACKET_RATE;
|
||||||
return;
|
// AllSoundEvents.CONTROLLER_CLICK.playAt(player.level, player.blockPosition(), 1f, .75f, true);
|
||||||
}
|
|
||||||
|
|
||||||
// AllPackets.channel.sendToServer(new LinkedControllerInputPacket(newKeys, true, lecternPos));
|
|
||||||
// packetCooldown = PACKET_RATE;
|
|
||||||
// AllSoundEvents.CONTROLLER_CLICK.playAt(player.level, player.blockPosition(), 1f, .75f, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keepalive Pressed Keys
|
// Keepalive Pressed Keys
|
||||||
if (packetCooldown == 0) {
|
if (packetCooldown == 0) {
|
||||||
// if (!pressedKeys.isEmpty()) {
|
if (!pressedKeys.isEmpty()) {
|
||||||
// AllPackets.channel.sendToServer(new LinkedControllerInputPacket(pressedKeys, true, lecternPos));
|
AllPackets.channel
|
||||||
// packetCooldown = PACKET_RATE;
|
.sendToServer(new ControlsInputPacket(pressedKeys, true, entity.getId(), controlsPos));
|
||||||
// }
|
packetCooldown = PACKET_RATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO do this server side
|
|
||||||
if (!entity.control(controlsPos, pressedKeys, player)) {
|
|
||||||
stopControlling();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currentlyPressed = pressedKeys;
|
currentlyPressed = pressedKeys;
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
||||||
|
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||||
|
|
||||||
|
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.level.Level;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import net.minecraftforge.network.NetworkEvent.Context;
|
||||||
|
|
||||||
|
public class ControlsInputPacket extends SimplePacketBase {
|
||||||
|
|
||||||
|
private Collection<Integer> activatedButtons;
|
||||||
|
private boolean press;
|
||||||
|
private int contraptionEntityId;
|
||||||
|
private BlockPos controlsPos;
|
||||||
|
|
||||||
|
public ControlsInputPacket(Collection<Integer> activatedButtons, boolean press, int contraptionEntityId,
|
||||||
|
BlockPos controlsPos) {
|
||||||
|
this.contraptionEntityId = contraptionEntityId;
|
||||||
|
this.activatedButtons = activatedButtons;
|
||||||
|
this.press = press;
|
||||||
|
this.controlsPos = controlsPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ControlsInputPacket(FriendlyByteBuf buffer) {
|
||||||
|
contraptionEntityId = buffer.readInt();
|
||||||
|
activatedButtons = new ArrayList<>();
|
||||||
|
press = buffer.readBoolean();
|
||||||
|
int size = buffer.readVarInt();
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
activatedButtons.add(buffer.readVarInt());
|
||||||
|
controlsPos = buffer.readBlockPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(FriendlyByteBuf buffer) {
|
||||||
|
buffer.writeInt(contraptionEntityId);
|
||||||
|
buffer.writeBoolean(press);
|
||||||
|
buffer.writeVarInt(activatedButtons.size());
|
||||||
|
activatedButtons.forEach(buffer::writeVarInt);
|
||||||
|
buffer.writeBlockPos(controlsPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Supplier<Context> context) {
|
||||||
|
Context ctx = context.get();
|
||||||
|
ctx.enqueueWork(() -> {
|
||||||
|
ServerPlayer player = ctx.getSender();
|
||||||
|
Level world = player.getCommandSenderWorld();
|
||||||
|
UUID uniqueID = player.getUUID();
|
||||||
|
|
||||||
|
if (player.isSpectator() && press)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Entity entity = world.getEntity(contraptionEntityId);
|
||||||
|
if (!(entity instanceof AbstractContraptionEntity ace))
|
||||||
|
return;
|
||||||
|
if (ace.toGlobalVector(Vec3.atCenterOf(controlsPos), 0)
|
||||||
|
.distanceTo(player.position()) > 10)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ControlsServerHandler.receivePressed(world, ace, controlsPos, uniqueID, activatedButtons, press);
|
||||||
|
});
|
||||||
|
ctx.setPacketHandled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
package com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls;
|
package com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour;
|
import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour;
|
||||||
|
@ -7,6 +10,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
|
||||||
public class ControlsInteractionBehaviour extends MovingInteractionBehaviour {
|
public class ControlsInteractionBehaviour extends MovingInteractionBehaviour {
|
||||||
|
|
||||||
|
@ -15,8 +20,23 @@ public class ControlsInteractionBehaviour extends MovingInteractionBehaviour {
|
||||||
AbstractContraptionEntity contraptionEntity) {
|
AbstractContraptionEntity contraptionEntity) {
|
||||||
if (AllItems.WRENCH.isIn(player.getItemInHand(activeHand)))
|
if (AllItems.WRENCH.isIn(player.getItemInHand(activeHand)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
UUID currentlyControlling = contraptionEntity.getControllingPlayer()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (currentlyControlling != null) {
|
||||||
|
contraptionEntity.stopControlling(localPos);
|
||||||
|
if (Objects.equal(currentlyControlling, player.getUUID()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!contraptionEntity.startControlling(localPos, player))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
contraptionEntity.setControllingPlayer(player.getUUID());
|
||||||
if (player.level.isClientSide)
|
if (player.level.isClientSide)
|
||||||
ControlsHandler.controllerClicked(contraptionEntity, localPos, player);
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
|
||||||
|
() -> () -> ControlsHandler.startControlling(contraptionEntity, localPos));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,50 +3,80 @@ package com.simibubi.create.content.contraptions.components.structureMovement.in
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
|
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionMatrices;
|
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionMatrices;
|
||||||
import com.simibubi.create.content.logistics.trains.entity.Carriage;
|
|
||||||
import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity;
|
import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity;
|
||||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.MultiBufferSource;
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
public class ControlsMovementBehaviour extends MovementBehaviour {
|
public class ControlsMovementBehaviour extends MovementBehaviour {
|
||||||
|
|
||||||
// TODO: this is specific to Carriage Contraptions - need to move this behaviour
|
// TODO: rendering the levers should be specific to Carriage Contraptions -
|
||||||
// there
|
static class LeverAngles {
|
||||||
LerpedFloat steering = LerpedFloat.linear();
|
LerpedFloat steering = LerpedFloat.linear();
|
||||||
LerpedFloat speed = LerpedFloat.linear();
|
LerpedFloat speed = LerpedFloat.linear();
|
||||||
LerpedFloat equipAnimation = LerpedFloat.linear();
|
LerpedFloat equipAnimation = LerpedFloat.linear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(MovementContext context) {
|
public void tick(MovementContext context) {
|
||||||
steering.tickChaser();
|
|
||||||
speed.tickChaser();
|
|
||||||
equipAnimation.tickChaser();
|
|
||||||
super.tick(context);
|
super.tick(context);
|
||||||
|
if (!context.world.isClientSide)
|
||||||
|
return;
|
||||||
|
if (!(context.temporaryData instanceof LeverAngles))
|
||||||
|
context.temporaryData = new LeverAngles();
|
||||||
|
LeverAngles angles = (LeverAngles) context.temporaryData;
|
||||||
|
angles.steering.tickChaser();
|
||||||
|
angles.speed.tickChaser();
|
||||||
|
angles.equipAnimation.tickChaser();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
|
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
|
||||||
ContraptionMatrices matrices, MultiBufferSource buffer) {
|
ContraptionMatrices matrices, MultiBufferSource buffer) {
|
||||||
if (ControlsHandler.entityRef.get() == context.contraption.entity && ControlsHandler.controlsPos != null
|
if (!(context.temporaryData instanceof LeverAngles angles))
|
||||||
|
return;
|
||||||
|
|
||||||
|
AbstractContraptionEntity entity = context.contraption.entity;
|
||||||
|
if (!(entity instanceof CarriageContraptionEntity cce))
|
||||||
|
return;
|
||||||
|
|
||||||
|
StructureBlockInfo info = context.contraption.getBlocks()
|
||||||
|
.get(context.localPos);
|
||||||
|
Direction initialOrientation = cce.getInitialOrientation()
|
||||||
|
.getCounterClockWise();
|
||||||
|
boolean inverted = false;
|
||||||
|
if (info != null && info.state.hasProperty(ControlsBlock.FACING))
|
||||||
|
inverted = !info.state.getValue(ControlsBlock.FACING)
|
||||||
|
.equals(initialOrientation);
|
||||||
|
|
||||||
|
if (ControlsHandler.entityRef.get() == entity && ControlsHandler.controlsPos != null
|
||||||
&& ControlsHandler.controlsPos.equals(context.localPos)) {
|
&& ControlsHandler.controlsPos.equals(context.localPos)) {
|
||||||
Collection<Integer> pressed = ControlsHandler.currentlyPressed;
|
Collection<Integer> pressed = ControlsHandler.currentlyPressed;
|
||||||
equipAnimation.chase(1, .2f, Chaser.EXP);
|
angles.equipAnimation.chase(1, .2f, Chaser.EXP);
|
||||||
steering.chase((pressed.contains(3) ? 1 : 0) + (pressed.contains(2) ? -1 : 0), 0.2f, Chaser.EXP);
|
angles.steering.chase((pressed.contains(3) ? 1 : 0) + (pressed.contains(2) ? -1 : 0), 0.2f, Chaser.EXP);
|
||||||
speed.chase(0, 0.2f, Chaser.EXP); // TODO
|
float f = cce.movingBackwards ^ inverted ? -1 : 1;
|
||||||
} else
|
angles.speed.chase(Math.min(context.motion.length(), 0.5f) * f, 0.2f, Chaser.EXP);
|
||||||
equipAnimation.chase(0, .2f, Chaser.EXP);
|
|
||||||
|
} else {
|
||||||
|
angles.equipAnimation.chase(0, .2f, Chaser.EXP);
|
||||||
|
angles.steering.chase(0, 0, Chaser.EXP);
|
||||||
|
angles.speed.chase(0, 0, Chaser.EXP);
|
||||||
|
}
|
||||||
|
|
||||||
float pt = AnimationTickHolder.getPartialTicks(context.world);
|
float pt = AnimationTickHolder.getPartialTicks(context.world);
|
||||||
ControlsRenderer.render(context, renderWorld, matrices, buffer, equipAnimation.getValue(pt), speed.getValue(pt),
|
ControlsRenderer.render(context, renderWorld, matrices, buffer, angles.equipAnimation.getValue(pt),
|
||||||
steering.getValue(pt));
|
angles.speed.getValue(pt), angles.steering.getValue(pt));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
package com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
||||||
|
import com.simibubi.create.foundation.utility.IntAttached;
|
||||||
|
import com.simibubi.create.foundation.utility.WorldAttached;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
|
||||||
|
public class ControlsServerHandler {
|
||||||
|
|
||||||
|
public static WorldAttached<Map<UUID, ControlsContext>> receivedInputs = new WorldAttached<>($ -> new HashMap<>());
|
||||||
|
static final int TIMEOUT = 30;
|
||||||
|
|
||||||
|
public static void tick(LevelAccessor world) {
|
||||||
|
Map<UUID, ControlsContext> map = receivedInputs.get(world);
|
||||||
|
for (Iterator<Entry<UUID, ControlsContext>> iterator = map.entrySet()
|
||||||
|
.iterator(); iterator.hasNext();) {
|
||||||
|
|
||||||
|
Entry<UUID, ControlsContext> entry = iterator.next();
|
||||||
|
ControlsContext ctx = entry.getValue();
|
||||||
|
Collection<ManuallyPressedKey> list = ctx.keys;
|
||||||
|
|
||||||
|
for (Iterator<ManuallyPressedKey> entryIterator = list.iterator(); entryIterator.hasNext();) {
|
||||||
|
ManuallyPressedKey pressedKey = entryIterator.next();
|
||||||
|
pressedKey.decrement();
|
||||||
|
if (!pressedKey.isAlive())
|
||||||
|
entryIterator.remove(); // key released
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctx.entity.control(ctx.controlsLocalPos, list.stream()
|
||||||
|
.map(ManuallyPressedKey::getSecond)
|
||||||
|
.toList(), world.getPlayerByUUID(entry.getKey()))) {
|
||||||
|
ctx.entity.stopControlling(ctx.controlsLocalPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.isEmpty())
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void receivePressed(LevelAccessor world, AbstractContraptionEntity entity, BlockPos controlsPos,
|
||||||
|
UUID uniqueID, Collection<Integer> collect, boolean pressed) {
|
||||||
|
Map<UUID, ControlsContext> map = receivedInputs.get(world);
|
||||||
|
|
||||||
|
if (map.containsKey(uniqueID) && map.get(uniqueID).entity != entity)
|
||||||
|
map.remove(uniqueID);
|
||||||
|
|
||||||
|
ControlsContext ctx = map.computeIfAbsent(uniqueID, $ -> new ControlsContext(entity, controlsPos));
|
||||||
|
Collection<ManuallyPressedKey> list = ctx.keys;
|
||||||
|
|
||||||
|
WithNext: for (Integer activated : collect) {
|
||||||
|
for (Iterator<ManuallyPressedKey> iterator = list.iterator(); iterator.hasNext();) {
|
||||||
|
ManuallyPressedKey entry = iterator.next();
|
||||||
|
Integer inputType = entry.getSecond();
|
||||||
|
if (inputType.equals(activated)) {
|
||||||
|
if (!pressed)
|
||||||
|
entry.setFirst(0);
|
||||||
|
else
|
||||||
|
entry.keepAlive();
|
||||||
|
continue WithNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pressed)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
list.add(new ManuallyPressedKey(activated)); // key newly pressed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ControlsContext {
|
||||||
|
|
||||||
|
Collection<ManuallyPressedKey> keys;
|
||||||
|
AbstractContraptionEntity entity;
|
||||||
|
BlockPos controlsLocalPos;
|
||||||
|
|
||||||
|
public ControlsContext(AbstractContraptionEntity entity, BlockPos controlsPos) {
|
||||||
|
this.entity = entity;
|
||||||
|
controlsLocalPos = controlsPos;
|
||||||
|
keys = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ManuallyPressedKey extends IntAttached<Integer> {
|
||||||
|
|
||||||
|
public ManuallyPressedKey(Integer second) {
|
||||||
|
super(TIMEOUT, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void keepAlive() {
|
||||||
|
setFirst(TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAlive() {
|
||||||
|
return getFirst() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||||
|
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraftforge.network.NetworkEvent.Context;
|
||||||
|
|
||||||
|
public class ControlsStopControllingPacket extends SimplePacketBase {
|
||||||
|
|
||||||
|
public ControlsStopControllingPacket() {}
|
||||||
|
|
||||||
|
public ControlsStopControllingPacket(FriendlyByteBuf buffer) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(FriendlyByteBuf buffer) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Supplier<Context> context) {
|
||||||
|
context.get()
|
||||||
|
.enqueueWork(ControlsHandler::stopControlling);
|
||||||
|
context.get()
|
||||||
|
.setPacketHandled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -57,7 +57,7 @@ public class DoubleFaceAttachedBlock extends HorizontalDirectionalBlock {
|
||||||
face = DoubleAttachFace.WALL_REVERSED;
|
face = DoubleAttachFace.WALL_REVERSED;
|
||||||
}
|
}
|
||||||
blockstate = this.defaultBlockState()
|
blockstate = this.defaultBlockState()
|
||||||
.setValue(FACE, face) // TODO wall reversed
|
.setValue(FACE, face)
|
||||||
.setValue(FACING, direction.getOpposite());
|
.setValue(FACING, direction.getOpposite());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,12 +157,12 @@ public class GlobalRailwayManager {
|
||||||
for (Train train : trains.values())
|
for (Train train : trains.values())
|
||||||
train.tick(level);
|
train.tick(level);
|
||||||
|
|
||||||
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_H) && AllKeys.altDown())
|
// if (AllKeys.isKeyDown(GLFW.GLFW_KEY_H) && AllKeys.altDown())
|
||||||
trackNetworks.values()
|
// trackNetworks.values()
|
||||||
.forEach(TrackGraph::debugViewSignalData);
|
// .forEach(TrackGraph::debugViewSignalData);
|
||||||
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_J) && AllKeys.altDown())
|
// if (AllKeys.isKeyDown(GLFW.GLFW_KEY_J) && AllKeys.altDown())
|
||||||
trackNetworks.values()
|
// trackNetworks.values()
|
||||||
.forEach(TrackGraph::debugViewNodes);
|
// .forEach(TrackGraph::debugViewNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clientTick() {
|
public void clientTick() {
|
||||||
|
|
|
@ -451,7 +451,7 @@ public class TrackGraph {
|
||||||
EdgeData signalData = edge.getEdgeData();
|
EdgeData signalData = edge.getEdgeData();
|
||||||
UUID singleGroup = signalData.singleSignalGroup;
|
UUID singleGroup = signalData.singleSignalGroup;
|
||||||
SignalEdgeGroup signalEdgeGroup =
|
SignalEdgeGroup signalEdgeGroup =
|
||||||
singleGroup == null ? null : Create.RAILWAYS.signalEdgeGroups.get(singleGroup);
|
singleGroup == null ? null : Create.RAILWAYS.sided(null).signalEdgeGroups.get(singleGroup);
|
||||||
|
|
||||||
if (!edge.isTurn()) {
|
if (!edge.isTurn()) {
|
||||||
Vec3 p1 = edge.getPosition(node, other, 0);
|
Vec3 p1 = edge.getPosition(node, other, 0);
|
||||||
|
@ -479,7 +479,7 @@ public class TrackGraph {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
prevBoundary = boundary;
|
prevBoundary = boundary;
|
||||||
group = Create.RAILWAYS.signalEdgeGroups.get(boundary.getGroup(node));
|
group = Create.RAILWAYS.sided(null).signalEdgeGroups.get(boundary.getGroup(node));
|
||||||
|
|
||||||
if (group != null)
|
if (group != null)
|
||||||
CreateClient.OUTLINER
|
CreateClient.OUTLINER
|
||||||
|
@ -496,7 +496,7 @@ public class TrackGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevBoundary != null) {
|
if (prevBoundary != null) {
|
||||||
group = Create.RAILWAYS.signalEdgeGroups.get(prevBoundary.getGroup(other));
|
group = Create.RAILWAYS.sided(null).signalEdgeGroups.get(prevBoundary.getGroup(other));
|
||||||
if (group != null)
|
if (group != null)
|
||||||
CreateClient.OUTLINER
|
CreateClient.OUTLINER
|
||||||
.showLine(edge, edge.getPosition(node, other, prev + 1 / 16f / length)
|
.showLine(edge, edge.getPosition(node, other, prev + 1 / 16f / length)
|
||||||
|
|
|
@ -30,7 +30,8 @@ public class TrackGraphHelper {
|
||||||
|
|
||||||
TrackNodeLocation location = new TrackNodeLocation(Vec3.atBottomCenterOf(pos)
|
TrackNodeLocation location = new TrackNodeLocation(Vec3.atBottomCenterOf(pos)
|
||||||
.add(0, track.getElevationAtCenter(level, pos, trackBlockState), 0));
|
.add(0, track.getElevationAtCenter(level, pos, trackBlockState), 0));
|
||||||
graph = Create.RAILWAYS.getGraph(level, location);
|
graph = Create.RAILWAYS.sided(level)
|
||||||
|
.getGraph(level, location);
|
||||||
if (graph != null) {
|
if (graph != null) {
|
||||||
TrackNode node = graph.locateNode(location);
|
TrackNode node = graph.locateNode(location);
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
|
@ -79,7 +80,8 @@ public class TrackGraphHelper {
|
||||||
for (int i = 0; i < 100 && distance < 32; i++) {
|
for (int i = 0; i < 100 && distance < 32; i++) {
|
||||||
DiscoveredLocation loc = current;
|
DiscoveredLocation loc = current;
|
||||||
if (graph == null)
|
if (graph == null)
|
||||||
graph = Create.RAILWAYS.getGraph(level, loc);
|
graph = Create.RAILWAYS.sided(level)
|
||||||
|
.getGraph(level, loc);
|
||||||
|
|
||||||
if (graph == null || graph.locateNode(loc) == null) {
|
if (graph == null || graph.locateNode(loc) == null) {
|
||||||
Collection<DiscoveredLocation> list = ITrackBlock.walkConnectedTracks(level, loc, true);
|
Collection<DiscoveredLocation> list = ITrackBlock.walkConnectedTracks(level, loc, true);
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package com.simibubi.create.content.logistics.trains.entity;
|
package com.simibubi.create.content.logistics.trains.entity;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.Optional;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@ -19,7 +20,9 @@ import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.Entity.RemovalReason;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
@ -65,6 +68,21 @@ public class Carriage {
|
||||||
CarriageContraptionEntity entity = CarriageContraptionEntity.create(level, contraption);
|
CarriageContraptionEntity entity = CarriageContraptionEntity.create(level, contraption);
|
||||||
entity.setCarriage(this);
|
entity.setCarriage(this);
|
||||||
contraption.startMoving(level);
|
contraption.startMoving(level);
|
||||||
|
contraption.onEntityInitialize(level, entity);
|
||||||
|
for (CarriageBogey carriageBogey : bogeys)
|
||||||
|
if (carriageBogey != null)
|
||||||
|
carriageBogey.updateAnchorPosition();
|
||||||
|
alignEntity(entity);
|
||||||
|
|
||||||
|
List<Entity> players = new ArrayList<>();
|
||||||
|
for (Entity passenger : entity.getPassengers())
|
||||||
|
if (!(passenger instanceof Player))
|
||||||
|
passenger.remove(RemovalReason.UNLOADED_WITH_PLAYER);
|
||||||
|
else
|
||||||
|
players.add(passenger);
|
||||||
|
for (Entity player : players)
|
||||||
|
player.stopRiding();
|
||||||
|
|
||||||
serialisedEntity = entity.serializeNBT();
|
serialisedEntity = entity.serializeNBT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,16 +155,18 @@ public class Carriage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createEntity(Level level) {
|
public void createEntity(Level level) {
|
||||||
Optional<Entity> entityFromData = EntityType.create(serialisedEntity, level);
|
Entity entity = EntityType.loadEntityRecursive(serialisedEntity, level, e -> {
|
||||||
Entity entity = entityFromData.orElse(null);
|
level.addFreshEntity(e);
|
||||||
|
return e;
|
||||||
|
});
|
||||||
if (!(entity instanceof CarriageContraptionEntity cce))
|
if (!(entity instanceof CarriageContraptionEntity cce))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Vec3 pos = leadingBogey().anchorPosition;
|
Vec3 pos = leadingBogey().anchorPosition;
|
||||||
cce.setPos(pos);
|
cce.setPos(pos);
|
||||||
cce.setCarriage(this);
|
cce.setCarriage(this);
|
||||||
cce.setGraph(train.graph == null ? null : train.graph.id);
|
cce.setGraph(train.graph == null ? null : train.graph.id);
|
||||||
cce.syncCarriage();
|
cce.syncCarriage();
|
||||||
level.addFreshEntity(cce);
|
|
||||||
this.entity = new WeakReference<>(cce);
|
this.entity = new WeakReference<>(cce);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,8 +181,12 @@ public class Carriage {
|
||||||
createEntity(level);
|
createEntity(level);
|
||||||
} else {
|
} else {
|
||||||
CarriageEntityHandler.validateCarriageEntity(entity);
|
CarriageEntityHandler.validateCarriageEntity(entity);
|
||||||
if (!entity.isAlive()) {
|
if (!entity.isAlive() || entity.leftTickingChunks) {
|
||||||
|
for (Entity passenger : entity.getPassengers())
|
||||||
|
if (!(passenger instanceof Player))
|
||||||
|
passenger.remove(RemovalReason.UNLOADED_WITH_PLAYER);
|
||||||
serialisedEntity = entity.serializeNBT();
|
serialisedEntity = entity.serializeNBT();
|
||||||
|
entity.discard();
|
||||||
this.entity.clear();
|
this.entity.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -195,13 +219,6 @@ public class Carriage {
|
||||||
entity.pitch = (float) (Math.atan2(diffY, Math.sqrt(diffX * diffX + diffZ * diffZ)) * 180 / Math.PI) * -1;
|
entity.pitch = (float) (Math.atan2(diffY, Math.sqrt(diffX * diffX + diffZ * diffZ)) * 180 / Math.PI) * -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void discardEntity() {
|
|
||||||
CarriageContraptionEntity entity = this.entity.get();
|
|
||||||
if (entity == null)
|
|
||||||
return;
|
|
||||||
entity.discard();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TravellingPoint getLeadingPoint() {
|
public TravellingPoint getLeadingPoint() {
|
||||||
return leadingBogey().leading();
|
return leadingBogey().leading();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.ListTag;
|
||||||
import net.minecraft.nbt.NbtUtils;
|
import net.minecraft.nbt.NbtUtils;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
@ -138,7 +139,7 @@ public class CarriageContraption extends Contraption {
|
||||||
tag.putBoolean("BackControls", backwardControls);
|
tag.putBoolean("BackControls", backwardControls);
|
||||||
tag.putBoolean("FrontBlazeConductor", blazeBurnerConductors.getFirst());
|
tag.putBoolean("FrontBlazeConductor", blazeBurnerConductors.getFirst());
|
||||||
tag.putBoolean("BackBlazeConductor", blazeBurnerConductors.getSecond());
|
tag.putBoolean("BackBlazeConductor", blazeBurnerConductors.getSecond());
|
||||||
NBTHelper.writeCompoundList(conductorSeats.entrySet(), e -> {
|
ListTag list = NBTHelper.writeCompoundList(conductorSeats.entrySet(), e -> {
|
||||||
CompoundTag compoundTag = new CompoundTag();
|
CompoundTag compoundTag = new CompoundTag();
|
||||||
compoundTag.put("Pos", NbtUtils.writeBlockPos(e.getKey()));
|
compoundTag.put("Pos", NbtUtils.writeBlockPos(e.getKey()));
|
||||||
compoundTag.putBoolean("Forward", e.getValue()
|
compoundTag.putBoolean("Forward", e.getValue()
|
||||||
|
@ -147,6 +148,7 @@ public class CarriageContraption extends Contraption {
|
||||||
.getSecond());
|
.getSecond());
|
||||||
return compoundTag;
|
return compoundTag;
|
||||||
});
|
});
|
||||||
|
tag.put("ConductorSeats", list);
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +162,7 @@ public class CarriageContraption extends Contraption {
|
||||||
conductorSeats.clear();
|
conductorSeats.clear();
|
||||||
NBTHelper.iterateCompoundList(nbt.getList("ConductorSeats", Tag.TAG_COMPOUND),
|
NBTHelper.iterateCompoundList(nbt.getList("ConductorSeats", Tag.TAG_COMPOUND),
|
||||||
c -> conductorSeats.put(NbtUtils.readBlockPos(c.getCompound("Pos")),
|
c -> conductorSeats.put(NbtUtils.readBlockPos(c.getCompound("Pos")),
|
||||||
Couple.create(nbt.getBoolean("Forward"), nbt.getBoolean("Backward"))));
|
Couple.create(c.getBoolean("Forward"), c.getBoolean("Backward"))));
|
||||||
super.readNBT(world, nbt, spawnData);
|
super.readNBT(world, nbt, spawnData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,13 @@ import com.simibubi.create.foundation.utility.Lang;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.Direction.Axis;
|
import net.minecraft.core.Direction.Axis;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.KeybindComponent;
|
||||||
import net.minecraft.network.chat.TextComponent;
|
import net.minecraft.network.chat.TextComponent;
|
||||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
|
@ -45,9 +45,6 @@ import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
|
||||||
|
|
||||||
public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
|
|
||||||
|
@ -61,6 +58,9 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
|
|
||||||
private Carriage carriage;
|
private Carriage carriage;
|
||||||
public boolean validForRender;
|
public boolean validForRender;
|
||||||
|
public boolean movingBackwards;
|
||||||
|
|
||||||
|
public boolean leftTickingChunks;
|
||||||
|
|
||||||
public CarriageContraptionEntity(EntityType<?> type, Level world) {
|
public CarriageContraptionEntity(EntityType<?> type, Level world) {
|
||||||
super(type, world);
|
super(type, world);
|
||||||
|
@ -95,10 +95,10 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
if (!level.isClientSide)
|
if (!level.isClientSide)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (key == TRACK_GRAPH)
|
if (TRACK_GRAPH.equals(key))
|
||||||
updateTrackGraph();
|
updateTrackGraph();
|
||||||
|
|
||||||
if (key == CARRIAGE_DATA) {
|
if (CARRIAGE_DATA.equals(key)) {
|
||||||
CarriageSyncData carriageData = getCarriageData();
|
CarriageSyncData carriageData = getCarriageData();
|
||||||
if (carriageData == null)
|
if (carriageData == null)
|
||||||
return;
|
return;
|
||||||
|
@ -177,8 +177,10 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
|
|
||||||
Vec3 diff = position().subtract(xo, yo, zo);
|
Vec3 diff = position().subtract(xo, yo, zo);
|
||||||
Vec3 relativeDiff = VecHelper.rotate(diff, yaw, Axis.Y);
|
Vec3 relativeDiff = VecHelper.rotate(diff, yaw, Axis.Y);
|
||||||
double distanceTo = diff.length() * Math.signum(-relativeDiff.x);
|
double signum = Math.signum(-relativeDiff.x);
|
||||||
|
double distanceTo = diff.length() * signum;
|
||||||
|
|
||||||
|
movingBackwards = signum < 0;
|
||||||
carriage.bogeys.getFirst()
|
carriage.bogeys.getFirst()
|
||||||
.updateAngles(distanceTo);
|
.updateAngles(distanceTo);
|
||||||
if (carriage.isOnTwoBogeys())
|
if (carriage.isOnTwoBogeys())
|
||||||
|
@ -272,6 +274,14 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
return false;
|
return false;
|
||||||
if (carriage.train.derailed)
|
if (carriage.train.derailed)
|
||||||
return false;
|
return false;
|
||||||
|
if (level.isClientSide)
|
||||||
|
return true;
|
||||||
|
if (player.isSpectator())
|
||||||
|
return false;
|
||||||
|
if (!toGlobalVector(VecHelper.getCenterOf(controlsLocalPos), 1).closerThan(player.position(), 10))
|
||||||
|
return false;
|
||||||
|
if (heldControls.contains(5))
|
||||||
|
return false;
|
||||||
|
|
||||||
StructureBlockInfo info = contraption.getBlocks()
|
StructureBlockInfo info = contraption.getBlocks()
|
||||||
.get(controlsLocalPos);
|
.get(controlsLocalPos);
|
||||||
|
@ -326,8 +336,8 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
new TextComponent(Strings.repeat("|", progress) + (arrived ? " ->" : " <-"));
|
new TextComponent(Strings.repeat("|", progress) + (arrived ? " ->" : " <-"));
|
||||||
TextComponent greenComponent =
|
TextComponent greenComponent =
|
||||||
new TextComponent((arrived ? "<- " : "-> ") + Strings.repeat("|", 30 - progress));
|
new TextComponent((arrived ? "<- " : "-> ") + Strings.repeat("|", 30 - progress));
|
||||||
int mixedColor = Color.mixColors(0xff_91EA44, 0xff_FFC244, progress / 30f);
|
int mixedColor = Color.mixColors(0x00_91EA44, 0x00_FFC244, progress / 30f);
|
||||||
int targetColor = arrived ? 0xff_91EA44 : 0xff_ffffff;
|
int targetColor = arrived ? 0x00_91EA44 : 0x00_ffffff;
|
||||||
player.displayClientMessage(greenComponent.withStyle(st -> st.withColor(mixedColor))
|
player.displayClientMessage(greenComponent.withStyle(st -> st.withColor(mixedColor))
|
||||||
.append(whiteComponent.withStyle(st -> st.withColor(targetColor))), true);
|
.append(whiteComponent.withStyle(st -> st.withColor(targetColor))), true);
|
||||||
return true;
|
return true;
|
||||||
|
@ -344,12 +354,9 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
navDistanceTotal = nav.distanceToDestination;
|
navDistanceTotal = nav.distanceToDestination;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (level.isClientSide)
|
displayApproachStationMessage(player, lookAhead);
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> displayApproachStationMessage(lookAhead));
|
} else
|
||||||
} else {
|
cleanUpApproachStationMessage(player);
|
||||||
if (level.isClientSide)
|
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> this::cleanUpApproachStationMessage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
carriage.train.manualSteer =
|
carriage.train.manualSteer =
|
||||||
|
@ -366,20 +373,17 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
|
|
||||||
boolean stationMessage = false;
|
boolean stationMessage = false;
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
private void displayApproachStationMessage(Player player, GlobalStation station) {
|
||||||
private void displayApproachStationMessage(GlobalStation station) {
|
player.displayClientMessage(
|
||||||
Minecraft instance = Minecraft.getInstance();
|
Lang.translate("contraption.controls.approach_station", new KeybindComponent("key.jump"), station.name),
|
||||||
instance.player.displayClientMessage(Lang.translate("contraption.controls.approach_station",
|
true);
|
||||||
instance.options.keyJump.getTranslatedKeyMessage(), station.name), true);
|
|
||||||
stationMessage = true;
|
stationMessage = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
private void cleanUpApproachStationMessage(Player player) {
|
||||||
private void cleanUpApproachStationMessage() {
|
|
||||||
if (!stationMessage)
|
if (!stationMessage)
|
||||||
return;
|
return;
|
||||||
Minecraft instance = Minecraft.getInstance();
|
player.displayClientMessage(new TextComponent(""), true);
|
||||||
instance.player.displayClientMessage(new TextComponent(""), true);
|
|
||||||
stationMessage = false;
|
stationMessage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,14 @@ public class CarriageEntityHandler {
|
||||||
if (!event.didChunkChange())
|
if (!event.didChunkChange())
|
||||||
return;
|
return;
|
||||||
Entity entity = event.getEntity();
|
Entity entity = event.getEntity();
|
||||||
if (!(entity instanceof CarriageContraptionEntity))
|
if (!(entity instanceof CarriageContraptionEntity cce))
|
||||||
return;
|
return;
|
||||||
SectionPos newPos = event.getNewPos();
|
SectionPos newPos = event.getNewPos();
|
||||||
Level level = entity.getLevel();
|
Level level = entity.getLevel();
|
||||||
if (level.isClientSide)
|
if (level.isClientSide)
|
||||||
return;
|
return;
|
||||||
if (!isActiveChunk(level, newPos.chunk()))
|
if (!isActiveChunk(level, newPos.chunk()))
|
||||||
entity.discard();
|
cce.leftTickingChunks = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void validateCarriageEntity(CarriageContraptionEntity entity) {
|
public static void validateCarriageEntity(CarriageContraptionEntity entity) {
|
||||||
|
@ -33,7 +33,7 @@ public class CarriageEntityHandler {
|
||||||
if (level.isClientSide)
|
if (level.isClientSide)
|
||||||
return;
|
return;
|
||||||
if (!isActiveChunk(level, entity.chunkPosition()))
|
if (!isActiveChunk(level, entity.chunkPosition()))
|
||||||
entity.discard();
|
entity.leftTickingChunks = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isActiveChunk(Level level, ChunkPos chunk) {
|
public static boolean isActiveChunk(Level level, ChunkPos chunk) {
|
||||||
|
|
|
@ -155,12 +155,14 @@ public class StationTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
Train imminentTrain = station.getImminentTrain();
|
Train imminentTrain = station.getImminentTrain();
|
||||||
boolean trainPresent = imminentTrain != null && imminentTrain.getCurrentStation() == station;
|
boolean trainPresent = imminentTrain != null && imminentTrain.getCurrentStation() == station;
|
||||||
|
boolean canDisassemble = trainPresent && imminentTrain.canDisassemble();
|
||||||
UUID imminentID = imminentTrain != null ? imminentTrain.id : null;
|
UUID imminentID = imminentTrain != null ? imminentTrain.id : null;
|
||||||
|
|
||||||
if (this.trainPresent != trainPresent || !Objects.equals(imminentID, this.imminentTrain)) {
|
if (this.trainPresent != trainPresent || this.trainCanDisassemble != canDisassemble
|
||||||
|
|| !Objects.equals(imminentID, this.imminentTrain)) {
|
||||||
this.imminentTrain = imminentID;
|
this.imminentTrain = imminentID;
|
||||||
this.trainPresent = trainPresent;
|
this.trainPresent = trainPresent;
|
||||||
this.trainCanDisassemble = trainPresent && imminentTrain.canDisassemble();
|
this.trainCanDisassemble = canDisassemble;
|
||||||
this.trainBackwards = imminentTrain != null && imminentTrain.currentlyBackwards;
|
this.trainBackwards = imminentTrain != null && imminentTrain.currentlyBackwards;
|
||||||
sendData();
|
sendData();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.events;
|
||||||
import com.simibubi.create.AllFluids;
|
import com.simibubi.create.AllFluids;
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsServerHandler;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingPhysics;
|
import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingPhysics;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController;
|
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController;
|
||||||
import com.simibubi.create.content.contraptions.fluids.recipe.FluidTransferRecipes;
|
import com.simibubi.create.content.contraptions.fluids.recipe.FluidTransferRecipes;
|
||||||
|
@ -114,6 +115,7 @@ public class CommonEvents {
|
||||||
CapabilityMinecartController.tick(world);
|
CapabilityMinecartController.tick(world);
|
||||||
CouplingPhysics.tick(world);
|
CouplingPhysics.tick(world);
|
||||||
LinkedControllerServerHandler.tick(world);
|
LinkedControllerServerHandler.tick(world);
|
||||||
|
ControlsServerHandler.tick(world);
|
||||||
Create.RAILWAYS.tick(world);
|
Create.RAILWAYS.tick(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import java.util.UUID;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
import com.mojang.brigadier.builder.ArgumentBuilder;
|
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||||
import com.simibubi.create.CreateClient;
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.content.logistics.trains.GlobalRailwayManager;
|
import com.simibubi.create.content.logistics.trains.GlobalRailwayManager;
|
||||||
import com.simibubi.create.content.logistics.trains.TrackGraph;
|
import com.simibubi.create.content.logistics.trains.TrackGraph;
|
||||||
import com.simibubi.create.content.logistics.trains.entity.Train;
|
import com.simibubi.create.content.logistics.trains.entity.Train;
|
||||||
|
@ -40,7 +40,7 @@ public class DumpRailwaysCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fillReport(ServerLevel level, BiConsumer<String, Integer> chat) {
|
static void fillReport(ServerLevel level, BiConsumer<String, Integer> chat) {
|
||||||
GlobalRailwayManager railways = CreateClient.RAILWAYS;
|
GlobalRailwayManager railways = Create.RAILWAYS;
|
||||||
int white = ChatFormatting.WHITE.getColor();
|
int white = ChatFormatting.WHITE.getColor();
|
||||||
int blue = 0xD3DEDC;
|
int blue = 0xD3DEDC;
|
||||||
int darkBlue = 0x92A9BD;
|
int darkBlue = 0x92A9BD;
|
||||||
|
|
|
@ -12,6 +12,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Con
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryContraptionUpdatePacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryContraptionUpdatePacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsInputPacket;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsStopControllingPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionFluidPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionFluidPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionInteractionPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionInteractionPacket;
|
||||||
|
@ -115,6 +117,7 @@ public enum AllPackets {
|
||||||
CONFIGURE_STATION(StationEditPacket.class, StationEditPacket::new, PLAY_TO_SERVER),
|
CONFIGURE_STATION(StationEditPacket.class, StationEditPacket::new, PLAY_TO_SERVER),
|
||||||
C_CONFIGURE_TRAIN(TrainEditPacket.class, TrainEditPacket::new, PLAY_TO_SERVER),
|
C_CONFIGURE_TRAIN(TrainEditPacket.class, TrainEditPacket::new, PLAY_TO_SERVER),
|
||||||
RELOCATE_TRAIN(TrainRelocationPacket.class, TrainRelocationPacket::new, PLAY_TO_SERVER),
|
RELOCATE_TRAIN(TrainRelocationPacket.class, TrainRelocationPacket::new, PLAY_TO_SERVER),
|
||||||
|
CONTROLS_INPUT(ControlsInputPacket.class, ControlsInputPacket::new, PLAY_TO_SERVER),
|
||||||
|
|
||||||
// Server to Client
|
// Server to Client
|
||||||
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),
|
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),
|
||||||
|
@ -142,6 +145,7 @@ public enum AllPackets {
|
||||||
SYNC_TRAIN(TrainPacket.class, TrainPacket::new, PLAY_TO_CLIENT),
|
SYNC_TRAIN(TrainPacket.class, TrainPacket::new, PLAY_TO_CLIENT),
|
||||||
REMOVE_TE(RemoveTileEntityPacket.class, RemoveTileEntityPacket::new, PLAY_TO_CLIENT),
|
REMOVE_TE(RemoveTileEntityPacket.class, RemoveTileEntityPacket::new, PLAY_TO_CLIENT),
|
||||||
S_CONFIGURE_TRAIN(TrainEditReturnPacket.class, TrainEditReturnPacket::new, PLAY_TO_CLIENT),
|
S_CONFIGURE_TRAIN(TrainEditReturnPacket.class, TrainEditReturnPacket::new, PLAY_TO_CLIENT),
|
||||||
|
CONTROLS_ABORT(ControlsStopControllingPacket.class, ControlsStopControllingPacket::new, PLAY_TO_CLIENT),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue