diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b5dc4e0c..e57172aa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ * Fixed #2818 * Fixed a duplication glitch with the Woodcutter Android * Fixed #2839 +* Fixed #2849 ## Release Candidate 20 (30 Jan 2021) diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/multiblocks/MultiBlockMachine.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/multiblocks/MultiBlockMachine.java index 3be2cb608..b5bad8660 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/multiblocks/MultiBlockMachine.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/multiblocks/MultiBlockMachine.java @@ -6,6 +6,7 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; import org.apache.commons.lang.Validate; import org.bukkit.Material; @@ -26,6 +27,7 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.handlers.MultiBlockInteractionHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.OutputChest; import io.papermc.lib.PaperLib; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; @@ -50,6 +52,7 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace protected final List displayRecipes; protected final MultiBlock multiblock; + @ParametersAreNonnullByDefault public MultiBlockMachine(Category category, SlimefunItemStack item, ItemStack[] recipe, ItemStack[] machineRecipes, BlockFace trigger) { super(category, item, RecipeType.MULTIBLOCK, recipe); this.recipes = new ArrayList<>(); @@ -60,6 +63,7 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace registerDefaultRecipes(displayRecipes); } + @ParametersAreNonnullByDefault public MultiBlockMachine(Category category, SlimefunItemStack item, ItemStack[] recipe, BlockFace trigger) { this(category, item, recipe, new ItemStack[0], trigger); } @@ -142,17 +146,25 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace * The {@link Block} of our {@link Dispenser} * @param dispInv * The {@link Inventory} of our {@link Dispenser} + * * @return The target {@link Inventory} */ + @Nullable + @ParametersAreNonnullByDefault protected Inventory findOutputInventory(ItemStack adding, Block dispBlock, Inventory dispInv) { return findOutputInventory(adding, dispBlock, dispInv, dispInv); } + @Nullable + @ParametersAreNonnullByDefault protected Inventory findOutputInventory(ItemStack product, Block dispBlock, Inventory dispInv, Inventory placeCheckerInv) { Inventory outputInv = findOutputChest(dispBlock, product); - // This if-clause will trigger if no suitable output chest was found. It's functionally the same as the old fit - // check for the dispenser, only refactored. + /* + * This if-clause will trigger if no suitable output chest was found. + * It's functionally the same as the old fit check for the dispenser, + * only refactored. + */ if (outputInv == null && InvUtils.fits(placeCheckerInv, product)) { return dispInv; } else { @@ -166,9 +178,9 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace Block potentialOutput = b.getRelative(face); if (potentialOutput.getType() == Material.CHEST) { - String id = BlockStorage.checkID(potentialOutput); + SlimefunItem slimefunItem = BlockStorage.check(potentialOutput); - if (id != null && id.equals("OUTPUT_CHEST")) { + if (slimefunItem instanceof OutputChest) { // Found the output chest! Now, let's check if we can fit the product in it. BlockState state = PaperLib.getBlockState(potentialOutput, false).getState(); @@ -187,7 +199,7 @@ public abstract class MultiBlockMachine extends SlimefunItem implements NotPlace } @Nonnull - private static Material[] convertItemStacksToMaterial(ItemStack[] items) { + private static Material[] convertItemStacksToMaterial(@Nonnull ItemStack[] items) { List materials = new ArrayList<>(); for (ItemStack item : items) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/OutputChest.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/OutputChest.java new file mode 100644 index 000000000..89db27a9a --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/OutputChest.java @@ -0,0 +1,62 @@ +package io.github.thebusybiscuit.slimefun4.implementation.items.blocks; + +import java.util.List; + +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; +import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine; +import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; +import io.papermc.lib.PaperLib; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; + +/** + * The {@link OutputChest} can be used to capture the output items from a {@link MultiBlockMachine}. + * + * @author TheBusyBiscuit + * + * @see MultiBlockMachine + * + */ +public class OutputChest extends SimpleSlimefunItem { + + @ParametersAreNonnullByDefault + public OutputChest(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { + super(category, item, recipeType, recipe); + } + + @Override + public BlockBreakHandler getItemHandler() { + /* + * Explosions don't need explicit handling here. + * The default of "destroy the chest and drop the contents" is + * fine for our purposes already. + */ + return new BlockBreakHandler(false, true) { + + @Override + public void onPlayerBreak(BlockBreakEvent e, ItemStack item, List drops) { + // Fixes #2849 - Manually drop inventory contents + Block b = e.getBlock(); + BlockState state = PaperLib.getBlockState(b, false).getState(); + + if (state instanceof InventoryHolder) { + for (ItemStack stack : ((InventoryHolder) state).getInventory()) { + if (stack != null && !stack.getType().isAir()) { + drops.add(stack); + } + } + } + } + }; + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java index 0757c2931..c04289f60 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java @@ -52,6 +52,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.Crucible; import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.EnhancedFurnace; import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.HardenedGlass; import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.HologramProjector; +import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.OutputChest; import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.RainbowBlock; import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.RepairedSpawner; import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.UnplaceableBlock; @@ -243,7 +244,7 @@ public final class SlimefunItemSetup { new ItemStack[] {new ItemStack(Material.COOKIE), SlimefunItems.ELYTRA_SCALE, null, null, null, null, null, null, null}) .register(plugin); - new SlimefunItem(categories.basicMachines, SlimefunItems.OUTPUT_CHEST, RecipeType.ENHANCED_CRAFTING_TABLE, + new OutputChest(categories.basicMachines, SlimefunItems.OUTPUT_CHEST, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] {SlimefunItems.LEAD_INGOT, new ItemStack(Material.HOPPER), SlimefunItems.LEAD_INGOT, SlimefunItems.LEAD_INGOT, new ItemStack(Material.CHEST), SlimefunItems.LEAD_INGOT, null, SlimefunItems.LEAD_INGOT, null}) .register(plugin);