diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java index 8e43223a2..095b94753 100644 --- a/src/main/java/com/simibubi/create/AllShapes.java +++ b/src/main/java/com/simibubi/create/AllShapes.java @@ -116,6 +116,7 @@ public class AllShapes { .build(), CRUSHING_WHEEL_COLLISION_SHAPE = cuboid(0, 0, 0, 16, 22, 16), SEAT = cuboid(0, 0, 0, 16, 8, 16), + SEAT_COLLISION = cuboid(0, 0, 0, 16, 6, 16), MECHANICAL_PROCESSOR_SHAPE = shape(VoxelShapes.fullCube()).erase(4, 0, 4, 12, 16, 12) .build(), TURNTABLE_SHAPE = shape(1, 4, 1, 15, 8, 15).add(5, 0, 5, 11, 4, 11) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java index b5df0a8c2..fb4d5c96f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java @@ -72,6 +72,12 @@ public class SeatBlock extends Block implements IPortableBlock { ISelectionContext p_220053_4_) { return AllShapes.SEAT; } + + @Override + public VoxelShape getCollisionShape(BlockState p_220071_1_, IBlockReader p_220071_2_, BlockPos p_220071_3_, + ISelectionContext p_220071_4_) { + return AllShapes.SEAT_COLLISION; + } @Override public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player, diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java index 21d1b545c..e400628cd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java @@ -1,9 +1,84 @@ package com.simibubi.create.content.contraptions.components.actors; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.block.SlabBlock; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.state.properties.SlabType; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; public class SeatMovementBehaviour extends MovementBehaviour { - - + @Override + public void startMoving(MovementContext context) { + super.startMoving(context); + int indexOf = context.contraption.getSeats() + .indexOf(context.localPos); + context.data.putInt("SeatIndex", indexOf); + } + + @Override + public void visitNewPosition(MovementContext context, BlockPos pos) { + super.visitNewPosition(context, pos); + ContraptionEntity contraptionEntity = context.contraption.entity; + if (contraptionEntity == null) + return; + int index = context.data.getInt("SeatIndex"); + if (index == -1) + return; + + Map seatMapping = context.contraption.getSeatMapping(); + BlockState blockState = context.world.getBlockState(pos); + boolean slab = blockState.getBlock() instanceof SlabBlock && blockState.get(SlabBlock.TYPE) == SlabType.BOTTOM; + boolean solid = blockState.isSolid() || slab; + + // Occupied + if (seatMapping.containsValue(index)) { + if (!solid) + return; + Entity toDismount = null; + for (Map.Entry entry : seatMapping.entrySet()) { + if (entry.getValue() != index) + continue; + for (Entity entity : contraptionEntity.getPassengers()) { + if (!entry.getKey() + .equals(entity.getUniqueID())) + continue; + toDismount = entity; + } + } + if (toDismount != null) { + toDismount.stopRiding(); + Vec3d position = VecHelper.getCenterOf(pos) + .add(0, slab ? .5f : 1f, 0); + toDismount.setPositionAndUpdate(position.x, position.y, position.z); + toDismount.getPersistentData() + .remove("ContraptionDismountLocation"); + } + return; + } + + if (solid) + return; + + List entitiesWithinAABB = context.world.getEntitiesWithinAABB(LivingEntity.class, + new AxisAlignedBB(pos).shrink(1 / 16f), e -> !(e instanceof PlayerEntity)); + if (entitiesWithinAABB.isEmpty()) + return; + LivingEntity passenger = entitiesWithinAABB.get(0); + contraptionEntity.addSittingPassenger(passenger, index); + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ClientMotionPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ClientMotionPacket.java new file mode 100644 index 000000000..17261237b --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ClientMotionPacket.java @@ -0,0 +1,55 @@ +package com.simibubi.create.content.contraptions.components.structureMovement; + +import java.util.function.Supplier; + +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class ClientMotionPacket extends SimplePacketBase { + + private Vec3d motion; + private boolean onGround; + + public ClientMotionPacket(Vec3d motion, boolean onGround) { + this.motion = motion; + this.onGround = onGround; + } + + public ClientMotionPacket(PacketBuffer buffer) { + motion = new Vec3d(buffer.readFloat(), buffer.readFloat(), buffer.readFloat()); + onGround = buffer.readBoolean(); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeFloat((float) motion.x); + buffer.writeFloat((float) motion.y); + buffer.writeFloat((float) motion.z); + buffer.writeBoolean(onGround); + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + ServerPlayerEntity sender = context.get() + .getSender(); + if (sender == null) + return; + sender.setMotion(motion); + sender.onGround = onGround; + if (onGround) { + sender.handleFallDamage(sender.fallDistance, 1); + sender.fallDistance = 0; + sender.connection.floatingTickCount = 0; + } + }); + context.get() + .setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 6ad59f9b2..4989e3d36 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -89,6 +89,7 @@ public abstract class Contraption { public CombinedInvWrapper inventory; public List customRenderTEs; public Set> superglue; + public ContraptionEntity entity; public AxisAlignedBB bounds; public boolean stalled; @@ -203,13 +204,14 @@ public abstract class Contraption { } public void mountPassengers(ContraptionEntity contraptionEntity) { + this.entity = contraptionEntity; if (contraptionEntity.world.isRemote) return; - for (BlockPos seatPos : seats) { + for (BlockPos seatPos : getSeats()) { Entity passenger = initialPassengers.get(seatPos); if (passenger == null) continue; - int seatIndex = seats.indexOf(seatPos); + int seatIndex = getSeats().indexOf(seatPos); if (seatIndex == -1) continue; contraptionEntity.addSittingPassenger(passenger, seatIndex); @@ -252,7 +254,7 @@ public abstract class Contraption { // Seats transfer their passenger to the contraption if (state.getBlock() instanceof SeatBlock) { BlockPos local = toLocalPos(pos); - seats.add(local); + getSeats().add(local); List seatsEntities = world.getEntitiesWithinAABB(SeatEntity.class, new AxisAlignedBB(pos)); if (!seatsEntities.isEmpty()) { SeatEntity seat = seatsEntities.get(0); @@ -516,11 +518,12 @@ public abstract class Contraption { if (nbt.contains("BoundsFront")) bounds = NBTHelper.readAABB(nbt.getList("BoundsFront", 5)); - seats.clear(); - NBTHelper.iterateCompoundList(nbt.getList("Seats", NBT.TAG_COMPOUND), c -> seats.add(NBTUtil.readBlockPos(c))); - seatMapping.clear(); + getSeats().clear(); + NBTHelper.iterateCompoundList(nbt.getList("Seats", NBT.TAG_COMPOUND), + c -> getSeats().add(NBTUtil.readBlockPos(c))); + getSeatMapping().clear(); NBTHelper.iterateCompoundList(nbt.getList("Passengers", NBT.TAG_COMPOUND), - c -> seatMapping.put(NBTUtil.readUniqueId(c.getCompound("Id")), c.getInt("Seat"))); + c -> getSeatMapping().put(NBTUtil.readUniqueId(c.getCompound("Id")), c.getInt("Seat"))); stalled = nbt.getBoolean("Stalled"); anchor = NBTUtil.readBlockPos(nbt.getCompound("Anchor")); @@ -568,8 +571,8 @@ public abstract class Contraption { storageNBT.add(c); } - nbt.put("Seats", NBTHelper.writeCompoundList(seats, NBTUtil::writeBlockPos)); - nbt.put("Passengers", NBTHelper.writeCompoundList(seatMapping.entrySet(), e -> { + nbt.put("Seats", NBTHelper.writeCompoundList(getSeats(), NBTUtil::writeBlockPos)); + nbt.put("Passengers", NBTHelper.writeCompoundList(getSeatMapping().entrySet(), e -> { CompoundNBT tag = new CompoundNBT(); tag.put("Id", NBTUtil.writeUniqueId(e.getKey())); tag.putInt("Seat", e.getValue()); @@ -635,10 +638,8 @@ public abstract class Contraption { } } - public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation, List seatedEntities) { + public void addBlocksToWorld(World world, StructureTransform transform) { stop(world); - StructureTransform transform = new StructureTransform(offset, rotation); - for (boolean nonBrittles : Iterate.trueAndFalse) { for (BlockInfo block : blocks.values()) { if (nonBrittles == BlockMovementTraits.isBrittle(block.state)) @@ -718,12 +719,14 @@ public abstract class Contraption { world.addEntity(entity); } } + } + public void addPassengersToWorld(World world, StructureTransform transform, List seatedEntities) { for (Entity seatedEntity : seatedEntities) { - if (seatMapping.isEmpty()) + if (getSeatMapping().isEmpty()) continue; - Integer seatIndex = seatMapping.get(seatedEntity.getUniqueID()); - BlockPos seatPos = seats.get(seatIndex); + Integer seatIndex = getSeatMapping().get(seatedEntity.getUniqueID()); + BlockPos seatPos = getSeats().get(seatIndex); seatPos = transform.apply(seatPos); if (!(world.getBlockState(seatPos) .getBlock() instanceof SeatBlock)) @@ -732,7 +735,6 @@ public abstract class Contraption { continue; SeatBlock.sitDown(world, seatPos, seatedEntity); } - } public void initActors(World world) { @@ -796,14 +798,22 @@ public abstract class Contraption { } public BlockPos getSeat(UUID entityId) { - if (!seatMapping.containsKey(entityId)) + if (!getSeatMapping().containsKey(entityId)) return null; - int seatIndex = seatMapping.get(entityId); - if (seatIndex >= seats.size()) + int seatIndex = getSeatMapping().get(entityId); + if (seatIndex >= getSeats().size()) return null; - return seats.get(seatIndex); + return getSeats().get(seatIndex); } protected abstract AllContraptionTypes getType(); + public Map getSeatMapping() { + return seatMapping; + } + + public List getSeats() { + return seats; + } + } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index d90f71db4..e8369ef14 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -23,6 +23,7 @@ import com.simibubi.create.content.contraptions.components.actors.BlockBreakingM import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold; import com.simibubi.create.foundation.collision.Matrix3d; import com.simibubi.create.foundation.collision.OrientedBB; +import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.VecHelper; @@ -143,6 +144,8 @@ public class ContraptionCollider { AxisAlignedBB bounds = contraptionEntity.getBoundingBox(); Vec3d contraptionPosition = contraptionEntity.getPositionVec(); Vec3d contraptionRotation = contraptionEntity.getRotationVec(); + Vec3d contraptionMotion = contraptionEntity.stationary ? Vec3d.ZERO + : contraptionPosition.subtract(contraptionEntity.getPrevPositionVec()); contraptionEntity.collidingEntities.clear(); if (contraption == null) @@ -154,14 +157,14 @@ public class ContraptionCollider { double conRotX = contraptionRotation.x; double conRotY = contraptionRotation.y; double conRotZ = contraptionRotation.z; - Vec3d conMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec()); Vec3d contraptionCentreOffset = contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0); boolean axisAlignedCollision = contraptionRotation.equals(Vec3d.ZERO); Matrix3d rotation = null; for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, bounds.grow(2) .expand(0, 32, 0), contraptionEntity::canCollideWith)) { - boolean serverPlayer = entity instanceof PlayerEntity && !world.isRemote; + boolean player = entity instanceof PlayerEntity; + boolean serverPlayer = player && !world.isRemote; // Init matrix if (rotation == null) { @@ -199,8 +202,8 @@ public class ContraptionCollider { // Prepare entity bounds OrientedBB obb = new OrientedBB(localBB); obb.setRotation(rotation); - motion = motion.subtract(conMotion); motion = rotation.transform(motion); + motion = motion.subtract(contraptionMotion); // Vec3d visualizerOrigin = new Vec3d(10, 64, 0); // CollisionDebugger.OBB = obb.copy(); @@ -268,7 +271,7 @@ public class ContraptionCollider { rotation.transpose(); motionResponse = rotation.transform(motionResponse) - .add(conMotion); + .add(contraptionMotion); totalResponse = rotation.transform(totalResponse); rotation.transpose(); @@ -282,10 +285,10 @@ public class ContraptionCollider { Vec3d contactPointMotion = Vec3d.ZERO; if (surfaceCollision.isTrue()) { -// entity.handleFallDamage(entity.fallDistance, 1); tunnelling issue entity.fallDistance = 0; entity.onGround = true; - if (!serverPlayer) + contraptionEntity.collidingEntities.add(entity); + if (!serverPlayer) contactPointMotion = contraptionEntity.getContactPointMotion(entityPosition); } @@ -321,6 +324,9 @@ public class ContraptionCollider { entity.setPosition(entityPosition.x + allowedMovement.x, entityPosition.y + allowedMovement.y, entityPosition.z + allowedMovement.z); entity.setMotion(entityMotion); + + if (!serverPlayer && player) + AllPackets.channel.sendToServer(new ClientMotionPacket(entityMotion, true)); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java index bf1748e47..2f468a4e8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java @@ -7,11 +7,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; import java.util.UUID; -import java.util.stream.Stream; import org.apache.commons.lang3.tuple.MutablePair; -import com.google.common.collect.ImmutableSet; import com.simibubi.create.AllEntityTypes; import com.simibubi.create.content.contraptions.components.actors.SeatEntity; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingContraption; @@ -49,15 +47,10 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.DamageSource; import net.minecraft.util.Direction; import net.minecraft.util.Hand; -import net.minecraft.util.ReuseableStream; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -import net.minecraft.util.math.shapes.IBooleanFunction; -import net.minecraft.util.math.shapes.ISelectionContext; -import net.minecraft.util.math.shapes.VoxelShape; -import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraftforge.api.distmarker.Dist; @@ -166,9 +159,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD passenger.startRiding(this, true); if (world.isRemote) return; - contraption.seatMapping.put(passenger.getUniqueID(), seatIndex); + contraption.getSeatMapping() + .put(passenger.getUniqueID(), seatIndex); AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), - new ContraptionSeatMappingPacket(getEntityId(), contraption.seatMapping)); + new ContraptionSeatMappingPacket(getEntityId(), contraption.getSeatMapping())); } @Override @@ -185,9 +179,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD if (transformedVector != null) passenger.getPersistentData() .put("ContraptionDismountLocation", VecHelper.writeNBT(transformedVector)); - contraption.seatMapping.remove(passenger.getUniqueID()); + contraption.getSeatMapping() + .remove(passenger.getUniqueID()); AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), - new ContraptionSeatMappingPacket(getEntityId(), contraption.seatMapping)); + new ContraptionSeatMappingPacket(getEntityId(), contraption.getSeatMapping())); } @Override @@ -199,7 +194,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return; callback.accept(passenger, transformedVector.x, transformedVector.y, transformedVector.z); } - + protected Vec3d getPassengerPosition(Entity passenger) { AxisAlignedBB bb = passenger.getBoundingBox(); double ySize = bb.getYSize(); @@ -214,18 +209,21 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @Override protected boolean canFitPassenger(Entity p_184219_1_) { - return getPassengers().size() < contraption.seats.size(); + return getPassengers().size() < contraption.getSeats() + .size(); } public boolean handlePlayerInteraction(PlayerEntity player, BlockPos localPos, Direction side, Hand interactionHand) { - int indexOfSeat = contraption.seats.indexOf(localPos); + int indexOfSeat = contraption.getSeats() + .indexOf(localPos); if (indexOfSeat == -1) return false; // Eject potential existing passenger Entity toDismount = null; - for (Entry entry : contraption.seatMapping.entrySet()) { + for (Entry entry : contraption.getSeatMapping() + .entrySet()) { if (entry.getValue() != indexOfSeat) continue; for (Entity entity : getPassengers()) { @@ -631,9 +629,20 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD remove(); BlockPos offset = new BlockPos(getAnchorVec().add(.5, .5, .5)); Vec3d rotation = getRotationVec(); - contraption.addBlocksToWorld(world, offset, rotation, getPassengers()); + StructureTransform transform = new StructureTransform(offset, rotation); + contraption.addBlocksToWorld(world, transform); + contraption.addPassengersToWorld(world, transform, getPassengers()); removePassengers(); -// preventMovedEntitiesFromGettingStuck(); + + for (Entity entity : collidingEntities) { + Vec3d positionVec = getPositionVec(); + Vec3d localVec = entity.getPositionVec() + .subtract(positionVec); + localVec = VecHelper.rotate(localVec, getRotationVec().scale(-1)); + Vec3d transformed = transform.apply(localVec); + entity.setPositionAndUpdate(transformed.x, transformed.y, transformed.z); + } + } } @@ -660,73 +669,18 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @Override protected void doWaterSplashEffect() {} - public void preventMovedEntitiesFromGettingStuck() { - Vec3d stuckTest = new Vec3d(0, -2, 0); - for (Entity e : collidingEntities) { - e.fallDistance = 0; - e.onGround = true; - - Vec3d vec = stuckTest; - AxisAlignedBB axisalignedbb = e.getBoundingBox() - .offset(0, 2, 0); - ISelectionContext iselectioncontext = ISelectionContext.forEntity(this); - VoxelShape voxelshape = e.world.getWorldBorder() - .getShape(); - Stream stream = - VoxelShapes.compare(voxelshape, VoxelShapes.create(axisalignedbb.shrink(1.0E-7D)), IBooleanFunction.AND) - ? Stream.empty() - : Stream.of(voxelshape); - Stream stream1 = - this.world.getEmptyCollisionShapes(e, axisalignedbb.expand(vec), ImmutableSet.of()); - ReuseableStream reuseablestream = new ReuseableStream<>(Stream.concat(stream1, stream)); - Vec3d vec3d = vec.lengthSquared() == 0.0D ? vec - : collideBoundingBoxHeuristically(this, vec, axisalignedbb, e.world, iselectioncontext, - reuseablestream); - boolean flag = vec.x != vec3d.x; - boolean flag1 = vec.y != vec3d.y; - boolean flag2 = vec.z != vec3d.z; - boolean flag3 = e.onGround || flag1 && vec.y < 0.0D; - if (this.stepHeight > 0.0F && flag3 && (flag || flag2)) { - Vec3d vec3d1 = collideBoundingBoxHeuristically(e, new Vec3d(vec.x, (double) e.stepHeight, vec.z), - axisalignedbb, e.world, iselectioncontext, reuseablestream); - Vec3d vec3d2 = collideBoundingBoxHeuristically(e, new Vec3d(0.0D, (double) e.stepHeight, 0.0D), - axisalignedbb.expand(vec.x, 0.0D, vec.z), e.world, iselectioncontext, reuseablestream); - if (vec3d2.y < (double) e.stepHeight) { - Vec3d vec3d3 = collideBoundingBoxHeuristically(e, new Vec3d(vec.x, 0.0D, vec.z), - axisalignedbb.offset(vec3d2), e.world, iselectioncontext, reuseablestream).add(vec3d2); - if (horizontalMag(vec3d3) > horizontalMag(vec3d1)) { - vec3d1 = vec3d3; - } - } - - if (horizontalMag(vec3d1) > horizontalMag(vec3d)) { - vec3d = vec3d1.add(collideBoundingBoxHeuristically(e, new Vec3d(0.0D, -vec3d1.y + vec.y, 0.0D), - axisalignedbb.offset(vec3d1), e.world, iselectioncontext, reuseablestream)); - } - } - - vec = vec3d.subtract(stuckTest); - if (vec.equals(Vec3d.ZERO)) - continue; - e.setPosition(e.getX() + vec.x, e.getY() + vec.y, e.getZ() + vec.z); - } - } - @SuppressWarnings("deprecation") @Override public CompoundNBT writeWithoutTypeId(CompoundNBT nbt) { Vec3d vec = getPositionVec(); List passengers = getPassengers(); - List positionVecs = new ArrayList<>(passengers.size()); for (Entity entity : passengers) { - Vec3d prevVec = entity.getPositionVec(); - positionVecs.add(prevVec); - // setPos has world accessing side-effects when removed == false entity.removed = true; // Gather passengers into same chunk when saving + Vec3d prevVec = entity.getPositionVec(); entity.setPos(vec.x, prevVec.y, vec.z); // Super requires all passengers to not be removed in order to write them to the diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java index 8b1ad911f..c3228b4c5 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java @@ -4,6 +4,7 @@ import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; @@ -17,6 +18,7 @@ public class MovementContext { public Vec3d rotation; public World world; public BlockState state; + public BlockPos localPos; public CompoundNBT tileData; public boolean stall; @@ -29,7 +31,8 @@ public class MovementContext { this.world = world; this.state = info.state; this.tileData = info.nbt; - + localPos = info.pos; + firstMovement = true; motion = Vec3d.ZERO; relativeMotion = Vec3d.ZERO; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java index a152542f7..ded55dfad 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java @@ -69,6 +69,13 @@ public class StructureTransform { } + public Vec3d apply(Vec3d localVec) { + Vec3d vec = localVec; + vec = VecHelper.rotateCentered(vec, angle, rotationAxis); + vec = vec.add(new Vec3d(offset)); + return vec; + } + public BlockPos apply(BlockPos localPos) { Vec3d vec = VecHelper.getCenterOf(localPos); vec = VecHelper.rotateCentered(vec, angle, rotationAxis); 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 0f7c095af..bd2e888da 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -5,6 +5,7 @@ import java.util.function.Function; import java.util.function.Supplier; import com.simibubi.create.Create; +import com.simibubi.create.content.contraptions.components.structureMovement.ClientMotionPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionInteractionPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionSeatMappingPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket; @@ -46,6 +47,7 @@ public enum AllPackets { CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new), EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new), CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new), + CLIENT_MOTION(ClientMotionPacket.class, ClientMotionPacket::new), PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new), // Server to Client