Merge pull request #1645 from reidbhuntley/deployer
A few more bug fixes
This commit is contained in:
commit
83e269e498
22 changed files with 228 additions and 95 deletions
|
@ -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);
|
||||
|
|
|
@ -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<ItemStack> requiredItems = requirement.getRequiredItems();
|
||||
ItemStack firstRequired = requiredItems.isEmpty() ? ItemStack.EMPTY : requiredItems.get(0);
|
||||
List<ItemRequirement.StackRequirement> 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;
|
||||
|
|
|
@ -89,8 +89,7 @@ public class AirCurrent {
|
|||
protected void tickAffectedEntities(World world, Direction facing) {
|
||||
for (Iterator<Entity> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -433,7 +433,7 @@ public class CartAssemblerBlock extends AbstractRailBlock
|
|||
}
|
||||
|
||||
@Override
|
||||
public ItemRequirement getRequiredItems(BlockState state) {
|
||||
public ItemRequirement getRequiredItems(BlockState state, TileEntity te) {
|
||||
ArrayList<ItemStack> reuiredItems = new ArrayList<>();
|
||||
reuiredItems.add(new ItemStack(getRailItem(state)));
|
||||
reuiredItems.add(new ItemStack(asItem()));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -43,11 +43,11 @@ public class PulleyBlock extends HorizontalAxisKineticBlock implements ITE<Pulle
|
|||
|
||||
private static void onRopeBroken(World world, BlockPos pulleyPos) {
|
||||
TileEntity te = world.getTileEntity(pulleyPos);
|
||||
if (!(te instanceof PulleyTileEntity))
|
||||
return;
|
||||
PulleyTileEntity pulley = (PulleyTileEntity) te;
|
||||
pulley.offset = 0;
|
||||
pulley.sendData();
|
||||
if (te instanceof PulleyTileEntity) {
|
||||
PulleyTileEntity pulley = (PulleyTileEntity) te;
|
||||
pulley.initialOffset = 0;
|
||||
pulley.onLengthBroken();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -98,7 +98,7 @@ public class PulleyBlock extends HorizontalAxisKineticBlock implements ITE<Pulle
|
|||
super(properties);
|
||||
setDefaultState(super.getDefaultState().with(BlockStateProperties.WATERLOGGED, false));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean allowsMovement(BlockState state, IBlockReader reader, BlockPos pos, PathType type) {
|
||||
return false;
|
||||
|
|
|
@ -138,10 +138,10 @@ public class EncasedPipeBlock extends Block implements IWrenchable, ISpecialBloc
|
|||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ItemRequirement getRequiredItems(BlockState state) {
|
||||
return ItemRequirement.of(AllBlocks.FLUID_PIPE.getDefaultState());
|
||||
public ItemRequirement getRequiredItems(BlockState state, TileEntity te) {
|
||||
return ItemRequirement.of(AllBlocks.FLUID_PIPE.getDefaultState(), te);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,15 +78,15 @@ public class GlassFluidPipeBlock extends AxisPipeBlock implements IWaterLoggable
|
|||
return state.get(BlockStateProperties.WATERLOGGED) ? Fluids.WATER.getStillFluidState(false)
|
||||
: Fluids.EMPTY.getDefaultState();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ItemRequirement getRequiredItems(BlockState state) {
|
||||
return ItemRequirement.of(AllBlocks.FLUID_PIPE.getDefaultState());
|
||||
public ItemRequirement getRequiredItems(BlockState state, TileEntity te) {
|
||||
return ItemRequirement.of(AllBlocks.FLUID_PIPE.getDefaultState(), te);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean allowsMovement(BlockState state, IBlockReader reader, BlockPos pos, PathType type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
|||
|
||||
/*
|
||||
* FIXME
|
||||
*
|
||||
*
|
||||
* @Override
|
||||
* public Material getMaterial(BlockState state) {
|
||||
* return state.get(CASING) ? Material.WOOD : Material.WOOL;
|
||||
|
@ -587,7 +587,7 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
|||
}
|
||||
|
||||
@Override
|
||||
public ItemRequirement getRequiredItems(BlockState state) {
|
||||
public ItemRequirement getRequiredItems(BlockState state, TileEntity te) {
|
||||
List<ItemStack> required = new ArrayList<>();
|
||||
if (state.get(PART) != BeltPart.MIDDLE)
|
||||
required.add(AllBlocks.SHAFT.asStack());
|
||||
|
|
|
@ -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<BlockState, ITriggerable> 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)));
|
||||
|
|
|
@ -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<CasingBlock> 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<CasingBlock> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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<ItemStack> 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<StackRequirement> 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<ItemStack> requiredItems) {
|
||||
this.usage = usage;
|
||||
public ItemRequirement(List<StackRequirement> 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<ItemStack> 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<ItemStack> getRequiredItems() {
|
||||
public List<StackRequirement> 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())
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ItemStack> requiredItems = requirement.getRequiredItems();
|
||||
List<ItemRequirement.StackRequirement> 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())
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue