From 6031d9fce109037b83ccd4228f885aea8749d02a Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Fri, 13 Mar 2020 00:51:25 +0100 Subject: [PATCH] Flimsy Collision - Fixed server crash on startup - Fixed crash when entities get killed by anything other than players - Pulleys no longer force push blocks below them - Drill and Saw now applies damage to entities while moved in a contraption - Made tooltip formatting a tad more lenient - Added contraption collision to Pistons and Pulleys - applied by stationary blocks, other contraptions and entities. (needs polish) --- .../foundation/block/IHaveColorHandler.java | 3 + .../create/foundation/item/TooltipHelper.java | 5 +- .../BlockBreakingMovementBehaviour.java | 30 ++- .../actors/DrillMovementBehaviour.java | 6 + .../actors/SawMovementBehaviour.java | 14 +- .../components/contraptions/Contraption.java | 9 +- .../contraptions/ContraptionCollider.java | 251 ++++++++++++++++++ .../contraptions/ContraptionEntity.java | 119 +++++---- .../contraptions/IControlContraption.java | 2 + .../bearing/ClockworkBearingBlock.java | 2 +- .../bearing/ClockworkBearingTileEntity.java | 23 +- .../bearing/MechanicalBearingBlock.java | 2 +- .../bearing/MechanicalBearingTileEntity.java | 16 +- .../piston/LinearActuatorTileEntity.java | 39 ++- .../piston/MechanicalPistonTileEntity.java | 99 ++----- .../piston/MovingConstructHandler.java | 167 ------------ .../piston/PistonContraption.java | 12 +- .../pulley/PulleyContraption.java | 3 +- .../contraptions/pulley/PulleyTileEntity.java | 23 +- .../contraptions/relays/belt/BeltBlock.java | 24 +- .../contraptions/relays/belt/BeltColor.java | 25 ++ .../modules/curiosities/tools/ToolEvents.java | 5 +- 22 files changed, 497 insertions(+), 382 deletions(-) create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionCollider.java delete mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MovingConstructHandler.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltColor.java diff --git a/src/main/java/com/simibubi/create/foundation/block/IHaveColorHandler.java b/src/main/java/com/simibubi/create/foundation/block/IHaveColorHandler.java index 51149816a..88560d998 100644 --- a/src/main/java/com/simibubi/create/foundation/block/IHaveColorHandler.java +++ b/src/main/java/com/simibubi/create/foundation/block/IHaveColorHandler.java @@ -1,9 +1,12 @@ package com.simibubi.create.foundation.block; import net.minecraft.client.renderer.color.IBlockColor; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; public interface IHaveColorHandler { + @OnlyIn(Dist.CLIENT) public IBlockColor getColorHandler(); } diff --git a/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java b/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java index 0aba2552b..6f6ecb75a 100644 --- a/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java +++ b/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java @@ -53,9 +53,8 @@ public class TooltipHelper { for (int i = 0; i < words.length; i++) { String word = words[i]; - if (word.matches("_.+_")) { - word = highlightColor + word.substring(1, word.length() - 1) + defaultColor; - } + if (word.matches("_.+_.?")) + word = highlightColor + word.replaceAll("\\_", "") + defaultColor; boolean lastWord = i == words.length - 1; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java index c82a2aba9..118b08f60 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java @@ -5,8 +5,11 @@ import com.simibubi.create.modules.contraptions.components.contraptions.Movement import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; import net.minecraft.block.BlockState; +import net.minecraft.entity.Entity; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.NBTUtil; +import net.minecraft.util.DamageSource; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -28,17 +31,28 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { if (world.isRemote) return; - if (stateVisited.getCollisionShape(world, pos).isEmpty()) + if (stateVisited.getCollisionShape(world, pos).isEmpty()) { + DamageSource damageSource = getDamageSource(); + if (damageSource == null) + return; + for (Entity entity : world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos))) { + float damage = (float) MathHelper.clamp(Math.abs(context.relativeMotion.length() * 10) + 1, 5, 20); + entity.attackEntityFrom(damageSource, damage); + entity.setMotion(entity.getMotion().add(context.relativeMotion.scale(3))); + } return; - if (stateVisited.getBlockHardness(world, pos) == -1) - return; - if (!canBreak(stateVisited)) + } + if (!canBreak(world, pos, stateVisited)) return; context.data.put("BreakingPos", NBTUtil.writeBlockPos(pos)); context.stall = true; } + protected DamageSource getDamageSource() { + return null; + } + @Override public void stopMoving(MovementContext context) { CompoundNBT data = context.data; @@ -84,7 +98,7 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { BlockState stateToBreak = world.getBlockState(breakingPos); float blockHardness = stateToBreak.getBlockHardness(world, breakingPos); - if (!BlockBreakingKineticTileEntity.isBreakable(stateToBreak, blockHardness) || !canBreak(stateToBreak)) { + if (!canBreak(world, breakingPos, stateToBreak)) { if (destroyProgress != 0) { destroyProgress = 0; data.remove("Progress"); @@ -117,12 +131,12 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { data.putInt("Progress", destroyProgress); } - protected boolean canBreak(BlockState state) { - return true; + public boolean canBreak(World world, BlockPos breakingPos, BlockState state) { + float blockHardness = state.getBlockHardness(world, breakingPos); + return BlockBreakingKineticTileEntity.isBreakable(state, blockHardness); } protected void onBlockBroken(MovementContext context, BlockPos pos) { - } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillMovementBehaviour.java index 5e67577b6..9fdc5a399 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillMovementBehaviour.java @@ -4,6 +4,7 @@ import com.simibubi.create.foundation.utility.SuperByteBuffer; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; +import net.minecraft.util.DamageSource; import net.minecraft.util.math.Vec3d; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -26,5 +27,10 @@ public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour { public SuperByteBuffer renderInContraption(MovementContext context) { return DrillTileEntityRenderer.renderInContraption(context); } + + @Override + protected DamageSource getDamageSource() { + return DrillBlock.damageSourceDrill; + } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/SawMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/SawMovementBehaviour.java index cdc068cca..bd03396b3 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/SawMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/SawMovementBehaviour.java @@ -11,6 +11,7 @@ import net.minecraft.block.BlockState; import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.ItemStack; import net.minecraft.tags.BlockTags; +import net.minecraft.util.DamageSource; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -22,15 +23,15 @@ public class SawMovementBehaviour extends BlockBreakingMovementBehaviour { public boolean isActive(MovementContext context) { return SawBlock.isHorizontal(context.state); } - + @Override public Vec3d getActiveAreaOffset(MovementContext context) { return new Vec3d(context.state.get(SawBlock.FACING).getDirectionVec()).scale(.65f); } - + @Override - protected boolean canBreak(BlockState state) { - return super.canBreak(state) && state.isIn(BlockTags.LOGS); + public boolean canBreak(World world, BlockPos breakingPos, BlockState state) { + return super.canBreak(world, breakingPos, state) && state.isIn(BlockTags.LOGS); } @Override @@ -57,4 +58,9 @@ public class SawMovementBehaviour extends BlockBreakingMovementBehaviour { entity.setMotion(context.relativeMotion.scale(distance / 20f)); world.addEntity(entity); } + + @Override + protected DamageSource getDamageSource() { + return SawBlock.damageSourceSaw; + } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java index 22cd8c9d9..1aca3b434 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java @@ -192,7 +192,10 @@ public abstract class Contraption { return false; ChassisTileEntity chassis = (ChassisTileEntity) te; chassis.addAttachedChasses(frontier, visited); - for (BlockPos blockPos : chassis.getIncludedBlockPositions(movementDirection, false)) + List includedBlockPositions = chassis.getIncludedBlockPositions(movementDirection, false); + if (includedBlockPositions == null) + return false; + for (BlockPos blockPos : includedBlockPositions) if (!visited.contains(blockPos)) frontier.add(blockPos); return true; @@ -259,7 +262,7 @@ public abstract class Contraption { NBTUtil.readBlockState(comp.getCompound("Block")), comp.contains("Data") ? comp.getCompound("Data") : null); blocks.put(info.pos, info); - + if (world.isRemote) { Block block = info.state.getBlock(); BlockRenderLayer renderLayer = block.getRenderLayer(); @@ -407,6 +410,8 @@ public abstract class Contraption { if (AllBlocks.SAW.typeOf(state)) state = state.with(SawBlock.RUNNING, false); + if (world.getBlockState(targetPos).getBlockHardness(world, targetPos) == -1) + continue; world.destroyBlock(targetPos, world.getBlockState(targetPos).getCollisionShape(world, targetPos).isEmpty()); world.setBlockState(targetPos, state, 3 | BlockFlags.IS_MOVING); TileEntity tileEntity = world.getTileEntity(targetPos); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionCollider.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionCollider.java new file mode 100644 index 000000000..852c7fb8a --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionCollider.java @@ -0,0 +1,251 @@ +package com.simibubi.create.modules.contraptions.components.contraptions; + +import java.util.HashMap; +import java.util.Map; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.modules.contraptions.components.actors.BlockBreakingMovementBehaviour; + +import net.minecraft.block.BlockState; +import net.minecraft.block.material.PushReaction; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.MoverType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.ReuseableStream; +import net.minecraft.util.math.AxisAlignedBB; +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.world.World; +import net.minecraft.world.gen.feature.template.Template.BlockInfo; + +public class ContraptionCollider { + + static Map renderedBBs = new HashMap<>(); + + public static void collideEntities(ContraptionEntity contraptionEntity) { + if (Contraption.isFrozen()) + return; + if (!contraptionEntity.collisionEnabled()) + return; + + World world = contraptionEntity.getEntityWorld(); + Vec3d contraptionMotion = contraptionEntity.getMotion(); + Contraption contraption = contraptionEntity.getContraption(); + AxisAlignedBB bounds = contraptionEntity.getBoundingBox(); + Vec3d contraptionPosition = contraptionEntity.getPositionVec(); + + if (contraption == null) + return; + if (bounds == null) + return; + + for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, bounds.grow(1), + e -> e.getPushReaction() == PushReaction.NORMAL)) { + + ReuseableStream potentialHits = + getPotentiallyCollidedShapes(world, contraption, contraptionPosition, entity); + if (potentialHits.createStream().count() == 0) + continue; + + Vec3d positionOffset = contraptionPosition.scale(-1); + AxisAlignedBB entityBB = entity.getBoundingBox().offset(positionOffset).grow(1.0E-7D); + Vec3d entityMotion = entity.getMotion(); + Vec3d relativeMotion = entityMotion.subtract(contraptionMotion); + Vec3d allowedMovement = Entity.getAllowedMovement(relativeMotion, entityBB, world, + ISelectionContext.forEntity(entity), potentialHits); + potentialHits.createStream() + .forEach(voxelShape -> pushEntityOutOfShape(entity, voxelShape, positionOffset)); + + if (allowedMovement.equals(relativeMotion)) + continue; + if (allowedMovement.y != relativeMotion.y) { + entity.fall(entity.fallDistance, 1); + entity.fallDistance = 0; + entity.onGround = true; + } + + if (entity instanceof PlayerEntity && !world.isRemote) + return; + + entity.setMotion(allowedMovement.add(contraptionMotion)); + entity.velocityChanged = true; + } + + } + + public static void pushEntityOutOfShape(Entity entity, VoxelShape voxelShape, Vec3d positionOffset) { + AxisAlignedBB entityBB = entity.getBoundingBox().offset(positionOffset); + Vec3d entityMotion = entity.getMotion(); + + if (!voxelShape.toBoundingBoxList().stream().anyMatch(entityBB::intersects)) + return; + + AxisAlignedBB shapeBB = voxelShape.getBoundingBox(); + Direction bestSide = Direction.DOWN; + double bestOffset = 100; + double finalOffset = 0; + + for (Direction face : Direction.values()) { + Axis axis = face.getAxis(); + double d = axis == Axis.X ? entityBB.getXSize() + shapeBB.getXSize() + : axis == Axis.Y ? entityBB.getYSize() + shapeBB.getYSize() + : entityBB.getZSize() + shapeBB.getZSize(); + d = d + .5f; + + Vec3d nudge = new Vec3d(face.getDirectionVec()).scale(d); + AxisAlignedBB nudgedBB = entityBB.offset(nudge.getX(), nudge.getY(), nudge.getZ()); + double nudgeDistance = face.getAxisDirection() == AxisDirection.POSITIVE ? -d : d; + double offset = voxelShape.getAllowedOffset(face.getAxis(), nudgedBB, nudgeDistance); + double abs = Math.abs(nudgeDistance - offset); + if (abs < Math.abs(bestOffset) && abs != 0) { + bestOffset = abs; + finalOffset = abs; + bestSide = face; + } + } + + if (bestOffset != 0) { + entity.move(MoverType.SELF, new Vec3d(bestSide.getDirectionVec()).scale(finalOffset)); + boolean positive = bestSide.getAxisDirection() == AxisDirection.POSITIVE; + + double clamped; + switch (bestSide.getAxis()) { + case X: + clamped = positive ? Math.max(0, entityMotion.x) : Math.min(0, entityMotion.x); + entity.setMotion(clamped, entityMotion.y, entityMotion.z); + break; + case Y: + clamped = positive ? Math.max(0, entityMotion.y) : Math.min(0, entityMotion.y); + entity.setMotion(entityMotion.x, clamped, entityMotion.z); + entity.fall(entity.fallDistance, 1); + entity.fallDistance = 0; + entity.onGround = true; + break; + case Z: + clamped = positive ? Math.max(0, entityMotion.z) : Math.min(0, entityMotion.z); + entity.setMotion(entityMotion.x, entityMotion.y, clamped); + break; + } + } + } + + public static ReuseableStream getPotentiallyCollidedShapes(World world, Contraption contraption, + Vec3d contraptionPosition, Entity entity) { + AxisAlignedBB blockScanBB = entity.getBoundingBox().offset(contraptionPosition.scale(-1)).grow(.5f); + BlockPos min = new BlockPos(blockScanBB.minX, blockScanBB.minY, blockScanBB.minZ); + BlockPos max = new BlockPos(blockScanBB.maxX, blockScanBB.maxY, blockScanBB.maxZ); + + ReuseableStream potentialHits = + new ReuseableStream<>(BlockPos.getAllInBox(min, max).filter(contraption.blocks::containsKey).map(p -> { + BlockState blockState = contraption.blocks.get(p).state; + BlockPos pos = contraption.blocks.get(p).pos; + VoxelShape collisionShape = blockState.getCollisionShape(world, p); + return collisionShape.withOffset(pos.getX(), pos.getY(), pos.getZ()); + })); + + return potentialHits; + } + + public static boolean collideBlocks(ContraptionEntity contraptionEntity) { + if (Contraption.isFrozen()) + return true; + if (!contraptionEntity.collisionEnabled()) + return false; + + World world = contraptionEntity.getEntityWorld(); + Vec3d motion = contraptionEntity.getMotion(); + Contraption contraption = contraptionEntity.getContraption(); + AxisAlignedBB bounds = contraptionEntity.getBoundingBox(); + Vec3d position = contraptionEntity.getPositionVec(); + BlockPos gridPos = new BlockPos(position); + + if (contraption == null) + return false; + if (bounds == null) + return false; + if (motion.equals(Vec3d.ZERO)) + return false; + + Direction movementDirection = Direction.getFacingFromVector(motion.x, motion.y, motion.z); + + // Blocks in the world + if (movementDirection.getAxisDirection() == AxisDirection.POSITIVE) + gridPos = gridPos.offset(movementDirection); + if (isCollidingWithWorld(world, contraption, gridPos, movementDirection)) + return true; + + // Other moving Contraptions + for (ContraptionEntity otherContraptionEntity : world.getEntitiesWithinAABB(ContraptionEntity.class, + bounds.grow(1), e -> !e.equals(contraptionEntity))) { + + if (!otherContraptionEntity.collisionEnabled()) + continue; + + Vec3d otherMotion = otherContraptionEntity.getMotion(); + Contraption otherContraption = otherContraptionEntity.getContraption(); + AxisAlignedBB otherBounds = otherContraptionEntity.getBoundingBox(); + Vec3d otherPosition = otherContraptionEntity.getPositionVec(); + + if (otherContraption == null) + return false; + if (otherBounds == null) + return false; + + if (!bounds.offset(motion).intersects(otherBounds.offset(otherMotion))) + continue; + + for (BlockPos colliderPos : contraption.getColliders(world, movementDirection)) { + colliderPos = colliderPos.add(gridPos).subtract(new BlockPos(otherPosition)); + if (!otherContraption.blocks.containsKey(colliderPos)) + continue; + return true; + } + } + + return false; + } + + public static boolean isCollidingWithWorld(World world, Contraption contraption, BlockPos anchor, + Direction movementDirection) { + for (BlockPos pos : contraption.getColliders(world, movementDirection)) { + BlockPos colliderPos = pos.add(anchor); + + if (!world.isBlockPresent(colliderPos)) + return true; + + BlockState collidedState = world.getBlockState(colliderPos); + BlockInfo blockInfo = contraption.blocks.get(pos); + + if (blockInfo.state.getBlock() instanceof IPortableBlock) { + IPortableBlock block = (IPortableBlock) blockInfo.state.getBlock(); + if (block.getMovementBehaviour() instanceof BlockBreakingMovementBehaviour) { + BlockBreakingMovementBehaviour behaviour = + (BlockBreakingMovementBehaviour) block.getMovementBehaviour(); + if (!behaviour.canBreak(world, colliderPos, collidedState) + && !collidedState.getCollisionShape(world, pos).isEmpty()) { + return true; + } + continue; + } + } + + if (AllBlocks.PULLEY_MAGNET.typeOf(collidedState) && pos.equals(BlockPos.ZERO) + && movementDirection == Direction.UP) + continue; + + if (!collidedState.getMaterial().isReplaceable() + && !collidedState.getCollisionShape(world, colliderPos).isEmpty()) { + return true; + } + + } + return false; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java index 2274cdce0..c1b029d6b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java @@ -9,7 +9,9 @@ import com.simibubi.create.AllEntities; import com.simibubi.create.AllPackets; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.BearingContraption; +import com.simibubi.create.modules.contraptions.components.contraptions.piston.LinearActuatorTileEntity; +import net.minecraft.block.material.PushReaction; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; @@ -93,6 +95,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return this; } + public boolean collisionEnabled() { + return stationary && controllerTE instanceof LinearActuatorTileEntity; + } + @Override public void tick() { if (contraption == null) { @@ -102,52 +108,19 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD attachToController(); - Entity e = getRidingEntity(); - if (e != null) { - 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); - 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); -// } - - boolean wasStalled = isStalled(); - tickActors(movementVector); - if (isStalled()) { - if (!wasStalled) - motionBeforeStall = riding.getMotion(); - riding.setMotion(0, 0, 0); - } - - if (wasStalled && !isStalled()) { - riding.setMotion(motionBeforeStall); - motionBeforeStall = Vec3d.ZERO; - } - - super.tick(); + Entity mountedEntity = getRidingEntity(); + if (mountedEntity != null) { + tickAsPassenger(mountedEntity); return; } - if (getMotion().length() > 1 / 4098f) - move(getMotion().x, getMotion().y, getMotion().z); + if (getMotion().length() < 1 / 4098f) + setMotion(Vec3d.ZERO); + + move(getMotion().x, getMotion().y, getMotion().z); + if (ContraptionCollider.collideBlocks(this)) + controllerTE.collided(); + tickActors(new Vec3d(posX - prevPosX, posY - prevPosY, posZ - prevPosZ)); prevYaw = yaw; @@ -156,6 +129,46 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD super.tick(); } + + public void collisionTick() { + ContraptionCollider.collideEntities(this); + } + + public void tickAsPassenger(Entity e) { + 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); + if (targetYaw < 0) + targetYaw += 360; + if (yaw < 0) + yaw += 360; + } + + prevYaw = yaw; + yaw = angleLerp(0.2f, yaw, targetYaw); + + boolean wasStalled = isStalled(); + tickActors(movementVector); + if (isStalled()) { + if (!wasStalled) + motionBeforeStall = riding.getMotion(); + riding.setMotion(0, 0, 0); + } + + if (wasStalled && !isStalled()) { + riding.setMotion(motionBeforeStall); + motionBeforeStall = Vec3d.ZERO; + } + + super.tick(); + } public void tickActors(Vec3d movementVector) { float anglePitch = getPitch(1); @@ -237,14 +250,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } } - public void moveTo(double x, double y, double z) { - move(x - posX, y - posY, z - posZ); - } - public void move(double x, double y, double z) { - - // Collision and stuff - setPosition(posX + x, posY + y, posZ + z); } @@ -259,9 +265,6 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } public void rotate(double roll, double yaw, double pitch) { - - // Collision and stuff - this.yaw += yaw; this.pitch += pitch; this.roll += roll; @@ -397,9 +400,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD public void disassemble() { if (getContraption() != null) { - float yaw = getYaw(1); getContraption().disassemble(world, new BlockPos(getPositionVec().add(.5, .5, .5)), - new Vec3d(getRoll(1), yaw, getPitch(1))); + new Vec3d(getRoll(1), getYaw(1), getPitch(1))); } remove(); } @@ -440,8 +442,13 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } @Override + // Make sure nothing can move contraptions out of the way public void setMotion(Vec3d motionIn) { - // Make sure nothing can move contraptions out of the way + } + + @Override + public PushReaction getPushReaction() { + return PushReaction.IGNORE; } public void setContraptionMotion(Vec3d vec) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/IControlContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/IControlContraption.java index f78468fcc..556e08986 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/IControlContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/IControlContraption.java @@ -68,4 +68,6 @@ public interface IControlContraption { } + public void collided(); + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingBlock.java index 5a2cd7f73..d94397794 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingBlock.java @@ -29,7 +29,7 @@ public class ClockworkBearingBlock extends BearingBlock implements IWithTileEnti if (!worldIn.isRemote) { withTileEntityDo(worldIn, pos, te -> { if (te.running) { - te.disassembleConstruct(); + te.disassemble(); return; } te.assembleNextTick = true; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java index b41a55464..88a7d11c6 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java @@ -46,7 +46,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe } if (running && Contraption.isFrozen()) - disassembleConstruct(); + disassemble(); if (!world.isRemote && assembleNextTick) { assembleNextTick = false; @@ -57,12 +57,11 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe hourHand.getContraption().stop(world); if (minuteHand != null) minuteHand.getContraption().stop(world); - disassembleConstruct(); + disassemble(); } return; - } else { - assembleConstruct(); - } + } else + assemble(); return; } @@ -148,7 +147,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe return speed; } - public void assembleConstruct() { + public void assemble() { Direction direction = getBlockState().get(BlockStateProperties.FACING); // Collect Construct @@ -182,14 +181,14 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe sendData(); } - public void disassembleConstruct() { + public void disassemble() { if (!running) return; - + hourAngle = 0; minuteAngle = 0; applyRotations(); - + if (hourHand != null) { hourHand.disassemble(); } @@ -280,8 +279,12 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe @Override public void remove() { if (!world.isRemote) - disassembleConstruct(); + disassemble(); super.remove(); } + @Override + public void collided() { + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingBlock.java index 9cba2e4d1..5652a3562 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingBlock.java @@ -30,7 +30,7 @@ public class MechanicalBearingBlock extends BearingBlock implements IWithTileEnt if (!worldIn.isRemote) { withTileEntityDo(worldIn, pos, te -> { if (te.running) { - te.disassembleConstruct(); + te.disassemble(); return; } te.assembleNextTick = true; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java index 90bbd19c2..9b49716b2 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java @@ -81,7 +81,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp @Override public void remove() { if (!world.isRemote) - disassembleConstruct(); + disassemble(); super.remove(); } @@ -144,7 +144,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp return speed; } - public void assembleConstruct() { + public void assemble() { Direction direction = getBlockState().get(BlockStateProperties.FACING); // Collect Construct @@ -168,7 +168,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp updateGeneratedRotation(); } - public void disassembleConstruct() { + public void disassemble() { if (!running) return; if (movedContraption != null) @@ -190,7 +190,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp clientAngleDiff /= 2; if (running && Contraption.isFrozen()) - disassembleConstruct(); + disassemble(); if (!world.isRemote && assembleNextTick) { assembleNextTick = false; @@ -201,13 +201,13 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp || movedContraption.getContraption().blocks.isEmpty())) { if (movedContraption != null) movedContraption.getContraption().stop(world); - disassembleConstruct(); + disassemble(); } return; } else { if (speed == 0 && !isWindmill) return; - assembleConstruct(); + assemble(); } return; } @@ -275,4 +275,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp }); } + @Override + public void collided() { + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java index 515b0b243..888156cd9 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java @@ -50,16 +50,23 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme super.tick(); boolean contraptionPresent = movedContraption != null; - if (contraptionPresent) + if (contraptionPresent) { + movedContraption.collisionTick(); if (!movedContraption.isAlive()) movedContraption = null; + } if (world.isRemote) clientOffsetDiff *= .75f; - if (waitingForSpeedChange) { + if (waitingForSpeedChange && contraptionPresent) { + if (world.isRemote) { + float syncSpeed = clientOffsetDiff / 2f; + offset += syncSpeed; + movedContraption.setContraptionMotion(toMotionVector(syncSpeed)); + return; + } movedContraption.setContraptionMotion(Vec3d.ZERO); -// movedContraption.setMotion(Vec3d.ZERO); return; } @@ -72,7 +79,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme sendData(); return; } - assembleConstruct(); + assemble(); return; } @@ -96,6 +103,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme offset = offset <= 0 ? 0 : extensionRange; if (!world.isRemote) { applyContraptionMotion(); + applyContraptionPosition(); tryDisassemble(); if (waitingForSpeedChange) { forceMove = true; @@ -134,7 +142,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme public void remove() { this.removed = true; if (!world.isRemote) - disassembleConstruct(); + disassemble(); super.remove(); } @@ -185,9 +193,9 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme } - protected abstract void assembleConstruct(); + public abstract void disassemble(); - protected abstract void disassembleConstruct(); + protected abstract void assemble(); protected abstract int getExtensionRange(); @@ -203,7 +211,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme protected void tryDisassemble() { if (removed) { - disassembleConstruct(); + disassemble(); return; } if (movementMode.get() == MovementMode.MOVE_NEVER_PLACE) { @@ -215,7 +223,18 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme waitingForSpeedChange = true; return; } - disassembleConstruct(); + disassemble(); + } + + @Override + public void collided() { + if (world.isRemote) { + waitingForSpeedChange = true; + return; + } + offset = getGridOffset(offset - getMovementSpeed()); + applyContraptionPosition(); + tryDisassemble(); } protected void applyContraptionMotion() { @@ -229,6 +248,8 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme } protected void applyContraptionPosition() { + if (movedContraption == null) + return; Vec3d vec = toPosition(offset); movedContraption.setPosition(vec.x, vec.y, vec.z); if (getSpeed() == 0 || waitingForSpeedChange) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java index 2b521af70..421846553 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java @@ -5,6 +5,7 @@ import com.simibubi.create.AllTileEntities; import com.simibubi.create.foundation.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.modules.contraptions.base.IRotate; +import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionCollider; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; import com.simibubi.create.modules.contraptions.components.contraptions.DirectionalExtenderScrollOptionSlot; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState; @@ -39,11 +40,20 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity { } @Override - public void assembleConstruct() { + public void assemble() { Direction direction = getBlockState().get(BlockStateProperties.FACING); // Collect Construct PistonContraption contraption = PistonContraption.movePistonAt(world, pos, direction, getMovementSpeed() < 0); + Direction movementDirection = getSpeed() > 0 ? direction : direction.getOpposite(); + + if (contraption != null) { + BlockPos anchor = contraption.getAnchor().offset(direction, contraption.initialExtensionProgress); + if (ContraptionCollider.isCollidingWithWorld(world, contraption, anchor.offset(movementDirection), + movementDirection)) + contraption = null; + } + if (contraption == null) return; @@ -69,7 +79,7 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity { } @Override - public void disassembleConstruct() { + public void disassemble() { if (!running) return; if (!removed) @@ -86,6 +96,13 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity { AllBlocks.MECHANICAL_PISTON.get().onBlockHarvested(world, pos, getBlockState(), null); } + @Override + public void collided() { + super.collided(); + if (!running && getSpeed() > 0) + assembleNextTick = true; + } + @Override public float getMovementSpeed() { float movementSpeed = getSpeed() / 512f; @@ -138,82 +155,4 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity { : ((PistonContraption) movedContraption.getContraption()).initialExtensionProgress; } -// private boolean hasBlockCollisions(float newOffset) { -// if (PistonContraption.isFrozen()) -// return true; -// -// Direction movementDirection = getBlockState().get(BlockStateProperties.FACING); -// BlockPos relativePos = BlockPos.ZERO.offset(movementDirection, getModulatedOffset(newOffset)); -// -// // Other moving Pistons -// int maxPossibleRange = parameters.maxPistonPoles.get() + parameters.maxChassisRange.get() -// + parameters.maxChassisForTranslation.get(); -// Iterator iterator = Create.constructHandler.getOtherMovingPistonsInWorld(this) -// .iterator(); -// pistonLoop: while (iterator.hasNext()) { -// MechanicalPistonTileEntity otherPiston = iterator.next(); -// -// if (otherPiston == this) -// continue; -// if (!otherPiston.running || otherPiston.movedContraption == null) { -// iterator.remove(); -// continue; -// } -// if (otherPiston.pos.manhattanDistance(pos) > maxPossibleRange * 2) -// continue; -// -// Direction otherMovementDirection = otherPiston.getBlockState().get(BlockStateProperties.FACING); -// BlockPos otherRelativePos = BlockPos.ZERO.offset(otherMovementDirection, -// getModulatedOffset(otherPiston.offset)); -// -// for (AxisAlignedBB tBB : Arrays.asList(movedContraption.constructCollisionBox, -// movedContraption.pistonCollisionBox)) { -// for (AxisAlignedBB oBB : Arrays.asList(otherPiston.movedContraption.constructCollisionBox, -// otherPiston.movedContraption.pistonCollisionBox)) { -// if (tBB == null || oBB == null) -// continue; -// -// boolean frontalCollision = otherMovementDirection == movementDirection.getOpposite(); -// BlockPos thisColliderOffset = relativePos.offset(movementDirection, -// frontalCollision ? (getMovementSpeed() > 0 ? 1 : -1) : 0); -// AxisAlignedBB thisBB = tBB.offset(thisColliderOffset); -// AxisAlignedBB otherBB = oBB.offset(otherRelativePos); -// -// if (thisBB.intersects(otherBB)) { -// boolean actuallyColliding = false; -// for (BlockPos colliderPos : movedContraption.getColliders(world, movementDirection)) { -// colliderPos = colliderPos.add(thisColliderOffset).subtract(otherRelativePos); -// if (!otherPiston.movedContraption.blocks.containsKey(colliderPos)) -// continue; -// actuallyColliding = true; -// } -// if (!actuallyColliding) -// continue pistonLoop; -// hadCollisionWithOtherPiston = true; -// return true; -// } -// -// } -// } -// -// } -// -// if (!running) -// return false; -// -// // Other Blocks in world -// for (BlockPos pos : movedContraption.getColliders(world, -// getMovementSpeed() > 0 ? movementDirection : movementDirection.getOpposite())) { -// BlockPos colliderPos = pos.add(relativePos); -// -// if (!world.isBlockPresent(colliderPos)) -// return true; -// if (!world.getBlockState(colliderPos).getMaterial().isReplaceable() -// && !world.getBlockState(colliderPos).getCollisionShape(world, colliderPos).isEmpty()) -// return true; -// } -// -// return false; -// } - } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MovingConstructHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MovingConstructHandler.java deleted file mode 100644 index 66d2f4c74..000000000 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MovingConstructHandler.java +++ /dev/null @@ -1,167 +0,0 @@ -/*package com.simibubi.create.modules.contraptions.receivers.constructs.piston; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import com.simibubi.create.Create; - -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.world.IWorld; -import net.minecraftforge.fml.common.Mod.EventBusSubscriber; - -@EventBusSubscriber -public class MovingConstructHandler { - - static List renderedBBs = new LinkedList<>(); - static Map> movingPistons = new HashMap<>(); - - public void onLoadWorld(IWorld world) { - movingPistons.put(world, new ArrayList<>()); - Create.logger.debug("Prepared Construct List for " + world.getDimension().getType().getRegistryName()); - } - - public void onUnloadWorld(IWorld world) { - movingPistons.remove(world); - Create.logger.debug("Removed Construct List for " + world.getDimension().getType().getRegistryName()); - } - -// public static void moveEntities(MechanicalPistonTileEntity te, float movementSpeed, Direction movementDirection, -// float newOffset) { -// if (PistonContraption.isFrozen()) -// return; -// -// World world = te.getWorld(); -// Vec3d movementVec = new Vec3d(te.getBlockState().get(BlockStateProperties.FACING).getDirectionVec()); -// Contraption construct = te.movedContraption; -// -//// if (world.isRemote) { -//// renderedBBs.clear(); -//// if (construct.pistonCollisionBox != null) -//// renderedBBs.add(construct.pistonCollisionBox.offset(te.getConstructOffset(0))); -//// if (construct.constructCollisionBox != null) -//// renderedBBs.add(construct.constructCollisionBox.offset(te.getConstructOffset(0))); -//// -//// } -// -// if (construct.getCollisionBoxFront() != null) { -// AxisAlignedBB constructBB = construct.getCollisionBoxFront().offset(te.getConstructOffset(0)).grow(.5f); -// -// for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, constructBB, -// e -> e.getPushReaction() == PushReaction.NORMAL)) { -// -// AxisAlignedBB entityScanBB = entity.getBoundingBox().offset(movementVec.scale(-1 * newOffset)) -// .grow(.5f); -// BlockPos min = new BlockPos(entityScanBB.minX, entityScanBB.minY, entityScanBB.minZ); -// BlockPos max = new BlockPos(entityScanBB.maxX, entityScanBB.maxY, entityScanBB.maxZ); -// -// Stream hits = BlockPos.getAllInBox(min, max).filter(construct.blocks::containsKey) -// .map(pos -> { -// Vec3d vec = new Vec3d(pos).add(te.getConstructOffset(te.getMovementSpeed() > 0 ? 1 : 0)); -// return construct.blocks.get(pos).state.getShape(world, new BlockPos(vec)).withOffset(vec.x, -// vec.y, vec.z); -// }); -// ReuseableStream potentialHits = new ReuseableStream<>(hits); -// -// AxisAlignedBB entityBB = entity.getBoundingBox(); -// Vec3d motion = entity.getMotion(); -// Vec3d movement = new Vec3d(movementDirection.getDirectionVec()).scale(-movementSpeed).add(motion); -// Vec3d allowedMovement = Entity.getAllowedMovement(movement, entityBB, world, -// ISelectionContext.forEntity(entity), potentialHits); -// -// for (Object shape : potentialHits.createStream().toArray()) { -// VoxelShape voxelShape = (VoxelShape) shape; -// if (!entityBB.intersects(voxelShape.getBoundingBox())) -// continue; -// -// Direction bestSide = Direction.DOWN; -// double bestOffset = 100; -// double finalOffset = 0; -// -// for (Direction face : Direction.values()) { -// Axis axis = face.getAxis(); -// double d = axis == Axis.X ? entityBB.getXSize() -// : axis == Axis.Y ? entityBB.getYSize() : entityBB.getZSize(); -// d = d + 1.5f; -// -// Vec3d nudge = new Vec3d(face.getDirectionVec()).scale(d); -// AxisAlignedBB nudgedBB = entityBB.offset(nudge.getX(), nudge.getY(), nudge.getZ()); -// double nudgeDistance = face.getAxisDirection() == AxisDirection.POSITIVE ? -d : d; -// double offset = voxelShape.getAllowedOffset(face.getAxis(), nudgedBB, nudgeDistance); -// double abs = Math.abs(nudgeDistance - offset); -// if (abs < Math.abs(bestOffset) && abs != 0) { -// bestOffset = abs; -// finalOffset = abs; -// bestSide = face; -// } -// } -// -// if (bestOffset != 0) { -// entity.move(MoverType.SELF, new Vec3d(bestSide.getDirectionVec()).scale(finalOffset)); -// switch (bestSide.getAxis()) { -// case X: -// entity.setMotion(0, motion.y, motion.z); -// break; -// case Y: -// entity.setMotion(motion.x, bestSide == Direction.UP ? movementSpeed + 1 / 8f : 0, motion.z); -// entity.fall(entity.fallDistance, 1); -// entity.fallDistance = 0; -// entity.onGround = true; -// break; -// case Z: -// entity.setMotion(motion.x, motion.y, 0); -// break; -// } -// -// break; -// } -// } -// -// if (!allowedMovement.equals(movement)) { -// if (allowedMovement.y != movement.y) { -// entity.fall(entity.fallDistance, 1); -// entity.fallDistance = 0; -// entity.onGround = true; -// } -// if (entity instanceof PlayerEntity && !world.isRemote) -// return; -// entity.setMotion(allowedMovement.subtract(movement.subtract(motion))); -// entity.velocityChanged = true; -// } -// -// } -// } -// } - - public void add(MechanicalPistonTileEntity mechanicalPistonTileEntity) { - movingPistons.get(mechanicalPistonTileEntity.getWorld()).add(mechanicalPistonTileEntity); - } - - public void remove(MechanicalPistonTileEntity mechanicalPistonTileEntity) { - movingPistons.get(mechanicalPistonTileEntity.getWorld()).remove(mechanicalPistonTileEntity); - } - - public List getOtherMovingPistonsInWorld( - MechanicalPistonTileEntity mechanicalPistonTileEntity) { - return movingPistons.get(mechanicalPistonTileEntity.getWorld()); - } - -// @SubscribeEvent -// @OnlyIn(value = Dist.CLIENT) -// public static void onRenderWorld(RenderWorldLastEvent event) { -// for (AxisAlignedBB bb : renderedBBs) { -// TessellatorHelper.prepareForDrawing(); -// GlStateManager.disableTexture(); -// GlStateManager.lineWidth(3); -// int color = ColorHelper.rainbowColor(renderedBBs.indexOf(bb) * 170); -// WorldRenderer.drawSelectionBoundingBox(bb.grow(1 / 256f), (color >> 16 & 0xFF) / 256f, -// (color >> 8 & 0xFF) / 256f, (color & 0xFF) / 256f, 1); -// GlStateManager.lineWidth(1); -// GlStateManager.enableTexture(); -// TessellatorHelper.cleanUpAfterDrawing(); -// } -// } - -}*/ diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java index 00ea4401c..ec1bbba64 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java @@ -131,24 +131,24 @@ public class PistonContraption extends Contraption { return true; for (int offset = 0; offset <= AllConfigs.SERVER.kinetics.maxChassisRange.get(); offset++) { if (offset == 1 && retracting) - break; + return true; BlockPos currentPos = pos.offset(orientation, offset + initialExtensionProgress); if (!world.isBlockPresent(currentPos)) return false; BlockState state = world.getBlockState(currentPos); if (state.getMaterial().isReplaceable()) - break; + return true; if (state.getCollisionShape(world, currentPos).isEmpty()) - break; + return true; if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state) && state.get(FACING) == direction.getOpposite()) - break; + return true; if (!BlockMovementTraits.movementAllowed(world, currentPos)) return retracting; frontier.add(currentPos); if (BlockMovementTraits.notSupportive(state, orientation)) - break; + return true; } - return true; + return false; // too many } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyContraption.java index 2382a0a94..31087a617 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyContraption.java @@ -4,7 +4,6 @@ import com.simibubi.create.modules.contraptions.components.contraptions.AllContr import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -22,7 +21,7 @@ public class PulleyContraption extends Contraption { return null; PulleyContraption construct = new PulleyContraption(); construct.initialOffset = initialOffset; - if (!construct.searchMovedStructure(world, pos, Direction.DOWN)) + if (!construct.searchMovedStructure(world, pos, null)) return null; construct.initActors(world); return construct; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java index 3b4ec31bf..be4597827 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java @@ -5,6 +5,7 @@ import com.simibubi.create.AllTileEntities; import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform; import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionCollider; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; import com.simibubi.create.modules.contraptions.components.contraptions.piston.LinearActuatorTileEntity; @@ -19,7 +20,7 @@ import net.minecraft.util.math.Vec3d; public class PulleyTileEntity extends LinearActuatorTileEntity { protected int initialOffset; - + public PulleyTileEntity() { super(AllTileEntities.ROPE_PULLEY.type); } @@ -30,7 +31,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { } @Override - protected void assembleConstruct() { + protected void assemble() { if (speed == 0) return; if (offset >= getExtensionRange() && getSpeed() > 0) @@ -43,6 +44,14 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { BlockPos anchor = pos.down((int) (offset + 1)); initialOffset = (int) (offset); PulleyContraption contraption = PulleyContraption.assemblePulleyAt(world, anchor, (int) offset); + + if (contraption != null) { + Direction movementDirection = getSpeed() > 0 ? Direction.DOWN : Direction.UP; + if (ContraptionCollider.isCollidingWithWorld(world, contraption, anchor.offset(movementDirection), + movementDirection)) + contraption = null; + } + if (contraption == null && getSpeed() > 0) return; @@ -66,7 +75,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { } @Override - protected void disassembleConstruct() { + public void disassemble() { if (!running) return; offset = getGridOffset(offset); @@ -124,7 +133,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { if (stateBelow.getMaterial().isReplaceable() || stateBelow.getShape(world, posBelow).isEmpty()) return; - disassembleConstruct(); + disassemble(); assembleNextTick = true; } @@ -133,18 +142,18 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { initialOffset = tag.getInt("InitialOffset"); super.read(tag); } - + @Override public CompoundNBT write(CompoundNBT tag) { tag.putInt("InitialOffset", initialOffset); return super.write(tag); } - + @Override protected int getExtensionRange() { return Math.min(AllConfigs.SERVER.kinetics.maxRopeLength.get(), pos.getY() - 1); } - + @Override protected int getInitialOffset() { return initialOffset; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java index 3259bf037..619706039 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java @@ -53,10 +53,11 @@ import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; -import net.minecraft.world.IEnviromentBlockReader; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; import net.minecraft.world.storage.loot.LootParameters; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.Tags; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; @@ -317,6 +318,7 @@ public class BeltBlock extends HorizontalKineticBlock } @Override + @OnlyIn(Dist.CLIENT) public boolean addDestroyEffects(BlockState state, World world, BlockPos pos, ParticleManager manager) { // From Particle Manager, but reduced density for belts with lots of boxes VoxelShape voxelshape = state.getShape(world, pos); @@ -603,25 +605,9 @@ public class BeltBlock extends HorizontalKineticBlock } @Override + @OnlyIn(Dist.CLIENT) public IBlockColor getColorHandler() { - return color; - } - - private static BeltColor color = new BeltColor(); - - private static class BeltColor implements IBlockColor { - - @Override - public int getColor(BlockState state, IEnviromentBlockReader reader, BlockPos pos, int layer) { - TileEntity tileEntity = reader.getTileEntity(pos); - if (tileEntity instanceof BeltTileEntity) { - BeltTileEntity te = (BeltTileEntity) tileEntity; - if (te.color != -1) - return te.color; - } - return 0; - } - + return new BeltColor(); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltColor.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltColor.java new file mode 100644 index 000000000..258cea032 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltColor.java @@ -0,0 +1,25 @@ +package com.simibubi.create.modules.contraptions.relays.belt; + +import net.minecraft.block.BlockState; +import net.minecraft.client.renderer.color.IBlockColor; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IEnviromentBlockReader; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +@OnlyIn(Dist.CLIENT) +class BeltColor implements IBlockColor { + + @Override + public int getColor(BlockState state, IEnviromentBlockReader reader, BlockPos pos, int layer) { + TileEntity tileEntity = reader.getTileEntity(pos); + if (tileEntity instanceof BeltTileEntity) { + BeltTileEntity te = (BeltTileEntity) tileEntity; + if (te.color != -1) + return te.color; + } + return 0; + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/modules/curiosities/tools/ToolEvents.java b/src/main/java/com/simibubi/create/modules/curiosities/tools/ToolEvents.java index 178960f71..e765b8709 100644 --- a/src/main/java/com/simibubi/create/modules/curiosities/tools/ToolEvents.java +++ b/src/main/java/com/simibubi/create/modules/curiosities/tools/ToolEvents.java @@ -152,7 +152,10 @@ public class ToolEvents { @SubscribeEvent public static void shadowSteelToolsDropMoreXPonKill(LivingExperienceDropEvent event) { - ItemStack heldItemMainhand = event.getAttackingPlayer().getHeldItemMainhand(); + PlayerEntity attackingPlayer = event.getAttackingPlayer(); + if (attackingPlayer == null) + return; + ItemStack heldItemMainhand = attackingPlayer.getHeldItemMainhand(); if (heldItemMainhand.getItem() instanceof ShadowSteelToolItem) { int level = EnchantmentHelper.getEnchantmentLevel(Enchantments.LOOTING, heldItemMainhand); float modifier = 1 + event.getEntity().world.getRandom().nextFloat() * level;