Contraption Bug-Fixes

- Fixed the generated rendering bounding box of rotating contraptions
- Fixed clockwork bearings moving their hands inconsistently in some cases
- Pistons, Pulleys and Bearings can now be kick-started with a right click
- Contacts no longer apply a pulse to the contact they were powering before movement
- Fixed deployers animating strangely when the contaption is stalled
- Fixed minecart contraptions not having the same orientation on server and client
- Fixed minecart contraptions not reacting to movement when the minecart is itself mounting another entity
- Fixed minecart contraptions not remembering their motion when unloaded while stalling
- Fixed minecart contraptions not being initialized with the correct angles
This commit is contained in:
simibubi 2020-03-07 19:08:16 +01:00
parent ea5c77b2b2
commit bea5d783ce
17 changed files with 243 additions and 79 deletions

View file

@ -19,6 +19,7 @@ import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
@ -34,6 +35,8 @@ import net.minecraft.nbt.NBTUtil;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
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;
@ -50,7 +53,7 @@ public abstract class Contraption {
public List<MutablePair<BlockInfo, MovementContext>> actors;
public CombinedInvWrapper inventory;
public AxisAlignedBB constructCollisionBox;
public AxisAlignedBB bounds;
public boolean stalled;
protected Set<BlockPos> cachedColliders;
@ -95,8 +98,8 @@ public abstract class Contraption {
Set<BlockPos> visited = new HashSet<>();
anchor = pos;
if (constructCollisionBox == null)
constructCollisionBox = new AxisAlignedBB(BlockPos.ZERO);
if (bounds == null)
bounds = new AxisAlignedBB(BlockPos.ZERO);
frontier.add(pos);
if (!addToInitialFrontier(world, pos, forcedDirection, frontier))
@ -203,7 +206,7 @@ public abstract class Contraption {
if (blocks.put(localPos, blockInfo) != null)
return;
constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(localPos));
bounds = bounds.union(new AxisAlignedBB(localPos));
TileEntity te = pair.getValue();
if (te != null && MountedStorage.canUseAsStorage(te))
@ -257,7 +260,7 @@ public abstract class Contraption {
inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class));
if (nbt.contains("BoundsFront"))
constructCollisionBox = NBTHelper.readAABB(nbt.getList("BoundsFront", 5));
bounds = NBTHelper.readAABB(nbt.getList("BoundsFront", 5));
stalled = nbt.getBoolean("Stalled");
anchor = NBTUtil.readBlockPos(nbt.getCompound("Anchor"));
@ -302,8 +305,8 @@ public abstract class Contraption {
nbt.put("Anchor", NBTUtil.writeBlockPos(anchor));
nbt.putBoolean("Stalled", stalled);
if (constructCollisionBox != null) {
ListNBT bb = NBTHelper.writeAABB(constructCollisionBox);
if (bounds != null) {
ListNBT bb = NBTHelper.writeAABB(bounds);
nbt.put("BoundsFront", bb);
}
@ -387,8 +390,8 @@ public abstract class Contraption {
}
}
public AxisAlignedBB getCollisionBox() {
return constructCollisionBox;
public AxisAlignedBB getBoundingBox() {
return bounds;
}
public List<MutablePair<BlockInfo, MovementContext>> getActors() {
@ -421,6 +424,27 @@ public abstract class Contraption {
return ((IPortableBlock) block).getMovementBehaviour();
}
public void expandBoundsAroundAxis(Axis axis) {
AxisAlignedBB bb = bounds;
double maxXDiff = Math.max(bb.maxX - 1, -bb.minX);
double maxYDiff = Math.max(bb.maxY - 1, -bb.minY);
double maxZDiff = Math.max(bb.maxZ - 1, -bb.minZ);
double maxDiff = 0;
if (axis == Axis.X)
maxDiff = Math.max(maxZDiff, maxYDiff);
if (axis == Axis.Y)
maxDiff = Math.max(maxZDiff, maxXDiff);
if (axis == Axis.Z)
maxDiff = Math.max(maxXDiff, maxYDiff);
Vec3d vec = new Vec3d(Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis).getDirectionVec());
Vec3d planeByNormal = VecHelper.planeByNormal(vec);
Vec3d min = vec.mul(bb.minX, bb.minY, bb.minZ).add(planeByNormal.scale(-maxDiff));
Vec3d max = vec.mul(bb.maxX, bb.maxY, bb.maxZ).add(planeByNormal.scale(maxDiff + 1));
bounds = new AxisAlignedBB(min, max);
}
protected abstract AllContraptionTypes getType();
}

View file

@ -12,6 +12,7 @@ import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.BoatEntity;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
@ -43,8 +44,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
protected Vec3d motionBeforeStall;
protected boolean stationary;
private static final DataParameter<Boolean> STALLED = EntityDataManager.createKey(ContraptionEntity.class,
DataSerializers.BOOLEAN);
private static final DataParameter<Boolean> STALLED =
EntityDataManager.createKey(ContraptionEntity.class, DataSerializers.BOOLEAN);
public float prevYaw;
public float prevPitch;
@ -101,39 +102,41 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
Entity e = getRidingEntity();
if (e != null) {
Vec3d movementVector = e.getMotion();
Entity riding = e;
while (riding.getRidingEntity() != null)
riding = riding.getRidingEntity();
Vec3d movementVector = riding.getMotion();
if (riding instanceof BoatEntity)
movementVector = new Vec3d(posX - prevPosX, posY - prevPosY, posZ - prevPosZ);
Vec3d motion = movementVector.normalize();
if (motion.length() > 0) {
targetYaw = yawFromVector(motion);
targetPitch = (float) ((Math.atan(motion.y) * 73.0D) / Math.PI * 180);
if (targetYaw < 0)
targetYaw += 360;
if (yaw < 0)
yaw += 360;
}
if (Math.abs(getShortestAngleDiff(yaw, targetYaw)) >= 175) {
initialAngle += 180;
yaw += 180;
prevYaw = yaw;
} else {
float speed = 0.2f;
prevYaw = yaw;
yaw = angleLerp(speed, yaw, targetYaw);
prevPitch = pitch;
pitch = angleLerp(speed, pitch, targetPitch);
}
// if (Math.abs(getShortestAngleDiff(yaw, targetYaw)) >= 175) {
// initialAngle += 180;
// yaw += 180;
// prevYaw = yaw;
// } else {
float speed = 0.2f;
prevYaw = yaw;
yaw = angleLerp(speed, yaw, targetYaw);
// }
boolean wasStalled = isStalled();
tickActors(movementVector);
if (isStalled()) {
if (!wasStalled)
motionBeforeStall = e.getMotion();
e.setMotion(0, 0, 0);
motionBeforeStall = riding.getMotion();
riding.setMotion(0, 0, 0);
}
if (wasStalled && !isStalled()) {
e.setMotion(motionBeforeStall);
riding.setMotion(motionBeforeStall);
motionBeforeStall = Vec3d.ZERO;
}
@ -249,8 +252,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
public void setPosition(double x, double y, double z) {
Entity e = getRidingEntity();
if (e != null && e instanceof AbstractMinecartEntity) {
x -= .5;
z -= .5;
Entity riding = e;
while (riding.getRidingEntity() != null)
riding = riding.getRidingEntity();
x = riding.posX - .5;
z = riding.posZ - .5;
}
this.posX = x;
@ -260,7 +266,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
if (this.isAddedToWorld() && !this.world.isRemote && world instanceof ServerWorld)
((ServerWorld) this.world).chunkCheck(this); // Forge - Process chunk registration after moving.
if (contraption != null) {
AxisAlignedBB cbox = contraption.getCollisionBox();
AxisAlignedBB cbox = contraption.getBoundingBox();
if (cbox != null)
this.setBoundingBox(cbox.offset(x, y, z));
}
@ -268,9 +274,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
@Override
public void stopRiding() {
super.stopRiding();
if (!world.isRemote)
disassemble();
super.stopRiding();
}
public static float yawFromVector(Vec3d vec) {
@ -309,14 +315,17 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
protected void readAdditional(CompoundNBT compound) {
contraption = Contraption.fromNBT(world, compound.getCompound("Contraption"));
initialAngle = compound.getFloat("InitialAngle");
targetYaw = yaw = prevYaw = initialAngle;
dataManager.set(STALLED, compound.getBoolean("Stalled"));
ListNBT vecNBT = compound.getList("CachedMotion", 6);
if (!vecNBT.isEmpty())
if (!vecNBT.isEmpty()) {
motionBeforeStall = new Vec3d(vecNBT.getDouble(0), vecNBT.getDouble(1), vecNBT.getDouble(2));
if (!motionBeforeStall.equals(Vec3d.ZERO))
targetYaw = prevYaw = yaw += yawFromVector(motionBeforeStall);
setMotion(Vec3d.ZERO);
}
if (compound.contains("Controller"))
controllerPos = NBTUtil.readBlockPos(compound.getCompound("Controller"));
prevYaw = initialAngle;
yaw = initialAngle;
targetYaw = initialAngle;
}
public void attachToController() {
@ -341,7 +350,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
protected void writeAdditional(CompoundNBT compound) {
compound.put("Contraption", getContraption().writeNBT());
compound.putFloat("InitialAngle", initialAngle);
compound.put("CachedMotion", newDoubleNBTList(motionBeforeStall.x, motionBeforeStall.y, motionBeforeStall.z));
if (!stationary)
compound.put("CachedMotion",
newDoubleNBTList(motionBeforeStall.x, motionBeforeStall.y, motionBeforeStall.z));
compound.putBoolean("Stalled", isStalled());
if (controllerPos != null)
compound.put("Controller", NBTUtil.writeBlockPos(controllerPos));
}
@ -364,9 +376,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
}
public void disassemble() {
if (getContraption() != null)
if (getContraption() != null) {
float yaw = getYaw(1);
getContraption().disassemble(world, new BlockPos(getPositionVec().add(.5, .5, .5)),
new Vec3d(getRoll(1), getYaw(1), getPitch(1)));
new Vec3d(getRoll(1), yaw, getPitch(1)));
}
remove();
}

View file

@ -28,9 +28,11 @@ public class BearingContraption extends Contraption {
return null;
BearingContraption construct = new BearingContraption();
construct.facing = direction;
if (!construct.searchMovedStructure(world, pos.offset(direction), null))
BlockPos offset = pos.offset(direction);
if (!construct.searchMovedStructure(world, offset, null))
return null;
construct.initActors(world);
construct.expandBoundsAroundAxis(direction.getAxis());
return construct;
}

View file

@ -1,14 +1,43 @@
package com.simibubi.create.modules.contraptions.components.contraptions.bearing;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockReader;
import com.simibubi.create.foundation.block.IWithTileEntity;
public class ClockworkBearingBlock extends BearingBlock {
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
public class ClockworkBearingBlock extends BearingBlock implements IWithTileEntity<ClockworkBearingTileEntity> {
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new ClockworkBearingTileEntity();
}
@Override
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) {
if (!player.isAllowEdit())
return false;
if (player.isSneaking())
return false;
if (player.getHeldItem(handIn).isEmpty()) {
if (!worldIn.isRemote) {
withTileEntityDo(worldIn, pos, te -> {
if (te.running) {
te.disassembleConstruct();
return;
}
te.assembleNextTick = true;
});
}
return true;
}
return false;
}
}

View file

@ -104,31 +104,41 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
}
public float getHourArmSpeed() {
float speed = getAngularSpeed() / 2f + clientHourAngleDiff / 3f;
float speed = getAngularSpeed() / 2f;
if (speed != 0) {
int dayTime = (int) (world.getDayTime() % 24000);
int hours = (dayTime / 1000 + 6) % 24;
int offset = getBlockState().get(ClockworkBearingBlock.FACING).getAxisDirection().getOffset();
float hourTarget = (float) (offset * -360 / 12f * (hours % 12));
speed = Math.max(speed, AngleHelper.getShortestAngleDiff(hourAngle, hourTarget));
float shortestAngleDiff = AngleHelper.getShortestAngleDiff(hourAngle, hourTarget);
if (shortestAngleDiff < 0) {
speed = Math.max(speed, shortestAngleDiff);
} else {
speed = Math.min(-speed, shortestAngleDiff);
}
}
return speed;
return speed + clientHourAngleDiff / 3f;
}
public float getMinuteArmSpeed() {
float speed = getAngularSpeed() + clientMinuteAngleDiff / 3f;
float speed = getAngularSpeed();
if (speed != 0) {
int dayTime = (int) (world.getDayTime() % 24000);
int minutes = (dayTime % 1000) * 60 / 1000;
int offset = getBlockState().get(ClockworkBearingBlock.FACING).getAxisDirection().getOffset();
float hourTarget = (float) (offset * -360 / 60f * (minutes));
speed = Math.max(speed, AngleHelper.getShortestAngleDiff(minuteAngle, hourTarget));
float minuteTarget = (float) (offset * -360 / 60f * (minutes));
float shortestAngleDiff = AngleHelper.getShortestAngleDiff(minuteAngle, minuteTarget);
if (shortestAngleDiff < 0) {
speed = Math.max(speed, shortestAngleDiff);
} else {
speed = Math.min(-speed, shortestAngleDiff);
}
}
return speed;
return speed + clientMinuteAngleDiff / 3f;
}
public float getAngularSpeed() {
@ -175,16 +185,20 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
public void disassembleConstruct() {
if (!running)
return;
if (hourHand != null)
hourAngle = 0;
minuteAngle = 0;
applyRotations();
if (hourHand != null) {
hourHand.disassemble();
}
if (minuteHand != null)
minuteHand.disassemble();
hourHand = null;
minuteHand = null;
running = false;
hourAngle = 0;
minuteAngle = 0;
sendData();
}

View file

@ -67,8 +67,11 @@ public class ClockworkContraption extends Contraption {
}
hourArm.initActors(world);
if (minuteArm != null)
hourArm.expandBoundsAroundAxis(direction.getAxis());
if (minuteArm != null) {
minuteArm.initActors(world);
minuteArm.expandBoundsAroundAxis(direction.getAxis());
}
return Pair.of(hourArm, minuteArm);
}

View file

@ -4,8 +4,11 @@ import com.simibubi.create.foundation.block.IWithTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
@ -16,6 +19,28 @@ public class MechanicalBearingBlock extends BearingBlock implements IWithTileEnt
return new MechanicalBearingTileEntity();
}
@Override
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) {
if (!player.isAllowEdit())
return false;
if (player.isSneaking())
return false;
if (player.getHeldItem(handIn).isEmpty()) {
if (!worldIn.isRemote) {
withTileEntityDo(worldIn, pos, te -> {
if (te.running) {
te.disassembleConstruct();
return;
}
te.assembleNextTick = true;
});
}
return true;
}
return false;
}
@Override
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
withTileEntityDo(worldIn, pos, MechanicalBearingTileEntity::neighbourChanged);

