Minecart Issues

- Fixed displaced coords between contraptions and their mounts, should fix cart structures from disappearing when loaded near chunk borders
- Contraptions no longer render with default yaw if their mount is out of render distance
- Fixed ploughs and other actors not activating properly when other actors had just stalled the contraption
- Fixed ploughs leaving behind breaking overlays when stopped/disassembled
- Fixed ploughs, drills and saws throwing entities back by unreasonable distances
- Drills now break columns of falling blocks from top to bottom while moved
This commit is contained in:
simibubi 2020-05-01 15:21:00 +02:00
parent 75638b7c8d
commit 8bfc4445b0
4 changed files with 46 additions and 35 deletions

View file

@ -1,12 +1,14 @@
package com.simibubi.create.modules.contraptions.components.actors; package com.simibubi.create.modules.contraptions.components.actors;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.Debug;
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour; import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour;
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.FallingBlock; import net.minecraft.block.FallingBlock;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity; import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
@ -64,7 +66,12 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
if (damageSource != null && !world.isRemote) if (damageSource != null && !world.isRemote)
entity.attackEntityFrom(damageSource, damage); entity.attackEntityFrom(damageSource, damage);
if (throwsEntities() && (world.isRemote == (entity instanceof PlayerEntity))) { if (throwsEntities() && (world.isRemote == (entity instanceof PlayerEntity))) {
entity.setMotion(entity.getMotion().add(context.motion.add(0, context.motion.length() / 4f, 0))); Vec3d motionBoost = context.motion.add(0, context.motion.length() / 4f, 0);
int maxBoost = 4;
if (motionBoost.length() > maxBoost) {
motionBoost = motionBoost.subtract(motionBoost.normalize().scale(motionBoost.length() - maxBoost));
}
entity.setMotion(entity.getMotion().add(motionBoost));
entity.velocityChanged = true; entity.velocityChanged = true;
} }
} }
@ -160,11 +167,21 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
destroyProgress += MathHelper.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress); destroyProgress += MathHelper.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress);
if (destroyProgress >= 10) { if (destroyProgress >= 10) {
BlockHelper.destroyBlock(context.world, breakingPos, 1f, stack -> this.dropItem(context, stack));
context.stall = false;
onBlockBroken(context, breakingPos, stateToBreak);
ticksUntilNextProgress = -1;
world.sendBlockBreakProgress(id, breakingPos, -1); world.sendBlockBreakProgress(id, breakingPos, -1);
// break falling blocks from top to bottom
BlockPos ogPos = breakingPos;
BlockState stateAbove = world.getBlockState(breakingPos.up());
while (stateAbove.getBlock() instanceof FallingBlock) {
breakingPos = breakingPos.up();
stateAbove = world.getBlockState(breakingPos.up());
}
stateToBreak = world.getBlockState(breakingPos);
context.stall = false;
BlockHelper.destroyBlock(context.world, breakingPos, 1f, stack -> this.dropItem(context, stack));
onBlockBroken(context, ogPos, stateToBreak);
ticksUntilNextProgress = -1;
data.remove("Progress"); data.remove("Progress");
data.remove("TicksUntilNextProgress"); data.remove("TicksUntilNextProgress");
data.remove("BreakingPos"); data.remove("BreakingPos");
@ -183,8 +200,8 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
} }
protected void onBlockBroken(MovementContext context, BlockPos pos, BlockState brokenState) { protected void onBlockBroken(MovementContext context, BlockPos pos, BlockState brokenState) {
BlockState above = context.world.getBlockState(pos.up()); // Check for falling blocks
if (!(above.getBlock() instanceof FallingBlock)) if (!(brokenState.getBlock() instanceof FallingBlock))
return; return;
CompoundNBT data = context.data; CompoundNBT data = context.data;

View file

@ -32,7 +32,6 @@ public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour {
@Override @Override
public void visitNewPosition(MovementContext context, BlockPos pos) { public void visitNewPosition(MovementContext context, BlockPos pos) {
super.visitNewPosition(context, pos); super.visitNewPosition(context, pos);
World world = context.world; World world = context.world;
if (world.isRemote) if (world.isRemote)
return; return;
@ -72,6 +71,7 @@ public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour {
@Override @Override
public void stopMoving(MovementContext context) { public void stopMoving(MovementContext context) {
super.stopMoving(context);
if (context.temporaryData instanceof PloughFakePlayer) if (context.temporaryData instanceof PloughFakePlayer)
((PloughFakePlayer) context.temporaryData).remove(); ((PloughFakePlayer) context.temporaryData).remove();
} }

View file

@ -26,7 +26,6 @@ import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.BoatEntity; import net.minecraft.entity.item.BoatEntity;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.entity.item.minecart.FurnaceMinecartEntity; import net.minecraft.entity.item.minecart.FurnaceMinecartEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
@ -54,7 +53,6 @@ import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraft.world.gen.feature.template.Template.BlockInfo;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
@ -104,8 +102,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
contraption.gatherStoredItems(); contraption.gatherStoredItems();
return entity; return entity;
} }
public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle, Direction facing) { public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle,
Direction facing) {
ContraptionEntity entity = createMounted(world, contraption, initialAngle); ContraptionEntity entity = createMounted(world, contraption, initialAngle);
entity.forcedAngle = facing.getHorizontalAngle(); entity.forcedAngle = facing.getHorizontalAngle();
entity.forceYaw(entity.forcedAngle); entity.forceYaw(entity.forcedAngle);
@ -279,12 +278,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
Vec3d actorPosition = new Vec3d(blockInfo.pos); Vec3d actorPosition = new Vec3d(blockInfo.pos);
actorPosition = actorPosition.add(actor.getActiveAreaOffset(context)); actorPosition = actorPosition.add(actor.getActiveAreaOffset(context));
actorPosition = VecHelper.rotate(actorPosition, angleRoll, angleYaw, anglePitch); actorPosition = VecHelper.rotate(actorPosition, angleRoll, angleYaw, anglePitch);
actorPosition = actorPosition.add(rotationOffset).add(posX, posY, posZ); actorPosition = actorPosition.add(rotationOffset).add(getAnchorVec());
boolean newPosVisited = false; boolean newPosVisited = false;
BlockPos gridPosition = new BlockPos(actorPosition); BlockPos gridPosition = new BlockPos(actorPosition);
if (!stalledPreviously) { if (!context.stall) {
Vec3d previousPosition = context.position; Vec3d previousPosition = context.position;
if (previousPosition != null) { if (previousPosition != null) {
context.motion = actorPosition.subtract(previousPosition); context.motion = actorPosition.subtract(previousPosition);
@ -314,13 +313,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
} }
} }
} }
} }
} }
context.rotation = rotationVec; context.rotation = rotationVec;
context.position = actorPosition; context.position = actorPosition;
if (actor.isActive(context)) { if (actor.isActive(context)) {
if (newPosVisited && !context.stall) { if (newPosVisited && !context.stall) {
actor.visitNewPosition(context, gridPosition); actor.visitNewPosition(context, gridPosition);
@ -349,6 +346,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
setPosition(posX + x, posY + y, posZ + z); setPosition(posX + x, posY + y, posZ + z);
} }
private Vec3d getAnchorVec() {
if (contraption != null && contraption.getType() == AllContraptionTypes.MOUNTED)
return new Vec3d(posX - .5, posY, posZ - .5);
return getPositionVec();
}
public void rotateTo(double roll, double yaw, double pitch) { public void rotateTo(double roll, double yaw, double pitch) {
rotate(getShortestAngleDiff(this.roll, roll), getShortestAngleDiff(this.yaw, yaw), rotate(getShortestAngleDiff(this.roll, roll), getShortestAngleDiff(this.yaw, yaw),
getShortestAngleDiff(this.pitch, pitch)); getShortestAngleDiff(this.pitch, pitch));
@ -367,25 +370,13 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
@Override @Override
public void setPosition(double x, double y, double z) { public void setPosition(double x, double y, double z) {
Entity e = getRidingEntity(); super.setPosition(x, y, z);
if (e != null && e instanceof AbstractMinecartEntity) {
Entity riding = e;
while (riding.getRidingEntity() != null)
riding = riding.getRidingEntity();
x = riding.posX - .5;
z = riding.posZ - .5;
}
this.posX = x;
this.posY = y;
this.posZ = z;
if (this.isAddedToWorld() && !this.world.isRemote && world instanceof ServerWorld)
((ServerWorld) this.world).chunkCheck(this); // Forge - Process chunk registration after moving.
if (contraption != null) { if (contraption != null) {
AxisAlignedBB cbox = contraption.getBoundingBox(); AxisAlignedBB cbox = contraption.getBoundingBox();
if (cbox != null) if (cbox != null) {
this.setBoundingBox(cbox.offset(x, y, z)); Vec3d actualVec = getAnchorVec();
this.setBoundingBox(cbox.offset(actualVec));
}
} }
} }
@ -478,7 +469,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
compound.put("Controller", NBTUtil.writeBlockPos(controllerPos)); compound.put("Controller", NBTUtil.writeBlockPos(controllerPos));
if (forcedAngle != -1) if (forcedAngle != -1)
compound.putFloat("ForcedYaw", forcedAngle); compound.putFloat("ForcedYaw", forcedAngle);
compound.putFloat("InitialAngle", initialAngle); compound.putFloat("InitialAngle", initialAngle);
compound.putBoolean("Stalled", isStalled()); compound.putBoolean("Stalled", isStalled());
} }
@ -502,7 +493,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
public void disassemble() { public void disassemble() {
if (getContraption() != null) { if (getContraption() != null) {
BlockPos offset = new BlockPos(getPositionVec().add(.5, .5, .5)); BlockPos offset = new BlockPos(getAnchorVec().add(.5, .5, .5));
Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1)); Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1));
getContraption().addBlocksToWorld(world, offset, rotation); getContraption().addBlocksToWorld(world, offset, rotation);
preventMovedEntitiesFromGettingStuck(); preventMovedEntitiesFromGettingStuck();

View file

@ -34,6 +34,8 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
return; return;
if (entity.getContraption() == null) if (entity.getContraption() == null)
return; return;
if (entity.getContraption().getType() == AllContraptionTypes.MOUNTED && entity.getRidingEntity() == null)
return;
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
long randomBits = (long) entity.getEntityId() * 493286711L; long randomBits = (long) entity.getEntityId() * 493286711L;
@ -74,6 +76,7 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
GlStateManager.translatef((float) cartX, (float) cartY, (float) cartZ); GlStateManager.translatef((float) cartX, (float) cartY, (float) cartZ);
} }
GlStateManager.translatef(-.5f, 0, -.5f);
} }
Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO); Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO);