diff --git a/src/main/java/com/simibubi/create/AllItems.java b/src/main/java/com/simibubi/create/AllItems.java index 289cd0cdb..2e6300b06 100644 --- a/src/main/java/com/simibubi/create/AllItems.java +++ b/src/main/java/com/simibubi/create/AllItems.java @@ -4,7 +4,6 @@ import static com.simibubi.create.foundation.item.AllToolTypes.AXE; import static com.simibubi.create.foundation.item.AllToolTypes.HOE; import static com.simibubi.create.foundation.item.AllToolTypes.PICKAXE; import static com.simibubi.create.foundation.item.AllToolTypes.SHOVEL; -import static com.simibubi.create.foundation.item.AllToolTypes.SWORD; import java.util.function.Function; @@ -21,6 +20,7 @@ import com.simibubi.create.modules.curiosities.RefinedRadianceItem; import com.simibubi.create.modules.curiosities.ShadowSteelItem; import com.simibubi.create.modules.curiosities.deforester.DeforesterItem; import com.simibubi.create.modules.curiosities.symmetry.SymmetryWandItem; +import com.simibubi.create.modules.curiosities.tools.AllToolTiers; import com.simibubi.create.modules.curiosities.tools.BlazingToolItem; import com.simibubi.create.modules.curiosities.tools.RoseQuartzToolItem; import com.simibubi.create.modules.curiosities.tools.SandPaperItem; @@ -39,6 +39,7 @@ import net.minecraft.item.Item; import net.minecraft.item.Item.Properties; import net.minecraft.item.ItemStack; import net.minecraft.item.Rarity; +import net.minecraft.item.SwordItem; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.event.RegistryEvent; @@ -113,16 +114,16 @@ public enum AllItems { BLAZING_PICKAXE(p -> new BlazingToolItem(1, -2.8F, p, PICKAXE)), BLAZING_SHOVEL(p -> new BlazingToolItem(1.5F, -3.0F, p, SHOVEL)), BLAZING_AXE(p -> new BlazingToolItem(5.0F, -3.0F, p, AXE)), - BLAZING_SWORD(p -> new BlazingToolItem(3, -2.4F, p, SWORD)), + BLAZING_SWORD(p -> new SwordItem(AllToolTiers.BLAZING, 3, -2.4F, p)), ROSE_QUARTZ_PICKAXE(p -> new RoseQuartzToolItem(1, -2.8F, p, PICKAXE)), ROSE_QUARTZ_SHOVEL(p -> new RoseQuartzToolItem(1.5F, -3.0F, p, SHOVEL)), ROSE_QUARTZ_AXE(p -> new RoseQuartzToolItem(5.0F, -3.0F, p, AXE)), - ROSE_QUARTZ_SWORD(p -> new RoseQuartzToolItem(3, -2.4F, p, SWORD)), + ROSE_QUARTZ_SWORD(p -> new SwordItem(AllToolTiers.ROSE_QUARTZ, 3, -2.4F, p)), SHADOW_STEEL_PICKAXE(p -> new ShadowSteelToolItem(2.5F, -2.0F, p, PICKAXE)), SHADOW_STEEL_MATTOCK(p -> new ShadowSteelToolItem(2.5F, -1.5F, p, SHOVEL, AXE, HOE)), - SHADOW_STEEL_SWORD(p -> new ShadowSteelToolItem(3, -2.0F, p, SWORD)), + SHADOW_STEEL_SWORD(p -> new SwordItem(AllToolTiers.SHADOW_STEEL, 3, -2.0F, p)), ; diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java index fea3afc19..82fa386e5 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java @@ -145,7 +145,7 @@ public class FilteringBehaviour extends TileEntityBehaviour { } public boolean test(ItemStack stack) { - return filter.isEmpty() || FilterItem.test(stack, filter); + return filter.isEmpty() || FilterItem.test(tileEntity.getWorld(), stack, filter); } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java b/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java index a0ae23f18..ef4d62a29 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java @@ -61,7 +61,7 @@ public class KineticNetwork { if (te.isSource()) sources.put(te, te.getAddedStressCapacity()); members.put(te, te.getStressApplied()); - te.updateStressFromNetwork(currentCapacity, currentStress); + te.updateFromNetwork(currentCapacity, currentStress, getSize()); te.networkDirty = true; } @@ -81,7 +81,7 @@ public class KineticNetwork { if (te.isSource()) sources.remove(te); members.remove(te); - te.updateStressFromNetwork(0, 0); + te.updateFromNetwork(0, 0, 0); if (members.isEmpty()) { TorquePropagator.networks.get(te.getWorld()).remove(this.id); @@ -93,7 +93,7 @@ public class KineticNetwork { public void sync() { for (KineticTileEntity te : members.keySet()) - te.updateStressFromNetwork(currentCapacity, currentStress); + te.updateFromNetwork(currentCapacity, currentStress, getSize()); } public void updateCapacity() { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java index 15bfe06ba..373c0493f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java @@ -123,7 +123,8 @@ public class RotationPropagator { if (isLargeGearToSpeedController(stateTo, stateFrom, diff)) return SpeedControllerTileEntity.getConveyedSpeed(to, from, false); - return from.getTheoreticalSpeed() * getRotationSpeedModifier(from, to); + float rotationSpeedModifier = getRotationSpeedModifier(from, to); + return from.getTheoreticalSpeed() * rotationSpeedModifier; } private static boolean isLargeToLargeGear(BlockState from, BlockState to, BlockPos diff) { @@ -233,8 +234,8 @@ public class RotationPropagator { // Neighbour faster, overpower the incoming tree if (Math.abs(oppositeSpeed) > Math.abs(speedOfCurrent)) { float prevSpeed = currentTE.getSpeed(); - currentTE.setSpeed(oppositeSpeed); currentTE.setSource(neighbourTE.getPos()); + currentTE.setSpeed(getConveyedSpeed(neighbourTE, currentTE)); currentTE.onSpeedChanged(prevSpeed); currentTE.sendData(); @@ -256,8 +257,8 @@ public class RotationPropagator { currentTE.removeSource(); float prevSpeed = neighbourTE.getSpeed(); - neighbourTE.setSpeed(newSpeed); neighbourTE.setSource(currentTE.getPos()); + neighbourTE.setSpeed(getConveyedSpeed(currentTE, neighbourTE)); neighbourTE.onSpeedChanged(prevSpeed); neighbourTE.sendData(); propagateNewSource(neighbourTE); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java index ff189d48e..3f4f88cef 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java @@ -120,10 +120,11 @@ public abstract class KineticTileEntity extends SmartTileEntity } } - public void updateStressFromNetwork(float maxStress, float currentStress) { + public void updateFromNetwork(float maxStress, float currentStress, int networkSize) { networkDirty = false; this.capacity = maxStress; this.stress = currentStress; + this.networkSize = networkSize; boolean overStressed = maxStress < currentStress && StressImpact.isEnabled(); if (overStressed != this.overStressed) { @@ -182,7 +183,7 @@ public abstract class KineticTileEntity extends SmartTileEntity networkTag.putLong("Id", this.network); networkTag.putFloat("Stress", stress); networkTag.putFloat("Capacity", capacity); - networkTag.putInt("Size", getOrCreateNetwork().getSize()); + networkTag.putInt("Size", networkSize); float stressApplied = getStressApplied(); float addedStressCapacity = getAddedStressCapacity(); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterMovementBehaviour.java index 8daef1d42..2f3bfe2b0 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterMovementBehaviour.java @@ -13,6 +13,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.Movement import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.CropsBlock; +import net.minecraft.block.KelpBlock; import net.minecraft.block.SugarCaneBlock; import net.minecraft.item.ItemStack; import net.minecraft.state.IProperty; @@ -111,6 +112,8 @@ public class HarvesterMovementBehaviour extends MovementBehaviour { return false; } + if (state.getBlock() instanceof KelpBlock) + return true; if (state.getBlock() instanceof IPlantable) return true; } @@ -124,7 +127,9 @@ public class HarvesterMovementBehaviour extends MovementBehaviour { return crop.withAge(0); } if (state.getBlock() == Blocks.SUGAR_CANE) { - return Blocks.AIR.getDefaultState(); + if (state.getFluidState().isEmpty()) + return Blocks.AIR.getDefaultState(); + return state.getFluidState().getBlockState(); } if (state.getCollisionShape(world, pos).isEmpty()) { for (IProperty property : state.getProperties()) { @@ -136,7 +141,9 @@ public class HarvesterMovementBehaviour extends MovementBehaviour { } } - return Blocks.AIR.getDefaultState(); + if (state.getFluidState().isEmpty()) + return Blocks.AIR.getDefaultState(); + return state.getFluidState().getBlockState(); } } 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 75e51b50a..573e4b63d 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 @@ -4,6 +4,10 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock; import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; +import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock; +import com.simibubi.create.modules.logistics.block.belts.FunnelBlock; +import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; +import com.simibubi.create.modules.logistics.block.transposer.TransposerBlock; import net.minecraft.block.AbstractPressurePlateBlock; import net.minecraft.block.AbstractRailBlock; @@ -11,6 +15,7 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.DoorBlock; +import net.minecraft.block.FenceGateBlock; import net.minecraft.block.FlowerPotBlock; import net.minecraft.block.HorizontalFaceBlock; import net.minecraft.block.LadderBlock; @@ -32,6 +37,8 @@ public class BlockMovementTraits { BlockState state = world.getBlockState(pos); if (isBrittle(state)) return true; + if (state.getBlock() instanceof FenceGateBlock) + return true; if (state.getMaterial().isReplaceable()) return false; if (state.getCollisionShape(world, pos).isEmpty()) @@ -41,14 +48,19 @@ public class BlockMovementTraits { public static boolean movementAllowed(World world, BlockPos pos) { BlockState blockState = world.getBlockState(pos); - if (blockState.getBlock() instanceof AbstractChassisBlock) + Block block = blockState.getBlock(); + if (block instanceof AbstractChassisBlock) return true; if (blockState.getBlockHardness(world, pos) == -1) return false; - if (blockState.getBlock() == Blocks.OBSIDIAN) + if (block == Blocks.OBSIDIAN) return false; if (AllBlocks.BELT.typeOf(blockState)) return true; + if (block instanceof ExtractorBlock) + return true; + if (block instanceof FunnelBlock) + return true; return blockState.getPushReaction() != PushReaction.BLOCK; } @@ -62,6 +74,10 @@ public class BlockMovementTraits { return true; if (block instanceof LadderBlock) return true; + if (block instanceof ExtractorBlock) + return true; + if (block instanceof FunnelBlock) + return true; if (block instanceof TorchBlock) return true; if (block instanceof FlowerPotBlock) @@ -94,6 +110,8 @@ public class BlockMovementTraits { return direction == Direction.DOWN; if (block instanceof DoorBlock) return direction == Direction.DOWN; + if (block instanceof AttachedLogisticalBlock && !(block instanceof TransposerBlock)) + return direction == AttachedLogisticalBlock.getBlockFacing(state); if (block instanceof FlowerPotBlock) return direction == Direction.DOWN; if (block instanceof RedstoneDiodeBlock) 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 1b63899e1..84dd90e5f 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 @@ -114,9 +114,7 @@ public abstract class Contraption { frontier.add(pos); if (!addToInitialFrontier(world, pos, forcedDirection, frontier)) return false; - - Integer blockLimit = AllConfigs.SERVER.kinetics.maxBlocksMoved.get(); - for (int limit = blockLimit; limit > 0; limit--) { + for (int limit = 100000; limit > 0; limit--) { if (frontier.isEmpty()) return true; if (!moveBlock(world, frontier.remove(0), forcedDirection, frontier, visited)) @@ -183,6 +181,8 @@ public abstract class Contraption { } add(pos, capture(world, pos)); + if (blocks.size() > AllConfigs.SERVER.kinetics.maxBlocksMoved.get()) + return false; return 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 8033bbd6c..0ac222e99 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 @@ -126,7 +126,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp @Override public float getInterpolatedAngle(float partialTicks) { - if (movedContraption == null || movedContraption.isStalled()) + if (movedContraption == null || movedContraption.isStalled() || !running) partialTicks = 0; return MathHelper.lerp(partialTicks, angle, angle + getAngularSpeed()); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerMovementBehaviour.java index a700fced5..91485ee75 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerMovementBehaviour.java @@ -104,8 +104,9 @@ public class DeployerMovementBehaviour extends MovementBehaviour { if (player == null) return; if (player.getHeldItemMainhand().isEmpty()) { + ItemStack filter = getFilter(context); ItemStack held = ItemHelper.extract(context.contraption.inventory, - stack -> FilterItem.test(stack, getFilter(context)), 1, false); + stack -> FilterItem.test(context.world, stack, filter), 1, false); player.setHeldItem(Hand.MAIN_HAND, held); } } @@ -123,7 +124,8 @@ public class DeployerMovementBehaviour extends MovementBehaviour { if (itemstack.isEmpty()) continue; - if (list == inv.mainInventory && i == inv.currentItem && FilterItem.test(itemstack, filter)) + if (list == inv.mainInventory && i == inv.currentItem + && FilterItem.test(context.world, itemstack, filter)) continue; dropItem(context, itemstack); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java index a83f21e74..0bf9f9bc4 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java @@ -37,12 +37,14 @@ public class BeltInventory { final BeltTileEntity belt; final List items; + final List toInsert; boolean beltMovementPositive; final float SEGMENT_WINDOW = .75f; public BeltInventory(BeltTileEntity te) { this.belt = te; items = new LinkedList<>(); + toInsert = new LinkedList<>(); } public void tick() { @@ -54,6 +56,14 @@ public class BeltInventory { belt.markDirty(); belt.sendData(); } + + // Add items from previous cycle + if (!toInsert.isEmpty()) { + toInsert.forEach(this::insert); + toInsert.clear(); + belt.markDirty(); + belt.sendData(); + } // Assuming the first entry is furthest on the belt TransportedItemStack stackInFront = null; @@ -325,18 +335,29 @@ public class BeltInventory { else if (!beltMovementPositive) segmentPos += 1f; - for (TransportedItemStack stack : items) { - float currentPos = stack.beltPosition; - - if (stack.insertedAt == segment && stack.insertedFrom == side - && (beltMovementPositive ? currentPos <= segmentPos + 1 : currentPos >= segmentPos - 1)) + for (TransportedItemStack stack : items) + if (isBlocking(segment, side, segmentPos, stack)) return false; - - } + for (TransportedItemStack stack : toInsert) + if (isBlocking(segment, side, segmentPos, stack)) + return false; + return true; } - protected void insert(TransportedItemStack newStack) { + private boolean isBlocking(int segment, Direction side, float segmentPos, TransportedItemStack stack) { + float currentPos = stack.beltPosition; + if (stack.insertedAt == segment && stack.insertedFrom == side + && (beltMovementPositive ? currentPos <= segmentPos + 1 : currentPos >= segmentPos - 1)) + return true; + return false; + } + + public void addItem(TransportedItemStack newStack) { + toInsert.add(newStack); + } + + private void insert(TransportedItemStack newStack) { if (items.isEmpty()) items.add(newStack); else { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java index 7c9117173..45afa22a5 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java @@ -347,7 +347,7 @@ public class BeltTileEntity extends KineticTileEntity { transportedStack.insertedAt = index; transportedStack.insertedFrom = side; transportedStack.prevBeltPosition = transportedStack.beltPosition; - nextInventory.insert(transportedStack); + nextInventory.addItem(transportedStack); nextBeltController.markDirty(); nextBeltController.sendData(); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/ItemHandlerBeltSegment.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/ItemHandlerBeltSegment.java index 8a1884b03..6ba9f7c1a 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/ItemHandlerBeltSegment.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/ItemHandlerBeltSegment.java @@ -34,7 +34,7 @@ public class ItemHandlerBeltSegment implements IItemHandler { newStack.insertedAt = offset; newStack.beltPosition = offset + .5f + (beltInventory.beltMovementPositive ? -1 : 1) / 16f; newStack.prevBeltPosition = newStack.beltPosition; - this.beltInventory.insert(newStack); + this.beltInventory.addItem(newStack); this.beltInventory.belt.markDirty(); this.beltInventory.belt.sendData(); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/StressGaugeTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/StressGaugeTileEntity.java index 180edce95..fb4523184 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/StressGaugeTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/gauge/StressGaugeTileEntity.java @@ -18,8 +18,8 @@ public class StressGaugeTileEntity extends GaugeTileEntity { } @Override - public void updateStressFromNetwork(float maxStress, float currentStress) { - super.updateStressFromNetwork(maxStress, currentStress); + public void updateFromNetwork(float maxStress, float currentStress, int networkSize) { + super.updateFromNetwork(maxStress, currentStress, networkSize); if (!StressImpact.isEnabled()) dialTarget = 0; @@ -51,7 +51,8 @@ public class StressGaugeTileEntity extends GaugeTileEntity { markDirty(); return; } - updateStressFromNetwork(capacity, stress); + + updateFromNetwork(capacity, stress, getOrCreateNetwork().getSize()); } @Override @@ -67,7 +68,8 @@ public class StressGaugeTileEntity extends GaugeTileEntity { tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("gui.stress_gauge.title")); if (getTheoreticalSpeed() == 0) - tooltip.add(TextFormatting.DARK_GRAY + ItemDescription.makeProgressBar(3, -1) + Lang.translate("gui.stress_gauge.no_rotation")); + tooltip.add(TextFormatting.DARK_GRAY + ItemDescription.makeProgressBar(3, -1) + + Lang.translate("gui.stress_gauge.no_rotation")); else { tooltip.add(spacing + StressImpact.getFormattedStressText(stressFraction)); @@ -76,10 +78,13 @@ public class StressGaugeTileEntity extends GaugeTileEntity { double remainingCapacity = capacity - getNetworkStress(); double remainingCapacityAtBase = remainingCapacity / Math.abs(getTheoreticalSpeed()); - String capacityString = spacing + StressImpact.of(stressFraction).getRelativeColor() + "%s" + Lang.translate("generic.unit.stress") + " " + TextFormatting.DARK_GRAY + "%s"; + String capacityString = spacing + StressImpact.of(stressFraction).getRelativeColor() + "%s" + + Lang.translate("generic.unit.stress") + " " + TextFormatting.DARK_GRAY + "%s"; - tooltip.add(String.format(capacityString, IHaveGoggleInformation.format(remainingCapacityAtBase), Lang.translate("gui.goggles.base_value"))); - tooltip.add(String.format(capacityString, IHaveGoggleInformation.format(remainingCapacity), Lang.translate("gui.goggles.at_current_speed"))); + tooltip.add(String.format(capacityString, IHaveGoggleInformation.format(remainingCapacityAtBase), + Lang.translate("gui.goggles.base_value"))); + tooltip.add(String.format(capacityString, IHaveGoggleInformation.format(remainingCapacity), + Lang.translate("gui.goggles.at_current_speed"))); } diff --git a/src/main/java/com/simibubi/create/modules/curiosities/deforester/DeforesterItem.java b/src/main/java/com/simibubi/create/modules/curiosities/deforester/DeforesterItem.java index aa9c3eb4c..a265b31a2 100644 --- a/src/main/java/com/simibubi/create/modules/curiosities/deforester/DeforesterItem.java +++ b/src/main/java/com/simibubi/create/modules/curiosities/deforester/DeforesterItem.java @@ -32,7 +32,7 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; public class DeforesterItem extends AxeItem implements IHaveCustomItemModel { public DeforesterItem(Properties builder) { - super(AllToolTiers.RADIANT, 10.0F, -3.1F, builder); + super(AllToolTiers.RADIANT, 5.0F, -3.1F, builder); } // Moved away from Item#onBlockDestroyed as it does not get called in Creative diff --git a/src/main/java/com/simibubi/create/modules/curiosities/tools/BlazingToolItem.java b/src/main/java/com/simibubi/create/modules/curiosities/tools/BlazingToolItem.java index 27aa1107a..7c24a302f 100644 --- a/src/main/java/com/simibubi/create/modules/curiosities/tools/BlazingToolItem.java +++ b/src/main/java/com/simibubi/create/modules/curiosities/tools/BlazingToolItem.java @@ -67,12 +67,16 @@ public class BlazingToolItem extends AbstractToolItem { public void modifyDrops(Collection drops, IWorld world, BlockPos pos, ItemStack tool, BlockState state) { super.modifyDrops(drops, world, pos, tool, state); World worldIn = world.getWorld(); - helperFurnace.setWorld(worldIn); - - RecipeManager recipeManager = worldIn.getRecipeManager(); int enchantmentLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, tool); if (state == null) enchantmentLevel = 0; + List smeltedStacks = smeltDrops(drops, worldIn, enchantmentLevel); + drops.addAll(smeltedStacks); + } + + public static List smeltDrops(Collection drops, World worldIn, int enchantmentLevel) { + helperFurnace.setWorld(worldIn); + RecipeManager recipeManager = worldIn.getRecipeManager(); List smeltedStacks = new ArrayList<>(); Iterator dropper = drops.iterator(); while (dropper.hasNext()) { @@ -87,13 +91,12 @@ public class BlazingToolItem extends AbstractToolItem { float modifier = 1; if (stack.getItem() instanceof BlockItem && !(out.getItem() instanceof BlockItem)) - modifier += world.getRandom().nextFloat() * enchantmentLevel; + modifier += worldIn.getRandom().nextFloat() * enchantmentLevel; out.setCount((int) (out.getCount() * modifier + .4f)); smeltedStacks.addAll(ItemHelper.multipliedOutput(stack, out)); } - - drops.addAll(smeltedStacks); + return smeltedStacks; } @Override diff --git a/src/main/java/com/simibubi/create/modules/curiosities/tools/SandPaperItem.java b/src/main/java/com/simibubi/create/modules/curiosities/tools/SandPaperItem.java index ff23eafc6..d50bd5948 100644 --- a/src/main/java/com/simibubi/create/modules/curiosities/tools/SandPaperItem.java +++ b/src/main/java/com/simibubi/create/modules/curiosities/tools/SandPaperItem.java @@ -113,7 +113,12 @@ public class SandPaperItem extends Item implements IHaveCustomItemModel { public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) { return enchantment == Enchantments.FORTUNE || super.canApplyAtEnchantingTable(stack, enchantment); } - + + @Override + public int getItemEnchantability(ItemStack stack) { + return 1; + } + @Override public ItemStack onItemUseFinish(ItemStack stack, World worldIn, LivingEntity entityLiving) { if (!(entityLiving instanceof PlayerEntity)) 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 8c845a458..5b10dc99a 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 @@ -16,8 +16,10 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.item.IItemTier; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.TieredItem; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.EntityDamageSource; import net.minecraft.util.math.BlockPos; @@ -98,8 +100,11 @@ public class ToolEvents { ItemStack heldItemMainhand = player.getHeldItemMainhand(); String marker = "create_roseQuartzRange"; CompoundNBT persistentData = player.getPersistentData(); + Item item = heldItemMainhand.getItem(); + boolean holdingRoseQuartz = + item instanceof TieredItem && ((TieredItem) item).getTier() == AllToolTiers.ROSE_QUARTZ; - if (!(heldItemMainhand.getItem() instanceof RoseQuartzToolItem)) { + if (!holdingRoseQuartz) { if (persistentData.contains(marker)) { player.getAttributes().removeAttributeModifiers(RoseQuartzToolItem.rangeModifier); persistentData.remove(marker); @@ -127,18 +132,20 @@ public class ToolEvents { PlayerEntity player = (PlayerEntity) trueSource; ItemStack heldItemMainhand = player.getHeldItemMainhand(); Item item = heldItemMainhand.getItem(); + IItemTier tier = item instanceof TieredItem ? ((TieredItem) item).getTier() : null; - if (item instanceof ShadowSteelToolItem) + if (tier == AllToolTiers.SHADOW_STEEL) event.setCanceled(true); - if (item instanceof BlazingToolItem) { - BlazingToolItem blazingToolItem = (BlazingToolItem) item; + if (tier == AllToolTiers.BLAZING) { List drops = event.getDrops().stream().map(entity -> { ItemStack stack = entity.getItem(); entity.remove(); return stack; }).collect(Collectors.toList()); - blazingToolItem.modifyDrops(drops, world, player.getPosition(), heldItemMainhand, null); + + drops = BlazingToolItem.smeltDrops(drops, world, 0); + event.getDrops().clear(); drops.stream().map(stack -> { ItemEntity entity = new ItemEntity(world, target.posX, target.posY, target.posZ, stack); @@ -156,7 +163,10 @@ public class ToolEvents { if (attackingPlayer == null) return; ItemStack heldItemMainhand = attackingPlayer.getHeldItemMainhand(); - if (heldItemMainhand.getItem() instanceof ShadowSteelToolItem) { + Item item = heldItemMainhand.getItem(); + IItemTier tier = item instanceof TieredItem ? ((TieredItem) item).getTier() : null; + + if (tier == AllToolTiers.SHADOW_STEEL) { int level = EnchantmentHelper.getEnchantmentLevel(Enchantments.LOOTING, heldItemMainhand); float modifier = 1 + event.getEntity().world.getRandom().nextFloat() * level; event.setDroppedExperience((int) (event.getDroppedExperience() * modifier + .4f)); diff --git a/src/main/java/com/simibubi/create/modules/logistics/InWorldProcessing.java b/src/main/java/com/simibubi/create/modules/logistics/InWorldProcessing.java index 498957d09..7153180af 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/InWorldProcessing.java +++ b/src/main/java/com/simibubi/create/modules/logistics/InWorldProcessing.java @@ -58,7 +58,7 @@ public class InWorldProcessing { public static Type byBlock(IBlockReader reader, BlockPos pos) { BlockState blockState = reader.getBlockState(pos); IFluidState fluidState = reader.getFluidState(pos); - if (fluidState.getFluid() == Fluids.WATER) + if (fluidState.getFluid() == Fluids.WATER || fluidState.getFluid() == Fluids.FLOWING_WATER) return Type.SPLASHING; if (blockState.getBlock() == Blocks.FIRE || (blockState.getBlock() == Blocks.CAMPFIRE && blockState.get(CampfireBlock.LIT))) @@ -103,16 +103,19 @@ public class InWorldProcessing { return recipe.isPresent(); } - if (type == Type.SPLASHING) { - splashingInv.setInventorySlotContents(0, stack); - Optional recipe = - world.getRecipeManager().getRecipe(AllRecipes.SPLASHING.getType(), splashingInv, world); - return recipe.isPresent(); - } + if (type == Type.SPLASHING) + return isWashable(stack, world); return false; } + public static boolean isWashable(ItemStack stack, World world) { + splashingInv.setInventorySlotContents(0, stack); + Optional recipe = + world.getRecipeManager().getRecipe(AllRecipes.SPLASHING.getType(), splashingInv, world); + return recipe.isPresent(); + } + public static void applyProcessing(ItemEntity entity, Type type) { if (decrementProcessingTime(entity, type) != 0) return; @@ -152,6 +155,8 @@ public class InWorldProcessing { List transportedStacks = new ArrayList<>(); for (ItemStack additional : stacks) { TransportedItemStack newTransported = transported.getSimilar(); + newTransported.beltPosition -= Math.signum(belt.getDirectionAwareBeltMovementSpeed()) * 1/32f; + newTransported.prevBeltPosition = newTransported.beltPosition; newTransported.stack = additional.copy(); transportedStacks.add(newTransported); } @@ -279,7 +284,7 @@ public class InWorldProcessing { public static void spawnParticlesForProcessing(World world, Vec3d vec, Type type) { if (!world.isRemote) return; - if (world.rand.nextInt(4) != 0) + if (world.rand.nextInt(8) != 0) return; switch (type) { diff --git a/src/main/java/com/simibubi/create/modules/logistics/RedstoneLinkNetworkHandler.java b/src/main/java/com/simibubi/create/modules/logistics/RedstoneLinkNetworkHandler.java index 84068e0d5..71fd9a820 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/RedstoneLinkNetworkHandler.java +++ b/src/main/java/com/simibubi/create/modules/logistics/RedstoneLinkNetworkHandler.java @@ -93,6 +93,10 @@ public class RedstoneLinkNetworkHandler { iterator.remove(); continue; } + if (actor.getWorld().getTileEntity(other.tileEntity.getPos()) != other.tileEntity) { + iterator.remove(); + continue; + } if (!withinRange(actor, other)) continue; if (other.isTransmitting()) { diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkBlock.java index c6d4d6f2d..09fc35705 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkBlock.java @@ -2,6 +2,7 @@ package com.simibubi.create.modules.logistics.block; import com.simibubi.create.foundation.block.ProperDirectionalBlock; import com.simibubi.create.foundation.utility.AllShapes; +import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -61,6 +62,12 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock { return; boolean shouldPower = worldIn.getWorld().isBlockPowered(pos); + + for (Direction direction : Iterate.directions) { + BlockPos blockpos = pos.offset(direction); + shouldPower |= worldIn.getRedstonePower(blockpos, Direction.UP) > 0; + } + boolean previouslyPowered = state.get(POWERED); if (previouslyPowered != shouldPower) { @@ -134,7 +141,7 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock { @Override public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, Direction side) { - return state.get(FACING) == Direction.UP && side != null; + return side != null; } @Override diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelBlock.java index d8df6946e..53c0ce5c8 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelBlock.java @@ -9,6 +9,8 @@ import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.utility.AllShapes; +import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock; +import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; @@ -34,9 +36,10 @@ import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.World; -public class FunnelBlock extends AttachedLogisticalBlock implements IBeltAttachment, IWithTileEntity { +public class FunnelBlock extends AttachedLogisticalBlock implements IBeltAttachment, IWithTileEntity, IPortableBlock { public static final BooleanProperty BELT = BooleanProperty.create("belt"); + public static final MovementBehaviour MOVEMENT = new FunnelMovementBehaviour(); @Override protected void fillStateContainer(Builder builder) { @@ -211,4 +214,9 @@ public class FunnelBlock extends AttachedLogisticalBlock implements IBeltAttachm } } + @Override + public MovementBehaviour getMovementBehaviour() { + return MOVEMENT; + } + } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelMovementBehaviour.java new file mode 100644 index 000000000..0831d5b57 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelMovementBehaviour.java @@ -0,0 +1,48 @@ +package com.simibubi.create.modules.logistics.block.belts; + +import java.util.List; + +import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour; +import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; +import com.simibubi.create.modules.logistics.item.filter.FilterItem; + +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.items.ItemHandlerHelper; + +public class FunnelMovementBehaviour extends MovementBehaviour { + + @Override + public void visitNewPosition(MovementContext context, BlockPos pos) { + super.visitNewPosition(context, pos); + + World world = context.world; + List items = world.getEntitiesWithinAABB(ItemEntity.class, new AxisAlignedBB(pos)); + ItemStack filter = getFilter(context); + + for (ItemEntity item : items) { + ItemStack toInsert = item.getItem(); + if (!filter.isEmpty() && !FilterItem.test(context.world, toInsert, filter)) + continue; + ItemStack remainder = ItemHandlerHelper.insertItemStacked(context.contraption.inventory, toInsert, false); + if (remainder.getCount() == toInsert.getCount()) + continue; + if (remainder.isEmpty()) { + item.setItem(ItemStack.EMPTY); + item.remove(); + continue; + } + + item.setItem(remainder); + } + + } + + private ItemStack getFilter(MovementContext context) { + return ItemStack.read(context.tileData.getCompound("Filter")); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorBlock.java index 172ed7d97..c389bd418 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorBlock.java @@ -4,6 +4,8 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock; +import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour; import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock; import com.simibubi.create.modules.logistics.block.belts.BeltAttachableLogisticalBlock; @@ -22,9 +24,10 @@ import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; -public class ExtractorBlock extends BeltAttachableLogisticalBlock { +public class ExtractorBlock extends BeltAttachableLogisticalBlock implements IPortableBlock { public static BooleanProperty POWERED = BlockStateProperties.POWERED; + private static final MovementBehaviour MOVEMENT = new ExtractorMovementBehaviour(); public ExtractorBlock() { super(); @@ -119,4 +122,9 @@ public class ExtractorBlock extends BeltAttachableLogisticalBlock { } } + @Override + public MovementBehaviour getMovementBehaviour() { + return MOVEMENT; + } + } \ No newline at end of file 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 new file mode 100644 index 000000000..3662aab8c --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorMovementBehaviour.java @@ -0,0 +1,66 @@ +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.belts.AttachedLogisticalBlock; +import com.simibubi.create.modules.logistics.item.filter.FilterItem; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Direction; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.World; + +public class ExtractorMovementBehaviour extends MovementBehaviour { + + @Override + public void visitNewPosition(MovementContext context, BlockPos pos) { + super.visitNewPosition(context, pos); + + World world = context.world; + VoxelShape collisionShape = world.getBlockState(pos).getCollisionShape(world, pos); + if (!collisionShape.isEmpty()) + return; + if (!world.getEntitiesWithinAABB(ItemEntity.class, new AxisAlignedBB(pos)).isEmpty()) + return; + + 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); + + if (dropped.isEmpty()) + return; + if (world.isRemote) + return; + + Vec3d entityPos = VecHelper.getCenterOf(pos).add(0, -0.5f, 0); + Entity entityIn = null; + Direction facing = AttachedLogisticalBlock.getBlockFacing(context.state); + if (facing == Direction.DOWN) + entityPos = entityPos.add(0, .5, 0); + + entityIn = new ItemEntity(world, entityPos.x, entityPos.y, entityPos.z, dropped); + entityIn.setMotion(Vec3d.ZERO); + ((ItemEntity) entityIn).setPickupDelay(5); + world.playSound(null, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, 1/16f, .1f); + world.addEntity(entityIn); + } + + private ItemStack getFilter(MovementContext context) { + return ItemStack.read(context.tileData.getCompound("Filter")); + } + + private int getFilterAmount(MovementContext context) { + return context.tileData.getInt("FilterAmount"); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerBlock.java index c3580de1b..172541992 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerBlock.java @@ -30,7 +30,7 @@ public class TransposerBlock extends BeltAttachableLogisticalBlock implements IW public TransposerBlock() { setDefaultState(getDefaultState().with(POWERED, false)); } - + @Override public boolean hasTileEntity(BlockState state) { return true; diff --git a/src/main/java/com/simibubi/create/modules/logistics/item/filter/AttributeFilterScreen.java b/src/main/java/com/simibubi/create/modules/logistics/item/filter/AttributeFilterScreen.java index f5b32a1f7..4a1a4423a 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/item/filter/AttributeFilterScreen.java +++ b/src/main/java/com/simibubi/create/modules/logistics/item/filter/AttributeFilterScreen.java @@ -109,7 +109,7 @@ public class AttributeFilterScreen extends AbstractFilterScreen options = attributesOfItem.stream().map(ItemAttribute::format).collect(Collectors.toList()); attributeSelector.forOptions(options); attributeSelector.active = true; diff --git a/src/main/java/com/simibubi/create/modules/logistics/item/filter/FilterItem.java b/src/main/java/com/simibubi/create/modules/logistics/item/filter/FilterItem.java index 9d8b478c5..1e7b08a67 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/item/filter/FilterItem.java +++ b/src/main/java/com/simibubi/create/modules/logistics/item/filter/FilterItem.java @@ -152,11 +152,11 @@ public class FilterItem extends Item implements INamedContainerProvider { return newInv; } - public static boolean test(ItemStack stack, ItemStack filter) { - return test(stack, filter, false); + public static boolean test(World world, ItemStack stack, ItemStack filter) { + return test(world, stack, filter, false); } - private static boolean test(ItemStack stack, ItemStack filter, boolean matchNBT) { + private static boolean test(World world, ItemStack stack, ItemStack filter, boolean matchNBT) { if (filter.isEmpty()) return true; @@ -172,7 +172,7 @@ public class FilterItem extends Item implements INamedContainerProvider { ItemStack stackInSlot = filterItems.getStackInSlot(slot); if (stackInSlot.isEmpty()) continue; - boolean matches = test(stack, stackInSlot, respectNBT); + boolean matches = test(world, stack, stackInSlot, respectNBT); if (matches) return !blacklist; } @@ -184,7 +184,7 @@ public class FilterItem extends Item implements INamedContainerProvider { ListNBT attributes = filter.getOrCreateTag().getList("MatchedAttributes", NBT.TAG_COMPOUND); for (INBT inbt : attributes) { ItemAttribute attribute = ItemAttribute.fromNBT((CompoundNBT) inbt); - boolean matches = attribute.appliesTo(stack); + boolean matches = attribute.appliesTo(stack, world); if (matches) { switch (whitelistMode) { diff --git a/src/main/java/com/simibubi/create/modules/logistics/item/filter/ItemAttribute.java b/src/main/java/com/simibubi/create/modules/logistics/item/filter/ItemAttribute.java index 11f17fa82..43ac89f0a 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/item/filter/ItemAttribute.java +++ b/src/main/java/com/simibubi/create/modules/logistics/item/filter/ItemAttribute.java @@ -5,6 +5,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.function.BiPredicate; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -12,20 +13,27 @@ import org.apache.commons.lang3.StringUtils; import com.google.common.base.Predicates; import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.modules.logistics.InWorldProcessing; import net.minecraft.client.resources.I18n; +import net.minecraft.inventory.IInventory; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.IRecipeType; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.AbstractFurnaceTileEntity; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.ModContainer; import net.minecraftforge.fml.ModList; import net.minecraftforge.forgespi.language.IModInfo; +import net.minecraftforge.items.ItemStackHandler; +import net.minecraftforge.items.wrapper.RecipeWrapper; public interface ItemAttribute { @@ -41,7 +49,15 @@ public interface ItemAttribute { return attributeType; } - public boolean appliesTo(ItemStack stack); + default boolean appliesTo(ItemStack stack, World world) { + return appliesTo(stack); + } + + boolean appliesTo(ItemStack stack); + + default List listAttributesOf(ItemStack stack, World world) { + return listAttributesOf(stack); + } public List listAttributesOf(ItemStack stack); @@ -73,7 +89,7 @@ public interface ItemAttribute { default boolean canRead(CompoundNBT nbt) { return nbt.contains(getNBTKey()); } - + default String getNBTKey() { return getTranslationKey(); } @@ -93,28 +109,55 @@ public interface ItemAttribute { BADLY_DAMAGED(s -> s.isDamaged() && s.getDamage() / s.getMaxDamage() > 3 / 4f), NOT_STACKABLE(Predicates.not(ItemStack::isStackable)), EQUIPABLE(s -> s.getEquipmentSlot() != null), - FURNACE_FUEL(AbstractFurnaceTileEntity::isFuel); + FURNACE_FUEL(AbstractFurnaceTileEntity::isFuel), + WASHABLE(InWorldProcessing::isWashable), + SMELTABLE((s, w) -> testRecipe(s, w, IRecipeType.SMELTING)), + SMOKABLE((s, w) -> testRecipe(s, w, IRecipeType.SMOKING)), + BLASTABLE((s, w) -> testRecipe(s, w, IRecipeType.BLASTING)); + private static final RecipeWrapper RECIPE_WRAPPER = new RecipeWrapper(new ItemStackHandler(1)); private Predicate test; + private BiPredicate testWithWorld; private StandardTraits(Predicate test) { this.test = test; } + private static boolean testRecipe(ItemStack s, World w, IRecipeType> smelting) { + RECIPE_WRAPPER.setInventorySlotContents(0, s.copy()); + return w.getRecipeManager().getRecipe(smelting, RECIPE_WRAPPER, w).isPresent(); + } + + private StandardTraits(BiPredicate test) { + this.testWithWorld = test; + } + + @Override + public boolean appliesTo(ItemStack stack, World world) { + if (testWithWorld != null) + return testWithWorld.test(stack, world); + return appliesTo(stack); + } + @Override public boolean appliesTo(ItemStack stack) { return test.test(stack); } @Override - public List listAttributesOf(ItemStack stack) { + public List listAttributesOf(ItemStack stack, World world) { List attributes = new ArrayList<>(); for (StandardTraits trait : values()) - if (trait.test.test(stack)) + if (trait.appliesTo(stack, world)) attributes.add(trait); return attributes; } + @Override + public List listAttributesOf(ItemStack stack) { + return null; + } + @Override public String getTranslationKey() { return Lang.asId(name()); diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 5146cb722..3471d8dbe 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -14,7 +14,7 @@ Technology that empowers the player.''' [[dependencies.create]] modId="forge" mandatory=true - versionRange="[28.1.20,)" + versionRange="[28.1.56,)" ordering="NONE" side="BOTH" diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index f6c0b1bca..29539f949 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -545,6 +545,10 @@ "create.item_attributes.placeable": "is placeable", "create.item_attributes.consumable": "can be eaten", + "create.item_attributes.smeltable": "can be Smelted", + "create.item_attributes.washable": "can be Washed", + "create.item_attributes.smokable": "can be Smoked", + "create.item_attributes.blastable": "is smeltable in Blast Furnace", "create.item_attributes.enchanted": "is enchanted", "create.item_attributes.damaged": "is damaged", "create.item_attributes.badly_damaged": "is heavily damaged",