mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-19 16:32:31 +01:00
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
This commit is contained in:
parent
ce7356798c
commit
b657c6e389
3 changed files with 84 additions and 31 deletions
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package com.simibubi.create.modules.contraptions.receivers;
|
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.KineticBlock;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
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;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.math.BlockPos;
|
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.ISelectionContext;
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||||
|
@ -40,37 +42,51 @@ public class TurntableBlock extends KineticBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLanded(IBlockReader worldIn, Entity e) {
|
public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity e) {
|
||||||
TileEntity te = worldIn.getTileEntity(e.getPosition());
|
TileEntity te = worldIn.getTileEntity(pos);
|
||||||
if (!(te instanceof KineticTileEntity))
|
if (!(te instanceof KineticTileEntity))
|
||||||
return;
|
return;
|
||||||
|
if (!e.onGround)
|
||||||
|
return;
|
||||||
|
if (e.getMotion().y > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
float speed = ((KineticTileEntity) te).getSpeed() / 20;
|
float speed = ((KineticTileEntity) te).getSpeed() / 20;
|
||||||
World world = e.getEntityWorld();
|
World world = e.getEntityWorld();
|
||||||
|
|
||||||
if (speed == 0) {
|
if (speed == 0)
|
||||||
super.onLanded(worldIn, e);
|
|
||||||
return;
|
return;
|
||||||
}
|
if (e.posY < pos.getY() + .5f)
|
||||||
if (world.isRemote) {
|
|
||||||
super.onLanded(worldIn, e);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if ((e instanceof PlayerEntity)) {
|
Vec3d origin = VecHelper.getCenterOf(pos);
|
||||||
super.onLanded(worldIn, e);
|
Vec3d offset = e.getPositionVec().subtract(origin);
|
||||||
|
|
||||||
|
if (!world.isRemote && (e instanceof PlayerEntity))
|
||||||
return;
|
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)) {
|
if ((e instanceof LivingEntity)) {
|
||||||
float offset = e.getRotationYawHead() - speed;
|
float diff = e.getRotationYawHead() - speed;
|
||||||
e.setRenderYawOffset(offset);
|
((LivingEntity) e).setIdleTime(20);
|
||||||
e.setRotationYawHead(offset);
|
e.setRenderYawOffset(diff);
|
||||||
super.onLanded(worldIn, e);
|
e.setRotationYawHead(diff);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
e.rotationYaw -= speed;
|
e.rotationYaw -= speed;
|
||||||
|
|
||||||
super.onLanded(worldIn, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IRotate:
|
// IRotate:
|
||||||
|
|
|
@ -25,6 +25,7 @@ import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.Direction.AxisDirection;
|
import net.minecraft.util.Direction.AxisDirection;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.math.Vec3i;
|
import net.minecraft.util.math.Vec3i;
|
||||||
|
@ -120,14 +121,10 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn
|
||||||
TileEntity te = world.getTileEntity(pos);
|
TileEntity te = world.getTileEntity(pos);
|
||||||
TileEntity tileEntityBelowPassenger = world.getTileEntity(entityIn.getPosition());
|
TileEntity tileEntityBelowPassenger = world.getTileEntity(entityIn.getPosition());
|
||||||
BlockState blockState = info.lastCollidedState;
|
BlockState blockState = info.lastCollidedState;
|
||||||
|
|
||||||
boolean onEndingBelt = blockState.getBlock() instanceof BeltBlock && BeltBlock.isUpperEnd(blockState, speed);
|
|
||||||
Direction movementFacing = Direction.getFacingFromAxisDirection(
|
Direction movementFacing = Direction.getFacingFromAxisDirection(
|
||||||
blockState.get(BlockStateProperties.HORIZONTAL_FACING).getAxis(),
|
blockState.get(BlockStateProperties.HORIZONTAL_FACING).getAxis(),
|
||||||
speed < 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE);
|
speed < 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE);
|
||||||
|
|
||||||
boolean hasBeltAdjacent = onEndingBelt
|
|
||||||
&& AllBlocks.BELT.typeOf(world.getBlockState(pos.offset(movementFacing)));
|
|
||||||
boolean collidedWithBelt = te instanceof BeltTileEntity;
|
boolean collidedWithBelt = te instanceof BeltTileEntity;
|
||||||
boolean betweenBelts = tileEntityBelowPassenger instanceof BeltTileEntity && tileEntityBelowPassenger != te;
|
boolean betweenBelts = tileEntityBelowPassenger instanceof BeltTileEntity && tileEntityBelowPassenger != te;
|
||||||
|
|
||||||
|
@ -143,7 +140,7 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (entityIn instanceof LivingEntity) {
|
if (entityIn instanceof LivingEntity) {
|
||||||
((LivingEntity) entityIn).setIdleTime(20);
|
((LivingEntity) entityIn).setIdleTime(101);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Direction beltFacing = blockState.get(BlockStateProperties.HORIZONTAL_FACING);
|
final Direction beltFacing = blockState.get(BlockStateProperties.HORIZONTAL_FACING);
|
||||||
|
@ -175,7 +172,7 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn
|
||||||
movingDown = movingUp;
|
movingDown = movingUp;
|
||||||
movingUp = b;
|
movingUp = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (movingUp)
|
if (movingUp)
|
||||||
movement = movement.add(0, Math.abs(axis.getCoordinate(movement.x, movement.y, movement.z)), 0);
|
movement = movement.add(0, Math.abs(axis.getCoordinate(movement.x, movement.y, movement.z)), 0);
|
||||||
if (movingDown)
|
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);
|
Vec3d centering = new Vec3d(centeringDirection).scale(diffCenter * Math.min(Math.abs(movementSpeed), .1f) * 4);
|
||||||
movement = movement.add(centering);
|
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;
|
float step = entityIn.stepHeight;
|
||||||
entityIn.stepHeight = 1;
|
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) {
|
if (movingUp) {
|
||||||
float minVelocity = entityIn instanceof ItemEntity ? .09f : .13f;
|
float minVelocity = entityIn instanceof ItemEntity ? .09f : .13f;
|
||||||
float yMovement = (float) (Math.signum(movementSpeed) * Math.max(Math.abs(movement.y), minVelocity));
|
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;
|
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);
|
entityIn.setMotion(movement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue