diff --git a/src/main/java/net/guizhanss/fastmachines/core/recipes/IRecipe.java b/src/main/java/net/guizhanss/fastmachines/core/recipes/IRecipe.java index 97a63cc..52ed8b9 100644 --- a/src/main/java/net/guizhanss/fastmachines/core/recipes/IRecipe.java +++ b/src/main/java/net/guizhanss/fastmachines/core/recipes/IRecipe.java @@ -7,7 +7,7 @@ import org.bukkit.World; import org.bukkit.inventory.ItemStack; -import net.guizhanss.fastmachines.items.machines.abstracts.AbstractFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AbstractFastMachine; /** * This interface represents a recipe used by a {@link AbstractFastMachine}. diff --git a/src/main/java/net/guizhanss/fastmachines/core/recipes/RawRecipe.java b/src/main/java/net/guizhanss/fastmachines/core/recipes/RawRecipe.java index ddd417e..1fc794a 100644 --- a/src/main/java/net/guizhanss/fastmachines/core/recipes/RawRecipe.java +++ b/src/main/java/net/guizhanss/fastmachines/core/recipes/RawRecipe.java @@ -4,6 +4,14 @@ import org.bukkit.inventory.ItemStack; +/** + * A temporary class used to store a pair of input and output. This class is used before registering recipes. + * + * @param input + * The input {@link ItemStack}s. + * @param output + * The output {@link ItemStack}s. + */ public record RawRecipe(ItemStack[] input, ItemStack[] output) { @Override diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/abstracts/AbstractFastMachine.java b/src/main/java/net/guizhanss/fastmachines/items/machines/abstracts/AbstractFastMachine.java deleted file mode 100644 index a1375a3..0000000 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/abstracts/AbstractFastMachine.java +++ /dev/null @@ -1,419 +0,0 @@ -package net.guizhanss.fastmachines.items.machines.abstracts; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.ParametersAreNonnullByDefault; - -import com.google.common.base.Preconditions; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; -import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; -import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; -import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; -import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; -import io.github.thebusybiscuit.slimefun4.libraries.dough.blocks.BlockPosition; -import io.github.thebusybiscuit.slimefun4.libraries.dough.data.persistent.PersistentDataAPI; -import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; -import io.github.thebusybiscuit.slimefun4.utils.LoreBuilder; - -import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; -import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; - -import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.core.recipes.IRecipe; -import net.guizhanss.fastmachines.core.recipes.RandomRecipe; -import net.guizhanss.fastmachines.setup.Groups; -import net.guizhanss.fastmachines.utils.BlockStorageUtils; -import net.guizhanss.fastmachines.utils.Heads; -import net.guizhanss.fastmachines.utils.Keys; -import net.guizhanss.fastmachines.utils.MachineUtils; -import net.guizhanss.guizhanlib.minecraft.utils.ItemUtil; -import net.guizhanss.guizhanlib.slimefun.machines.TickingMenuBlock; - -/** - * A fast machine is a basic machine but uses energy to fast craft from the given materials. - *

- * Idea from FinalTECH. - * - * @author Final_ROOT - * @author ybw0014 - */ -@SuppressWarnings("ConstantConditions") -public abstract class AbstractFastMachine extends TickingMenuBlock implements EnergyNetComponent { - - // slots - protected static final int[] INPUT_SLOTS = new int[] { - 0, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35 - }; - protected static final int[] OUTPUT_SLOTS = new int[] { - 27, 28, 29, 30, 31, 32, 33, 34, 35, - 18, 19, 20, 21, 22, 23, 24, 25, 26, - 9, 10, 11, 12, 13, 14, 15, 16, 17, - 0, 1, 2, 3, 4, 5, 6, 7, 8, - }; - protected static final int[] PREVIEW_SLOTS = new int[] { - 36, 37, 38, 39, 40, 41, - 45, 46, 47, 48, 49, 50 - }; - protected static final int SCROLL_UP_SLOT = 42; - protected static final int SCROLL_DOWN_SLOT = 51; - protected static final int CHOICE_SLOT = 52; - protected static final int CRAFT_SLOT = 53; - protected static final int CHOICE_INDICATOR_SLOT = 43; - protected static final int INFO_SLOT = 44; - - // constants - protected static final int ITEMS_PER_PAGE = PREVIEW_SLOTS.length; - protected static final String KEY_CHOICE = "choice"; - - // menu items - protected static final ItemStack SCROLL_UP_ITEM = FastMachines.getLocalization().getItem( - "SCROLL_UP", Heads.ARROW_UP.getTexture()); - protected static final ItemStack SCROLL_DOWN_ITEM = FastMachines.getLocalization().getItem( - "SCROLL_DOWN", Heads.ARROW_DOWN.getTexture()); - protected static final ItemStack CHOICE_INDICATOR_ITEM = FastMachines.getLocalization().getItem( - "CHOICE_INDICATOR", Material.YELLOW_STAINED_GLASS_PANE); - protected static final ItemStack INFO_ITEM = FastMachines.getLocalization().getItem( - "INFO", Heads.INFO.getTexture()); - protected static final ItemStack NO_ITEM = FastMachines.getLocalization().getItem( - "NO_ITEM", Material.BARRIER); - - // outputs map - protected static final Map> OUTPUTS_MAP = new HashMap<>(); - - protected final List recipes = new ArrayList<>(); - - @ParametersAreNonnullByDefault - protected AbstractFastMachine(SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { - super(Groups.MACHINES, item, recipeType, recipe); - } - - @Nonnull - @Override - public EnergyNetComponentType getEnergyComponentType() { - return EnergyNetComponentType.CONSUMER; - } - - // Also getCapacity() which is already defined. - public abstract int getEnergyPerUse(); - - @Override - protected void setup(@Nonnull BlockMenuPreset preset) { - for (int slot : PREVIEW_SLOTS) { - preset.addItem(slot, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler()); - } - preset.addItem(CHOICE_INDICATOR_SLOT, CHOICE_INDICATOR_ITEM, ChestMenuUtils.getEmptyClickHandler()); - preset.addItem(INFO_SLOT, INFO_ITEM, ChestMenuUtils.getEmptyClickHandler()); - preset.addItem(CHOICE_SLOT, NO_ITEM, ChestMenuUtils.getEmptyClickHandler()); - preset.addItem(SCROLL_UP_SLOT, SCROLL_UP_ITEM, ChestMenuUtils.getEmptyClickHandler()); - preset.addItem(SCROLL_DOWN_SLOT, SCROLL_DOWN_ITEM, ChestMenuUtils.getEmptyClickHandler()); - - ItemStack craftItem = ItemUtil.appendLore( - getCraftItem(), - "", - LoreBuilder.power(getEnergyPerUse(), FastMachines.getLocalization().getString("lores.per-craft")) - ); - preset.addItem(CRAFT_SLOT, craftItem, ChestMenuUtils.getEmptyClickHandler()); - } - - @Override - @ParametersAreNonnullByDefault - protected void onNewInstance(BlockMenu blockMenu, Block block) { - BlockPosition pos = new BlockPosition(block); - blockMenu.addMenuClickHandler(SCROLL_UP_SLOT, (player, i, itemStack, clickAction) -> { - int currentPage = BlockStorageUtils.getInt(pos, "page", 1); - BlockStorageUtils.setInt(pos, "page", currentPage - 1); - updateMenu(blockMenu); - return false; - }); - blockMenu.addMenuClickHandler(SCROLL_DOWN_SLOT, (player, i, itemStack, clickAction) -> { - int currentPage = BlockStorageUtils.getInt(pos, "page", 1); - BlockStorageUtils.setInt(pos, "page", currentPage + 1); - updateMenu(blockMenu); - return false; - }); - blockMenu.addMenuClickHandler(CRAFT_SLOT, (player, i, itemStack, clickAction) -> { - if (clickAction.isShiftClicked()) { - if (clickAction.isRightClicked()) { - craft(blockMenu, player, Integer.MAX_VALUE); - } else { - craft(blockMenu, player, 64); - } - } else { - if (clickAction.isRightClicked()) { - craft(blockMenu, player, 16); - } else { - craft(blockMenu, player, 1); - } - } - return false; - }); - } - - @Override - @ParametersAreNonnullByDefault - protected void tick(Block block, BlockMenu blockMenu) { - if (blockMenu.hasViewer() && FastMachines.getSlimefunTickCount() % 2 == 0) { - // Calculate machine inputs - findAvailableOutputs(blockMenu); - // Display available outputs - updateMenu(blockMenu); - } - } - - @Override - public int[] getInputSlots() { - return INPUT_SLOTS; - } - - @Override - public int[] getOutputSlots() { - // Basic machines should not support cargo access - return new int[0]; - } - - @Override - public void register(@Nonnull SlimefunAddon addon) { - super.register(addon); - FastMachines.getScheduler().run(2, this::registerRecipes); - } - - @Override - @ParametersAreNonnullByDefault - protected void onBreak(BlockBreakEvent e, BlockMenu menu) { - super.onBreak(e, menu); - Location l = menu.getLocation(); - menu.dropItems(l, INPUT_SLOTS); - } - - @Nonnull - protected Map getMachineOutputs(@Nonnull BlockMenu menu) { - BlockPosition pos = new BlockPosition(menu.getLocation()); - var outputs = OUTPUTS_MAP.getOrDefault(pos, new LinkedHashMap<>()); - OUTPUTS_MAP.put(pos, outputs); - return outputs; - } - - /** - * Find all the available outputs based on the given inputs. - * - * @param blockMenu - * The {@link BlockMenu} of this machine. - */ - @ParametersAreNonnullByDefault - protected void findAvailableOutputs(BlockMenu blockMenu) { - BlockPosition pos = new BlockPosition(blockMenu.getLocation()); - Map machineInputs = MachineUtils.getMachineInputAmount(blockMenu, INPUT_SLOTS); - var outputs = getMachineOutputs(blockMenu); - outputs.clear(); - - if (machineInputs.isEmpty()) { - return; - } - - FastMachines.debug("current machine: {0}, location: {1}", getClass().getSimpleName(), pos); - FastMachines.debug("machine inputs: {0}", machineInputs); - - // Fetch available recipes based on inputs - for (var recipe : recipes) { - if (recipe.isDisabledInWorld(pos.getWorld())) { - continue; - } - - FastMachines.debug("checking recipe: {0}", recipe); - - // stores the possible maximum output amount - int outputAmount = Integer.MAX_VALUE; - - for (var recipeInputEntry : recipe.getInput().entrySet()) { - - // if the current recipe input isn't in the machine input, just ignore this - if (!machineInputs.containsKey(recipeInputEntry.getKey())) { - outputAmount = 0; - break; - } - - FastMachines.debug("input: {0}, machine amount: {1}", recipeInputEntry.getKey(), - machineInputs.get(recipeInputEntry.getKey())); - FastMachines.debug("recipe amount: {0}", recipeInputEntry.getValue()); - - // check the maximum possible output amount based on inputs - int inputAmount = machineInputs.get(recipeInputEntry.getKey()); - int recipeAmount = recipeInputEntry.getValue(); - outputAmount = Math.min(outputAmount, inputAmount / recipeAmount); - - FastMachines.debug("result amount: {0}", inputAmount / recipeAmount); - } - - // this recipe is available - if (outputAmount > 0) { - FastMachines.debug("recipe is available, output amount: {0}", outputAmount); - outputs.put(recipe, outputAmount); - } - } - - FastMachines.debug("outputs: " + outputs); - } - - @ParametersAreNonnullByDefault - protected void updateMenu(BlockMenu blockMenu) { - BlockPosition pos = new BlockPosition(blockMenu.getLocation()); - var outputs = getMachineOutputs(blockMenu); - ItemStack[] outputItems = - outputs.keySet().stream().map(recipe -> recipe.getOutput(pos.getWorld())).toArray(ItemStack[]::new); - int currentPage = BlockStorageUtils.getInt(pos, "page", 1); - int totalPages = (int) Math.ceil(outputs.size() * 1.0 / ITEMS_PER_PAGE); - // limit the page in range - if (currentPage < 1) { - currentPage = 1; - BlockStorageUtils.setInt(pos, "page", 1); - } - if (currentPage > totalPages) { - currentPage = totalPages; - BlockStorageUtils.setInt(pos, "page", totalPages); - } - - for (int i = 0; i < ITEMS_PER_PAGE; i++) { - int index = (currentPage - 1) * ITEMS_PER_PAGE + i; - if (totalPages == 0 || index >= outputs.size()) { - blockMenu.replaceExistingItem(PREVIEW_SLOTS[i], ChestMenuUtils.getBackground()); - blockMenu.addMenuClickHandler(PREVIEW_SLOTS[i], ChestMenuUtils.getEmptyClickHandler()); - continue; - } - ItemStack output = getDisplayItem(outputItems[index]); - blockMenu.replaceExistingItem(PREVIEW_SLOTS[i], output); - blockMenu.addMenuClickHandler(PREVIEW_SLOTS[i], ((player, slot, itemStack, clickAction) -> { - BlockStorageUtils.setInt(pos, KEY_CHOICE, index); - updateChoice(blockMenu); - return false; - })); - } - - updateChoice(blockMenu); - } - - @ParametersAreNonnullByDefault - protected void updateChoice(BlockMenu blockMenu) { - BlockPosition pos = new BlockPosition(blockMenu.getLocation()); - var outputs = getMachineOutputs(blockMenu); - ItemStack[] outputItems = - outputs.keySet().stream().map(recipe -> recipe.getOutput(pos.getWorld())).toArray(ItemStack[]::new); - - int choice = BlockStorageUtils.getInt(pos, KEY_CHOICE); - if (choice >= outputs.size()) { - blockMenu.replaceExistingItem(CHOICE_SLOT, NO_ITEM); - } else { - ItemStack output = getDisplayItem(outputItems[choice]); - blockMenu.replaceExistingItem(CHOICE_SLOT, output); - } - } - - @ParametersAreNonnullByDefault - protected void craft(BlockMenu blockMenu, Player p, int amount) { - Preconditions.checkArgument(amount > 0, "amount must greater than 0"); - - BlockPosition pos = new BlockPosition(blockMenu.getLocation()); - var outputs = getMachineOutputs(blockMenu); - var outputRecipes = outputs.entrySet().stream().toList(); - - int choice = BlockStorageUtils.getInt(pos, KEY_CHOICE); - // invalid choice, due to previous selection not available anymore - if (choice >= outputs.size()) { - return; - } - var recipe = outputRecipes.get(choice); - int maxAmount = recipe.getValue(); - amount = Math.min(maxAmount, amount); - - // check if the machine has enough energy - if (FastMachines.getAddonConfig().getBoolean("fast-machines.use-energy")) { - int energyNeeded = getEnergyPerUse() * amount; - int currentEnergy = getCharge(blockMenu.getLocation()); - if (currentEnergy < energyNeeded) { - FastMachines.getLocalization().sendMessage(p, "not-enough-energy"); - return; - } - setCharge(blockMenu.getLocation(), currentEnergy - energyNeeded); - } - - // remove recipe inputs - for (var inputEntry : recipe.getKey().getInput().entrySet()) { - int requiredAmount = inputEntry.getValue() * amount; - var itemAmount = MachineUtils.getItemAmount(blockMenu, INPUT_SLOTS, inputEntry.getKey()); - // total amount is less than required amount, usually shouldn't happen - if (itemAmount.getSecondValue() < requiredAmount) { - FastMachines.getLocalization().sendMessage(p, "not-enough-materials"); - return; - } - // remove items from machine - MachineUtils.removeItems(blockMenu, itemAmount.getFirstValue().stream().mapToInt(Integer::intValue).toArray(), - inputEntry.getKey(), requiredAmount); - } - - // push the product - if (recipe.getKey() instanceof RandomRecipe randomRecipe) { - boolean machineFull = false; - for (int i = 0; i < amount; i++) { - ItemStack product = randomRecipe.getOutput(pos.getWorld()).clone(); - if (MachineUtils.addItem(p, blockMenu, OUTPUT_SLOTS, product, 1)) { - machineFull = true; - } - } - if (machineFull) { - FastMachines.getLocalization().sendMessage(p, "not-enough-space"); - } - } else { - ItemStack product = recipe.getKey().getOutput(pos.getWorld()).clone(); - if (MachineUtils.addItem(p, blockMenu, OUTPUT_SLOTS, product, amount)) { - FastMachines.getLocalization().sendMessage(p, "not-enough-space"); - } - } - } - - /** - * Get the {@link ItemStack} that is used to display in the preview slots. - * - * @param item - * The original {@link ItemStack}. - * - * @return The new {@link ItemStack} that is used to display. - */ - @Nonnull - protected ItemStack getDisplayItem(@Nonnull ItemStack item) { - ItemStack newItem = item.clone(); - ItemMeta meta = newItem.getItemMeta(); - PersistentDataAPI.setBoolean(meta, Keys.get("display"), true); - newItem.setItemMeta(meta); - return newItem; - } - - /** - * Register available recipes for this machine. - *

- * Note: this method is called synchronously after server completes loading. - */ - protected abstract void registerRecipes(); - - /** - * Get the item that shows the craft button of this machine. - * - * @return the item that shows the craft button of this machine. - */ - protected abstract ItemStack getCraftItem(); -} diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/abstracts/AFastMachine.java b/src/main/java/net/guizhanss/fastmachines/items/machines/generic/AFastMachine.java similarity index 83% rename from src/main/java/net/guizhanss/fastmachines/items/machines/abstracts/AFastMachine.java rename to src/main/java/net/guizhanss/fastmachines/items/machines/generic/AFastMachine.java index ec72953..888363d 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/abstracts/AFastMachine.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/generic/AFastMachine.java @@ -1,4 +1,4 @@ -package net.guizhanss.fastmachines.items.machines.abstracts; +package net.guizhanss.fastmachines.items.machines.generic; import javax.annotation.ParametersAreNonnullByDefault; @@ -8,6 +8,12 @@ import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +/** + * General abstract class for Fast Machines. + * The default energy per use is 8 and the default capacity is 1024. + * + * @author ybw0014 + */ public abstract class AFastMachine extends AbstractFastMachine { private final IntRangeSetting energyPerUse = new IntRangeSetting(this, "energy-per-use", 0, 8, diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/abstracts/AInfinityMachine.java b/src/main/java/net/guizhanss/fastmachines/items/machines/generic/AInfinityMachine.java similarity index 83% rename from src/main/java/net/guizhanss/fastmachines/items/machines/abstracts/AInfinityMachine.java rename to src/main/java/net/guizhanss/fastmachines/items/machines/generic/AInfinityMachine.java index 8289e09..bfaad4f 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/abstracts/AInfinityMachine.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/generic/AInfinityMachine.java @@ -1,4 +1,4 @@ -package net.guizhanss.fastmachines.items.machines.abstracts; +package net.guizhanss.fastmachines.items.machines.generic; import javax.annotation.ParametersAreNonnullByDefault; @@ -8,6 +8,12 @@ import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +/** + * General abstract class for Infinity Fast Machines. + * The default energy per use is 10m and the default capacity is 100m. + * + * @author ybw0014 + */ public abstract class AInfinityMachine extends AbstractFastMachine { private final IntRangeSetting energyPerUse = new IntRangeSetting(this, "energy-per-use", 0, 10_000_000, diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/generic/AbstractFastMachine.java b/src/main/java/net/guizhanss/fastmachines/items/machines/generic/AbstractFastMachine.java new file mode 100644 index 0000000..6cc17c1 --- /dev/null +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/generic/AbstractFastMachine.java @@ -0,0 +1,180 @@ +package net.guizhanss.fastmachines.items.machines.generic; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; +import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; +import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; +import io.github.thebusybiscuit.slimefun4.libraries.dough.blocks.BlockPosition; +import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; +import io.github.thebusybiscuit.slimefun4.utils.LoreBuilder; + +import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; +import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; + +import net.guizhanss.fastmachines.FastMachines; +import net.guizhanss.fastmachines.core.recipes.IRecipe; +import net.guizhanss.fastmachines.setup.Groups; +import net.guizhanss.fastmachines.utils.Heads; +import net.guizhanss.guizhanlib.minecraft.utils.ItemUtil; +import net.guizhanss.guizhanlib.slimefun.machines.TickingMenuBlock; + +import lombok.Getter; + +/** + * A fast machine is a basic machine but uses energy to fast craft from the given materials. + *

+ * Idea from FinalTECH. + * + * @author Final_ROOT + * @author ybw0014 + */ +@SuppressWarnings("ConstantConditions") +public abstract class AbstractFastMachine extends TickingMenuBlock implements EnergyNetComponent { + // outputs map + protected static final Map> OUTPUTS_MAP = new HashMap<>(); + // slots + static final int[] INPUT_SLOTS = new int[] { + 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35 + }; + static final int[] OUTPUT_SLOTS = new int[] { + 27, 28, 29, 30, 31, 32, 33, 34, 35, + 18, 19, 20, 21, 22, 23, 24, 25, 26, + 9, 10, 11, 12, 13, 14, 15, 16, 17, + 0, 1, 2, 3, 4, 5, 6, 7, 8, + }; + static final int[] PREVIEW_SLOTS = new int[] { + 36, 37, 38, 39, 40, 41, + 45, 46, 47, 48, 49, 50 + }; + static final int SCROLL_UP_SLOT = 42; + static final int SCROLL_DOWN_SLOT = 51; + static final int CHOICE_SLOT = 52; + static final int CRAFT_SLOT = 53; + static final int CHOICE_INDICATOR_SLOT = 43; + static final int INFO_SLOT = 44; + // constants + static final int ITEMS_PER_PAGE = PREVIEW_SLOTS.length; + // menu items + static final ItemStack NO_ITEM = FastMachines.getLocalization().getItem( + "NO_ITEM", Material.BARRIER); + static final ItemStack SCROLL_UP_ITEM = FastMachines.getLocalization().getItem( + "SCROLL_UP", Heads.ARROW_UP.getTexture()); + static final ItemStack SCROLL_DOWN_ITEM = FastMachines.getLocalization().getItem( + "SCROLL_DOWN", Heads.ARROW_DOWN.getTexture()); + static final ItemStack CHOICE_INDICATOR_ITEM = FastMachines.getLocalization().getItem( + "CHOICE_INDICATOR", Material.YELLOW_STAINED_GLASS_PANE); + static final ItemStack INFO_ITEM = FastMachines.getLocalization().getItem( + "INFO", Heads.INFO.getTexture()); + + @Getter + protected final List recipes = new ArrayList<>(); + + private final Map CACHES = new HashMap<>(); + + @ParametersAreNonnullByDefault + protected AbstractFastMachine(SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { + super(Groups.MACHINES, item, recipeType, recipe); + } + + @Nonnull + @Override + public EnergyNetComponentType getEnergyComponentType() { + return EnergyNetComponentType.CONSUMER; + } + + // Also getCapacity() which is already defined. + public abstract int getEnergyPerUse(); + + @Override + protected void setup(@Nonnull BlockMenuPreset preset) { + for (int slot : PREVIEW_SLOTS) { + preset.addItem(slot, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler()); + } + preset.addItem(CHOICE_INDICATOR_SLOT, CHOICE_INDICATOR_ITEM, ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(INFO_SLOT, INFO_ITEM, ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(CHOICE_SLOT, NO_ITEM, ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(SCROLL_UP_SLOT, SCROLL_UP_ITEM, ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(SCROLL_DOWN_SLOT, SCROLL_DOWN_ITEM, ChestMenuUtils.getEmptyClickHandler()); + + ItemStack craftItem = ItemUtil.appendLore( + getCraftItem(), + "", + LoreBuilder.power(getEnergyPerUse(), FastMachines.getLocalization().getString("lores.per-craft")) + ); + preset.addItem(CRAFT_SLOT, craftItem, ChestMenuUtils.getEmptyClickHandler()); + } + + @Override + @ParametersAreNonnullByDefault + protected void onNewInstance(BlockMenu menu, Block block) { + BlockPosition pos = new BlockPosition(block); + CACHES.put(pos, new FastMachineCache(this, menu)); + } + + @Override + @ParametersAreNonnullByDefault + protected void tick(Block b, BlockMenu menu) { + BlockPosition pos = new BlockPosition(b); + if (menu.hasViewer() && CACHES.containsKey(pos)) { + CACHES.get(pos).tick(); + } + } + + @Override + public int[] getInputSlots() { + return INPUT_SLOTS; + } + + @Override + public int[] getOutputSlots() { + // Basic machines should not support cargo access + return new int[0]; + } + + @Override + public void register(@Nonnull SlimefunAddon addon) { + super.register(addon); + FastMachines.getScheduler().run(2, this::registerRecipes); + } + + @Override + @ParametersAreNonnullByDefault + protected void onBreak(BlockBreakEvent e, BlockMenu menu) { + super.onBreak(e, menu); + Location l = menu.getLocation(); + menu.dropItems(l, INPUT_SLOTS); + CACHES.remove(new BlockPosition(l)); + } + + /** + * Register available recipes for this machine. + *

+ * Note: this method is called synchronously 2 ticks after server completes loading. + */ + protected abstract void registerRecipes(); + + /** + * Get the item that shows the craft button of this machine. + * + * @return the item that shows the craft button of this machine. + */ + protected abstract ItemStack getCraftItem(); +} diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/generic/FastMachineCache.java b/src/main/java/net/guizhanss/fastmachines/items/machines/generic/FastMachineCache.java new file mode 100644 index 0000000..4aea723 --- /dev/null +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/generic/FastMachineCache.java @@ -0,0 +1,273 @@ +package net.guizhanss.fastmachines.items.machines.generic; + +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +import com.google.common.base.Preconditions; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import io.github.thebusybiscuit.slimefun4.libraries.dough.blocks.BlockPosition; +import io.github.thebusybiscuit.slimefun4.libraries.dough.data.persistent.PersistentDataAPI; +import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; + +import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; + +import net.guizhanss.fastmachines.FastMachines; +import net.guizhanss.fastmachines.core.recipes.IRecipe; +import net.guizhanss.fastmachines.core.recipes.RandomRecipe; +import net.guizhanss.fastmachines.utils.Keys; +import net.guizhanss.fastmachines.utils.MachineUtils; +import net.guizhanss.fastmachines.utils.RecipeUtils; + +import static net.guizhanss.fastmachines.items.machines.generic.AbstractFastMachine.CHOICE_SLOT; +import static net.guizhanss.fastmachines.items.machines.generic.AbstractFastMachine.CRAFT_SLOT; +import static net.guizhanss.fastmachines.items.machines.generic.AbstractFastMachine.INPUT_SLOTS; +import static net.guizhanss.fastmachines.items.machines.generic.AbstractFastMachine.ITEMS_PER_PAGE; +import static net.guizhanss.fastmachines.items.machines.generic.AbstractFastMachine.NO_ITEM; +import static net.guizhanss.fastmachines.items.machines.generic.AbstractFastMachine.OUTPUT_SLOTS; +import static net.guizhanss.fastmachines.items.machines.generic.AbstractFastMachine.PREVIEW_SLOTS; +import static net.guizhanss.fastmachines.items.machines.generic.AbstractFastMachine.SCROLL_DOWN_SLOT; +import static net.guizhanss.fastmachines.items.machines.generic.AbstractFastMachine.SCROLL_UP_SLOT; + +/** + * A cache layer to store some of the data of a Fast Machine. + */ +public final class FastMachineCache { + private final AbstractFastMachine machine; + private final BlockMenu menu; + private final BlockPosition blockPosition; + private final Map outputs = new LinkedHashMap<>(); + private int page = -1; + private ItemStack choice; + + @ParametersAreNonnullByDefault + public FastMachineCache(AbstractFastMachine machine, BlockMenu menu) { + this.machine = machine; + this.menu = menu; + this.blockPosition = new BlockPosition(menu.getLocation()); + init(); + } + + private void init() { + menu.addMenuClickHandler(SCROLL_UP_SLOT, (player, i, itemStack, clickAction) -> { + page--; + return false; + }); + menu.addMenuClickHandler(SCROLL_DOWN_SLOT, (player, i, itemStack, clickAction) -> { + page++; + return false; + }); + menu.addMenuClickHandler(CRAFT_SLOT, (player, i, itemStack, clickAction) -> { + int amount; + if (clickAction.isShiftClicked()) { + if (clickAction.isRightClicked()) { + amount = Integer.MAX_VALUE; + } else { + amount = 64; + } + } else { + if (clickAction.isRightClicked()) { + amount = 16; + } else { + amount = 1; + } + } + craft(player, amount); + return false; + }); + } + + public void tick() { + if (FastMachines.getSlimefunTickCount() % 2 == 0) { + findAvailableOutputs(); + } + updateMenu(); + } + + /** + * Find all the available outputs based on the given inputs. + */ + private void findAvailableOutputs() { + Map machineInputs = MachineUtils.getMachineInputAmount(menu, INPUT_SLOTS); + outputs.clear(); + + if (machineInputs.isEmpty()) { + return; + } + + FastMachines.debug("current machine: {0}, location: {1}", machine.getClass().getSimpleName(), blockPosition); + FastMachines.debug("machine inputs: {0}", machineInputs); + + // Fetch available recipes based on inputs + for (var recipe : machine.getRecipes()) { + if (recipe.isDisabledInWorld(blockPosition.getWorld())) { + continue; + } + + FastMachines.debug("checking recipe: {0}", recipe); + + // stores the possible maximum output amount + int outputAmount = Integer.MAX_VALUE; + + for (var recipeInputEntry : recipe.getInput().entrySet()) { + + // if the current recipe input isn't in the machine input, just ignore this + if (!machineInputs.containsKey(recipeInputEntry.getKey())) { + outputAmount = 0; + break; + } + + FastMachines.debug("input: {0}, machine amount: {1}", recipeInputEntry.getKey(), + machineInputs.get(recipeInputEntry.getKey())); + FastMachines.debug("recipe amount: {0}", recipeInputEntry.getValue()); + + // check the maximum possible output amount based on inputs + int inputAmount = machineInputs.get(recipeInputEntry.getKey()); + int recipeAmount = recipeInputEntry.getValue(); + outputAmount = Math.min(outputAmount, inputAmount / recipeAmount); + + FastMachines.debug("result amount: {0}", inputAmount / recipeAmount); + } + + // this recipe is available + if (outputAmount > 0) { + FastMachines.debug("recipe is available, output amount: {0}", outputAmount); + outputs.put(recipe, outputAmount); + } + } + + FastMachines.debug("outputs: " + outputs); + } + + private void updateMenu() { + ItemStack[] outputItems = + outputs.keySet().stream().map(recipe -> recipe.getOutput(blockPosition.getWorld())).toArray(ItemStack[]::new); + int totalPages = (int) Math.ceil(outputs.size() * 1.0 / ITEMS_PER_PAGE); + // limit the page in range + if (page < 1) { + page = 1; + } + if (page > totalPages) { + page = totalPages; + } + + for (int i = 0; i < ITEMS_PER_PAGE; i++) { + int index = (page - 1) * ITEMS_PER_PAGE + i; + if (totalPages == 0 || index >= outputs.size()) { + menu.replaceExistingItem(PREVIEW_SLOTS[i], ChestMenuUtils.getBackground()); + menu.addMenuClickHandler(PREVIEW_SLOTS[i], ChestMenuUtils.getEmptyClickHandler()); + continue; + } + ItemStack output = getDisplayItem(outputItems[index]); + menu.replaceExistingItem(PREVIEW_SLOTS[i], output); + menu.addMenuClickHandler(PREVIEW_SLOTS[i], (player, slot, itemStack, clickAction) -> { + choice = itemStack; + updateChoice(); + return false; + }); + } + + updateChoice(); + } + + private void updateChoice() { + ItemStack[] outputItems = + outputs.keySet().stream().map(recipe -> recipe.getOutput(blockPosition.getWorld())).toArray(ItemStack[]::new); + + for (ItemStack output : outputItems) { + if (RecipeUtils.isItemSimilar(output, choice)) { + menu.replaceExistingItem(CHOICE_SLOT, getDisplayItem(choice)); + return; + } + } + menu.replaceExistingItem(CHOICE_SLOT, NO_ITEM); + } + + @ParametersAreNonnullByDefault + private void craft(Player p, int amount) { + Preconditions.checkArgument(amount > 0, "amount must greater than 0"); + + var outputRecipes = outputs.entrySet().stream().toList(); + + // invalid choice, due to previous selection not available anymore + if (choice == null) { + return; + } + var recipeEntry = outputRecipes.stream().filter(entry -> + RecipeUtils.isItemSimilar(entry.getKey().getOutput(blockPosition.getWorld()), choice) + ).findFirst(); + if (recipeEntry.isEmpty()) { + return; + } + var recipe = recipeEntry.get(); + int maxAmount = recipe.getValue(); + amount = Math.min(maxAmount, amount); + + // check if the machine has enough energy + if (FastMachines.getAddonConfig().getBoolean("fast-machines.use-energy")) { + int energyNeeded = machine.getEnergyPerUse() * amount; + int currentEnergy = machine.getCharge(blockPosition.toLocation()); + if (currentEnergy < energyNeeded) { + FastMachines.getLocalization().sendMessage(p, "not-enough-energy"); + return; + } + machine.setCharge(blockPosition.toLocation(), currentEnergy - energyNeeded); + } + + // remove recipe inputs + for (var inputEntry : recipe.getKey().getInput().entrySet()) { + int requiredAmount = inputEntry.getValue() * amount; + var itemAmount = MachineUtils.getItemAmount(menu, INPUT_SLOTS, inputEntry.getKey()); + // total amount is less than required amount, usually shouldn't happen + if (itemAmount.getSecondValue() < requiredAmount) { + FastMachines.getLocalization().sendMessage(p, "not-enough-materials"); + return; + } + // remove items from machine + MachineUtils.removeItems(menu, itemAmount.getFirstValue().stream().mapToInt(Integer::intValue).toArray(), + inputEntry.getKey(), requiredAmount); + } + + // push the product + if (recipe.getKey() instanceof RandomRecipe randomRecipe) { + boolean machineFull = false; + for (int i = 0; i < amount; i++) { + ItemStack product = randomRecipe.getOutput(blockPosition.getWorld()).clone(); + if (MachineUtils.addItem(p, menu, OUTPUT_SLOTS, product, 1)) { + machineFull = true; + } + } + if (machineFull) { + FastMachines.getLocalization().sendMessage(p, "not-enough-space"); + } + } else { + ItemStack product = recipe.getKey().getOutput(blockPosition.getWorld()).clone(); + if (MachineUtils.addItem(p, menu, OUTPUT_SLOTS, product, amount)) { + FastMachines.getLocalization().sendMessage(p, "not-enough-space"); + } + } + } + + /** + * Get the {@link ItemStack} that is used to display in the preview slots. + * + * @param item + * The original {@link ItemStack}. + * + * @return The new {@link ItemStack} that is used to display. + */ + @Nonnull + private ItemStack getDisplayItem(@Nonnull ItemStack item) { + ItemStack newItem = item.clone(); + ItemMeta meta = newItem.getItemMeta(); + PersistentDataAPI.setBoolean(meta, Keys.get("display"), true); + newItem.setItemMeta(meta); + return newItem; + } +} diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/infinityexpansion/FastInfinityWorkbench.java b/src/main/java/net/guizhanss/fastmachines/items/machines/infinityexpansion/FastInfinityWorkbench.java index 7983751..17cd47b 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/infinityexpansion/FastInfinityWorkbench.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/infinityexpansion/FastInfinityWorkbench.java @@ -13,7 +13,7 @@ import net.guizhanss.fastmachines.FastMachines; import net.guizhanss.fastmachines.core.recipes.RawRecipe; -import net.guizhanss.fastmachines.items.machines.abstracts.AInfinityMachine; +import net.guizhanss.fastmachines.items.machines.generic.AInfinityMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastInfinityWorkbench extends AInfinityMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimeframe/FastSlimeFrameFoundry.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimeframe/FastSlimeFrameFoundry.java index a9869df..54ccfa3 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimeframe/FastSlimeFrameFoundry.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimeframe/FastSlimeFrameFoundry.java @@ -9,7 +9,7 @@ import me.voper.slimeframe.implementation.SFrameStacks; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public class FastSlimeFrameFoundry extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastArmorForge.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastArmorForge.java index 0b0e7ed..d937dec 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastArmorForge.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastArmorForge.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastArmorForge extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastComposter.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastComposter.java index 3779f48..3adf6b2 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastComposter.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastComposter.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastComposter extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastCompressor.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastCompressor.java index 7417490..f7159ba 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastCompressor.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastCompressor.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastCompressor extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastEnhancedCraftingTable.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastEnhancedCraftingTable.java index 5f3335a..cccb71a 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastEnhancedCraftingTable.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastEnhancedCraftingTable.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastEnhancedCraftingTable extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastGrindStone.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastGrindStone.java index 02815e0..7e1c6f2 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastGrindStone.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastGrindStone.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastGrindStone extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastJuicer.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastJuicer.java index 32a1e5d..f425d68 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastJuicer.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastJuicer.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastJuicer extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastMagicWorkbench.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastMagicWorkbench.java index ea21038..60423ac 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastMagicWorkbench.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastMagicWorkbench.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastMagicWorkbench extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastOreCrusher.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastOreCrusher.java index 7fedc79..2e9ea0d 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastOreCrusher.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastOreCrusher.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastOreCrusher extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastOreWasher.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastOreWasher.java index 08d9a25..31765af 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastOreWasher.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastOreWasher.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastOreWasher extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastPanningMachine.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastPanningMachine.java index 82966ef..7c841be 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastPanningMachine.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastPanningMachine.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastPanningMachine extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastPressureChamber.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastPressureChamber.java index 8b7bef7..9bf88ca 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastPressureChamber.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastPressureChamber.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastPressureChamber extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastSmeltery.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastSmeltery.java index 464fdb3..95264e9 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastSmeltery.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastSmeltery.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastSmeltery extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastTableSaw.java b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastTableSaw.java index a46387a..d8f170e 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastTableSaw.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/slimefun/FastTableSaw.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastTableSaw extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/vanilla/FastCraftingTable.java b/src/main/java/net/guizhanss/fastmachines/items/machines/vanilla/FastCraftingTable.java index 0ef9be0..7122321 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/vanilla/FastCraftingTable.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/vanilla/FastCraftingTable.java @@ -9,7 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastCraftingTable extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/items/machines/vanilla/FastFurnace.java b/src/main/java/net/guizhanss/fastmachines/items/machines/vanilla/FastFurnace.java index a848156..feabf2a 100644 --- a/src/main/java/net/guizhanss/fastmachines/items/machines/vanilla/FastFurnace.java +++ b/src/main/java/net/guizhanss/fastmachines/items/machines/vanilla/FastFurnace.java @@ -8,7 +8,7 @@ import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import net.guizhanss.fastmachines.FastMachines; -import net.guizhanss.fastmachines.items.machines.abstracts.AFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AFastMachine; import net.guizhanss.fastmachines.utils.RecipeUtils; public final class FastFurnace extends AFastMachine { diff --git a/src/main/java/net/guizhanss/fastmachines/utils/RecipeUtils.java b/src/main/java/net/guizhanss/fastmachines/utils/RecipeUtils.java index 2048e07..38b186c 100644 --- a/src/main/java/net/guizhanss/fastmachines/utils/RecipeUtils.java +++ b/src/main/java/net/guizhanss/fastmachines/utils/RecipeUtils.java @@ -14,6 +14,7 @@ import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; +import javax.annotation.ParametersAreNullableByDefault; import com.google.common.base.Preconditions; @@ -36,7 +37,7 @@ import net.guizhanss.fastmachines.core.recipes.RandomRecipe; import net.guizhanss.fastmachines.core.recipes.RawRecipe; import net.guizhanss.fastmachines.core.recipes.StandardRecipe; -import net.guizhanss.fastmachines.items.machines.abstracts.AbstractFastMachine; +import net.guizhanss.fastmachines.items.machines.generic.AbstractFastMachine; import lombok.experimental.UtilityClass; @@ -69,13 +70,11 @@ public final class RecipeUtils { * * @return Whether the two items are similar. */ - @ParametersAreNonnullByDefault - private static boolean isItemSimilar(ItemStack aItem, ItemStack bItem) { - if (aItem.getType() == Material.SPAWNER && bItem.getType() == Material.SPAWNER) { - return SlimefunUtils.isItemSimilar(aItem, bItem, true, true, true); - } else { - return SlimefunUtils.isItemSimilar(aItem, bItem, false, true, true); - } + @ParametersAreNullableByDefault + public static boolean isItemSimilar(ItemStack aItem, ItemStack bItem) { + if (aItem == null || bItem == null) return false; + boolean checkLore = aItem.getType() == Material.SPAWNER && bItem.getType() == Material.SPAWNER; + return SlimefunUtils.isItemSimilar(aItem, bItem, checkLore, true, true); } /**