From b657c6e3897045b10872fead40d0f1072e0170ed Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Mon, 19 Aug 2019 12:32:04 +0200 Subject: [PATCH] Moving Entities is fun - Refined rotation behaviour of turntable - Fixed Belts moving entities incosistenly - Fixed Living entities getting stuck on belt slopes - Improved the applied motion when entities leave fast belts - Entities now try to stay spaced apart on belts --- .../create/foundation/utility/VecHelper.java | 32 +++++++++++++ .../receivers/TurntableBlock.java | 46 +++++++++++++------ .../contraptions/relays/BeltTileEntity.java | 37 ++++++++------- 3 files changed, 84 insertions(+), 31 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/utility/VecHelper.java diff --git a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java new file mode 100644 index 000000000..5bf835917 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java @@ -0,0 +1,32 @@ +package com.simibubi.create.foundation.utility; + +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; + +public class VecHelper { + + public static Vec3d rotate(Vec3d vec, float deg, Axis axis) { + float angle = (float) (deg / 180f * Math.PI); + + double sin = MathHelper.sin(angle); + double cos = MathHelper.cos(angle); + double x = vec.x; + double y = vec.y; + double z = vec.z; + + if (axis == Axis.X) + return new Vec3d(x, y * cos - z * sin, z * cos + y * sin); + if (axis == Axis.Y) + return new Vec3d(x * cos + z * sin, y, z * cos - x * sin); + if (axis == Axis.Z) + return new Vec3d(x * cos - y * sin, y * cos + x * sin, z); + return vec; + } + + public static Vec3d getCenterOf(Vec3i pos) { + return new Vec3d(pos).add(.5f, .5f, .5f); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/TurntableBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/TurntableBlock.java index cca410ba1..cc5c55a17 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/TurntableBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/TurntableBlock.java @@ -1,5 +1,6 @@ package com.simibubi.create.modules.contraptions.receivers; +import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.base.KineticBlock; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; @@ -13,6 +14,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; @@ -40,37 +42,51 @@ public class TurntableBlock extends KineticBlock { } @Override - public void onLanded(IBlockReader worldIn, Entity e) { - TileEntity te = worldIn.getTileEntity(e.getPosition()); + public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity e) { + TileEntity te = worldIn.getTileEntity(pos); if (!(te instanceof KineticTileEntity)) return; + if (!e.onGround) + return; + if (e.getMotion().y > 0) + return; float speed = ((KineticTileEntity) te).getSpeed() / 20; World world = e.getEntityWorld(); - if (speed == 0) { - super.onLanded(worldIn, e); + if (speed == 0) return; - } - if (world.isRemote) { - super.onLanded(worldIn, e); + if (e.posY < pos.getY() + .5f) return; - } - if ((e instanceof PlayerEntity)) { - super.onLanded(worldIn, e); + + Vec3d origin = VecHelper.getCenterOf(pos); + Vec3d offset = e.getPositionVec().subtract(origin); + + if (!world.isRemote && (e instanceof PlayerEntity)) return; + + if (offset.length() > 1/16f) { + offset = VecHelper.rotate(offset, speed / 1f, Axis.Y); + Vec3d movement = origin.add(offset).subtract(e.getPositionVec()); + e.setMotion(e.getMotion().add(movement)); + e.velocityChanged = true; } + + if (world.isRemote) + return; + if ((e instanceof PlayerEntity)) + return; if ((e instanceof LivingEntity)) { - float offset = e.getRotationYawHead() - speed; - e.setRenderYawOffset(offset); - e.setRotationYawHead(offset); - super.onLanded(worldIn, e); + float diff = e.getRotationYawHead() - speed; + ((LivingEntity) e).setIdleTime(20); + e.setRenderYawOffset(diff); + e.setRotationYawHead(diff); return; } + e.rotationYaw -= speed; - super.onLanded(worldIn, e); } // IRotate: diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/BeltTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/BeltTileEntity.java index f8db0f1ce..1d68ff762 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/BeltTileEntity.java @@ -25,6 +25,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; @@ -120,14 +121,10 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn TileEntity te = world.getTileEntity(pos); TileEntity tileEntityBelowPassenger = world.getTileEntity(entityIn.getPosition()); BlockState blockState = info.lastCollidedState; - - boolean onEndingBelt = blockState.getBlock() instanceof BeltBlock && BeltBlock.isUpperEnd(blockState, speed); Direction movementFacing = Direction.getFacingFromAxisDirection( blockState.get(BlockStateProperties.HORIZONTAL_FACING).getAxis(), speed < 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE); - boolean hasBeltAdjacent = onEndingBelt - && AllBlocks.BELT.typeOf(world.getBlockState(pos.offset(movementFacing))); boolean collidedWithBelt = te instanceof BeltTileEntity; boolean betweenBelts = tileEntityBelowPassenger instanceof BeltTileEntity && tileEntityBelowPassenger != te; @@ -143,7 +140,7 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn return; if (entityIn instanceof LivingEntity) { - ((LivingEntity) entityIn).setIdleTime(20); + ((LivingEntity) entityIn).setIdleTime(101); } final Direction beltFacing = blockState.get(BlockStateProperties.HORIZONTAL_FACING); @@ -175,7 +172,7 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn movingDown = movingUp; movingUp = b; } - + if (movingUp) movement = movement.add(0, Math.abs(axis.getCoordinate(movement.x, movement.y, movement.z)), 0); if (movingDown) @@ -184,18 +181,22 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn Vec3d centering = new Vec3d(centeringDirection).scale(diffCenter * Math.min(Math.abs(movementSpeed), .1f) * 4); movement = movement.add(centering); - if (info.ticksSinceLastCollision > 0 && !betweenBelts && onEndingBelt && !hasBeltAdjacent) { - entityIn.setPosition(entityIn.posX, entityIn.posY + movement.y, entityIn.posZ); - float verticalMultiplier = entityIn instanceof ItemEntity ? .25f : 1; - if (movementSpeed > .25f) - movement = movement.add(0, Math.abs(movementSpeed) * verticalMultiplier, 0); - entityIn.setMotion(movement); - return; - } - float step = entityIn.stepHeight; entityIn.stepHeight = 1; + if (Math.abs(movementSpeed) < .5f) { + Vec3d checkDistance = movement.scale(2f).add(movement.normalize().scale(.5)); + AxisAlignedBB bb = entityIn.getBoundingBox(); + AxisAlignedBB checkBB = new AxisAlignedBB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); + if (!world + .getEntitiesWithinAABBExcludingEntity(entityIn, checkBB.offset(checkDistance) + .grow(-Math.abs(checkDistance.x), -Math.abs(checkDistance.y), -Math.abs(checkDistance.z))) + .isEmpty()) { + entityIn.setMotion(0, 0, 0); + return; + } + } + if (movingUp) { float minVelocity = entityIn instanceof ItemEntity ? .09f : .13f; float yMovement = (float) (Math.signum(movementSpeed) * Math.max(Math.abs(movement.y), minVelocity)); @@ -209,7 +210,11 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn } entityIn.stepHeight = step; - if (!betweenBelts && onEndingBelt && !hasBeltAdjacent) { + boolean movedPastEndingSlope = onSlope && AllBlocks.BELT.typeOf(world.getBlockState(entityIn.getPosition())) + || AllBlocks.BELT.typeOf(world.getBlockState(entityIn.getPosition().down())); + + if (movedPastEndingSlope && !movingDown && Math.abs(movementSpeed) > .25f) { + entityIn.setPosition(entityIn.posX, entityIn.posY + movement.y, entityIn.posZ); entityIn.setMotion(movement); } }