From 911f8aeceb002c0e987e7978d15087a4a3822336 Mon Sep 17 00:00:00 2001 From: TheBusyBiscuit Date: Thu, 9 Apr 2020 14:22:30 +0200 Subject: [PATCH] [CI skip] More refactoring and overall API improvements --- CHANGELOG.md | 2 + .../multiblocks/AutomatedPanningMachine.java | 181 ++++++------------ .../items/tools/ExplosivePickaxe.java | 5 +- .../implementation/items/tools/GoldPan.java | 10 +- .../Slimefun/Objects/Category.java | 14 +- .../Objects/SlimefunItem/ItemState.java | 2 +- .../Objects/SlimefunItem/SlimefunItem.java | 74 ++++--- 7 files changed, 132 insertions(+), 156 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09210105d..bc571bff7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,8 @@ * Split whitelist.yml up into individual /world-settings/worldname.yml files * Performance improvements * Slimefun Guide runs much faster now and can better deal with many Categories and items +* Lots of API improvements +* Faulty addons are now identified more easily and will no longer break Slimefun's main content this quickly #### Fixes * Fixed error message when clicking empty slots in the Slimefun Guide diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/AutomatedPanningMachine.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/AutomatedPanningMachine.java index 17d0ddd02..420520a64 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/AutomatedPanningMachine.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/AutomatedPanningMachine.java @@ -1,5 +1,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks; +import java.util.ArrayList; +import java.util.List; + import org.bukkit.Effect; import org.bukkit.GameMode; import org.bukkit.Material; @@ -10,141 +13,73 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import io.github.thebusybiscuit.cscorelib2.collections.RandomizedSet; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.cscorelib2.scheduling.TaskQueue; +import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GoldPan; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.Lists.Categories; import me.mrCookieSlime.Slimefun.Lists.SlimefunItems; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.multiblocks.MultiBlockMachine; -import me.mrCookieSlime.Slimefun.api.Slimefun; public class AutomatedPanningMachine extends MultiBlockMachine { - - private final RandomizedSet randomizer = new RandomizedSet<>(); - private int weights; - - private final RandomizedSet randomizerNether = new RandomizedSet<>(); - private int weightsNether; - public AutomatedPanningMachine() { - super( - Categories.MACHINES_1, - SlimefunItems.AUTOMATED_PANNING_MACHINE, - new ItemStack[] { - null, null, null, - null, new ItemStack(Material.OAK_TRAPDOOR), null, - null, new ItemStack(Material.CAULDRON), null - }, - new ItemStack[] { - new ItemStack(Material.GRAVEL), new ItemStack(Material.FLINT), - new ItemStack(Material.GRAVEL), SlimefunItems.SIFTED_ORE, - new ItemStack(Material.GRAVEL), new ItemStack(Material.CLAY_BALL), - new ItemStack(Material.GRAVEL), new ItemStack(Material.IRON_NUGGET), - new ItemStack(Material.SOUL_SAND), new ItemStack(Material.QUARTZ), - new ItemStack(Material.SOUL_SAND), new ItemStack(Material.GOLD_NUGGET), - new ItemStack(Material.SOUL_SAND), new ItemStack(Material.NETHER_WART), - new ItemStack(Material.SOUL_SAND), new ItemStack(Material.BLAZE_POWDER), - new ItemStack(Material.SOUL_SAND), new ItemStack(Material.GLOWSTONE_DUST), - new ItemStack(Material.SOUL_SAND), new ItemStack(Material.GHAST_TEAR) - }, - BlockFace.SELF - ); - } - - @Override - public void postRegister() { - super.postRegister(); - - String goldPan = "GOLD_PAN"; - String netherGoldPan = "NETHER_GOLD_PAN"; - - add(false, SlimefunItems.SIFTED_ORE, (int) Slimefun.getItemValue(goldPan, "chance.SIFTED_ORE")); - add(false, new ItemStack(Material.CLAY_BALL), (int) Slimefun.getItemValue(goldPan, "chance.CLAY")); - add(false, new ItemStack(Material.FLINT), (int) Slimefun.getItemValue(goldPan, "chance.FLINT")); - add(false, new ItemStack(Material.IRON_NUGGET), (int) Slimefun.getItemValue(goldPan, "chance.IRON_NUGGET")); + private final GoldPan goldPan = (GoldPan) SlimefunItems.GOLD_PAN.getItem(); + private final GoldPan netherGoldPan = (GoldPan) SlimefunItems.NETHER_GOLD_PAN.getItem(); - if (weights < 100) { - add(false, new ItemStack(Material.AIR), 100 - weights); - } - - add(true, new ItemStack(Material.QUARTZ), (int) Slimefun.getItemValue(netherGoldPan, "chance.QUARTZ")); - add(true, new ItemStack(Material.GOLD_NUGGET), (int) Slimefun.getItemValue(netherGoldPan, "chance.GOLD_NUGGET")); - add(true, new ItemStack(Material.NETHER_WART), (int) Slimefun.getItemValue(netherGoldPan, "chance.NETHER_WART")); - add(true, new ItemStack(Material.BLAZE_POWDER), (int) Slimefun.getItemValue(netherGoldPan, "chance.BLAZE_POWDER")); - add(true, new ItemStack(Material.GLOWSTONE_DUST), (int) Slimefun.getItemValue(netherGoldPan, "chance.GLOWSTONE_DUST")); - add(true, new ItemStack(Material.GHAST_TEAR), (int) Slimefun.getItemValue(netherGoldPan, "chance.GHAST_TEAR")); - + public AutomatedPanningMachine() { + super(Categories.MACHINES_1, SlimefunItems.AUTOMATED_PANNING_MACHINE, new ItemStack[] { null, null, null, null, new ItemStack(Material.OAK_TRAPDOOR), null, null, new ItemStack(Material.CAULDRON), null }, new ItemStack[0], BlockFace.SELF); + } - if (weightsNether < 100) { - add(true, new ItemStack(Material.AIR), 100 - weightsNether); - } - } - - private void add(boolean nether, ItemStack item, int chance) { - if (nether) { - randomizerNether.add(item, chance); - weightsNether += chance; - } - else { - randomizer.add(item, chance); - weights += chance; - } - } - - @Override - public void onInteract(Player p, Block b) { - ItemStack input = p.getInventory().getItemInMainHand(); - - if (SlimefunUtils.isItemSimilar(input, new ItemStack(Material.GRAVEL), true) || SlimefunUtils.isItemSimilar(input, new ItemStack(Material.SOUL_SAND), true)) { - Material block = input.getType(); - - if (p.getGameMode() != GameMode.CREATIVE) { - ItemUtils.consumeItem(input, false); - } - - ItemStack output = getRandomDrop(block); - TaskQueue queue = new TaskQueue(); - - queue.thenRepeatEvery(20, 5, () -> - b.getWorld().playEffect(b.getRelative(BlockFace.DOWN).getLocation(), Effect.STEP_SOUND, block) - ); - - queue.thenRun(20, () -> { - if (output.getType() != Material.AIR) { - Inventory outputChest = findOutputChest(b.getRelative(BlockFace.DOWN), output); - - if (outputChest != null) { - outputChest.addItem(output.clone()); - } - else { - b.getWorld().dropItemNaturally(b.getLocation(), output.clone()); - } - - p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F); - } - else { - p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARMOR_STAND_BREAK, 1F, 1F); - } - }); - - queue.execute(SlimefunPlugin.instance); - } - else { - SlimefunPlugin.getLocal().sendMessage(p, "machines.wrong-item", true); - } - } + @Override + public List getDisplayRecipes() { + List recipes = new ArrayList<>(); - private ItemStack getRandomDrop(Material input) { - if (input == Material.GRAVEL) { - return randomizer.getRandom(); - } - else if (input == Material.SOUL_SAND) { - return randomizerNether.getRandom(); - } - - return new ItemStack(Material.AIR); - } + recipes.addAll(goldPan.getDisplayRecipes()); + recipes.addAll(netherGoldPan.getDisplayRecipes()); + + return recipes; + } + + @Override + public void onInteract(Player p, Block b) { + ItemStack input = p.getInventory().getItemInMainHand(); + + if (SlimefunUtils.isItemSimilar(input, new ItemStack(Material.GRAVEL), true) || SlimefunUtils.isItemSimilar(input, new ItemStack(Material.SOUL_SAND), true)) { + Material material = input.getType(); + + if (p.getGameMode() != GameMode.CREATIVE) { + ItemUtils.consumeItem(input, false); + } + + ItemStack output = material == Material.GRAVEL ? goldPan.getRandomOutput() : netherGoldPan.getRandomOutput(); + TaskQueue queue = new TaskQueue(); + + queue.thenRepeatEvery(20, 5, () -> b.getWorld().playEffect(b.getRelative(BlockFace.DOWN).getLocation(), Effect.STEP_SOUND, material)); + + queue.thenRun(20, () -> { + if (output.getType() != Material.AIR) { + Inventory outputChest = findOutputChest(b.getRelative(BlockFace.DOWN), output); + + if (outputChest != null) { + outputChest.addItem(output.clone()); + } + else { + b.getWorld().dropItemNaturally(b.getLocation(), output.clone()); + } + + p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F); + } + else { + p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARMOR_STAND_BREAK, 1F, 1F); + } + }); + + queue.execute(SlimefunPlugin.instance); + } + else { + SlimefunPlugin.getLocal().sendMessage(p, "machines.wrong-item", true); + } + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosivePickaxe.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosivePickaxe.java index 2ce833316..877df6287 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosivePickaxe.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ExplosivePickaxe.java @@ -91,6 +91,7 @@ public class ExplosivePickaxe extends SimpleSlimefunItem impl for (ItemStack drop : b.getDrops(getItem())) { b.getWorld().dropItemNaturally(b.getLocation(), (b.getType().toString().endsWith("_ORE") && b.getType() != Material.IRON_ORE && b.getType() != Material.GOLD_ORE) ? new CustomItem(drop, fortune) : drop); } + b.setType(Material.AIR); } @@ -103,7 +104,9 @@ public class ExplosivePickaxe extends SimpleSlimefunItem impl return true; } - else return false; + else { + return false; + } } }; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GoldPan.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GoldPan.java index 3721b45b6..148b0fa07 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GoldPan.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GoldPan.java @@ -81,6 +81,10 @@ public class GoldPan extends SimpleSlimefunItem implements Recip randomizer.add(new ItemStack(Material.AIR), 100 - randomizer.sumWeights()); } } + + public ItemStack getRandomOutput() { + return randomizer.getRandom(); + } @Override public String getLabelLocalPath() { @@ -96,7 +100,7 @@ public class GoldPan extends SimpleSlimefunItem implements Recip Block b = block.get(); if (b.getType() == getInput() && SlimefunPlugin.getProtectionManager().hasPermission(e.getPlayer(), b.getLocation(), ProtectableAction.BREAK_BLOCK)) { - ItemStack output = randomizer.getRandom(); + ItemStack output = getRandomOutput(); b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType()); b.setType(Material.AIR); @@ -125,11 +129,11 @@ public class GoldPan extends SimpleSlimefunItem implements Recip return recipes; } - class GoldPanDrop extends ItemSetting { + public class GoldPanDrop extends ItemSetting { private final ItemStack output; - public GoldPanDrop(String key, int defaultValue, ItemStack output) { + protected GoldPanDrop(String key, int defaultValue, ItemStack output) { super(key, defaultValue); this.output = output; diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java index 95507d34b..44035ea02 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java @@ -34,9 +34,9 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; */ public class Category implements Keyed { + protected final List items = new ArrayList<>(); protected final NamespacedKey key; protected final ItemStack item; - protected final List items; protected final int tier; /** @@ -73,8 +73,6 @@ public class Category implements Keyed { meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); this.item.setItemMeta(meta); - - this.items = new ArrayList<>(); this.tier = tier; } @@ -105,6 +103,16 @@ public class Category implements Keyed { items.add(item); } + /** + * Removes the given {@link SlimefunItem} from this {@link Category}. + * + * @param item + * the {@link SlimefunItem} that should be removed from this {@link Category} + */ + public void remove(SlimefunItem item) { + items.remove(item); + } + /** * This method returns a localized display item of this {@link Category} * for the specified {@link Player}. diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/ItemState.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/ItemState.java index 9d2b7814c..a200c7bf4 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/ItemState.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/ItemState.java @@ -31,5 +31,5 @@ public enum ItemState { * This {@link SlimefunItem} has fallen back to its vanilla behavior, because it is disabled and an instance of * {@link VanillaItem}. */ - VANILLA + VANILLA_FALLBACK } \ No newline at end of file diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java index edff16718..d626cf937 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java @@ -103,6 +103,7 @@ public class SlimefunItem implements Placeable { public SlimefunItem(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { Validate.notNull(category, "'category' is not allowed to be null!"); Validate.notNull(item, "'item' is not allowed to be null!"); + Validate.notNull(recipeType, "'recipeType' is not allowed to be null!"); this.category = category; this.item = item; @@ -248,40 +249,32 @@ public class SlimefunItem implements Placeable { * * @return Whether this {@link SlimefunItem} is hidden. */ - public boolean isHidden() { + public final boolean isHidden() { return hidden; } + public void setHidden(boolean hidden) { + this.hidden = hidden; + + if (state == ItemState.ENABLED) { + if (hidden) { + category.remove(this); + } + else { + category.add(this); + } + } + } + /** * This method returns whether this {@link SlimefunItem} was added by an addon. * * @return Whether this {@link SlimefunItem} was added by an addon. */ - public boolean isAddonItem() { + public final boolean isAddonItem() { return !(addon instanceof SlimefunPlugin); } - /** - * This method returns the {@link SlimefunAddon} that registered this - * {@link SlimefunItem}. If this Item is from Slimefun itself, the current - * instance of {@link SlimefunPlugin} will be returned. - * Use an instanceof check or {@link SlimefunItem#isAddonItem()} to account for that. - * - * @return The {@link SlimefunAddon} that registered this {@link SlimefunItem} - */ - public SlimefunAddon getAddon() { - return addon; - } - - public BlockTicker getBlockTicker() { - return blockTicker; - } - - // We should maybe refactor this and move it to a subclass - public GeneratorTicker getEnergyTicker() { - return generatorTicker; - } - /** * This method returns whether this {@link SlimefunItem} is disabled. * @@ -296,6 +289,32 @@ public class SlimefunItem implements Placeable { return state != ItemState.ENABLED; } + /** + * This method returns the {@link SlimefunAddon} that registered this + * {@link SlimefunItem}. If this Item is from Slimefun itself, the current + * instance of {@link SlimefunPlugin} will be returned. + * Use an instanceof check or {@link SlimefunItem#isAddonItem()} to account for that. + * + * @return The {@link SlimefunAddon} that registered this {@link SlimefunItem} + */ + public SlimefunAddon getAddon() { + if (addon == null) { + error("getAddon() cannot be called before registering the item", new UnregisteredItemException(this)); + return null; + } + + return addon; + } + + public BlockTicker getBlockTicker() { + return blockTicker; + } + + // We should maybe refactor this and move it to a subclass + public GeneratorTicker getEnergyTicker() { + return generatorTicker; + } + /** * This method registers this {@link SlimefunItem}. * Always call this method after your {@link SlimefunItem} has been initialized. @@ -374,7 +393,7 @@ public class SlimefunItem implements Placeable { loadItemHandlers(); } else if (this instanceof VanillaItem) { - state = ItemState.VANILLA; + state = ItemState.VANILLA_FALLBACK; } else { state = ItemState.DISABLED; @@ -382,7 +401,7 @@ public class SlimefunItem implements Placeable { postRegister(); - if (SlimefunPlugin.getRegistry().isAutoLoadingEnabled()) { + if (SlimefunPlugin.getRegistry().isAutoLoadingEnabled() && state == ItemState.ENABLED) { info("Item was registered during runtime."); load(); } @@ -436,11 +455,16 @@ public class SlimefunItem implements Placeable { } public void setRecipeType(RecipeType type) { + Validate.notNull(type, "'recipeType' is not allowed to be null!"); this.recipeType = type; } public void setCategory(Category category) { Validate.notNull(category, "'category' is not allowed to be null!"); + + this.category.remove(this); + category.add(this); + this.category = category; }