These are not the chunks you are looking for

- Experimental fix to disappearing entities when contraption seating reaches across chunk boundaries on save
This commit is contained in:
simibubi 2020-07-22 14:12:19 +02:00
parent 7994835cb0
commit 9a04c51418
6 changed files with 83 additions and 84 deletions

View file

@ -26,7 +26,7 @@ public class AllEntityTypes {
public static final RegistryEntry<EntityType<SuperGlueEntity>> SUPER_GLUE =
register("super_glue", SuperGlueEntity::new, EntityClassification.MISC, 10, Integer.MAX_VALUE, false, SuperGlueEntity::build);
public static final RegistryEntry<EntityType<SeatEntity>> SEAT =
register("seat", SeatEntity::new, EntityClassification.MISC, 5, Integer.MAX_VALUE, false, SeatEntity::build);
register("seat", SeatEntity::new, EntityClassification.MISC, 0, Integer.MAX_VALUE, false, SeatEntity::build);
private static <T extends Entity> RegistryEntry<EntityType<T>> register(String name, IFactory<T> factory,
EntityClassification group, int range, int updateFrequency, boolean sendVelocity,

View file

@ -1,36 +0,0 @@
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.minecraftforge.fml.network.NetworkEvent.Context;
public class CancelPlayerFallPacket extends SimplePacketBase {
public CancelPlayerFallPacket() {
}
public CancelPlayerFallPacket(PacketBuffer buffer) {
}
@Override
public void write(PacketBuffer buffer) {
}
@Override
public void handle(Supplier<Context> context) {
context.get().enqueueWork(() -> {
ServerPlayerEntity sender = context.get().getSender();
if (sender == null)
return;
sender.handleFallDamage(sender.fallDistance, 1.0F);
sender.fallDistance = 0;
sender.onGround = true;
});
context.get().setPacketHandled(true);
}
}

View file

@ -61,7 +61,6 @@ import net.minecraftforge.event.TickEvent.WorldTickEvent;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber
@ -118,7 +117,7 @@ public class ContraptionCollider {
if (!data.contains("ContraptionDismountLocation"))
return;
Vec3d position = VecHelper.readNBT(data.getList("ContraptionDismountLocation", NBT.TAG_DOUBLE));
if (entityLiving.getRidingEntity() == null)
if (entityLiving.getRidingEntity() == null)
entityLiving.setPositionAndUpdate(position.x, position.y, position.z);
data.remove("ContraptionDismountLocation");
}
@ -156,7 +155,6 @@ public class ContraptionCollider {
double conRotY = contraptionRotation.y;
double conRotZ = contraptionRotation.z;
Vec3d conMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec());
Vec3d conAngularMotion = contraptionRotation.subtract(contraptionEntity.getPrevRotationVec());
Vec3d contraptionCentreOffset = contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0);
boolean axisAlignedCollision = contraptionRotation.equals(Vec3d.ZERO);
Matrix3d rotation = null;
@ -287,19 +285,8 @@ public class ContraptionCollider {
// entity.handleFallDamage(entity.fallDistance, 1); tunnelling issue
entity.fallDistance = 0;
entity.onGround = true;
if (!serverPlayer) {
Vec3d contactPoint = entityPosition.subtract(contraptionCentreOffset)
.subtract(contraptionPosition);
contactPoint =
VecHelper.rotate(contactPoint, conAngularMotion.x, conAngularMotion.y, conAngularMotion.z);
contactPoint = contactPoint.add(contraptionPosition)
.add(contraptionCentreOffset)
.add(conMotion);
contactPointMotion = contactPoint.subtract(entityPosition);
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity));
}
if (!serverPlayer)
contactPointMotion = contraptionEntity.getContactPointMotion(entityPosition);
}
if (hardCollision) {
@ -379,13 +366,6 @@ public class ContraptionCollider {
return vec3d;
}
@OnlyIn(Dist.CLIENT)
private static void checkForClientPlayerCollision(Entity entity) {
if (entity != Minecraft.getInstance().player)
return;
wasClientPlayerGrounded = true;
}
public static void pushEntityOutOfShape(Entity entity, VoxelShape voxelShape, Vec3d positionOffset,
Vec3d shapeMotion) {
AxisAlignedBB entityBB = entity.getBoundingBox()

View file

@ -171,6 +171,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
new ContraptionSeatMappingPacket(getEntityId(), contraption.seatMapping));
}
@Override
public void remove() {
super.remove();
}
@Override
protected void removePassenger(Entity passenger) {
Vec3d transformedVector = getPassengerPosition(passenger);
@ -219,24 +224,27 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
return false;
// Eject potential existing passenger
Entity toDismount = null;
for (Entry<UUID, Integer> entry : contraption.seatMapping.entrySet()) {
if (entry.getValue() != indexOfSeat)
continue;
for (Entity entity : getPassengers()) {
if (!entry.getKey().equals(entity.getUniqueID()))
if (!entry.getKey()
.equals(entity.getUniqueID()))
continue;
if (entity instanceof PlayerEntity)
return false;
if (!world.isRemote) {
Vec3d transformedVector = getPassengerPosition(entity);
entity.stopRiding();
if (transformedVector != null)
entity.setPositionAndUpdate(transformedVector.x, transformedVector.y, transformedVector.z);
}
toDismount = entity;
}
}
if (toDismount != null && !world.isRemote) {
Vec3d transformedVector = getPassengerPosition(toDismount);
toDismount.stopRiding();
if (transformedVector != null)
toDismount.setPositionAndUpdate(transformedVector.x, transformedVector.y, transformedVector.z);
}
if (world.isRemote)
return true;
addSittingPassenger(player, indexOfSeat);
@ -623,12 +631,32 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
remove();
BlockPos offset = new BlockPos(getAnchorVec().add(.5, .5, .5));
Vec3d rotation = getRotationVec();
setBoundingBox(new AxisAlignedBB(0, 300, 0, 0, 300, 0));
contraption.addBlocksToWorld(world, offset, rotation, getPassengers());
removePassengers();
// preventMovedEntitiesFromGettingStuck();
}
}
@Override
public void onKillCommand() {
removePassengers();
super.onKillCommand();
}
@Override
protected void outOfWorld() {
removePassengers();
super.outOfWorld();
}
@Override
public void onRemovedFromWorld() {
super.onRemovedFromWorld();
if (world != null && world.isRemote)
return;
getPassengers().forEach(Entity::remove);
}
@Override
protected void doWaterSplashEffect() {}
@ -684,6 +712,32 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
}
}
@SuppressWarnings("deprecation")
@Override
public CompoundNBT writeWithoutTypeId(CompoundNBT nbt) {
Vec3d vec = getPositionVec();
List<Entity> passengers = getPassengers();
List<Vec3d> 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
entity.setPos(vec.x, prevVec.y, vec.z);
// Super requires all passengers to not be removed in order to write them to the
// tag
entity.removed = false;
}
CompoundNBT tag = super.writeWithoutTypeId(nbt);
return tag;
}
public Contraption getContraption() {
return contraption;
}
@ -762,6 +816,20 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
return new Vec3d(prevPosX, prevPosY, prevPosZ);
}
public Vec3d getContactPointMotion(Vec3d globalContactPoint) {
Vec3d positionVec = getPositionVec();
Vec3d conMotion = positionVec.subtract(getPrevPositionVec());
Vec3d conAngularMotion = getRotationVec().subtract(getPrevRotationVec());
Vec3d contraptionCentreOffset = stationary ? VecHelper.getCenterOf(BlockPos.ZERO) : Vec3d.ZERO.add(0, 0.5, 0);
Vec3d contactPoint = globalContactPoint.subtract(contraptionCentreOffset)
.subtract(positionVec);
contactPoint = VecHelper.rotate(contactPoint, conAngularMotion.x, conAngularMotion.y, conAngularMotion.z);
contactPoint = contactPoint.add(positionVec)
.add(contraptionCentreOffset)
.add(conMotion);
return contactPoint.subtract(globalContactPoint);
}
public boolean canCollideWith(Entity e) {
if (e instanceof PlayerEntity && e.isSpectator())
return false;

View file

@ -3,11 +3,8 @@ package com.simibubi.create.content.contraptions.components.structureMovement.pi
import java.util.List;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.CancelPlayerFallPacket;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.IControlContraption;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOptionBehaviour;
@ -42,7 +39,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
movementMode = new ScrollOptionBehaviour<>(MovementMode.class, Lang.translate("contraptions.movement_mode"),
this, getMovementModeSlot());
this, getMovementModeSlot());
movementMode.requiresWrench();
movementMode.withCallback(t -> waitingForSpeedChange = false);
behaviours.add(movementMode);
@ -208,15 +205,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
protected abstract Vec3d toPosition(float offset);
protected void visitNewPosition() {
if (!world.isRemote)
return;
if (!ContraptionCollider.wasClientPlayerGrounded)
return;
// Send falldamage-cancel for the colliding player
ContraptionCollider.wasClientPlayerGrounded = false;
AllPackets.channel.sendToServer(new CancelPlayerFallPacket());
}
protected void visitNewPosition() {}
protected void tryDisassemble() {
if (removed) {

View file

@ -5,7 +5,6 @@ import java.util.function.Function;
import java.util.function.Supplier;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.components.structureMovement.CancelPlayerFallPacket;
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;
@ -45,7 +44,6 @@ public enum AllPackets {
CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket::new),
CONFIGURE_FILTERING_AMOUNT(FilteringCountUpdatePacket.class, FilteringCountUpdatePacket::new),
CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new),
CANCEL_FALL(CancelPlayerFallPacket.class, CancelPlayerFallPacket::new),
EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new),
CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new),
PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new),