View file

@ -178,6 +178,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
running = false;
angle = 0;
updateGeneratedRotation();
assembleNextTick = false;
sendData();
}

View file

@ -22,6 +22,7 @@ import net.minecraft.state.properties.RailShape;
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;
@ -30,8 +31,8 @@ import net.minecraft.world.World;
public class CartAssemblerBlock extends AbstractRailBlock {
public static IProperty<RailShape> RAIL_SHAPE = EnumProperty.create("shape", RailShape.class, RailShape.EAST_WEST,
RailShape.NORTH_SOUTH);
public static IProperty<RailShape> RAIL_SHAPE =
EnumProperty.create("shape", RailShape.class, RailShape.EAST_WEST, RailShape.NORTH_SOUTH);
public static BooleanProperty POWERED = BlockStateProperties.POWERED;
public CartAssemblerBlock() {
@ -62,6 +63,16 @@ public class CartAssemblerBlock extends AbstractRailBlock {
public void onMinecartPass(BlockState state, World world, BlockPos pos, AbstractMinecartEntity cart) {
if (!cart.canBeRidden())
return;
Vec3d p = cart.getPositionVec();
Vec3d m = cart.getMotion();
Vec3d p2 = p.add(m);
Direction facing = Direction.getFacingFromVector(m.x, m.y, m.z);
Axis axis = facing.getAxis();
double coord = axis.getCoordinate(pos.getX(), pos.getY(), pos.getZ()) + .5 + .25f * facing.getAxisDirection().getOffset();
if ((axis.getCoordinate(p.x, p.y, p.z) > coord) == (axis.getCoordinate(p2.x, p2.y, p2.z) % 1 > coord))
return;
if (state.get(POWERED))
disassemble(world, pos, cart);
else
@ -75,6 +86,8 @@ public class CartAssemblerBlock extends AbstractRailBlock {
Contraption contraption = MountedContraption.assembleMinecart(world, pos);
if (contraption == null)
return;
if (contraption.blocks.size() == 1)
return;
float initialAngle = ContraptionEntity.yawFromVector(cart.getMotion());
ContraptionEntity entity = ContraptionEntity.createMounted(world, contraption, initialAngle);
entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
@ -136,6 +149,11 @@ public class CartAssemblerBlock extends AbstractRailBlock {
super.fillStateContainer(builder);
}
@Override
public boolean isSolid(BlockState state) {
return false;
}
}
public static BlockState createAnchor(BlockState state) {

View file

@ -48,6 +48,7 @@ public class MountedContraption extends Contraption {
null), null));
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
contraption.initActors(world);
contraption.expandBoundsAroundAxis(Axis.Y);
return contraption;
}

View file

@ -20,7 +20,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
public float offset;
public boolean running;
protected boolean assembleNextTick;
public boolean assembleNextTick;
public ContraptionEntity movedContraption;
protected boolean forceMove;
protected ScrollOptionBehaviour<MovementMode> movementMode;

View file

@ -3,6 +3,7 @@ package com.simibubi.create.modules.contraptions.components.contraptions.piston;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
@ -32,7 +33,8 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.common.Tags;
public class MechanicalPistonBlock extends DirectionalAxisKineticBlock {
public class MechanicalPistonBlock extends DirectionalAxisKineticBlock
implements IWithTileEntity<MechanicalPistonTileEntity> {
public static final EnumProperty<PistonState> STATE = EnumProperty.create("state", PistonState.class);
protected boolean isSticky;
@ -52,11 +54,18 @@ public class MechanicalPistonBlock extends DirectionalAxisKineticBlock {
@Override
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) {
if (state.get(STATE) != PistonState.RETRACTED)
return false;
if (!player.isAllowEdit())
return false;
if (!player.getHeldItem(handIn).getItem().isIn(Tags.Items.SLIMEBALLS))
if (player.isSneaking())
return false;
if (!player.getHeldItem(handIn).getItem().isIn(Tags.Items.SLIMEBALLS)) {
if (player.getHeldItem(handIn).isEmpty()) {
withTileEntityDo(worldIn, pos, te -> te.assembleNextTick = true);
return true;
}
return false;
}
if (state.get(STATE) != PistonState.RETRACTED)
return false;
Direction direction = state.get(FACING);
if (hit.getFace() != direction)
@ -99,9 +108,7 @@ public class MechanicalPistonBlock extends DirectionalAxisKineticBlock {
}
public enum PistonState implements IStringSerializable {
RETRACTED,
MOVING,
EXTENDED;
RETRACTED, MOVING, EXTENDED;
@Override
public String getName() {

View file

@ -110,7 +110,7 @@ public class PistonContraption extends Contraption {
if (extensionLength == 0)
return false;
constructCollisionBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
for (BlockInfo pole : poles) {
BlockPos relPos = pole.pos.offset(direction, -extensionsInFront);
@ -213,7 +213,7 @@ public class PistonContraption extends Contraption {
}
@Override
public AxisAlignedBB getCollisionBox() {
return super.getCollisionBox().union(pistonExtensionCollisionBox);
public AxisAlignedBB getBoundingBox() {
return super.getBoundingBox().union(pistonExtensionCollisionBox);
}
}

View file

@ -2,24 +2,28 @@ package com.simibubi.create.modules.contraptions.components.contraptions.pulley;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IHaveNoBlockItem;
import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.EnumProperty;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
public class PulleyBlock extends HorizontalAxisKineticBlock {
public class PulleyBlock extends HorizontalAxisKineticBlock implements IWithTileEntity<PulleyTileEntity> {
public static EnumProperty<Axis> HORIZONTAL_AXIS = BlockStateProperties.HORIZONTAL_AXIS;
@ -37,6 +41,20 @@ public class PulleyBlock extends HorizontalAxisKineticBlock {
return true;
}
@Override
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) {
if (!player.isAllowEdit())
return false;
if (player.isSneaking())
return false;
if (player.getHeldItem(handIn).isEmpty()) {
withTileEntityDo(worldIn, pos, te -> te.assembleNextTick = true);
return true;
}
return false;
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
return AllShapes.PULLEY.get(state.get(HORIZONTAL_AXIS));

View file

@ -52,7 +52,6 @@ public class DeployerMovementBehaviour extends MovementBehaviour {
Vec3d facingVec = new Vec3d(context.state.get(DeployerBlock.FACING).getDirectionVec());
facingVec = VecHelper.rotate(facingVec, context.rotation.x, context.rotation.y, context.rotation.z);
Vec3d vec = context.position.subtract(facingVec.scale(2));
player.rotationYaw = ContraptionEntity.yawFromVector(facingVec);
player.rotationPitch = ContraptionEntity.pitchFromVector(facingVec) - 90;

View file

@ -167,11 +167,18 @@ public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerT
SuperByteBuffer pole = renderAndTransform(world, AllBlockPartials.DEPLOYER_POLE, blockState, pos, true);
SuperByteBuffer hand = renderAndTransform(world, handPose, blockState, pos, false);
Vec3d center = VecHelper.getCenterOf(new BlockPos(context.position));
double distance = context.position.distanceTo(center);
double nextDistance = context.position.add(context.motion).distanceTo(center);
double factor;
if (context.contraption.stalled) {
factor = MathHelper.sin(AnimationTickHolder.getRenderTick() * .5f) * .25f + .25f;
} else {
Vec3d center = VecHelper.getCenterOf(new BlockPos(context.position));
double distance = context.position.distanceTo(center);
double nextDistance = context.position.add(context.motion).distanceTo(center);
factor = .5f - MathHelper.lerp(Minecraft.getInstance().getRenderPartialTicks(), distance, nextDistance);
}
Vec3d offset = new Vec3d(blockState.get(FACING).getDirectionVec())
.scale(.5f - MathHelper.lerp(Minecraft.getInstance().getRenderPartialTicks(), distance, nextDistance));
.scale(factor);
pole.translate(offset.x, offset.y, offset.z);
hand.translate(offset.x, offset.y, offset.z);

View file

@ -27,6 +27,8 @@ public class ContactMovementBehaviour extends MovementBehaviour {
if (world.isRemote)
return;
if (context.firstMovement)
return;
deactivateLastVisitedContact(context);
BlockState visitedState = world.getBlockState(pos);