diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java index 55d86719c..dce0411c2 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java @@ -26,6 +26,7 @@ import com.simibubi.create.modules.logistics.block.transposer.TransposerBlock; import net.minecraft.block.AbstractPressurePlateBlock; import net.minecraft.block.AbstractRailBlock; +import net.minecraft.block.BellBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -33,6 +34,7 @@ import net.minecraft.block.CarpetBlock; import net.minecraft.block.DoorBlock; import net.minecraft.block.FenceGateBlock; import net.minecraft.block.FlowerPotBlock; +import net.minecraft.block.HorizontalBlock; import net.minecraft.block.HorizontalFaceBlock; import net.minecraft.block.LadderBlock; import net.minecraft.block.RedstoneDiodeBlock; @@ -42,6 +44,7 @@ import net.minecraft.block.TorchBlock; import net.minecraft.block.WallTorchBlock; import net.minecraft.block.material.PushReaction; import net.minecraft.state.properties.AttachFace; +import net.minecraft.state.properties.BellAttachment; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; @@ -145,6 +148,8 @@ public class BlockMovementTraits { return true; if (block instanceof CarpetBlock) return true; + if (block instanceof BellBlock) + return true; return false; } @@ -198,6 +203,16 @@ public class BlockMovementTraits { return direction == state.get(NozzleBlock.FACING).getOpposite(); if (block instanceof EngineBlock) return direction == state.get(EngineBlock.HORIZONTAL_FACING).getOpposite(); + if (block instanceof BellBlock) { + BellAttachment attachment = state.get(BlockStateProperties.BELL_ATTACHMENT); + if (attachment == BellAttachment.FLOOR) { + return direction == Direction.DOWN; + } + if (attachment == BellAttachment.CEILING) { + return direction == Direction.UP; + } + return direction == state.get(HorizontalBlock.HORIZONTAL_FACING); + } return false; } 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 d06f73f8a..6602497c4 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 @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -519,16 +520,20 @@ public abstract class Contraption { glueToRemove.forEach(SuperGlueEntity::remove); for (boolean brittles : Iterate.trueAndFalse) { - for (BlockInfo block : blocks.values()) { + for (Iterator iterator = blocks.values().iterator(); iterator.hasNext();) { + BlockInfo block = iterator.next(); if (brittles != BlockMovementTraits.isBrittle(block.state)) continue; BlockPos add = block.pos.add(anchor).add(offset); if (customRemoval.test(add, block.state)) continue; + Block blockIn = world.getBlockState(add).getBlock(); + if (block.state.getBlock() != blockIn) + iterator.remove(); world.getWorld().removeTileEntity(add); int flags = 67; - if (world.getBlockState(add).getBlock() instanceof DoorBlock) + if (blockIn instanceof DoorBlock) flags = flags | 32 | 16; world.setBlockState(add, Blocks.AIR.getDefaultState(), flags); } @@ -565,11 +570,15 @@ public abstract class Contraption { state = state.with(SawBlock.RUNNING, false); BlockState blockState = world.getBlockState(targetPos); - if (blockState.getBlockHardness(world, targetPos) == -1) - continue; - if (state.getCollisionShape(world, targetPos).isEmpty() - && !blockState.getCollisionShape(world, targetPos).isEmpty()) + if (blockState.getBlockHardness(world, targetPos) == -1 + || (state.getCollisionShape(world, targetPos).isEmpty() + && !blockState.getCollisionShape(world, targetPos).isEmpty())) { + if (targetPos.getY() == 0) + targetPos = targetPos.up(); + world.playEvent(2001, targetPos, Block.getStateId(state)); + Block.spawnDrops(state, world, targetPos, null); continue; + } world.destroyBlock(targetPos, true); world.setBlockState(targetPos, state, 3 | BlockFlags.IS_MOVING); 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 56c7623f6..56291e421 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 @@ -497,13 +497,16 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } public void disassemble() { + if (!isAlive()) { + return; + } if (getContraption() != null) { + remove(); BlockPos offset = new BlockPos(getAnchorVec().add(.5, .5, .5)); Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1)); getContraption().addBlocksToWorld(world, offset, rotation); preventMovedEntitiesFromGettingStuck(); } - remove(); } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java index 1b3109e36..fe2e7b15d 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java @@ -12,6 +12,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.chassis. import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; +import net.minecraft.block.BellBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.HorizontalFaceBlock; @@ -19,6 +20,8 @@ import net.minecraft.block.SlabBlock; import net.minecraft.block.StairsBlock; import net.minecraft.state.BooleanProperty; import net.minecraft.state.properties.AttachFace; +import net.minecraft.state.properties.BellAttachment; +import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.Half; import net.minecraft.state.properties.SlabType; import net.minecraft.util.Direction; @@ -78,11 +81,18 @@ public class StructureTransform { * horizontal axes */ public BlockState apply(BlockState state) { - if (rotationAxis == Axis.Y) - return state.rotate(rotation); - Block block = state.getBlock(); + if (rotationAxis == Axis.Y) { + if (block instanceof BellBlock) { + if (state.get(BlockStateProperties.BELL_ATTACHMENT) == BellAttachment.DOUBLE_WALL) { + state = state.with(BlockStateProperties.BELL_ATTACHMENT, BellAttachment.SINGLE_WALL); + } + return state.with(HorizontalFaceBlock.HORIZONTAL_FACING, rotation.rotate(state.get(HorizontalFaceBlock.HORIZONTAL_FACING))); + } + return state.rotate(rotation); + } + if (block instanceof AbstractChassisBlock) return rotateChassis(state); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java index 775e74b0c..5eca4e99b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java @@ -8,10 +8,12 @@ import com.simibubi.create.AllEntities; import com.simibubi.create.AllItems; import com.simibubi.create.AllPackets; import com.simibubi.create.AllSoundEvents; +import com.simibubi.create.modules.contraptions.components.contraptions.BlockMovementTraits; import com.simibubi.create.modules.schematics.ISpecialEntityItemRequirement; import com.simibubi.create.modules.schematics.ItemRequirement; import com.simibubi.create.modules.schematics.ItemRequirement.ItemUseType; +import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.world.ClientWorld; @@ -157,11 +159,22 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat BlockPos pos2 = hangingPosition.offset(getFacingDirection().getOpposite()); if (!world.isAreaLoaded(pos, 0) || !world.isAreaLoaded(pos2, 0)) return true; - if (world.isAirBlock(pos) && world.isAirBlock(pos2)) + if (!isValidFace(world, pos2, getFacingDirection()) && !isValidFace(world, pos, getFacingDirection().getOpposite())) return false; return world.getEntitiesInAABBexcluding(this, getBoundingBox(), e -> e instanceof SuperGlueEntity).isEmpty(); } + public static boolean isValidFace(World world, BlockPos pos, Direction direction) { + BlockState state = world.getBlockState(pos); + if (BlockMovementTraits.isBlockAttachedTowards(state, direction)) + return true; + if (!BlockMovementTraits.movementNecessary(world, pos)) + return false; + if (BlockMovementTraits.notSupportive(state, direction)) + return false; + return true; + } + @Override public boolean canBeCollidedWith() { return true; @@ -236,11 +249,6 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat return Math.max(light, light2); } - @Override - public void applyEntityCollision(Entity entityIn) { - super.applyEntityCollision(entityIn); - } - @Override public boolean processInitialInteract(PlayerEntity player, Hand hand) { DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java index 2e595f9d0..11717232f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java @@ -83,7 +83,7 @@ public class SuperGlueRenderer extends EntityRenderer { return false; BlockPos pos = entity.hangingPosition; BlockPos pos2 = pos.offset(entity.getFacingDirection().getOpposite()); - return entity.world.isAirBlock(pos) != entity.world.isAirBlock(pos2); + return SuperGlueEntity.isValidFace(entity.world, pos2, entity.getFacingDirection()) != SuperGlueEntity.isValidFace(entity.world, pos, entity.getFacingDirection().getOpposite()); } private void initQuads() { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerFakePlayer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerFakePlayer.java index fa8e15b89..f5f71dc1a 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerFakePlayer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerFakePlayer.java @@ -66,6 +66,7 @@ public class DeployerFakePlayer extends FakePlayer { return new StringTextComponent(Lang.translate("block.deployer.damage_source_name")); } + @Override @OnlyIn(Dist.CLIENT) public float getEyeHeight(Pose poseIn) { return 0; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java index 303c79761..14400a1ac 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java @@ -1,6 +1,7 @@ package com.simibubi.create.modules.contraptions.components.deployer; import static net.minecraftforge.eventbus.api.Event.Result.DENY; +import static net.minecraftforge.eventbus.api.Event.Result.DEFAULT; import java.util.ArrayList; import java.util.List; @@ -47,7 +48,7 @@ import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock; import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock; -import net.minecraftforge.eventbus.api.Event.Result; +import net.minecraftforge.eventbus.api.Event; public class DeployerHandler { @@ -81,7 +82,7 @@ public class DeployerHandler { static boolean shouldActivate(ItemStack held, World world, BlockPos targetPos) { if (held.getItem() instanceof BlockItem) - if (!world.getBlockState(targetPos).getMaterial().isReplaceable()) + if (world.getBlockState(targetPos).getBlock() == ((BlockItem) held.getItem()).getBlock()) return false; if (held.getItem() instanceof BucketItem) { @@ -164,18 +165,18 @@ public class DeployerHandler { // Left click if (mode == Mode.PUNCH) { - LeftClickBlock event = ForgeHooks.onLeftClickBlock(player, clickedPos, face); - if (event.isCanceled()) - return; if (!world.isBlockModifiable(player, clickedPos)) return; - if (world.extinguishFire(player, clickedPos, face)) - return; - if (clickedState.isAir(world, clickedPos)) { + if (clickedState.getRenderShape(world, clickedPos).isEmpty()) { player.blockBreakingProgress = null; return; } - if (event.getUseBlock() != Result.DENY) + LeftClickBlock event = ForgeHooks.onLeftClickBlock(player, clickedPos, face); + if (event.isCanceled()) + return; + if (world.extinguishFire(player, clickedPos, face)) + return; + if (event.getUseBlock() != DENY) clickedState.onBlockClicked(world, clickedPos, player); if (stack.isEmpty()) return; @@ -193,6 +194,10 @@ public class DeployerHandler { player.blockBreakingProgress = null; return; } + if (progress <= 0) { + player.blockBreakingProgress = null; + return; + } if ((int) (before * 10) != (int) (progress * 10)) world.sendBlockBreakProgress(player.getEntityId(), clickedPos, (int) (progress * 10)); @@ -202,10 +207,16 @@ public class DeployerHandler { // Right click ItemUseContext itemusecontext = new ItemUseContext(player, hand, result); - RightClickBlock event = ForgeHooks.onRightClickBlock(player, hand, clickedPos, face); + Event.Result useBlock = DENY; + Event.Result useItem = DEFAULT; + if (!clickedState.getRenderShape(world, clickedPos).isEmpty()) { + RightClickBlock event = ForgeHooks.onRightClickBlock(player, hand, clickedPos, face); + useBlock = event.getUseBlock(); + useItem = event.getUseItem(); + } // Item has custom active use - if (event.getUseItem() != DENY) { + if (useItem != DENY) { ActionResultType actionresult = stack.onItemUseFirst(itemusecontext); if (actionresult != ActionResultType.PASS) return; @@ -216,11 +227,11 @@ public class DeployerHandler { !(player.isSneaking() && holdingSomething) || (stack.doesSneakBypassUse(world, clickedPos, player)); // Use on block - if (event.getUseBlock() != DENY && flag1 && clickedState.onBlockActivated(world, player, hand, result)) + if (useBlock != DENY && flag1 && clickedState.onBlockActivated(world, player, hand, result)) return; if (stack.isEmpty()) return; - if (event.getUseItem() == DENY) + if (useItem == DENY) return; if (item instanceof BlockItem && !clickedState.isReplaceable(new BlockItemUseContext(itemusecontext))) return; diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorMovementBehaviour.java index bcb4b888d..3816d2af8 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorMovementBehaviour.java @@ -1,7 +1,6 @@ package com.simibubi.create.modules.logistics.block.extractor; import com.simibubi.create.foundation.item.ItemHelper; -import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour; import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; import com.simibubi.create.modules.logistics.block.AttachedLogisticalBlock; @@ -35,18 +34,18 @@ public class ExtractorMovementBehaviour extends MovementBehaviour { ItemStack filter = getFilter(context); int amount = getFilterAmount(context); ItemStack dropped = ItemHelper.extract(context.contraption.inventory, - stack -> FilterItem.test(context.world, stack, filter), amount == 0 ? -1 : amount, false); + stack -> FilterItem.test(context.world, stack, filter), amount == 0 ? 64 : amount, false); if (dropped.isEmpty()) return; if (world.isRemote) return; - Vec3d entityPos = VecHelper.getCenterOf(pos).add(0, -0.5f, 0); + Vec3d entityPos = context.position; Entity entityIn = null; Direction facing = AttachedLogisticalBlock.getBlockFacing(context.state); - if (facing == Direction.DOWN) - entityPos = entityPos.add(0, .5, 0); + if (facing != Direction.DOWN) + entityPos = entityPos.add(0, -0.5f, 0); entityIn = new ItemEntity(world, entityPos.x, entityPos.y, entityPos.z, dropped); entityIn.setMotion(Vec3d.ZERO); diff --git a/src/main/java/com/simibubi/create/modules/schematics/ItemRequirement.java b/src/main/java/com/simibubi/create/modules/schematics/ItemRequirement.java index 3c08adf47..7df7fc7fe 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/ItemRequirement.java +++ b/src/main/java/com/simibubi/create/modules/schematics/ItemRequirement.java @@ -7,6 +7,9 @@ import java.util.List; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.block.SeaPickleBlock; +import net.minecraft.block.SnowBlock; +import net.minecraft.block.TurtleEggBlock; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.item.ArmorStandEntity; @@ -56,6 +59,12 @@ public class ItemRequirement { // double slab needs two items if (state.has(BlockStateProperties.SLAB_TYPE) && state.get(BlockStateProperties.SLAB_TYPE) == SlabType.DOUBLE) return new ItemRequirement(ItemUseType.CONSUME, Arrays.asList(new ItemStack(item, 2))); + if (block instanceof TurtleEggBlock) + return new ItemRequirement(ItemUseType.CONSUME, Arrays.asList(new ItemStack(item, state.get(TurtleEggBlock.EGGS).intValue()))); + if (block instanceof SeaPickleBlock) + return new ItemRequirement(ItemUseType.CONSUME, Arrays.asList(new ItemStack(item, state.get(SeaPickleBlock.PICKLES).intValue()))); + if (block instanceof SnowBlock) + return new ItemRequirement(ItemUseType.CONSUME, Arrays.asList(new ItemStack(item, state.get(SnowBlock.LAYERS).intValue()))); return item == Items.AIR ? INVALID : new ItemRequirement(ItemUseType.CONSUME, item); } diff --git a/src/main/java/com/simibubi/create/modules/schematics/block/LaunchedItem.java b/src/main/java/com/simibubi/create/modules/schematics/block/LaunchedItem.java index f283eb3fe..0cdc872b8 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/block/LaunchedItem.java +++ b/src/main/java/com/simibubi/create/modules/schematics/block/LaunchedItem.java @@ -8,17 +8,24 @@ import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part; import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorItem; import com.simibubi.create.modules.contraptions.relays.elementary.ShaftBlock; +import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.NBTUtil; +import net.minecraft.particles.ParticleTypes; import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tags.FluidTags; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; +import net.minecraftforge.common.IPlantable; public abstract class LaunchedItem { @@ -108,13 +115,31 @@ public abstract class LaunchedItem { void place(World world) { // Piston if (state.has(BlockStateProperties.EXTENDED)) - state = state.with(BlockStateProperties.EXTENDED, false); + state = state.with(BlockStateProperties.EXTENDED, Boolean.FALSE); + if (state.has(BlockStateProperties.WATERLOGGED)) + state = state.with(BlockStateProperties.WATERLOGGED, Boolean.FALSE); if (AllBlocks.BELT.typeOf(state)) { world.setBlockState(target, state, 2); return; } + else if (state.getBlock() == Blocks.COMPOSTER) + state = Blocks.COMPOSTER.getDefaultState(); + else if (state.getBlock() != Blocks.SEA_PICKLE && state.getBlock() instanceof IPlantable) + state = ((IPlantable) state.getBlock()).getPlant(world, target); + if (world.dimension.doesWaterVaporize() && state.getFluidState().getFluid().isIn(FluidTags.WATER)) { + int i = target.getX(); + int j = target.getY(); + int k = target.getZ(); + world.playSound(null, target, SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.5F, 2.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.8F); + + for (int l = 0; l < 8; ++l) { + world.addParticle(ParticleTypes.LARGE_SMOKE, i + Math.random(), j + Math.random(), k + Math.random(), 0.0D, 0.0D, 0.0D); + } + Block.spawnDrops(state, world, target); + return; + } world.setBlockState(target, state, 18); state.getBlock().onBlockPlacedBy(world, target, state, null, stack); }