diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerHandler.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerHandler.java index 55f3a928d..6125d3150 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerHandler.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerHandler.java @@ -8,6 +8,12 @@ import java.util.List; import javax.annotation.Nullable; +import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlockItem; + +import net.minecraft.block.DoublePlantBlock; + +import net.minecraft.state.properties.DoubleBlockHalf; + import org.apache.commons.lang3.tuple.Pair; import com.google.common.collect.Multimap; @@ -277,7 +283,9 @@ public class DeployerHandler { return; if (useItem == DENY) return; - if (item instanceof BlockItem && !clickedState.isReplaceable(new BlockItemUseContext(itemusecontext))) + if (item instanceof BlockItem + && !(item instanceof CartAssemblerBlockItem) + && !clickedState.isReplaceable(new BlockItemUseContext(itemusecontext))) return; // Reposition fire placement for convenience @@ -349,8 +357,22 @@ public class DeployerHandler { prevHeldItem.onBlockDestroyed(world, blockstate, pos, player); if (prevHeldItem.isEmpty() && !heldItem.isEmpty()) net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(player, heldItem, Hand.MAIN_HAND); - if (!blockstate.removedByPlayer(world, pos, player, canHarvest, world.getFluidState(pos))) - return true; + + + BlockPos posUp = pos.up(); + BlockState stateUp = world.getBlockState(posUp); + if (blockstate.getBlock() instanceof DoublePlantBlock + && blockstate.get(DoublePlantBlock.HALF) == DoubleBlockHalf.LOWER + && stateUp.getBlock() == blockstate.getBlock() + && stateUp.get(DoublePlantBlock.HALF) == DoubleBlockHalf.UPPER + ) { + // hack to prevent DoublePlantBlock from dropping a duplicate item + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 35); + world.setBlockState(posUp, Blocks.AIR.getDefaultState(), 35); + } else { + if (!blockstate.removedByPlayer(world, pos, player, canHarvest, world.getFluidState(pos))) + return true; + } blockstate.getBlock() .onPlayerDestroy(world, pos, blockstate); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovementBehaviour.java index ab152a5f5..147885f31 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovementBehaviour.java @@ -107,28 +107,28 @@ public class DeployerMovementBehaviour extends MovementBehaviour { .isVecInside(pos.subtract(schematicWorld.anchor))) return; BlockState blockState = schematicWorld.getBlockState(pos); - ItemRequirement requirement = ItemRequirement.of(blockState); + ItemRequirement requirement = ItemRequirement.of(blockState, schematicWorld.getTileEntity(pos)); if (requirement.isInvalid() || requirement.isEmpty()) return; if (AllBlocks.BELT.has(blockState)) return; - List requiredItems = requirement.getRequiredItems(); - ItemStack firstRequired = requiredItems.isEmpty() ? ItemStack.EMPTY : requiredItems.get(0); + List requiredItems = requirement.getRequiredItems(); + ItemStack firstRequired = requiredItems.isEmpty() ? ItemStack.EMPTY : requiredItems.get(0).item; if (!context.contraption.hasUniversalCreativeCrate) { IItemHandler iItemHandler = context.contraption.inventory; - for (ItemStack required : requiredItems) { + for (ItemRequirement.StackRequirement required : requiredItems) { int amountFound = ItemHelper - .extract(iItemHandler, s -> ItemRequirement.validate(required, s), ExtractionCountMode.UPTO, - required.getCount(), true) + .extract(iItemHandler, s -> ItemRequirement.validate(required.item, s), ExtractionCountMode.UPTO, + required.item.getCount(), true) .getCount(); - if (amountFound < required.getCount()) + if (amountFound < required.item.getCount()) return; } - for (ItemStack required : requiredItems) - ItemHelper.extract(iItemHandler, s -> ItemRequirement.validate(required, s), ExtractionCountMode.UPTO, - required.getCount(), false); + for (ItemRequirement.StackRequirement required : requiredItems) + ItemHelper.extract(iItemHandler, s -> ItemRequirement.validate(required.item, s), ExtractionCountMode.UPTO, + required.item.getCount(), false); } CompoundNBT data = null; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java index 0440de076..3b4d2ba91 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java @@ -89,8 +89,7 @@ public class AirCurrent { protected void tickAffectedEntities(World world, Direction facing) { for (Iterator iterator = caughtEntities.iterator(); iterator.hasNext();) { Entity entity = iterator.next(); - if (!entity.isAlive() || !entity.getBoundingBox() - .intersects(bounds)) { + if (!entity.isAlive() || !entity.getBoundingBox().intersects(bounds) || isPlayerCreativeFlying(entity)) { iterator.remove(); continue; } @@ -389,4 +388,12 @@ public class AirCurrent { isClientPlayerInAirCurrent = false; } + public static boolean isPlayerCreativeFlying(Entity entity) { + if (entity instanceof PlayerEntity) { + PlayerEntity player = (PlayerEntity) entity; + return player.isCreative() && player.abilities.isFlying; + } + return false; + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/NozzleTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/NozzleTileEntity.java index 945e8498c..74c7a83b4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/NozzleTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/NozzleTileEntity.java @@ -49,7 +49,7 @@ public class NozzleTileEntity extends SmartTileEntity { compound.putFloat("Range", range); compound.putBoolean("Pushing", pushing); } - + @Override protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) { super.fromTag(state, compound, clientPacket); @@ -95,8 +95,7 @@ public class NozzleTileEntity extends SmartTileEntity { continue; double distance = diff.length(); - if (distance > range || entity.isSneaking() - || (entity instanceof PlayerEntity && ((PlayerEntity) entity).isCreative())) { + if (distance > range || entity.isSneaking() || AirCurrent.isPlayerCreativeFlying(entity)) { iterator.remove(); continue; } @@ -153,10 +152,8 @@ public class NozzleTileEntity extends SmartTileEntity { .subtract(center); double distance = diff.length(); - if (distance > range || entity.isSneaking() - || (entity instanceof PlayerEntity && ((PlayerEntity) entity).isCreative())) { + if (distance > range || entity.isSneaking() || AirCurrent.isPlayerCreativeFlying(entity)) continue; - } boolean canSee = canSee(entity); if (!canSee) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java index 1da586170..62c811bf8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java @@ -433,7 +433,7 @@ public class CartAssemblerBlock extends AbstractRailBlock } @Override - public ItemRequirement getRequiredItems(BlockState state) { + public ItemRequirement getRequiredItems(BlockState state, TileEntity te) { ArrayList reuiredItems = new ArrayList<>(); reuiredItems.add(new ItemStack(getRailItem(state))); reuiredItems.add(new ItemStack(asItem())); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java index 6cb418ec2..300f17aab 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java @@ -288,6 +288,11 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity } } + public void onLengthBroken() { + offset = 0; + sendData(); + } + @Override public boolean isValid() { return !isRemoved(); @@ -311,4 +316,4 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity public BlockPos getBlockPosition() { return pos; } -} \ No newline at end of file +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java index b88ef5c3a..d42563d24 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java @@ -9,6 +9,7 @@ import java.util.function.Predicate; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState; +import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.foundation.block.ProperDirectionalBlock; import com.simibubi.create.foundation.utility.placement.IPlacementHelper; @@ -29,6 +30,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.pathfinding.PathType; import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; @@ -71,7 +73,7 @@ public class PistonExtensionPoleBlock extends ProperDirectionalBlock implements public boolean isToolEffective(BlockState state, ToolType tool) { return tool == ToolType.AXE || tool == ToolType.PICKAXE; } - + @Override public PushReaction getPushReaction(BlockState state) { return PushReaction.NORMAL; @@ -117,6 +119,13 @@ public class PistonExtensionPoleBlock extends ProperDirectionalBlock implements .forEach(p -> worldIn.destroyBlock(p, !player.isCreative())); worldIn.setBlockState(basePos, worldIn.getBlockState(basePos) .with(MechanicalPistonBlock.STATE, PistonState.RETRACTED)); + + TileEntity te = worldIn.getTileEntity(basePos); + if (te instanceof MechanicalPistonTileEntity) { + MechanicalPistonTileEntity baseTE = (MechanicalPistonTileEntity) te; + baseTE.offset = 0; + baseTE.onLengthBroken(); + } } super.onBlockHarvested(worldIn, pos, state, player); @@ -168,7 +177,7 @@ public class PistonExtensionPoleBlock extends ProperDirectionalBlock implements } return state; } - + @Override public boolean allowsMovement(BlockState state, IBlockReader reader, BlockPos pos, PathType type) { return false; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyBlock.java index 2aa7b6d13..8ec99fff0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyBlock.java @@ -43,11 +43,11 @@ public class PulleyBlock extends HorizontalAxisKineticBlock implements ITE required = new ArrayList<>(); if (state.get(PART) != BeltPart.MIDDLE) required.add(AllBlocks.SHAFT.asStack()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/BracketedTileEntityBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/BracketedTileEntityBehaviour.java index f2dbec548..a5da7e74e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/BracketedTileEntityBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/BracketedTileEntityBehaviour.java @@ -4,6 +4,7 @@ import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; +import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.advancement.ITriggerable; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; @@ -38,7 +39,7 @@ public class BracketedTileEntityBehaviour extends TileEntityBehaviour { this.pred = pred; bracket = Optional.empty(); } - + public BracketedTileEntityBehaviour withTrigger(Function trigger) { this.trigger = trigger; return this; @@ -54,7 +55,7 @@ public class BracketedTileEntityBehaviour extends TileEntityBehaviour { reRender = true; tileEntity.notifyUpdate(); } - + public void triggerAdvancements(World world, PlayerEntity player, BlockState state) { if (trigger == null) return; @@ -81,6 +82,14 @@ public class BracketedTileEntityBehaviour extends TileEntityBehaviour { return bracket.orElse(Blocks.AIR.getDefaultState()); } + @Override + public ItemRequirement getRequiredItems() { + return ItemRequirement.of(getBracket(), null); + } + + @Override + public boolean isSafeNBT() { return true; } + @Override public void write(CompoundNBT nbt, boolean clientPacket) { bracket.ifPresent(p -> nbt.put("Bracket", NBTUtil.writeBlockState(p))); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedShaftBlock.java index d74f8f72e..09e6749a7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/EncasedShaftBlock.java @@ -22,11 +22,11 @@ public class EncasedShaftBlock extends AbstractEncasedShaftBlock implements ISpe public static EncasedShaftBlock andesite(Properties properties) { return new EncasedShaftBlock(properties, AllBlocks.ANDESITE_CASING); } - + public static EncasedShaftBlock brass(Properties properties) { return new EncasedShaftBlock(properties, AllBlocks.BRASS_CASING); } - + protected EncasedShaftBlock(Properties properties, BlockEntry casing) { super(properties); this.casing = casing; @@ -36,7 +36,7 @@ public class EncasedShaftBlock extends AbstractEncasedShaftBlock implements ISpe public TileEntity createTileEntity(BlockState state, IBlockReader world) { return AllTileEntities.ENCASED_SHAFT.create(); } - + public BlockEntry getCasing() { return casing; } @@ -49,10 +49,10 @@ public class EncasedShaftBlock extends AbstractEncasedShaftBlock implements ISpe KineticTileEntity.switchToBlockState(context.getWorld(), context.getPos(), AllBlocks.SHAFT.getDefaultState().with(AXIS, state.get(AXIS))); return ActionResultType.SUCCESS; } - + @Override - public ItemRequirement getRequiredItems(BlockState state) { - return ItemRequirement.of(AllBlocks.SHAFT.getDefaultState()); + public ItemRequirement getRequiredItems(BlockState state, TileEntity te) { + return ItemRequirement.of(AllBlocks.SHAFT.getDefaultState(), te); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/BeltFunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/BeltFunnelBlock.java index 839053db0..56de5730e 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/BeltFunnelBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/BeltFunnelBlock.java @@ -22,6 +22,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; import net.minecraft.state.EnumProperty; import net.minecraft.state.StateContainer.Builder; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.IStringSerializable; @@ -192,8 +193,8 @@ public class BeltFunnelBlock extends AbstractHorizontalFunnelBlock implements IS } @Override - public ItemRequirement getRequiredItems(BlockState state) { - return ItemRequirement.of(parent.getDefaultState()); + public ItemRequirement getRequiredItems(BlockState state, TileEntity te) { + return ItemRequirement.of(parent.getDefaultState(), te); } } diff --git a/src/main/java/com/simibubi/create/content/schematics/ISpecialBlockItemRequirement.java b/src/main/java/com/simibubi/create/content/schematics/ISpecialBlockItemRequirement.java index c23feb02a..d8c65892a 100644 --- a/src/main/java/com/simibubi/create/content/schematics/ISpecialBlockItemRequirement.java +++ b/src/main/java/com/simibubi/create/content/schematics/ISpecialBlockItemRequirement.java @@ -1,11 +1,12 @@ package com.simibubi.create.content.schematics; import net.minecraft.block.BlockState; +import net.minecraft.tileentity.TileEntity; public interface ISpecialBlockItemRequirement { - default ItemRequirement getRequiredItems(BlockState state) { + default ItemRequirement getRequiredItems(BlockState state, TileEntity te) { return ItemRequirement.INVALID; } - + } diff --git a/src/main/java/com/simibubi/create/content/schematics/ItemRequirement.java b/src/main/java/com/simibubi/create/content/schematics/ItemRequirement.java index 67c013348..eae1a4d4e 100644 --- a/src/main/java/com/simibubi/create/content/schematics/ItemRequirement.java +++ b/src/main/java/com/simibubi/create/content/schematics/ItemRequirement.java @@ -3,6 +3,10 @@ package com.simibubi.create.content.schematics; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -24,6 +28,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.SlabType; +import net.minecraft.tileentity.TileEntity; public class ItemRequirement { @@ -31,8 +36,17 @@ public class ItemRequirement { CONSUME, DAMAGE } - ItemUseType usage; - List requiredItems; + public static class StackRequirement { + public final ItemStack item; + public final ItemUseType usage; + + public StackRequirement(ItemUseType usage, ItemStack item) { + this.item = item; + this.usage = usage; + } + } + + List requiredItems; public static ItemRequirement INVALID = new ItemRequirement(); public static ItemRequirement NONE = new ItemRequirement(); @@ -40,21 +54,43 @@ public class ItemRequirement { private ItemRequirement() { } - public ItemRequirement(ItemUseType usage, Item item) { - this(usage, Arrays.asList(new ItemStack(item))); - } - - public ItemRequirement(ItemUseType usage, List requiredItems) { - this.usage = usage; + public ItemRequirement(List requiredItems) { this.requiredItems = requiredItems; } - public static ItemRequirement of(BlockState state) { + public ItemRequirement(ItemUseType usage, ItemStack items) { + this(Arrays.asList(new StackRequirement(usage, items))); + } + + public ItemRequirement(ItemUseType usage, Item item) { + this(usage, new ItemStack(item)); + } + + public ItemRequirement(ItemUseType usage, List requiredItems) { + this(requiredItems.stream().map(req -> new StackRequirement(usage, req)).collect(Collectors.toList())); + } + + + public static ItemRequirement of(BlockState state, TileEntity te) { Block block = state.getBlock(); + + ItemRequirement baseRequirement; + if (block instanceof ISpecialBlockItemRequirement) { + baseRequirement = ((ISpecialBlockItemRequirement) block).getRequiredItems(state, te); + } else { + baseRequirement = ofBlockState(state, block); + } + + // Behaviours can add additional required items + if (te instanceof SmartTileEntity) + baseRequirement = baseRequirement.with(((SmartTileEntity) te).getRequiredItems()); + + return baseRequirement; + } + + private static ItemRequirement ofBlockState(BlockState state, Block block) { if (block == Blocks.AIR) return NONE; - if (block instanceof ISpecialBlockItemRequirement) - return ((ISpecialBlockItemRequirement) block).getRequiredItems(state); Item item = BlockItem.BLOCK_TO_ITEM.getOrDefault(state.getBlock(), Items.AIR); @@ -125,16 +161,25 @@ public class ItemRequirement { return INVALID == this; } - public List getRequiredItems() { + public List getRequiredItems() { return requiredItems; } - public ItemUseType getUsage() { - return usage; - } - public static boolean validate(ItemStack required, ItemStack present) { return required.isEmpty() || required.getItem() == present.getItem(); } + public ItemRequirement with(ItemRequirement other) { + if (this.isInvalid() || other.isInvalid()) + return INVALID; + if (this.isEmpty()) + return other; + if (other.isEmpty()) + return this; + + return new ItemRequirement( + Stream.concat(requiredItems.stream(), other.requiredItems.stream()).collect(Collectors.toList()) + ); + } + } diff --git a/src/main/java/com/simibubi/create/content/schematics/MaterialChecklist.java b/src/main/java/com/simibubi/create/content/schematics/MaterialChecklist.java index e4a37dcc3..1619173b4 100644 --- a/src/main/java/com/simibubi/create/content/schematics/MaterialChecklist.java +++ b/src/main/java/com/simibubi/create/content/schematics/MaterialChecklist.java @@ -43,11 +43,11 @@ public class MaterialChecklist { if (requirement.isInvalid()) return; - for (ItemStack stack : requirement.requiredItems) { - if (requirement.getUsage() == ItemUseType.DAMAGE) - putOrIncrement(damageRequired, stack); - if (requirement.getUsage() == ItemUseType.CONSUME) - putOrIncrement(required, stack); + for (ItemRequirement.StackRequirement stack : requirement.requiredItems) { + if (stack.usage == ItemUseType.DAMAGE) + putOrIncrement(damageRequired, stack.item); + if (stack.usage == ItemUseType.CONSUME) + putOrIncrement(required, stack.item); } } diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java index ef443d62d..d3a96fc1b 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java @@ -11,6 +11,7 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllTags.AllBlockTags; +import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits; import com.simibubi.create.content.contraptions.relays.belt.BeltBlock; import com.simibubi.create.content.contraptions.relays.belt.BeltPart; import com.simibubi.create.content.contraptions.relays.belt.BeltSlope; @@ -432,6 +433,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC boolean shouldSkip = false; BlockState blockState = Blocks.AIR.getDefaultState(); + TileEntity tileEntity = null; ItemRequirement requirement; if (entityMode) { @@ -441,8 +443,9 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC } else { blockState = BlockHelper.setZeroAge(blockReader.getBlockState(target)); - requirement = ItemRequirement.of(blockState); - shouldSkip = !shouldPlace(target, blockState); + tileEntity = blockReader.getTileEntity(target); + requirement = ItemRequirement.of(blockState, tileEntity); + shouldSkip = !shouldPlace(target, blockState, tileEntity); } if (shouldSkip || requirement.isInvalid()) { @@ -452,10 +455,10 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC } // Find item - List requiredItems = requirement.getRequiredItems(); + List requiredItems = requirement.getRequiredItems(); if (!requirement.isEmpty()) { - for (ItemStack required : requiredItems) { - if (!grabItemsFromAttachedInventories(required, requirement.getUsage(), true)) { + for (ItemRequirement.StackRequirement required : requiredItems) { + if (!grabItemsFromAttachedInventories(required.item, required.usage, true)) { if (skipMissing) { statusMsg = "skipping"; blockSkipped = true; @@ -466,15 +469,15 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC return; } - missingItem = required; + missingItem = required.item; state = State.PAUSED; statusMsg = "missingBlock"; return; } } - for (ItemStack required : requiredItems) - grabItemsFromAttachedInventories(required, requirement.getUsage(), false); + for (ItemRequirement.StackRequirement required : requiredItems) + grabItemsFromAttachedInventories(required.item, required.usage, false); } // Success @@ -484,7 +487,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC else statusMsg = "clearing"; - ItemStack icon = requirement.isEmpty() || requiredItems.isEmpty() ? ItemStack.EMPTY : requiredItems.get(0); + ItemStack icon = requirement.isEmpty() || requiredItems.isEmpty() ? ItemStack.EMPTY : requiredItems.get(0).item; if (entityMode) launchEntity(target, icon, blockReader.getEntities() .collect(Collectors.toList()) @@ -728,8 +731,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC } public static boolean shouldDeferBlock(BlockState state) { - Block block = state.getBlock(); - return block instanceof AbstractRailBlock || block.is(AllBlocks.GANTRY_CARRIAGE.get()); + return state.getBlock().is(AllBlocks.GANTRY_CARRIAGE.get()) || BlockMovementTraits.isBrittle(state); } public void finishedPrinting() { @@ -759,7 +761,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC deferredBlocks.clear(); } - protected boolean shouldPlace(BlockPos pos, BlockState state) { + protected boolean shouldPlace(BlockPos pos, BlockState state, TileEntity te) { if (world == null) return false; BlockState toReplace = world.getBlockState(pos); @@ -790,7 +792,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC && (toReplace.hasTileEntity() || (toReplaceOther != null && toReplaceOther.hasTileEntity()))) return false; - if (shouldIgnoreBlockState(state)) + if (shouldIgnoreBlockState(state, te)) return false; if (replaceMode == 3) @@ -809,12 +811,12 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC return false; } - protected boolean shouldIgnoreBlockState(BlockState state) { + protected boolean shouldIgnoreBlockState(BlockState state, TileEntity te) { // Block doesnt have a mapping (Water, lava, etc) if (state.getBlock() == Blocks.STRUCTURE_VOID) return true; - ItemRequirement requirement = ItemRequirement.of(state); + ItemRequirement requirement = ItemRequirement.of(state, te); if (requirement.isEmpty()) return false; if (requirement.isInvalid()) @@ -951,15 +953,17 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC if (schematicLoaded) { blocksToPlace = blocksPlaced; for (BlockPos pos : blockReader.getAllPositions()) { - BlockState required = blockReader.getBlockState(pos.add(schematicAnchor)); + BlockPos relPos = pos.add(schematicAnchor); + BlockState required = blockReader.getBlockState(relPos); + TileEntity requiredTE = blockReader.getTileEntity(relPos); if (!getWorld().isAreaLoaded(pos.add(schematicAnchor), 0)) { checklist.warnBlockNotLoaded(); continue; } - if (!shouldPlace(pos.add(schematicAnchor), required)) + if (!shouldPlace(pos.add(schematicAnchor), required, requiredTE)) continue; - ItemRequirement requirement = ItemRequirement.of(required); + ItemRequirement requirement = ItemRequirement.of(required, blockReader.getTileEntity(relPos)); if (requirement.isEmpty()) continue; if (requirement.isInvalid()) diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java b/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java index e036d7dab..bee1a0f3e 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Map; import java.util.function.Consumer; +import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType; import com.simibubi.create.foundation.utility.IPartialSafeNBT; @@ -13,6 +14,7 @@ import com.simibubi.create.foundation.utility.IPartialSafeNBT; import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; @@ -120,6 +122,7 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka behaviourList.forEach(tb -> tb.write(compound, clientPacket)); } + @Override public void writeSafe(CompoundNBT compound, boolean clientPacket) { super.write(compound); behaviourList.forEach(tb -> { @@ -128,6 +131,14 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka }); } + public ItemRequirement getRequiredItems() { + return behaviourList.stream().reduce( + ItemRequirement.NONE, + (a,b) -> a.with(b.getRequiredItems()), + (a,b) -> a.with(b) + ); + } + @Override public void remove() { forEachBehaviour(TileEntityBehaviour::remove); diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/TileEntityBehaviour.java b/src/main/java/com/simibubi/create/foundation/tileEntity/TileEntityBehaviour.java index 931b5f4bd..cfba21b6b 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/TileEntityBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/TileEntityBehaviour.java @@ -1,8 +1,10 @@ package com.simibubi.create.foundation.tileEntity; +import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType; import net.minecraft.block.BlockState; +import net.minecraft.item.Item; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; @@ -44,6 +46,8 @@ public abstract class TileEntityBehaviour { public boolean isSafeNBT() { return false; } + public ItemRequirement getRequiredItems() { return ItemRequirement.NONE; } + public void onBlockChanged(BlockState oldState) { } diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringBehaviour.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringBehaviour.java index c6b7acebe..1768fd0cd 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringBehaviour.java @@ -4,6 +4,7 @@ import java.util.function.Consumer; import java.util.function.Supplier; import com.simibubi.create.content.logistics.item.filter.FilterItem; +import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; @@ -13,6 +14,7 @@ import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; @@ -168,6 +170,15 @@ public class FilteringBehaviour extends TileEntityBehaviour { super.destroy(); } + @Override + public ItemRequirement getRequiredItems() { + Item filterItem = filter.getItem(); + if (filterItem instanceof FilterItem) + return new ItemRequirement(ItemRequirement.ItemUseType.CONSUME, filterItem); + + return ItemRequirement.NONE; + } + public ItemStack getFilter(Direction side) { return getFilter(); } diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/SidedFilteringBehaviour.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/SidedFilteringBehaviour.java index 9a7f0a490..a1ea9383b 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/SidedFilteringBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/SidedFilteringBehaviour.java @@ -7,6 +7,7 @@ import java.util.Set; import java.util.function.BiFunction; import java.util.function.Predicate; +import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform.Sided; @@ -58,9 +59,6 @@ public class SidedFilteringBehaviour extends FilteringBehaviour { removeFilter(d); } - @Override - public boolean isSafeNBT() { return true; } - @Override public void write(CompoundNBT nbt, boolean clientPacket) { nbt.put("Filters", NBTHelper.writeCompoundList(sidedFilters.entrySet(), entry -> { @@ -122,6 +120,15 @@ public class SidedFilteringBehaviour extends FilteringBehaviour { super.destroy(); } + @Override + public ItemRequirement getRequiredItems() { + return sidedFilters.values().stream().reduce( + ItemRequirement.NONE, + (a,b) -> a.with(b.getRequiredItems()), + (a,b) -> a.with(b) + ); + } + public void removeFilter(Direction side) { if (!sidedFilters.containsKey(side)) return;