From 54c53d733735d6925f09c6ab57c13a84e932a8c9 Mon Sep 17 00:00:00 2001 From: caucow Date: Fri, 4 Jun 2021 10:27:40 -0500 Subject: [PATCH 01/21] Simplify multiblock constructor --- .../structures/FurnCraftChestStructure.java | 58 +++---------------- 1 file changed, 8 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java b/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java index f121f502..681d0b58 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java +++ b/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java @@ -27,60 +27,18 @@ public FurnCraftChestStructure(Block center) { chestBlocks.addAll(searchForBlockOnAllSides(center, Material.CHEST)); chestBlocks.addAll(searchForBlockOnAllSides(center, Material.TRAPPED_CHEST)); for (Block b : chestBlocks) { - switch (center.getFace(b)) { - case SOUTH: - if (center.getRelative(BlockFace.NORTH).getType() == Material.FURNACE) { - chest = b.getLocation(); - furnace = center.getRelative(BlockFace.NORTH) - .getLocation(); - } - break; - case NORTH: - if (center.getRelative(BlockFace.SOUTH).getType() == Material.FURNACE) { - chest = b.getLocation(); - furnace = center.getRelative(BlockFace.SOUTH) - .getLocation(); - } - break; - case WEST: - if (center.getRelative(BlockFace.EAST).getType() == Material.FURNACE) { - chest = b.getLocation(); - furnace = center.getRelative(BlockFace.EAST) - .getLocation(); - } - break; - case EAST: - if (center.getRelative(BlockFace.WEST).getType() == Material.FURNACE) { - chest = b.getLocation(); - furnace = center.getRelative(BlockFace.WEST) - .getLocation(); - } - break; - case UP: - if (center.getRelative(BlockFace.DOWN).getType() == Material.FURNACE) { - chest = b.getLocation(); - furnace = center.getRelative(BlockFace.DOWN) - .getLocation(); - } - break; - case DOWN: - if (center.getRelative(BlockFace.UP).getType() == Material.FURNACE) { - chest = b.getLocation(); - furnace = center.getRelative(BlockFace.UP) - .getLocation(); - } - break; - default: + BlockFace chestFace = center.getFace(b); + if (chestFace == null) continue; // fricc off nullcheck + BlockFace furnaceFace = chestFace.getOppositeFace(); + if (center.getRelative(furnaceFace).getType() == Material.FURNACE) { + chest = b.getLocation(); + furnace = center.getRelative(BlockFace.UP) + .getLocation(); break; } - } } - if (chest != null && furnace != null) { - complete = true; - } else { - complete = false; - } + complete = chest != null && furnace != null; } public FurnCraftChestStructure(List blocks) { From d6facaee99e45df8db89a91b0abb3c2d7518d458 Mon Sep 17 00:00:00 2001 From: caucow Date: Sun, 6 Jun 2021 14:45:04 -0500 Subject: [PATCH 02/21] Bump version 2.5.1 -> 2.5.2 + CMC dep 1.8.2 -> 1.8.4 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ec9517ef..8e24ca0f 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ com.github.igotyou FactoryMod jar - 2.5.1 + 2.5.2 FactoryMod https://github.com/Civclassic/FactoryMod @@ -39,7 +39,7 @@ vg.civcraft.mc.civmodcore CivModCore - 1.8.2 + 1.8.4 provided From c42779a15da9429bfb2f118292fbb3527d5cd37a Mon Sep 17 00:00:00 2001 From: caucow Date: Sun, 6 Jun 2021 15:53:40 -0500 Subject: [PATCH 03/21] Add configurable factory IO --- .../factories/FurnCraftChestFactory.java | 100 ++++- .../FurnCraftChestInteractionManager.java | 68 +++- .../FactoryMod/recipes/AOERepairRecipe.java | 11 +- .../FactoryMod/recipes/CompactingRecipe.java | 33 +- .../recipes/DecompactingRecipe.java | 27 +- .../DeterministicEnchantingRecipe.java | 19 +- .../recipes/DummyParsingRecipe.java | 4 +- .../recipes/FactoryMaterialReturnRecipe.java | 4 +- .../igotyou/FactoryMod/recipes/IRecipe.java | 23 +- .../FactoryMod/recipes/InputRecipe.java | 4 +- .../FactoryMod/recipes/LoreEnchantRecipe.java | 19 +- .../FactoryMod/recipes/PlayerHeadRecipe.java | 15 +- .../FactoryMod/recipes/PrintBookRecipe.java | 43 +- .../FactoryMod/recipes/PrintNoteRecipe.java | 43 +- .../recipes/PrintingPlateJsonRecipe.java | 26 +- .../recipes/PrintingPlateRecipe.java | 28 +- .../FactoryMod/recipes/ProductionRecipe.java | 17 +- .../FactoryMod/recipes/PylonRecipe.java | 17 +- .../recipes/RandomEnchantingRecipe.java | 13 +- .../recipes/RandomOutputRecipe.java | 15 +- .../recipes/RecipeScalingUpgradeRecipe.java | 13 +- .../FactoryMod/recipes/RepairRecipe.java | 13 +- .../FactoryMod/recipes/Upgraderecipe.java | 13 +- .../FactoryMod/recipes/WordBankRecipe.java | 25 +- .../FactoryMod/utility/DirectionMask.java | 96 +++++ .../FactoryMod/utility/FileHandler.java | 9 +- .../FactoryMod/utility/IOConfigSection.java | 110 +++++ .../FactoryMod/utility/IOSelector.java | 129 ++++++ .../utility/MultiInventoryWrapper.java | 376 ++++++++++++++++++ 29 files changed, 1099 insertions(+), 214 deletions(-) create mode 100644 src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java create mode 100644 src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java create mode 100644 src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java create mode 100644 src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java index facad425..dc2d7d98 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java @@ -15,6 +15,7 @@ import com.github.igotyou.FactoryMod.repairManager.IRepairManager; import com.github.igotyou.FactoryMod.repairManager.PercentageHealthRepairManager; import com.github.igotyou.FactoryMod.structures.FurnCraftChestStructure; +import com.github.igotyou.FactoryMod.utility.IOSelector; import com.github.igotyou.FactoryMod.utility.LoggingUtils; import java.util.ArrayList; import java.util.HashMap; @@ -22,10 +23,13 @@ import java.util.List; import java.util.Map; import java.util.UUID; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.block.Chest; import org.bukkit.block.Furnace; import org.bukkit.entity.Player; @@ -53,6 +57,8 @@ public class FurnCraftChestFactory extends Factory { private UUID activator; private double citadelBreakReduction; private boolean autoSelect; + private IOSelector furnaceIoSelector; + private IOSelector tableIoSelector; private static HashSet pylonFactories; @@ -66,6 +72,8 @@ public FurnCraftChestFactory(IInteractionManager im, IRepairManager rm, IPowerMa this.recipes = new ArrayList<>(); this.citadelBreakReduction = citadelBreakReduction; this.autoSelect = false; + this.furnaceIoSelector = new IOSelector(); + this.tableIoSelector = new IOSelector(); for (IRecipe rec : recipes) { addRecipe(rec); } @@ -92,6 +100,90 @@ public Inventory getInventory() { return chestBlock.getInventory(); } + public Inventory getInputInventory() { + if (!furnaceIoSelector.hasInputs() && !tableIoSelector.hasInputs()) { + return getInventory(); + } + FurnCraftChestStructure fccs = (FurnCraftChestStructure) getMultiBlockStructure(); + ArrayList invs = new ArrayList<>(12); + Block fblock = getFurnace(); + if (fblock.getType() != Material.FURNACE) { + return null; + } + Furnace fstate = (Furnace) fblock.getState(); + org.bukkit.block.data.type.Furnace fdata = (org.bukkit.block.data.type.Furnace) fstate.getBlockData(); + BlockFace facing = fdata.getFacing(); + for (BlockFace relativeFace : furnaceIoSelector.getInputs(facing)) { + Block relBlock = fblock.getRelative(relativeFace); + if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { + invs.add(((Chest) relBlock.getState()).getInventory()); + } + } + Block tblock = fccs.getCraftingTable(); + for (BlockFace relativeFace : tableIoSelector.getInputs(facing)) { + Block relBlock = tblock.getRelative(relativeFace); + if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { + invs.add(((Chest) relBlock.getState()).getInventory()); + } + } + MultiInventoryWrapper wrapper = new MultiInventoryWrapper(invs); + if (wrapper.getSize() == 0) { + return getInventory(); + } else { + return wrapper; + } + } + + public Inventory getOutputInventory() { + if (!furnaceIoSelector.hasOutputs() && !tableIoSelector.hasOutputs()) { + return getInventory(); + } + FurnCraftChestStructure fccs = (FurnCraftChestStructure) getMultiBlockStructure(); + ArrayList invs = new ArrayList<>(12); + Block fblock = getFurnace(); + if (fblock.getType() != Material.FURNACE) { + return null; + } + Furnace fstate = (Furnace) fblock.getState(); + org.bukkit.block.data.type.Furnace fdata = (org.bukkit.block.data.type.Furnace) fstate.getBlockData(); + BlockFace facing = fdata.getFacing(); + for (BlockFace relativeFace : furnaceIoSelector.getOutputs(facing)) { + Block relBlock = fblock.getRelative(relativeFace); + if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { + invs.add(((Chest) relBlock.getState()).getInventory()); + } + } + Block tblock = fccs.getCraftingTable(); + for (BlockFace relativeFace : tableIoSelector.getOutputs(facing)) { + Block relBlock = tblock.getRelative(relativeFace); + if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { + invs.add(((Chest) relBlock.getState()).getInventory()); + } + } + MultiInventoryWrapper wrapper = new MultiInventoryWrapper(invs); + if (wrapper.getSize() == 0) { + return getInventory(); + } else { + return wrapper; + } + } + + public void setFurnaceIOSelector(IOSelector ioSelector) { + this.furnaceIoSelector = ioSelector; + } + + public IOSelector getFurnaceIOSelector() { + return furnaceIoSelector; + } + + public void setTableIOSelector(IOSelector ioSelector) { + this.tableIoSelector = ioSelector; + } + + public IOSelector getTableIOSelector() { + return tableIoSelector; + } + /** * @return Inventory of the furnace or null if there is no furnace where one * should be @@ -362,11 +454,11 @@ public void run() { // this if else might look a bit weird, but because // upgrading changes the current recipe and a lot of // other stuff, this is needed - currentRecipe.applyEffect(getInventory(), this); + currentRecipe.applyEffect(getInputInventory(), getOutputInventory(), this); deactivate(); return; } else { - if (currentRecipe.applyEffect(getInventory(), this)) { + if (currentRecipe.applyEffect(getInputInventory(), getOutputInventory(), this)) { runCount.put(currentRecipe, runCount.get(currentRecipe) + 1); } else { sendActivatorMessage(ChatColor.RED + currentRecipe.getName() + " in " + name + " deactivated because it ran out of storage space"); @@ -506,12 +598,12 @@ public void setProductionTimer(int timer) { * selected recipe at least once */ public boolean hasInputMaterials() { - return currentRecipe.enoughMaterialAvailable(getInventory()); + return currentRecipe.enoughMaterialAvailable(getInputInventory()); } public IRecipe getAutoSelectRecipe() { for (IRecipe rec : recipes) { - if (rec.enoughMaterialAvailable(getInventory())) { + if (rec.enoughMaterialAvailable(getInputInventory())) { return rec; } } diff --git a/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java b/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java index 84a78a9e..9caa59bc 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java +++ b/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java @@ -11,12 +11,15 @@ import com.github.igotyou.FactoryMod.structures.MultiBlockStructure; import com.github.igotyou.FactoryMod.utility.FactoryModGUI; import java.text.DecimalFormat; -import java.util.HashMap; +import java.util.ArrayList; import java.util.List; + +import com.github.igotyou.FactoryMod.utility.IOConfigSection; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.Furnace; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockRedstoneEvent; import org.bukkit.inventory.ItemStack; @@ -25,6 +28,11 @@ import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; import vg.civcraft.mc.civmodcore.inventorygui.Clickable; import vg.civcraft.mc.civmodcore.inventorygui.ClickableInventory; +import vg.civcraft.mc.civmodcore.inventorygui.IClickable; +import vg.civcraft.mc.civmodcore.inventorygui.components.ComponableInventory; +import vg.civcraft.mc.civmodcore.inventorygui.components.Scrollbar; +import vg.civcraft.mc.civmodcore.inventorygui.components.SlotPredicates; +import vg.civcraft.mc.civmodcore.inventorygui.components.StaticDisplaySection; import vg.civcraft.mc.civmodcore.itemHandling.ItemMap; import vg.civcraft.mc.namelayer.NameAPI; import vg.civcraft.mc.namelayer.group.Group; @@ -33,8 +41,7 @@ public class FurnCraftChestInteractionManager implements IInteractionManager { private FurnCraftChestFactory fccf; - private HashMap recipes = new HashMap<>(); - private DecimalFormat decimalFormatting; + private final DecimalFormat decimalFormatting; public FurnCraftChestInteractionManager(FurnCraftChestFactory fccf) { this(); @@ -100,7 +107,7 @@ public void leftClick(Player p, Block b, BlockFace bf) { ClickableInventory ci = new ClickableInventory(54, fccf.getCurrentRecipe().getName()); int index = 4; List inp = ((InputRecipe) fccf.getCurrentRecipe()) - .getInputRepresentation(fccf.getInventory(), fccf); + .getInputRepresentation(fccf.getInputInventory(), fccf); if (inp.size() > 18) { inp = new ItemMap(inp).getLoredItemCountRepresentation(); } @@ -130,7 +137,7 @@ public void clicked(Player arg0) { } index = 49; List outp = ((InputRecipe) fccf.getCurrentRecipe()) - .getOutputRepresentation(fccf.getInventory(), fccf); + .getOutputRepresentation(fccf.getOutputInventory(), fccf); if (outp.size() > 18) { outp = new ItemMap(outp).getLoredItemCountRepresentation(); } @@ -189,15 +196,9 @@ public void clicked(Player arg0) { } if (b.equals(((FurnCraftChestStructure) fccf.getMultiBlockStructure()).getCraftingTable())) { // crafting table // interaction - int rows = ((fccf.getRecipes().size() + 2) / 9) + 1; - if (fccf.getRecipes().size() > 52 || rows > 6) { - p.sendMessage(ChatColor.RED - + "This factory has more than 52 recipes and the GUI for it can't be opened. Either complain to " - + "your admin to have them put less recipes in this factory or complain to /u/maxopoly to add " - + "scrollviews to this"); - return; - } - ClickableInventory ci = new ClickableInventory(rows * 9, "Select a recipe"); + ComponableInventory compInv = new ComponableInventory("Select a recipe", 6, p); + List recipeList = fccf.getRecipes(); + List recipeClickList = new ArrayList<>(recipeList.size()); for (IRecipe rec : fccf.getRecipes()) { InputRecipe recipe = (InputRecipe) (rec); ItemStack recStack = recipe.getRecipeRepresentation(); @@ -223,15 +224,17 @@ public void clicked(Player p) { if (fccf.isActive()) { p.sendMessage(ChatColor.RED + "You can't switch recipes while the factory is running"); } else { - fccf.setRecipe(recipes.get(this)); - p.sendMessage(ChatColor.GREEN + "Switched recipe to " + recipes.get(this).getName()); + fccf.setRecipe(recipe); + p.sendMessage(ChatColor.GREEN + "Switched recipe to " + recipe.getName()); } - } }; - recipes.put(c, recipe); - ci.addSlot(c); + recipeClickList.add(c); } + Scrollbar recipeScroller = new Scrollbar(recipeClickList, 27); + recipeScroller.setBackwardsClickSlot(8); + compInv.addComponent(recipeScroller, SlotPredicates.offsetRectangle(3, 9, 0, 0)); + ItemStack autoSelectStack = new ItemStack(Material.REDSTONE_BLOCK); ItemUtils.setDisplayName(autoSelectStack, "Toggle auto select"); ItemUtils.addLore(autoSelectStack, @@ -247,7 +250,7 @@ public void clicked(Player p) { fccf.setAutoSelect(!fccf.isAutoSelect()); } }; - ci.setSlot(autoClick, (rows * 9) - 2); + ItemStack menuStack = new ItemStack(Material.PAINTING); ItemUtils.setDisplayName(menuStack, "Open menu"); ItemUtils.addLore(menuStack, ChatColor.LIGHT_PURPLE + "Click to open a detailed menu"); @@ -258,9 +261,30 @@ public void clicked(Player p) { gui.showForFactory((FurnCraftChestEgg)FactoryMod.getInstance().getManager().getEgg(fccf.getName())); } }; - ci.setSlot(menuC, (rows * 9) - 1); - ci.showInventory(p); + Block fblock = fccf.getFurnace(); + if (fblock.getType() == Material.FURNACE) { + Furnace fstate = (Furnace) fblock.getState(); + org.bukkit.block.data.type.Furnace fdata = (org.bukkit.block.data.type.Furnace) fstate.getBlockData(); + BlockFace facing = fdata.getFacing(); + IOConfigSection furnaceConfigSection = new IOConfigSection( + fccf.getFurnaceIOSelector(), + Material.FURNACE, + fblock, + facing); + IOConfigSection tableConfigSection = new IOConfigSection( + fccf.getTableIOSelector(), + Material.CRAFTING_TABLE, + ((FurnCraftChestStructure) fccf.getMultiBlockStructure()).getCraftingTable(), + facing); + compInv.addComponent(furnaceConfigSection, SlotPredicates.offsetRectangle(3, 3, 3, 0)); + compInv.addComponent(tableConfigSection, SlotPredicates.offsetRectangle(3, 3, 3, 4)); + } + Clickable[] buddons = new Clickable[] { autoClick, menuC }; + StaticDisplaySection lowerSection = new StaticDisplaySection(buddons); + compInv.addComponent(lowerSection, SlotPredicates.offsetRectangle(3, 1, 3, 8)); + compInv.update(); + compInv.updatePlayerView(); return; } if (b.equals(fccf.getFurnace())) { // furnace interaction diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/AOERepairRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/AOERepairRecipe.java index 668fb6cc..2970a4c3 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/AOERepairRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/AOERepairRecipe.java @@ -9,6 +9,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; @@ -133,11 +135,10 @@ public List getOutputRepresentation(Inventory i, FurnCraftChestFactor } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - Chest c = (Chest) i.getHolder(); - Location loc = c.getLocation(); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + Location loc = fccf.getChest().getLocation(); List facs = getNearbyFactoriesSortedByDistance(loc); - int essenceCount = new ItemMap(i).getAmount(essence); + int essenceCount = new ItemMap(inputInv).getAmount(essence); for (FurnCraftChestFactory fac : facs) { PercentageHealthRepairManager rm = (PercentageHealthRepairManager) fac .getRepairManager(); @@ -154,7 +155,7 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { Inventory targetInv = ((InventoryHolder) (fac.getChest() .getState())).getInventory(); if (remMap.fitsIn(targetInv)) { - if (remMap.removeSafelyFrom(i)) { + if (remMap.removeSafelyFrom(inputInv)) { targetInv.addItem(remStack); for (IRecipe rec : fac.getRecipes()) { if (rec instanceof RepairRecipe) { diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/CompactingRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/CompactingRecipe.java index 70edaa31..b41926fa 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/CompactingRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/CompactingRecipe.java @@ -5,6 +5,8 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Material; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -30,12 +32,12 @@ public CompactingRecipe(String identifier, ItemMap input, List exclude } @Override - public boolean enoughMaterialAvailable(Inventory i) { - if (!input.isContainedIn(i)) { + public boolean enoughMaterialAvailable(Inventory inputInv) { + if (!input.isContainedIn(inputInv)) { return false; } - ItemMap im = new ItemMap(i); - for (ItemStack is : i.getContents()) { + ItemMap im = new ItemMap(inputInv); + for (ItemStack is : inputInv.getContents()) { if (is != null) { if (compactable(is, im)) { return true; @@ -56,25 +58,26 @@ public String getName() { } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); - if (input.isContainedIn(i)) { - ItemMap im = new ItemMap(i); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); + if (input.isContainedIn(inputInv)) { + ItemMap im = new ItemMap(inputInv); //technically we could just directly work with the ItemMap here to iterate over the items so we dont check identical items multiple times, //but using the iterator of the inventory preserves the order of the inventory, which is more important here to guarantee one behavior //to the player - for (ItemStack is : i.getContents()) { + for (ItemStack is : inputInv.getContents()) { if (is != null) { if (compactable(is, im)) { - if (input.removeSafelyFrom(i)) { - compact(is,i); + if (input.removeSafelyFrom(inputInv)) { + compact(is, inputInv, outputInv); } break; } } } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } @@ -134,13 +137,13 @@ public Material getRecipeRepresentationMaterial() { * * @param is */ - private void compact(ItemStack is, Inventory i) { + private void compact(ItemStack is, Inventory inputInv, Inventory outputInv) { ItemStack copy = is.clone(); copy.setAmount(getCompactStackSize(copy.getType())); ItemMap toRemove = new ItemMap(copy); - if (toRemove.removeSafelyFrom(i)) { + if (toRemove.removeSafelyFrom(inputInv)) { compactStack(copy); - i.addItem(copy); + outputInv.addItem(copy); } } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/DecompactingRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/DecompactingRecipe.java index bf40ff23..3ac9dae0 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/DecompactingRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/DecompactingRecipe.java @@ -4,6 +4,8 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Material; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -27,11 +29,11 @@ public DecompactingRecipe(String identifier, ItemMap input, String name, int pro } @Override - public boolean enoughMaterialAvailable(Inventory i) { - if (!input.isContainedIn(i)) { + public boolean enoughMaterialAvailable(Inventory inputInv) { + if (!input.isContainedIn(inputInv)) { return false; } - for (ItemStack is : i.getContents()) { + for (ItemStack is : inputInv.getContents()) { if (is != null) { if (isDecompactable(is)) { return true; @@ -42,10 +44,11 @@ public boolean enoughMaterialAvailable(Inventory i) { } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); - if (input.isContainedIn(i)) { - for (ItemStack is : i.getContents()) { + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); + if (input.isContainedIn(inputInv)) { + for (ItemStack is : inputInv.getContents()) { if (is != null) { if (isDecompactable(is)) { ItemStack removeClone = is.clone(); @@ -54,11 +57,11 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { ItemMap toAdd = new ItemMap(); removeCompactLore(removeClone); toAdd.addItemAmount(removeClone, CompactingRecipe.getCompactStackSize(removeClone.getType())); - if (toAdd.fitsIn(i)) { //fits in chest - if (input.removeSafelyFrom(i)) { //remove extra input - if (toRemove.removeSafelyFrom(i)) { //remove one compacted item + if (toAdd.fitsIn(outputInv)) { //fits in chest + if (input.removeSafelyFrom(inputInv)) { //remove extra input + if (toRemove.removeSafelyFrom(inputInv)) { //remove one compacted item for(ItemStack add : toAdd.getItemStackRepresentation()) { - i.addItem(add); + outputInv.addItem(add); } } } @@ -70,7 +73,7 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { } } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/DeterministicEnchantingRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/DeterministicEnchantingRecipe.java index 15a5ed0f..a58b2f0b 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/DeterministicEnchantingRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/DeterministicEnchantingRecipe.java @@ -4,6 +4,8 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; @@ -27,10 +29,10 @@ public DeterministicEnchantingRecipe(String identifier, String name, int product } @Override - public boolean enoughMaterialAvailable(Inventory i) { - if (input.isContainedIn(i)) { + public boolean enoughMaterialAvailable(Inventory inputInv) { + if (input.isContainedIn(inputInv)) { ItemStack toolio = tool.getItemStackRepresentation().get(0); - for (ItemStack is : i.getContents()) { + for (ItemStack is : inputInv.getContents()) { if (is != null && toolio.getType() == is.getType() && toolio.getEnchantmentLevel(enchant) == is.getEnchantmentLevel(enchant)) { return true; @@ -80,11 +82,12 @@ public List getInputRepresentation(Inventory i, FurnCraftChestFactory } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); - if (input.removeSafelyFrom(i)) { + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); + if (input.removeSafelyFrom(inputInv)) { ItemStack toolio = tool.getItemStackRepresentation().get(0); - for (ItemStack is : i.getContents()) { + for (ItemStack is : inputInv.getContents()) { if (is != null && toolio.getType() == is.getType() && toolio.getEnchantmentLevel(enchant) == is.getEnchantmentLevel(enchant)) { ItemMeta im = is.getItemMeta(); @@ -95,7 +98,7 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { } } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/DummyParsingRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/DummyParsingRecipe.java index 9c3a3d69..fa233ee4 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/DummyParsingRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/DummyParsingRecipe.java @@ -2,6 +2,8 @@ import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; import java.util.List; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Material; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -14,7 +16,7 @@ public DummyParsingRecipe(String identifier, String name, int productionTime, It } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/FactoryMaterialReturnRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/FactoryMaterialReturnRecipe.java index 1e4aca3d..75cf0771 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/FactoryMaterialReturnRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/FactoryMaterialReturnRecipe.java @@ -6,6 +6,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; @@ -68,7 +70,7 @@ public Material getRecipeRepresentationMaterial() { } @Override - public boolean applyEffect(Inventory i, final FurnCraftChestFactory fccf) { + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { FactoryMod.getInstance().getManager().removeFactory(fccf); for (Block b : fccf.getMultiBlockStructure().getRelevantBlocks()) { b.setType(Material.AIR); diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/IRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/IRecipe.java index 3d5bf6ce..b0c3d1e5 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/IRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/IRecipe.java @@ -7,12 +7,11 @@ * Encapsulates a specific functionality for a FurnCraftChest factory. Each * factory of this type can have of many different recipes and what the recipe * actually does is completly kept inside the recipe's class - * */ public interface IRecipe { /** * @return The identifier for this recipe, which is used both internally and - * to display the recipe to a player + * to display the recipe to a player */ public String getName(); @@ -29,28 +28,26 @@ public interface IRecipe { /** * Checks whether enough material is available in the given inventory to run * this recipe at least once - * - * @param i - * Inventory to check + * + * @param inputInv Inventory to check * @return true if the recipe could be run at least once, false if not */ - public boolean enoughMaterialAvailable(Inventory i); + public boolean enoughMaterialAvailable(Inventory inputInv); /** * Applies whatever the recipe actually does, it's main functionality - * - * @param i - * Inventory which contains the materials to work with - * @param f - * Factory which is run + * + * @param inputInv Inventory which contains the materials to work with + * @param outputInv Inventory to add output items to. + * @param fccf Factory which is run * @return true if the recipe could be run; false otherwise (e.g: not enough storage space) */ - public boolean applyEffect(Inventory i, FurnCraftChestFactory f); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf); /** * Each implementation of this class has to specify a unique identifier, * which is used to identify instances of this recipe in the config - * + * * @return Unique identifier for the implementation */ public String getTypeIdentifier(); diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/InputRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/InputRecipe.java index d9344751..29457c84 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/InputRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/InputRecipe.java @@ -140,8 +140,8 @@ public ItemMap getInput() { } @Override - public boolean enoughMaterialAvailable(Inventory i) { - return input.isContainedIn(i); + public boolean enoughMaterialAvailable(Inventory inputInv) { + return input.isContainedIn(inputInv); } @Override diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/LoreEnchantRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/LoreEnchantRecipe.java index d9ee9305..a619278f 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/LoreEnchantRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/LoreEnchantRecipe.java @@ -4,6 +4,8 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -38,10 +40,10 @@ public LoreEnchantRecipe(String identifier, String name, int productionTime, Ite } @Override - public boolean enoughMaterialAvailable(Inventory i) { - if (input.isContainedIn(i)) { + public boolean enoughMaterialAvailable(Inventory inputInv) { + if (input.isContainedIn(inputInv)) { ItemStack toolio = tool.getItemStackRepresentation().get(0); - for (ItemStack is : i.getContents()) { + for (ItemStack is : inputInv.getContents()) { if (is != null && toolio.getType() == is.getType() && hasStackRequiredLore(is)) { return true; } @@ -88,11 +90,12 @@ public List getInputRepresentation(Inventory i, FurnCraftChestFactory } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); - if (input.removeSafelyFrom(i)) { + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); + if (input.removeSafelyFrom(inputInv)) { ItemStack toolio = tool.getItemStackRepresentation().get(0); - for (ItemStack is : i.getContents()) { + for (ItemStack is : inputInv.getContents()) { if (is != null && toolio.getType() == is.getType() && hasStackRequiredLore(is)) { ItemMeta im = is.getItemMeta(); if (im == null) { @@ -112,7 +115,7 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { } } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/PlayerHeadRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/PlayerHeadRecipe.java index 77987fee..cae1ddde 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/PlayerHeadRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/PlayerHeadRecipe.java @@ -5,6 +5,8 @@ import java.util.Collections; import java.util.List; import java.util.Random; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -48,15 +50,16 @@ public Material getRecipeRepresentationMaterial() { } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory f) { - logBeforeRecipeRun(i, f); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); ItemMap toRemove = input.clone(); ArrayList players = new ArrayList<>(Bukkit.getOnlinePlayers()); if (players.isEmpty()) { return false; } - if (toRemove.isContainedIn(i)) { - if (toRemove.removeSafelyFrom(i)) { + if (toRemove.isContainedIn(inputInv)) { + if (toRemove.removeSafelyFrom(inputInv)) { Random rand = new Random(); Player player = players.get(rand.nextInt(players.size())); ItemStack is = new ItemStack(Material.PLAYER_HEAD, 1); @@ -64,10 +67,10 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory f) { im.setOwningPlayer(Bukkit.getOfflinePlayer(player.getUniqueId())); im.setDisplayName(player.getDisplayName()); is.setItemMeta(im); - i.addItem(is); + outputInv.addItem(is); } } - logAfterRecipeRun(i, f); + logAfterRecipeRun(combo, fccf); return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintBookRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintBookRecipe.java index ba813585..6ad5bb62 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintBookRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintBookRecipe.java @@ -1,9 +1,12 @@ package com.github.igotyou.FactoryMod.recipes; import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; + import java.util.ArrayList; import java.util.LinkedList; import java.util.List; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; @@ -33,35 +36,34 @@ public PrintBookRecipe( ItemMap input, ItemMap printingPlate, int outputAmount - ) - { + ) { super(identifier, name, productionTime, input); this.printingPlate = printingPlate; this.outputAmount = outputAmount; - } + } @Override - public boolean enoughMaterialAvailable(Inventory i) { - return this.input.isContainedIn(i) && getPrintingPlateItemStack(i, this.printingPlate) != null; + public boolean enoughMaterialAvailable(Inventory inputInv) { + return this.input.isContainedIn(inputInv) && getPrintingPlateItemStack(inputInv, this.printingPlate) != null; } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); - ItemStack printingPlateStack = getPrintingPlateItemStack(i, this.printingPlate); + ItemStack printingPlateStack = getPrintingPlateItemStack(inputInv, this.printingPlate); ItemMap toRemove = this.input.clone(); if (printingPlateStack != null - && toRemove.isContainedIn(i) - && toRemove.removeSafelyFrom(i) - ) - { - ItemStack book = createBook(printingPlateStack, this.outputAmount); - i.addItem(book); + && toRemove.isContainedIn(inputInv) + && toRemove.removeSafelyFrom(inputInv) + ) { + ItemStack book = createBook(printingPlateStack, this.outputAmount); + outputInv.addItem(book); } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } @@ -90,7 +92,7 @@ public List getInputRepresentation(Inventory i, FurnCraftChestFactory ItemStack printingPlateStack = getPrintingPlateItemStack(i, this.printingPlate); - if(printingPlateStack != null) { + if (printingPlateStack != null) { result.add(printingPlateStack.clone()); } @@ -125,13 +127,12 @@ public Material getRecipeRepresentationMaterial() { protected ItemStack getPrintingPlateItemStack(Inventory i, ItemMap printingPlate) { ItemMap items = new ItemMap(i).getStacksByMaterial(printingPlate.getItemStackRepresentation().get(0).getType()); - for(ItemStack is : items.getItemStackRepresentation()) { + for (ItemStack is : items.getItemStackRepresentation()) { ItemMeta itemMeta = is.getItemMeta(); - if(itemMeta.getDisplayName().equals(PrintingPlateRecipe.itemName) + if (itemMeta.getDisplayName().equals(PrintingPlateRecipe.itemName) && itemMeta.hasEnchant(Enchantment.DURABILITY) - ) - { + ) { return is; } } @@ -143,7 +144,7 @@ protected ItemStack getPrintingPlateItemStack(Inventory i, ItemMap printingPlate public String getTypeIdentifier() { return "PRINTBOOK"; } - + @Override public List getTextualOutputRepresentation(Inventory i, FurnCraftChestFactory fccf) { ItemStack is = new ItemStack(Material.WRITTEN_BOOK, outputAmount); diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintNoteRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintNoteRecipe.java index e7942f0a..66054cb9 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintNoteRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintNoteRecipe.java @@ -1,13 +1,15 @@ /** * @author Aleksey Terzi - * */ package com.github.igotyou.FactoryMod.recipes; import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; + import java.util.ArrayList; import java.util.List; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.inventory.Inventory; @@ -42,36 +44,35 @@ public PrintNoteRecipe( String identifier, String name, int productionTime, - ItemMap input, + ItemMap input, ItemMap printingPlate, int outputAmount, boolean secureNote, String title - ) - { + ) { super(identifier, name, productionTime, input, printingPlate, outputAmount); this.secureNote = secureNote; - if(title != null && title.length() > 0) { + if (title != null && title.length() > 0) { this.title = title; } else { - this.title = secureNote ? secureNoteName: pamphletName; + this.title = secureNote ? secureNoteName : pamphletName; } - } + } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); - ItemStack printingPlateStack = getPrintingPlateItemStack(i, getPrintingPlate()); + ItemStack printingPlateStack = getPrintingPlateItemStack(inputInv, getPrintingPlate()); ItemMap toRemove = this.input.clone(); if (printingPlateStack != null - && toRemove.isContainedIn(i) - && toRemove.removeSafelyFrom(i) - ) - { + && toRemove.isContainedIn(inputInv) + && toRemove.removeSafelyFrom(inputInv) + ) { BookInfo info = getBookInfo(printingPlateStack); ItemStack paper = new ItemStack(Material.PAPER, getOutputAmount()); @@ -80,21 +81,21 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { paperMeta.setLore(info.lines); paper.setItemMeta(paperMeta); - i.addItem(paper); + outputInv.addItem(paper); } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } private BookInfo getBookInfo(ItemStack printingPlateStack) { ItemStack book = createBook(printingPlateStack, 1); - BookMeta bookMeta = (BookMeta)book.getItemMeta(); - String text = bookMeta.getPageCount() > 0 ? bookMeta.getPage(1): ""; + BookMeta bookMeta = (BookMeta) book.getItemMeta(); + String text = bookMeta.getPageCount() > 0 ? bookMeta.getPage(1) : ""; String[] lines = text.split("\n"); List fixedLines = new ArrayList<>(); - for(String line : lines) { + for (String line : lines) { fixedLines.add(ChatColor.GRAY + line .replaceAll(ChatColor.BLACK.toString(), ChatColor.GRAY.toString()) .replaceAll(ChatColor.RESET.toString(), ChatColor.GRAY.toString())); @@ -104,9 +105,9 @@ private BookInfo getBookInfo(ItemStack printingPlateStack) { BookInfo info = new BookInfo(); info.lines = fixedLines; - info.title = bookTitle != null && bookTitle.length() > 0 ? bookTitle: this.title; + info.title = bookTitle != null && bookTitle.length() > 0 ? bookTitle : this.title; - if(this.secureNote) { + if (this.secureNote) { TagManager printingPlateTag = new TagManager(printingPlateStack); String serialNumber = printingPlateTag.getString("SN"); info.lines.add(serialNumber); diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintingPlateJsonRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintingPlateJsonRecipe.java index fc13db26..9c59008a 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintingPlateJsonRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintingPlateJsonRecipe.java @@ -2,6 +2,7 @@ import com.github.igotyou.FactoryMod.FactoryMod; import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -40,8 +41,8 @@ public PrintingPlateJsonRecipe(String identifier, String name, int productionTim } @Override - public boolean enoughMaterialAvailable(Inventory i) { - String[] pages = String.join("", ((BookMeta) getBook(i).getItemMeta()).getPages()).split("<>"); + public boolean enoughMaterialAvailable(Inventory inputInv) { + String[] pages = String.join("", ((BookMeta) getBook(inputInv).getItemMeta()).getPages()).split("<>"); for (String page : pages) { try { @@ -50,25 +51,26 @@ public boolean enoughMaterialAvailable(Inventory i) { String result = checkForIllegalSections(element); if (result != null) { - factioryError(i, "Banned Tag Error", "Error Message: " + result); + factioryError(inputInv, "Banned Tag Error", "Error Message: " + result); return false; } } catch (JsonSyntaxException e) { - factioryError(i, "JSON Syntax Error", e.toString()); + factioryError(inputInv, "JSON Syntax Error", e.toString()); return false; } } - return this.input.isContainedIn(i) && getBook(i) != null; + return this.input.isContainedIn(inputInv) && getBook(inputInv) != null; } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); - ItemStack book = getBook(i); + ItemStack book = getBook(inputInv); BookMeta bookMeta = (BookMeta) book.getItemMeta(); if (!bookMeta.hasGeneration()) { bookMeta.setGeneration(BookMeta.Generation.ORIGINAL); @@ -91,9 +93,9 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { ItemMap toRemove = input.clone(); ItemMap toAdd = output.clone(); - if (toRemove.isContainedIn(i) && toRemove.removeSafelyFrom(i)) { + if (toRemove.isContainedIn(inputInv) && toRemove.removeSafelyFrom(inputInv)) { for (ItemStack is : toAdd.getItemStackRepresentation()) { - is = addTags(i, serialNumber, is, bookNBT); + is = addTags(serialNumber, is, bookNBT); ItemUtils.setDisplayName(is, itemName); ItemUtils.setLore(is, @@ -105,11 +107,11 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { ); is.addUnsafeEnchantment(Enchantment.DURABILITY, 1); is.getItemMeta().addItemFlags(ItemFlag.HIDE_ENCHANTS); - i.addItem(is); + outputInv.addItem(is); } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintingPlateRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintingPlateRecipe.java index aafd3bd4..ece77d85 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintingPlateRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/PrintingPlateRecipe.java @@ -10,6 +10,8 @@ import java.util.LinkedList; import java.util.List; import java.util.UUID; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import net.minecraft.server.v1_16_R3.NBTTagCompound; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -38,15 +40,16 @@ public PrintingPlateRecipe(String identifier, String name, int productionTime, I } @Override - public boolean enoughMaterialAvailable(Inventory i) { - return this.input.isContainedIn(i) && getBook(i) != null; + public boolean enoughMaterialAvailable(Inventory inputInv) { + return this.input.isContainedIn(inputInv) && getBook(inputInv) != null; } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); - ItemStack book = getBook(i); + ItemStack book = getBook(inputInv); BookMeta bookMeta = (BookMeta)book.getItemMeta(); if (!bookMeta.hasGeneration()){ bookMeta.setGeneration(Generation.TATTERED); @@ -56,9 +59,9 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { ItemMap toRemove = input.clone(); ItemMap toAdd = output.clone(); - if (toRemove.isContainedIn(i) && toRemove.removeSafelyFrom(i)) { + if (toRemove.isContainedIn(inputInv) && toRemove.removeSafelyFrom(inputInv)) { for(ItemStack is: toAdd.getItemStackRepresentation()) { - is = addTags(i, serialNumber, is, CraftItemStack.asNMSCopy(book).getTag()); + is = addTags(serialNumber, is, CraftItemStack.asNMSCopy(book).getTag()); ItemUtils.setDisplayName(is, itemName); ItemUtils.setLore(is, @@ -69,15 +72,22 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { ); is.addUnsafeEnchantment(Enchantment.DURABILITY, 1); is.getItemMeta().addItemFlags(ItemFlag.HIDE_ENCHANTS); - i.addItem(is); + outputInv.addItem(is); } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } + /** + * @deprecated {@code Inventory i} isn't being used, switch to the overload without it. + */ public static ItemStack addTags(Inventory i, String serialNumber, ItemStack plate, NBTTagCompound bookTag) { + return addTags(serialNumber, plate, bookTag); + } + + public static ItemStack addTags(String serialNumber, ItemStack plate, NBTTagCompound bookTag) { net.minecraft.server.v1_16_R3.ItemStack nmsPlate = CraftItemStack.asNMSCopy(plate); NBTTagCompound plateTag = nmsPlate.getOrCreateTag(); diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java index 1d3819c9..5038e057 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Map.Entry; import java.util.Random; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.inventory.Inventory; @@ -111,8 +113,9 @@ public List getGuaranteedOutput(Inventory i, FurnCraftChestFactory fc } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); ItemMap toRemove = input.clone(); ItemMap toAdd; if (getModifier() == null) { @@ -128,17 +131,17 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { } } } - if (toRemove.isContainedIn(i)) { - if (!toAdd.fitsIn(i)) { // does not fit in chest + if (toRemove.isContainedIn(inputInv)) { + if (!toAdd.fitsIn(outputInv)) { // does not fit in chest return false; } - if (toRemove.removeSafelyFrom(i)) { + if (toRemove.removeSafelyFrom(inputInv)) { for (ItemStack is : toAdd.getItemStackRepresentation()) { - i.addItem(is); + outputInv.addItem(is); } } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/PylonRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/PylonRecipe.java index 3ebb141e..f93740c8 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/PylonRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/PylonRecipe.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Map.Entry; import java.util.Set; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.inventory.Inventory; @@ -28,17 +30,18 @@ public PylonRecipe(String identifier, String name, int productionTime, ItemMap i } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - if (!input.isContainedIn(i)) { + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + if (!input.isContainedIn(inputInv)) { return false; } ItemMap actualOutput = getCurrentOutput(); - if (!actualOutput.fitsIn(i)) { + if (!actualOutput.fitsIn(outputInv)) { return false; } - if (input.removeSafelyFrom(i)) { + if (input.removeSafelyFrom(inputInv)) { for (ItemStack is : actualOutput.getItemStackRepresentation()) { - i.addItem(is); + outputInv.addItem(is); } } return true; @@ -81,8 +84,8 @@ public Material getRecipeRepresentationMaterial() { } @Override - public boolean enoughMaterialAvailable(Inventory i) { - return input.isContainedIn(i) && skyView(); + public boolean enoughMaterialAvailable(Inventory inputInv) { + return input.isContainedIn(inputInv) && skyView(); } public int getWeight() { diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/RandomEnchantingRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/RandomEnchantingRecipe.java index 41329934..6c4aa90e 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/RandomEnchantingRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/RandomEnchantingRecipe.java @@ -5,6 +5,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; @@ -91,12 +93,13 @@ public List getOutputRepresentation(Inventory i, FurnCraftChestFactor } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); for (ItemStack is : input.getItemStackRepresentation()) { - i.removeItem(is); + inputInv.removeItem(is); } - for (ItemStack is : i.getContents()) { + for (ItemStack is : inputInv.getContents()) { if (is != null && is.getType() == tool && !is.getItemMeta().hasEnchants()) { boolean applied = false; @@ -112,7 +115,7 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { break; } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/RandomOutputRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/RandomOutputRecipe.java index 21cf4e22..e1b417b0 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/RandomOutputRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/RandomOutputRecipe.java @@ -7,6 +7,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Random; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.inventory.Inventory; @@ -45,8 +47,9 @@ public RandomOutputRecipe(String identifier, String name, int productionTime, It } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); ItemMap toRemove = input.clone(); ItemMap toAdd = null; int counter = 0; @@ -64,14 +67,14 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { FactoryMod.getInstance().warning("Unable to find a random item to output. Recipe execution was cancelled," + fccf.getLogData()); return false; } - if (toRemove.isContainedIn(i)) { - if (toRemove.removeSafelyFrom(i)) { + if (toRemove.isContainedIn(inputInv)) { + if (toRemove.removeSafelyFrom(inputInv)) { for(ItemStack is: toAdd.getItemStackRepresentation()) { - i.addItem(is); + outputInv.addItem(is); } } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/RecipeScalingUpgradeRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/RecipeScalingUpgradeRecipe.java index f622e8f8..4279ca74 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/RecipeScalingUpgradeRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/RecipeScalingUpgradeRecipe.java @@ -4,6 +4,8 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Material; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -24,14 +26,15 @@ public RecipeScalingUpgradeRecipe(String identifier, String name, int production } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); if (toUpgrade == null || !fccf.getRecipes().contains(toUpgrade)) { return false; } ItemMap toRemove = input.clone(); - if (toRemove.isContainedIn(i)) { - if (toRemove.removeSafelyFrom(i)) { + if (toRemove.isContainedIn(inputInv)) { + if (toRemove.removeSafelyFrom(inputInv)) { if (newRank == 1) { fccf.addRecipe(toUpgrade); } @@ -46,7 +49,7 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { } } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/RepairRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/RepairRecipe.java index 7b65eca8..7eec6a10 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/RepairRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/RepairRecipe.java @@ -6,6 +6,8 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.inventory.Inventory; @@ -45,10 +47,11 @@ public List getInputRepresentation(Inventory i, FurnCraftChestFactory } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logBeforeRecipeRun(i, fccf); - if (enoughMaterialAvailable(i)) { - if (input.removeSafelyFrom(i)) { + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); + if (enoughMaterialAvailable(inputInv)) { + if (input.removeSafelyFrom(inputInv)) { ((PercentageHealthRepairManager) (fccf.getRepairManager())) .repair(healthPerRun); LoggingUtils.log(((PercentageHealthRepairManager) (fccf @@ -57,7 +60,7 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { + fccf.getLogData() + " after repairing"); } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/Upgraderecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/Upgraderecipe.java index 867b96f1..11347b37 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/Upgraderecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/Upgraderecipe.java @@ -6,6 +6,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; @@ -26,10 +28,11 @@ public Upgraderecipe(String identifier, String name, int productionTime, ItemMap } @Override - public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { - logAfterRecipeRun(i, fccf); - if (input.isContainedIn(i)) { - if (input.removeSafelyFrom(i)) { + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + logBeforeRecipeRun(combo, fccf); + if (input.isContainedIn(inputInv)) { + if (input.removeSafelyFrom(inputInv)) { FurnCraftChestEgg e = egg; fccf.upgrade(e.getName(), e.getRecipes(), e.getFuel(), @@ -37,7 +40,7 @@ public boolean applyEffect(Inventory i, FurnCraftChestFactory fccf) { e.getDamagePerDamagingPeriod(), e.getBreakGracePeriod(), e.getCitadelBreakReduction()); } } - logAfterRecipeRun(i, fccf); + logAfterRecipeRun(combo, fccf); return true; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/recipes/WordBankRecipe.java b/src/main/java/com/github/igotyou/FactoryMod/recipes/WordBankRecipe.java index 5e6f4e10..3e5eae6c 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/recipes/WordBankRecipe.java +++ b/src/main/java/com/github/igotyou/FactoryMod/recipes/WordBankRecipe.java @@ -12,6 +12,8 @@ import java.util.List; import java.util.Map.Entry; import java.util.Random; + +import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -47,8 +49,9 @@ public WordBankRecipe(String identifier, String name, int productionTime, String } @Override - public boolean applyEffect(Inventory inventory, FurnCraftChestFactory factory) { - ItemStack toApply = inventory.getItem(0); + public boolean applyEffect(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { + MultiInventoryWrapper combo = new MultiInventoryWrapper(inputInv, outputInv); + ItemStack toApply = inputInv.getItem(0); if (!ItemUtils.isValidItem(toApply)) { return false; } @@ -56,13 +59,13 @@ public boolean applyEffect(Inventory inventory, FurnCraftChestFactory factory) { return false; } ItemMap input = new ItemMap(); - for (int i = 1; i < inventory.getSize(); i++) { - ItemStack is = inventory.getItem(i); + for (int i = 1; i < inputInv.getSize(); i++) { + ItemStack is = inputInv.getItem(i); if (!ItemUtils.isValidItem(is)) { continue; } input.addItemStack(is); - inventory.setItem(i, null); + inputInv.setItem(i, null); } //tell player what the recipe consumed StringBuilder sb = new StringBuilder(); @@ -77,8 +80,8 @@ public boolean applyEffect(Inventory inventory, FurnCraftChestFactory factory) { String result = sb.substring(0, sb.length() - 2); String name = getHash(input); ItemUtils.setDisplayName(toApply, name); - if (factory.getActivator() != null) { - Player player = Bukkit.getPlayer(factory.getActivator()); + if (fccf.getActivator() != null) { + Player player = Bukkit.getPlayer(fccf.getActivator()); if (player != null) { player.sendMessage(result + " into " + name); } @@ -121,16 +124,16 @@ public Material getRecipeRepresentationMaterial() { } @Override - public boolean enoughMaterialAvailable(Inventory inventory) { - ItemStack toApply = inventory.getItem(0); + public boolean enoughMaterialAvailable(Inventory inputInv) { + ItemStack toApply = inputInv.getItem(0); if (!ItemUtils.isValidItem(toApply)) { return false; } if (ItemUtils.getDisplayName(toApply) != null) { return false; } - for (int i = 1; i < inventory.getSize(); i++) { - ItemStack is = inventory.getItem(i); + for (int i = 1; i < inputInv.getSize(); i++) { + ItemStack is = inputInv.getItem(i); if (!ItemUtils.isValidItem(is)) { continue; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java b/src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java new file mode 100644 index 00000000..52885a97 --- /dev/null +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java @@ -0,0 +1,96 @@ +package com.github.igotyou.FactoryMod.utility; + +import org.bukkit.block.BlockFace; + +import java.util.function.Function; + +/** + * @author caucow + */ +public class DirectionMask { + + private byte mask; + + public DirectionMask(Direction... dirs) { + for (Direction dir : dirs) { + set(dir, true); + } + } + + public DirectionMask(byte mask) { + this.mask = mask; + } + + public void set(Direction dir, boolean set) { + if (set) { + mask |= dir.dmask; + } else { + mask &= ~dir.dmask; + } + } + + public boolean isSet(Direction dir) { + return (mask & dir.dmask) != 0; + } + + public byte getMask() { + return mask; + } + + public enum Direction { + TOP((byte) 0b0000_0001, bf -> BlockFace.UP), // 1 + BOTTOM((byte) 0b0000_0010, bf -> BlockFace.DOWN), // 2 + LEFT ((byte) 0b0000_0100, bf -> { + switch (bf) { + case NORTH: return BlockFace.EAST; + case EAST: return BlockFace.SOUTH; + case SOUTH: return BlockFace.WEST; + case WEST: return BlockFace.NORTH; + default: return bf; + } + }), // 4 + RIGHT ((byte) 0b0000_1000, bf -> { + switch (bf) { + case NORTH: return BlockFace.WEST; + case EAST: return BlockFace.NORTH; + case SOUTH: return BlockFace.EAST; + case WEST: return BlockFace.SOUTH; + default: return bf; + } + }), // 8 + FRONT ((byte) 0b0001_0000, bf -> bf), // 16 + BACK ((byte) 0b0010_0000, BlockFace::getOppositeFace); // 32 + + public final byte dmask; + private final Function facingModifier; + + private Direction(byte dmask, Function facingModifier) { + this.dmask = dmask; + this.facingModifier = facingModifier; + } + + /** + * @param front direction a block (such as a furnace) is facing. + * @return BlockFace in this direction, relative to the player's perspective when the player and block are + * facing each other. + */ + public BlockFace getBlockFacing(BlockFace front) { + return facingModifier.apply(front); + } + + private static BlockFace getBlockFaceFromDirection(int dirx, int dirz) { + switch (dirz) { + case 1: return BlockFace.SOUTH; + case -1: return BlockFace.NORTH; + case 0: { + switch (dirx) { + case 1: return BlockFace.EAST; + case -1: return BlockFace.WEST; + } + } + } + throw new IllegalArgumentException("Not a horizontal ordinal: (" + dirx + "," + dirz + ")"); + } + } + +} diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java index 5978f938..dc41109b 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java @@ -99,6 +99,8 @@ public void save(Collection factories) { config.set(current + ".runcounts." + i.getName(), fccf.getRunCount(i)); config.set(current + ".recipeLevels." + i.getName(), fccf.getRecipeLevel(i)); } + config.set(current + ".furnace-io-mask", fccf.getFurnaceIOSelector().toShortMask()); + config.set(current + ".table-io-mask", fccf.getTableIOSelector().toShortMask()); } else if (f instanceof Pipe) { Pipe p = (Pipe) f; config.set(current + ".type", "PIPE"); @@ -258,9 +260,6 @@ private void loadFromFile(File f, Map eggs) { } boolean autoSelect = current.getBoolean("autoSelect", false); - if (recipes == null) { - recipes = new LinkedList<>(); - } FurnCraftChestFactory fac = (FurnCraftChestFactory) egg.revive(blocks, health, selectedRecipe, runtime, breakTime, recipes); String activator = current.getString("activator", "null"); @@ -297,6 +296,10 @@ private void loadFromFile(File f, Map eggs) { } } fac.setAutoSelect(autoSelect); + IOSelector furnaceIoSelector = IOSelector.fromShortMask((short) current.getInt("furnace-io-mask", 0)); + fac.setFurnaceIOSelector(furnaceIoSelector); + IOSelector tableIoSelector = IOSelector.fromShortMask((short) current.getInt("table-io-mask", 0)); + fac.setTableIOSelector(tableIoSelector); manager.addFactory(fac); counter++; break; diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java new file mode 100644 index 00000000..cc29aff2 --- /dev/null +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java @@ -0,0 +1,110 @@ +package com.github.igotyou.FactoryMod.utility; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextColor; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; +import vg.civcraft.mc.civmodcore.inventorygui.Clickable; +import vg.civcraft.mc.civmodcore.inventorygui.ClickableInventory; +import vg.civcraft.mc.civmodcore.inventorygui.LClickable; +import vg.civcraft.mc.civmodcore.inventorygui.components.StaticDisplaySection; + +/** + * @author caucow + */ +public class IOConfigSection extends StaticDisplaySection { + + private final IOSelector ioSelector; + private final Material centerDisplay; + private final BlockFace front; + private final Block centerBlock; + + public IOConfigSection(IOSelector ioSelector, Material centerDisplay, Block centerBlock, BlockFace front) { + super(9); + this.ioSelector = ioSelector; + this.centerDisplay = centerDisplay; + this.centerBlock = centerBlock; + this.front = front; + + rebuild(); + } + + private Clickable getCycleButton(DirectionMask.Direction dir) { + if (!ioSelector.hasInputs() && !ioSelector.hasOutputs()) { + // TODO short/optimized default UI (?) + } + BlockFace relativeDir = dir.getBlockFacing(front); + Block relativeBlock = centerBlock.getRelative(relativeDir); + Material type = relativeBlock.getType(); + IOSelector.IOState dirState = ioSelector.getState(dir); + boolean hasChest = type != Material.CHEST && type != Material.TRAPPED_CHEST; + ItemStack display; + if (hasChest) { + display = new ItemStack(Material.BARRIER); + ItemUtils.addComponentLore(display, Component.text("").color(TextColor.color(255, 0, 0))); + } else { + display = dirState.getUIVisual(); + } + ItemUtils.setComponentDisplayName(display, + Component.text("\u00a7r") + .append(Component.text(dir.name()).color(TextColor.color(192, 192, 192))) + .append(Component.text(": ")) + .append(Component.text(dirState.name()).color(TextColor.color(dirState.color))) + .asComponent()); + ItemUtils.addComponentLore(display, + Component.text("Click to cycle IO mode").color(TextColor.color(192, 192, 192))); + return new Clickable(display) { + private ClickableInventory inventory; + private int slot; + + @Override + protected void clicked(Player player) { + cycleIoState(dir, false); + } + + @Override + protected void onRightClick(Player p) { + cycleIoState(dir, true); + } + + @Override + protected void onDoubleClick(Player p) { } // nop + + @Override + public void addedToInventory(ClickableInventory inv, int slot) { + this.inventory = inv; + this.slot = slot; + } + + private void cycleIoState(DirectionMask.Direction dir, boolean backwards) { + IOSelector.IOState newState = ioSelector.cycleDirection(dir, backwards); + ItemStack cstack = getItemStack(); + cstack.setType(newState.getUIVisual().getType()); + ItemUtils.setComponentDisplayName(cstack, + Component.text("\u00a7r") + .append(Component.text(dir.name()).color(TextColor.color(192, 192, 192))) + .append(Component.text(": ")) + .append(Component.text(newState.name()).color(TextColor.color(newState.color))) + .asComponent()); + if (inventory != null && inventory.getSlot(slot) == this) { + inventory.setSlot(this, slot); + } + } + }; + } + + @Override + protected void rebuild() { + set(getCycleButton(DirectionMask.Direction.TOP), 1); + set(getCycleButton(DirectionMask.Direction.FRONT), 2); + set(getCycleButton(DirectionMask.Direction.LEFT), 3); + set(getCycleButton(DirectionMask.Direction.RIGHT), 5); + set(getCycleButton(DirectionMask.Direction.BOTTOM), 7); + set(getCycleButton(DirectionMask.Direction.BACK), 8); + set(new LClickable(centerDisplay, p -> {}), 4); + } +} diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java new file mode 100644 index 00000000..14f9f2a3 --- /dev/null +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java @@ -0,0 +1,129 @@ +package com.github.igotyou.FactoryMod.utility; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author caucow + */ +public class IOSelector { + + private final DirectionMask inputs; + private final DirectionMask outputs; + + public IOSelector(byte inMask, byte outMask) { + this.inputs = new DirectionMask(inMask); + this.outputs = new DirectionMask(outMask); + } + + public IOSelector() { + this((byte) 0, (byte) 0); + } + + public IOState getState(DirectionMask.Direction direction) { + return IOState.fromIO(inputs.isSet(direction), outputs.isSet(direction)); + } + + public boolean hasInputs() { + return inputs.getMask() != 0; + } + + public List getInputs(BlockFace front) { + DirectionMask.Direction[] values = DirectionMask.Direction.values(); + List bfList = new ArrayList<>(values.length); + for (DirectionMask.Direction dir : values) { + if (inputs.isSet(dir)) { + bfList.add(dir.getBlockFacing(front)); + } + } + return bfList; + } + + public boolean hasOutputs() { + return outputs.getMask() != 0; + } + + public List getOutputs(BlockFace front) { + DirectionMask.Direction[] values = DirectionMask.Direction.values(); + List bfList = new ArrayList<>(values.length); + for (DirectionMask.Direction dir : values) { + if (outputs.isSet(dir)) { + bfList.add(dir.getBlockFacing(front)); + } + } + return bfList; + } + + public IOState cycleDirection(DirectionMask.Direction direction, boolean backwards) { + IOState cur = getState(direction); + if (backwards) { + cur = cur.last(); + } else { + cur = cur.next(); + } + inputs.set(direction, cur.isIn()); + outputs.set(direction, cur.isOut()); + return cur; + } + + /** + * @return a compact serialized form of the input and output bitmasks (high 8 bits => in; low 8 bits => out) + */ + public short toShortMask() { + return (short) ((short) inputs.getMask() << 8 | (short) outputs.getMask()); + } + + /** + * @param IShOrO compact serialized form of the input and output bitmasks (high 8 bits => in; low 8 bits => out) + * @return IOSelector with input and output masks set + */ + public static IOSelector fromShortMask(short IShOrO) { + return new IOSelector((byte) (IShOrO >>> 8 & 0xFF), (byte) (IShOrO & 0xFF)); + } + + public enum IOState { + IGNORED(new ItemStack(Material.WHITE_WOOL), 0x808080), + INPUT(new ItemStack(Material.BLUE_WOOL), 0x4040FF), + OUTPUT(new ItemStack(Material.RED_WOOL), 0xFF4040), + BOTH(new ItemStack(Material.PURPLE_WOOL), 0xFF40FF); + + private final ItemStack uiVisual; + public final int color; + + private IOState(ItemStack uiVisual, int color) { + this.uiVisual = uiVisual; + this.color = color; + } + + public ItemStack getUIVisual() { + return uiVisual.clone(); + } + + public boolean isIn() { + return (ordinal() & 1) != 0; + } + + public boolean isOut() { + return (ordinal() & 2) != 0; + } + + public IOState next() { + IOState[] values = values(); + return values[(ordinal() + values.length + 1) % values.length]; + } + + public IOState last() { + IOState[] values = values(); + return values[(ordinal() + values.length + values.length - 1) % values.length]; + } + + public static IOState fromIO(boolean in, boolean out) { + return IOState.values()[(in ? 1 : 0) | (out ? 2 : 0)]; + } + } + +} diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java b/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java new file mode 100644 index 00000000..a5de7d6d --- /dev/null +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java @@ -0,0 +1,376 @@ +package com.github.igotyou.FactoryMod.utility; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.DoubleChest; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +/** + * @author caucow + */ +public class MultiInventoryWrapper implements Inventory { + + private final Inventory[] wrapped; + private final int size; + private final int[] slotOffsets; + + public MultiInventoryWrapper(Inventory... wrapped) { + this(new ArrayList<>(Arrays.asList(wrapped))); + } + + public MultiInventoryWrapper(ArrayList wrapped) { + Inventory[] wrappedArr = uniquify(wrapped); + this.wrapped = wrappedArr; + int lsize = 0; + int[] lslotOffsets = new int[wrappedArr.length]; + for (int i = 0; i < wrappedArr.length; i++) { + Inventory inv = wrappedArr[i]; + lslotOffsets[i] = lsize; + lsize += inv.getSize(); + if (inv.getMaxStackSize() != 64) { + throw new IllegalArgumentException("Inventory max stack size must be 64"); + } + } + this.size = lsize; + this.slotOffsets = lslotOffsets; + } + + private int getInventoryIndex(int combinedSlot) { + for (int i = 0; i < wrapped.length - 1; i++) { + if (combinedSlot < slotOffsets[i + 1]) { + return i; + } + } + if (combinedSlot < size) { + return wrapped.length - 1; + } + throw new IndexOutOfBoundsException("Slot index " + combinedSlot + + " is outside the bounds of the multi-inventory"); + } + + @Override + public int getSize() { + return size; + } + + @Override + public int getMaxStackSize() { + return 64; + } + + @Override + public void setMaxStackSize(int i) { + throw new UnsupportedOperationException(); + } + + @Override + public @Nullable ItemStack getItem(int i) { + int invi = getInventoryIndex(i); + return wrapped[invi].getItem(i - slotOffsets[invi]); + } + + @Override + public void setItem(int i, @Nullable ItemStack itemStack) { + int invi = getInventoryIndex(i); + wrapped[invi].setItem(i - slotOffsets[invi], itemStack); + } + + @Override + public @NotNull HashMap addItem(@NotNull ItemStack... itemStacks) throws IllegalArgumentException { + HashMap result = null; + for (int i = 0; i < wrapped.length; i++) { + result = wrapped[i].addItem(itemStacks); + itemStacks = new ItemStack[result.size()]; + int index = 0; + Iterator> eit = result.entrySet().iterator(); + for (; eit.hasNext() && index < itemStacks.length; index++) { + Map.Entry entry = eit.next(); + itemStacks[i] = entry.getValue(); + } + } + return result == null ? new HashMap<>() : result; + } + + @Override + public @NotNull HashMap removeItem(@NotNull ItemStack... itemStacks) throws IllegalArgumentException { + HashMap result = null; + for (int i = 0; i < wrapped.length; i++) { + result = wrapped[i].removeItem(itemStacks); + itemStacks = new ItemStack[result.size()]; + int index = 0; + Iterator> eit = result.entrySet().iterator(); + for (; eit.hasNext() && index < itemStacks.length; index++) { + Map.Entry entry = eit.next(); + itemStacks[i] = entry.getValue(); + } + } + return result == null ? new HashMap<>() : result; + } + + @Override + public @NotNull HashMap removeItemAnySlot(@NotNull ItemStack... itemStacks) throws IllegalArgumentException { + HashMap result = null; + for (int i = 0; i < wrapped.length; i++) { + result = wrapped[i].removeItemAnySlot(itemStacks); + itemStacks = new ItemStack[result.size()]; + int index = 0; + Iterator> eit = result.entrySet().iterator(); + for (; eit.hasNext() && index < itemStacks.length; index++) { + Map.Entry entry = eit.next(); + itemStacks[i] = entry.getValue(); + } + } + return result == null ? new HashMap<>() : result; + } + + @Override + public @org.checkerframework.checker.nullness.qual.Nullable ItemStack @NonNull [] getContents() { + ItemStack[] combinedContents = new ItemStack[size]; + for (int inv = 0, slot = 0; inv < wrapped.length; inv++) { + ItemStack[] sub = wrapped[inv].getContents(); + System.arraycopy(sub, 0, combinedContents, slot, sub.length); + slot += sub.length; + } + return combinedContents; + } + + @Override + public void setContents(@NotNull ItemStack[] combinedContents) throws IllegalArgumentException { + for (int inv = 0, slot = 0; inv < wrapped.length && slotOffsets[inv] < combinedContents.length; inv++) { + ItemStack[] sub = new ItemStack[wrapped[inv].getSize()]; + System.arraycopy(combinedContents, slotOffsets[inv], sub, 0, Math.min(sub.length, slot - slotOffsets[inv])); + wrapped[inv].setContents(sub); + slot += sub.length; + } + } + + @Override + public @NotNull ItemStack[] getStorageContents() { + return getContents(); + } + + @Override + public void setStorageContents(@NotNull ItemStack[] combinedContents) throws IllegalArgumentException { + setContents(combinedContents); + } + + @Override + public boolean contains(@NotNull Material material) throws IllegalArgumentException { + for (Inventory inv : wrapped) { + if (inv.contains(material)) { + return true; + } + } + return false; + } + + @Override + public boolean contains(@Nullable ItemStack itemStack) { + for (Inventory inv : wrapped) { + if (inv.contains(itemStack)) { + return true; + } + } + return false; + } + + @Override + public boolean contains(@NotNull Material material, int i) throws IllegalArgumentException { + int invi = getInventoryIndex(i); + return wrapped[invi].contains(material, i - slotOffsets[invi]); + } + + @Override + public boolean contains(@Nullable ItemStack itemStack, int i) { + int invi = getInventoryIndex(i); + return wrapped[invi].contains(itemStack, i - slotOffsets[invi]); + } + + @Override + public boolean containsAtLeast(@Nullable ItemStack itemStack, int i) { + int invi = getInventoryIndex(i); + return wrapped[invi].containsAtLeast(itemStack, i - slotOffsets[invi]); + } + + @Override + public @NotNull HashMap all(@NotNull Material material) throws IllegalArgumentException { + HashMap result = new HashMap<>(); + for (int i = 0; i < wrapped.length; i++) { + HashMap partial = wrapped[i].all(material); + for (Map.Entry entry : partial.entrySet()) { + result.put(entry.getKey() + slotOffsets[i], entry.getValue()); + } + } + return result; + } + + @Override + public @NotNull HashMap all(@Nullable ItemStack itemStack) { + HashMap result = new HashMap<>(); + for (int i = 0; i < wrapped.length; i++) { + HashMap partial = wrapped[i].all(itemStack); + for (Map.Entry entry : partial.entrySet()) { + result.put(entry.getKey() + slotOffsets[i], entry.getValue()); + } + } + return result; + } + + @Override + public int first(@NotNull Material material) throws IllegalArgumentException { + for (int i = 0; i < wrapped.length; i++) { + int result = wrapped[i].first(material); + if (result != -1) { + return result + slotOffsets[i]; + } + } + return -1; + } + + @Override + public int first(@NotNull ItemStack itemStack) { + for (int i = 0; i < wrapped.length; i++) { + int result = wrapped[i].first(itemStack); + if (result != -1) { + return result + slotOffsets[i]; + } + } + return -1; + } + + @Override + public int firstEmpty() { + for (int i = 0; i < wrapped.length; i++) { + int result = wrapped[i].firstEmpty(); + if (result != -1) { + return result + slotOffsets[i]; + } + } + return -1; + } + + @Override + public boolean isEmpty() { + for (Inventory inv : wrapped) { + if (!inv.isEmpty()) { + return false; + } + } + return true; + } + + @Override + public void remove(@NotNull Material material) throws IllegalArgumentException { + for (Inventory inv : wrapped) { + inv.remove(material); + } + } + + @Override + public void remove(@NotNull ItemStack itemStack) { + for (Inventory inv : wrapped) { + inv.remove(itemStack); + } + } + + @Override + public void clear(int i) { + int invi = getInventoryIndex(i); + wrapped[invi].clear(i - slotOffsets[invi]); + } + + @Override + public void clear() { + for (Inventory inv : wrapped) { + inv.clear(); + } + } + + @Override + public @NotNull List getViewers() { + ArrayList list = new ArrayList<>(); + for (Inventory inv : wrapped) { + list.addAll(inv.getViewers()); + } + return list; + } + + @Override + public @NotNull InventoryType getType() { + return InventoryType.CHEST; + } + + @Override + public @Nullable InventoryHolder getHolder() { + return null; + } + + @Override + public @Nullable InventoryHolder getHolder(boolean b) { + return null; + } + + @Override + public @NotNull ListIterator iterator() { + throw new UnsupportedOperationException("More effort to implement than can be bothered atm. Feel free to CIY"); + } + + @Override + public @NotNull ListIterator iterator(int i) { + throw new UnsupportedOperationException("More effort to implement than can be bothered atm. Feel free to CIY"); + } + + @Override + public @Nullable Location getLocation() { + return null; + } + + private static Inventory[] uniquify(List wrapped) { + ListIterator inverator = wrapped.listIterator(); + while (inverator.hasNext()) { + Inventory next = inverator.next(); + if (next instanceof MultiInventoryWrapper) { + inverator.remove(); + for (Inventory inv : ((MultiInventoryWrapper) next).wrapped) { + inverator.add(inv); + inverator.previous(); + } + } + } + List invHolders = new ArrayList<>(wrapped.size()); + List uniqueInvs = new ArrayList<>(wrapped.size()); + for (Inventory inv : wrapped) { + + InventoryHolder holder = inv.getHolder(); + if (holder instanceof DoubleChest) { + DoubleChest dch = (DoubleChest) holder; + InventoryHolder hleft = dch.getLeftSide(); + InventoryHolder hright = dch.getRightSide(); + if (invHolders.contains(dch) || invHolders.contains(hleft) || invHolders.contains(hright)) { + continue; + } + invHolders.add(hleft); + invHolders.add(hright); + } + invHolders.add(holder); + uniqueInvs.add(inv); + } + Inventory[] wrappedArr = uniqueInvs.toArray(new Inventory[uniqueInvs.size()]); + return wrappedArr; + } +} From 5b1296d7e19cd68b3e7a0a01359400528be3cbba Mon Sep 17 00:00:00 2001 From: caucow Date: Sun, 6 Jun 2021 15:57:34 -0500 Subject: [PATCH 04/21] Fix overlooked change in simplified code --- .../FactoryMod/structures/FurnCraftChestStructure.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java b/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java index 681d0b58..17832767 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java +++ b/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java @@ -30,10 +30,10 @@ public FurnCraftChestStructure(Block center) { BlockFace chestFace = center.getFace(b); if (chestFace == null) continue; // fricc off nullcheck BlockFace furnaceFace = chestFace.getOppositeFace(); - if (center.getRelative(furnaceFace).getType() == Material.FURNACE) { + Block furnaceBlock = center.getRelative(furnaceFace); + if (furnaceBlock.getType() == Material.FURNACE) { chest = b.getLocation(); - furnace = center.getRelative(BlockFace.UP) - .getLocation(); + furnace = furnaceBlock.getLocation(); break; } } From 473c052535467519ee39c81c1c4486a45d671f51 Mon Sep 17 00:00:00 2001 From: caucow Date: Sun, 6 Jun 2021 18:27:21 -0500 Subject: [PATCH 05/21] fix typo in multiinv + rename locals for clarity --- .../utility/MultiInventoryWrapper.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java b/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java index a5de7d6d..e345a1c5 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java @@ -93,14 +93,14 @@ public void setItem(int i, @Nullable ItemStack itemStack) { @Override public @NotNull HashMap addItem(@NotNull ItemStack... itemStacks) throws IllegalArgumentException { HashMap result = null; - for (int i = 0; i < wrapped.length; i++) { - result = wrapped[i].addItem(itemStacks); + for (int invi = 0; invi < wrapped.length; invi++) { + result = wrapped[invi].addItem(itemStacks); itemStacks = new ItemStack[result.size()]; - int index = 0; + int itemi = 0; Iterator> eit = result.entrySet().iterator(); - for (; eit.hasNext() && index < itemStacks.length; index++) { + for (; eit.hasNext() && itemi < itemStacks.length; itemi++) { Map.Entry entry = eit.next(); - itemStacks[i] = entry.getValue(); + itemStacks[itemi] = entry.getValue(); } } return result == null ? new HashMap<>() : result; @@ -109,14 +109,14 @@ public void setItem(int i, @Nullable ItemStack itemStack) { @Override public @NotNull HashMap removeItem(@NotNull ItemStack... itemStacks) throws IllegalArgumentException { HashMap result = null; - for (int i = 0; i < wrapped.length; i++) { - result = wrapped[i].removeItem(itemStacks); + for (int invi = 0; invi < wrapped.length; invi++) { + result = wrapped[invi].removeItem(itemStacks); itemStacks = new ItemStack[result.size()]; - int index = 0; + int itemi = 0; Iterator> eit = result.entrySet().iterator(); - for (; eit.hasNext() && index < itemStacks.length; index++) { + for (; eit.hasNext() && itemi < itemStacks.length; itemi++) { Map.Entry entry = eit.next(); - itemStacks[i] = entry.getValue(); + itemStacks[itemi] = entry.getValue(); } } return result == null ? new HashMap<>() : result; From 19e7dd2dcaa696c180d825f29b144322b1ebf081 Mon Sep 17 00:00:00 2001 From: caucow Date: Sun, 6 Jun 2021 18:27:58 -0500 Subject: [PATCH 06/21] Fix redstone detect direction for diode types --- .../listeners/FactoryModListener.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java b/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java index 8533aab5..5fdb7f4d 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java +++ b/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java @@ -9,7 +9,10 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; import org.bukkit.block.Furnace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -59,14 +62,28 @@ public void blockBreakEvent(BlockBreakEvent e) { } @EventHandler - public void redstoneChange(BlockRedstoneEvent e) { - if (e.getOldCurrent() == e.getNewCurrent()) { + public void redstoneChange(BlockRedstoneEvent evt) { + if (evt.getOldCurrent() == evt.getNewCurrent()) { return; } - for (BlockFace face : WorldUtils.ALL_SIDES) { - Factory f = manager.getFactoryAt(e.getBlock().getRelative(face)); + Block powerSource = evt.getBlock(); + Material psType = powerSource.getType(); + if (psType == Material.REPEATER || psType == Material.COMPARATOR) { + BlockData psData = powerSource.getState().getBlockData(); + BlockFace direction = ((Directional) psData).getFacing(); + // repeaters "face" their input apparently + Block poweredBlock = powerSource.getRelative(direction.getOppositeFace()); + Factory f = manager.getFactoryAt(poweredBlock); if (f != null) { - f.getInteractionManager().redStoneEvent(e, e.getBlock().getRelative(face)); + f.getInteractionManager().redStoneEvent(evt, poweredBlock); + } + } else { + for (BlockFace direction : WorldUtils.ALL_SIDES) { + Block poweredBlock = powerSource.getRelative(direction); + Factory f = manager.getFactoryAt(poweredBlock); + if (f != null) { + f.getInteractionManager().redStoneEvent(evt, poweredBlock); + } } } } From 0beaf522e5cc50854567626e18c65b63d97ff88f Mon Sep 17 00:00:00 2001 From: caucow Date: Sun, 6 Jun 2021 18:28:28 -0500 Subject: [PATCH 07/21] Fix flashing diodes when factories are powered --- .../igotyou/FactoryMod/factories/Factory.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java index 1742f6cd..aa4da85a 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java @@ -5,6 +5,7 @@ import com.github.igotyou.FactoryMod.powerManager.IPowerManager; import com.github.igotyou.FactoryMod.repairManager.IRepairManager; import com.github.igotyou.FactoryMod.structures.MultiBlockStructure; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Furnace; @@ -124,8 +125,12 @@ public void turnFurnaceOn(Block f) { return; } Furnace furnace = (Furnace) f.getState(); - furnace.setBurnTime(Short.MAX_VALUE); - furnace.update(); + Bukkit.getScheduler().runTask(FactoryMod.getInstance(), () -> { + if (this.isActive()) { + furnace.setBurnTime(Short.MAX_VALUE); + furnace.update(); + } + }); } public String getLogData() { @@ -137,7 +142,11 @@ public void turnFurnaceOff(Block f) { return; } Furnace furnace = (Furnace) f.getState(); - furnace.setBurnTime((short) 0); - furnace.update(); + Bukkit.getScheduler().runTask(FactoryMod.getInstance(), () -> { + if (!this.isActive()) { + furnace.setBurnTime((short) 0); + furnace.update(); + } + }); } } From 9c14c5463e869fcbb3819e8d1ec807e2f4072f8d Mon Sep 17 00:00:00 2001 From: caucow Date: Thu, 10 Jun 2021 16:22:54 -0500 Subject: [PATCH 08/21] Default main factory chest to BOTH for unconfigured --- .../factories/FurnCraftChestFactory.java | 56 ++++++++--------- .../FactoryMod/utility/DirectionMask.java | 60 +++++++++++++------ .../FactoryMod/utility/FileHandler.java | 27 +++++++-- .../FactoryMod/utility/IOSelector.java | 5 ++ 4 files changed, 96 insertions(+), 52 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java index dc2d7d98..4e415caa 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java @@ -36,6 +36,7 @@ import org.bukkit.inventory.FurnaceInventory; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; import vg.civcraft.mc.citadel.ReinforcementLogic; import vg.civcraft.mc.citadel.model.Reinforcement; import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; @@ -101,18 +102,10 @@ public Inventory getInventory() { } public Inventory getInputInventory() { - if (!furnaceIoSelector.hasInputs() && !tableIoSelector.hasInputs()) { - return getInventory(); - } FurnCraftChestStructure fccs = (FurnCraftChestStructure) getMultiBlockStructure(); ArrayList invs = new ArrayList<>(12); Block fblock = getFurnace(); - if (fblock.getType() != Material.FURNACE) { - return null; - } - Furnace fstate = (Furnace) fblock.getState(); - org.bukkit.block.data.type.Furnace fdata = (org.bukkit.block.data.type.Furnace) fstate.getBlockData(); - BlockFace facing = fdata.getFacing(); + BlockFace facing = getFacing(); for (BlockFace relativeFace : furnaceIoSelector.getInputs(facing)) { Block relBlock = fblock.getRelative(relativeFace); if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { @@ -126,27 +119,14 @@ public Inventory getInputInventory() { invs.add(((Chest) relBlock.getState()).getInventory()); } } - MultiInventoryWrapper wrapper = new MultiInventoryWrapper(invs); - if (wrapper.getSize() == 0) { - return getInventory(); - } else { - return wrapper; - } + return new MultiInventoryWrapper(invs); } public Inventory getOutputInventory() { - if (!furnaceIoSelector.hasOutputs() && !tableIoSelector.hasOutputs()) { - return getInventory(); - } FurnCraftChestStructure fccs = (FurnCraftChestStructure) getMultiBlockStructure(); ArrayList invs = new ArrayList<>(12); Block fblock = getFurnace(); - if (fblock.getType() != Material.FURNACE) { - return null; - } - Furnace fstate = (Furnace) fblock.getState(); - org.bukkit.block.data.type.Furnace fdata = (org.bukkit.block.data.type.Furnace) fstate.getBlockData(); - BlockFace facing = fdata.getFacing(); + BlockFace facing = getFacing(); for (BlockFace relativeFace : furnaceIoSelector.getOutputs(facing)) { Block relBlock = fblock.getRelative(relativeFace); if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { @@ -160,12 +140,7 @@ public Inventory getOutputInventory() { invs.add(((Chest) relBlock.getState()).getInventory()); } } - MultiInventoryWrapper wrapper = new MultiInventoryWrapper(invs); - if (wrapper.getSize() == 0) { - return getInventory(); - } else { - return wrapper; - } + return new MultiInventoryWrapper(invs); } public void setFurnaceIOSelector(IOSelector ioSelector) { @@ -184,6 +159,20 @@ public IOSelector getTableIOSelector() { return tableIoSelector; } + /** + * @return the direction the furnace (and thus this factory) is facing. + */ + public @Nullable BlockFace getFacing() { + Block fblock = getFurnace(); + if (fblock.getType() != Material.FURNACE) { + return null; + } + Furnace fstate = (Furnace) fblock.getState(); + org.bukkit.block.data.type.Furnace fdata = (org.bukkit.block.data.type.Furnace) fstate.getBlockData(); + BlockFace facing = fdata.getFacing(); + return facing; + } + /** * @return Inventory of the furnace or null if there is no furnace where one * should be @@ -350,6 +339,13 @@ public Block getFurnace() { return ((FurnCraftChestStructure) mbs).getFurnace(); } + /** + * @return The crafting table of this factory + */ + public Block getCraftingTable() { + return ((FurnCraftChestStructure) mbs).getCraftingTable(); + } + /** * @return The chest of this factory */ diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java b/src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java index 52885a97..03b8c300 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java @@ -40,26 +40,36 @@ public byte getMask() { public enum Direction { TOP((byte) 0b0000_0001, bf -> BlockFace.UP), // 1 BOTTOM((byte) 0b0000_0010, bf -> BlockFace.DOWN), // 2 - LEFT ((byte) 0b0000_0100, bf -> { + LEFT((byte) 0b0000_0100, bf -> { switch (bf) { - case NORTH: return BlockFace.EAST; - case EAST: return BlockFace.SOUTH; - case SOUTH: return BlockFace.WEST; - case WEST: return BlockFace.NORTH; - default: return bf; + case NORTH: + return BlockFace.EAST; + case EAST: + return BlockFace.SOUTH; + case SOUTH: + return BlockFace.WEST; + case WEST: + return BlockFace.NORTH; + default: + return bf; } }), // 4 - RIGHT ((byte) 0b0000_1000, bf -> { + RIGHT((byte) 0b0000_1000, bf -> { switch (bf) { - case NORTH: return BlockFace.WEST; - case EAST: return BlockFace.NORTH; - case SOUTH: return BlockFace.EAST; - case WEST: return BlockFace.SOUTH; - default: return bf; + case NORTH: + return BlockFace.WEST; + case EAST: + return BlockFace.NORTH; + case SOUTH: + return BlockFace.EAST; + case WEST: + return BlockFace.SOUTH; + default: + return bf; } }), // 8 - FRONT ((byte) 0b0001_0000, bf -> bf), // 16 - BACK ((byte) 0b0010_0000, BlockFace::getOppositeFace); // 32 + FRONT((byte) 0b0001_0000, bf -> bf), // 16 + BACK((byte) 0b0010_0000, BlockFace::getOppositeFace); // 32 public final byte dmask; private final Function facingModifier; @@ -78,14 +88,28 @@ public BlockFace getBlockFacing(BlockFace front) { return facingModifier.apply(front); } + public static Direction getDirection(BlockFace front, BlockFace axis) { + for (Direction dir : Direction.values()) { + // if dir's transformation of front == axis + if (dir.getBlockFacing(front) == axis) { + return dir; + } + } + throw new IllegalArgumentException("Direction can only be gotten from an axis-aligned BlockFace."); + } + private static BlockFace getBlockFaceFromDirection(int dirx, int dirz) { switch (dirz) { - case 1: return BlockFace.SOUTH; - case -1: return BlockFace.NORTH; + case 1: + return BlockFace.SOUTH; + case -1: + return BlockFace.NORTH; case 0: { switch (dirx) { - case 1: return BlockFace.EAST; - case -1: return BlockFace.WEST; + case 1: + return BlockFace.EAST; + case -1: + return BlockFace.WEST; } } } diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java index dc41109b..5bc6624b 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java @@ -296,10 +296,29 @@ private void loadFromFile(File f, Map eggs) { } } fac.setAutoSelect(autoSelect); - IOSelector furnaceIoSelector = IOSelector.fromShortMask((short) current.getInt("furnace-io-mask", 0)); - fac.setFurnaceIOSelector(furnaceIoSelector); - IOSelector tableIoSelector = IOSelector.fromShortMask((short) current.getInt("table-io-mask", 0)); - fac.setTableIOSelector(tableIoSelector); + { + int mask = current.getInt("furnace-io-mask", -1); + if (mask != -1) { + IOSelector furnaceIoSelector = IOSelector.fromShortMask((short) mask); + fac.setFurnaceIOSelector(furnaceIoSelector); + } else { + // Nothing I guess, the furnace has no default state. + } + mask = current.getInt("table-io-mask", -1); + if (mask != -1) { + IOSelector tableIoSelector = IOSelector.fromShortMask((short) mask); + fac.setTableIOSelector(tableIoSelector); + } else { + BlockFace chestDir = fac.getFurnace().getFace(fac.getCraftingTable()); + BlockFace front = fac.getFacing(); + if (chestDir != null && front != null) { + IOSelector tableIoSelector = new IOSelector(); + DirectionMask.Direction defaultDir = DirectionMask.Direction.getDirection(front, chestDir); + tableIoSelector.setState(defaultDir, IOSelector.IOState.BOTH); + fac.setTableIOSelector(tableIoSelector); + } + } + } manager.addFactory(fac); counter++; break; diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java index 14f9f2a3..b2a4b45d 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java @@ -28,6 +28,11 @@ public IOState getState(DirectionMask.Direction direction) { return IOState.fromIO(inputs.isSet(direction), outputs.isSet(direction)); } + public void setState(DirectionMask.Direction direction, IOState state) { + inputs.set(direction, state.isIn()); + outputs.set(direction, state.isOut()); + } + public boolean hasInputs() { return inputs.getMask() != 0; } From c6a8511135992e272385eba87d49036e71e9425d Mon Sep 17 00:00:00 2001 From: caucow Date: Thu, 10 Jun 2021 16:33:08 -0500 Subject: [PATCH 09/21] Make bold because the barrier wasn't visible enough ? ? ? ? --- .../igotyou/FactoryMod/utility/IOConfigSection.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java index cc29aff2..08126b8a 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java @@ -1,7 +1,9 @@ package com.github.igotyou.FactoryMod.utility; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -45,7 +47,10 @@ private Clickable getCycleButton(DirectionMask.Direction dir) { ItemStack display; if (hasChest) { display = new ItemStack(Material.BARRIER); - ItemUtils.addComponentLore(display, Component.text("").color(TextColor.color(255, 0, 0))); + ItemUtils.addComponentLore(display, Component + .text("") + .style(Style.style(TextDecoration.BOLD)) + .color(TextColor.color(255, 0, 0))); } else { display = dirState.getUIVisual(); } @@ -57,6 +62,7 @@ private Clickable getCycleButton(DirectionMask.Direction dir) { .asComponent()); ItemUtils.addComponentLore(display, Component.text("Click to cycle IO mode").color(TextColor.color(192, 192, 192))); + return new Clickable(display) { private ClickableInventory inventory; private int slot; From 253c1164c0cbe8dacf64fb4556b0f58e5db4119a Mon Sep 17 00:00:00 2001 From: caucow Date: Thu, 10 Jun 2021 16:51:45 -0500 Subject: [PATCH 10/21] Cardinals mode for nerds with a killer mental compass but no eyes Yes, I am 100% firing some shots at #feedback here. :glad: --- .../igotyou/FactoryMod/FactoryModManager.java | 6 + .../FactoryMod/FactoryModPlayerSettings.java | 69 +++++++++++ .../FactoryMod/utility/IOConfigSection.java | 117 ++++++++++++++++-- 3 files changed, 185 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/github/igotyou/FactoryMod/FactoryModPlayerSettings.java diff --git a/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java b/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java index ab631abe..d1a82aac 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java +++ b/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java @@ -55,6 +55,7 @@ public class FactoryModManager { private int redstoneRecipeChange; private Set compactLore; private Set forceInclude; + private FactoryModPlayerSettings playerSettings; public FactoryModManager(FactoryMod plugin, Material factoryInteractionMaterial, boolean citadelEnabled, boolean nameLayerEnabled, int redstonePowerOn, int redstoneRecipeChange, boolean logInventories, @@ -76,6 +77,7 @@ public FactoryModManager(FactoryMod plugin, Material factoryInteractionMaterial, recipes = new HashMap<>(); compactLore = new HashSet<>(); forceInclude = new HashSet<>(); + playerSettings = new FactoryModPlayerSettings(plugin); // Normal furnace, craftingtable, chest factories possibleCenterBlocks.add(Material.CRAFTING_TABLE); @@ -545,4 +547,8 @@ public boolean isForceInclude(String identifier) { public Collection getAllFactoryEggs() { return eggs.values(); } + + public FactoryModPlayerSettings getPlayerSettings() { + return playerSettings; + } } diff --git a/src/main/java/com/github/igotyou/FactoryMod/FactoryModPlayerSettings.java b/src/main/java/com/github/igotyou/FactoryMod/FactoryModPlayerSettings.java new file mode 100644 index 00000000..0ffcaed0 --- /dev/null +++ b/src/main/java/com/github/igotyou/FactoryMod/FactoryModPlayerSettings.java @@ -0,0 +1,69 @@ +package com.github.igotyou.FactoryMod; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import vg.civcraft.mc.civmodcore.playersettings.PlayerSettingAPI; +import vg.civcraft.mc.civmodcore.playersettings.gui.MenuSection; +import vg.civcraft.mc.civmodcore.playersettings.impl.EnumSetting; + +import java.util.UUID; + +public class FactoryModPlayerSettings { + + private final FactoryMod plugin; + EnumSetting ioDirectionSetting; + + public FactoryModPlayerSettings(FactoryMod plugin) { + this.plugin = plugin; + initSettings(); + } + + private void initSettings() { + MenuSection menu = PlayerSettingAPI.getMainMenu().createMenuSection( + "FactoryMod", + "FactoryMod settings", + new ItemStack(Material.FURNACE) + ); + + ioDirectionSetting = new EnumSetting<>( + plugin, + IoConfigDirectionMode.VISUAL_RELATIVE, + "Factory IOConfig Mode", + "ioconfig_visual_mode", + new ItemStack(Material.HOPPER), + "Change how the factory IO config appears", + true, + IoConfigDirectionMode.class + ); + PlayerSettingAPI.registerSetting(ioDirectionSetting, menu); + } + + public IoConfigDirectionMode getIoDirectionMode(UUID id) { + return ioDirectionSetting.getValue(id); + } + + public enum IoConfigDirectionMode { + + VISUAL_RELATIVE( + "Relative Directions", + new String[] { + "The furnace shows the", + "front of the factory." + }), + CARDINAL( + "Cardinal Directions", + new String[] { + "Cardinals (for those too", + "familiar with map mods.)" + }); + + public final String simpleDescription; + public final String[] fullDescription; + + private IoConfigDirectionMode(String simpleDescription, String[] fullDescription) { + this.simpleDescription = simpleDescription; + this.fullDescription = fullDescription; + } + } + +} diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java index 08126b8a..ff0c061e 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java @@ -1,5 +1,7 @@ package com.github.igotyou.FactoryMod.utility; +import com.github.igotyou.FactoryMod.FactoryMod; +import com.github.igotyou.FactoryMod.FactoryModPlayerSettings; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; @@ -15,18 +17,23 @@ import vg.civcraft.mc.civmodcore.inventorygui.LClickable; import vg.civcraft.mc.civmodcore.inventorygui.components.StaticDisplaySection; +import java.util.UUID; + /** * @author caucow */ public class IOConfigSection extends StaticDisplaySection { + private UUID viewerId; private final IOSelector ioSelector; private final Material centerDisplay; private final BlockFace front; private final Block centerBlock; + private FactoryModPlayerSettings.IoConfigDirectionMode ioDirectionMode; - public IOConfigSection(IOSelector ioSelector, Material centerDisplay, Block centerBlock, BlockFace front) { + public IOConfigSection(Player viewer, IOSelector ioSelector, Material centerDisplay, Block centerBlock, BlockFace front) { super(9); + this.viewerId = viewer.getUniqueId(); this.ioSelector = ioSelector; this.centerDisplay = centerDisplay; this.centerBlock = centerBlock; @@ -35,6 +42,80 @@ public IOConfigSection(IOSelector ioSelector, Material centerDisplay, Block cent rebuild(); } + private Clickable getCycleButton(BlockFace dir) { + if (!ioSelector.hasInputs() && !ioSelector.hasOutputs()) { + // TODO short/optimized default UI (?) + } + Block relativeBlock = centerBlock.getRelative(dir); + Material type = relativeBlock.getType(); + DirectionMask.Direction relativeDir = DirectionMask.Direction.getDirection(front, dir); + IOSelector.IOState dirState = ioSelector.getState(relativeDir); + boolean hasChest = type != Material.CHEST && type != Material.TRAPPED_CHEST; + ItemStack display; + if (hasChest) { + display = new ItemStack(Material.BARRIER); + ItemUtils.addComponentLore(display, Component + .text("") + .style(Style.style(TextDecoration.BOLD)) + .color(TextColor.color(255, 0, 0))); + } else { + display = dirState.getUIVisual(); + } + if (ioDirectionMode != null) { + for (String descLine : ioDirectionMode.fullDescription) { + ItemUtils.addComponentLore(display, Component + .text(descLine) + .color(TextColor.color(255, 255, 192))); + } + } + ItemUtils.setComponentDisplayName(display, + Component.text("\u00a7r") + .append(Component.text(dir.name()).color(TextColor.color(192, 192, 192))) + .append(Component.text(": ")) + .append(Component.text(dirState.name()).color(TextColor.color(dirState.color))) + .asComponent()); + ItemUtils.addComponentLore(display, + Component.text("Click to cycle IO mode").color(TextColor.color(192, 192, 192))); + return new Clickable(display) { + private ClickableInventory inventory; + private int slot; + + @Override + protected void clicked(Player player) { + cycleIoState(relativeDir, false); + } + + @Override + protected void onRightClick(Player p) { + cycleIoState(relativeDir, true); + } + + @Override + protected void onDoubleClick(Player p) { } // nop + + @Override + public void addedToInventory(ClickableInventory inv, int slot) { + this.inventory = inv; + this.slot = slot; + } + + private void cycleIoState(DirectionMask.Direction dir, boolean backwards) { + IOSelector.IOState newState = ioSelector.cycleDirection(dir, backwards); + ItemStack cstack = getItemStack(); + cstack.setType(newState.getUIVisual().getType()); + ItemUtils.setComponentDisplayName(cstack, + Component.text("\u00a7r") + .append(Component.text(dir.name()).color(TextColor.color(192, 192, 192))) + .append(Component.text(": ")) + .append(Component.text(newState.name()).color(TextColor.color(newState.color))) + .asComponent()); + if (inventory != null && inventory.getSlot(slot) == this) { + inventory.setSlot(this, slot); + } + } + }; + } + private Clickable getCycleButton(DirectionMask.Direction dir) { if (!ioSelector.hasInputs() && !ioSelector.hasOutputs()) { // TODO short/optimized default UI (?) @@ -54,6 +135,13 @@ private Clickable getCycleButton(DirectionMask.Direction dir) { } else { display = dirState.getUIVisual(); } + if (ioDirectionMode != null) { + for (String descLine : ioDirectionMode.fullDescription) { + ItemUtils.addComponentLore(display, Component + .text(descLine) + .color(TextColor.color(255, 255, 192))); + } + } ItemUtils.setComponentDisplayName(display, Component.text("\u00a7r") .append(Component.text(dir.name()).color(TextColor.color(192, 192, 192))) @@ -105,12 +193,27 @@ private void cycleIoState(DirectionMask.Direction dir, boolean backwards) { @Override protected void rebuild() { - set(getCycleButton(DirectionMask.Direction.TOP), 1); - set(getCycleButton(DirectionMask.Direction.FRONT), 2); - set(getCycleButton(DirectionMask.Direction.LEFT), 3); - set(getCycleButton(DirectionMask.Direction.RIGHT), 5); - set(getCycleButton(DirectionMask.Direction.BOTTOM), 7); - set(getCycleButton(DirectionMask.Direction.BACK), 8); + ioDirectionMode = FactoryMod.getInstance().getManager().getPlayerSettings().getIoDirectionMode(viewerId); + switch (ioDirectionMode) { + case VISUAL_RELATIVE: { + set(getCycleButton(DirectionMask.Direction.TOP), 1); + set(getCycleButton(DirectionMask.Direction.FRONT), 2); + set(getCycleButton(DirectionMask.Direction.LEFT), 3); + set(getCycleButton(DirectionMask.Direction.RIGHT), 5); + set(getCycleButton(DirectionMask.Direction.BOTTOM), 7); + set(getCycleButton(DirectionMask.Direction.BACK), 8); + break; + } + case CARDINAL: { + set(getCycleButton(BlockFace.NORTH), 1); + set(getCycleButton(BlockFace.UP), 2); + set(getCycleButton(BlockFace.WEST), 3); + set(getCycleButton(BlockFace.EAST), 5); + set(getCycleButton(BlockFace.SOUTH), 7); + set(getCycleButton(BlockFace.DOWN), 8); + break; + } + } set(new LClickable(centerDisplay, p -> {}), 4); } } From 302431ff3e7611bf29ff6ad2d68c7624f335f5db Mon Sep 17 00:00:00 2001 From: caucow Date: Thu, 10 Jun 2021 16:56:49 -0500 Subject: [PATCH 11/21] Make factory IO config section collapsible --- .../factories/FurnCraftChestFactory.java | 22 ++ .../FurnCraftChestInteractionManager.java | 251 ++++++++++++------ .../FactoryMod/utility/FileHandler.java | 13 + 3 files changed, 199 insertions(+), 87 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java index 4e415caa..8ed68e11 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java @@ -60,6 +60,7 @@ public class FurnCraftChestFactory extends Factory { private boolean autoSelect; private IOSelector furnaceIoSelector; private IOSelector tableIoSelector; + private UiMenuMode uiMenuMode; private static HashSet pylonFactories; @@ -159,6 +160,14 @@ public IOSelector getTableIOSelector() { return tableIoSelector; } + public void setUiMenuMode(UiMenuMode uiMenuMode) { + this.uiMenuMode = uiMenuMode; + } + + public UiMenuMode getUiMenuMode() { + return uiMenuMode; + } + /** * @return the direction the furnace (and thus this factory) is facing. */ @@ -643,4 +652,17 @@ public void upgrade(String name, List recipes, ItemStack fuel, int fuel public double getCitadelBreakReduction() { return citadelBreakReduction; } + + public enum UiMenuMode { + SIMPLE(Material.PAPER, "Show simple menu"), + IOCONFIG(Material.HOPPER, "Show IO config menu"); + + public final Material uiMaterial; + public final String uiDescription; + + private UiMenuMode(Material uiMaterial, String uiDescription) { + this.uiMaterial = uiMaterial; + this.uiDescription = uiDescription; + } + } } diff --git a/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java b/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java index 9caa59bc..5865b0a1 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java +++ b/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java @@ -15,6 +15,7 @@ import java.util.List; import com.github.igotyou.FactoryMod.utility.IOConfigSection; +import net.kyori.adventure.text.Component; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.block.Block; @@ -196,93 +197,7 @@ public void clicked(Player arg0) { } if (b.equals(((FurnCraftChestStructure) fccf.getMultiBlockStructure()).getCraftingTable())) { // crafting table // interaction - ComponableInventory compInv = new ComponableInventory("Select a recipe", 6, p); - List recipeList = fccf.getRecipes(); - List recipeClickList = new ArrayList<>(recipeList.size()); - for (IRecipe rec : fccf.getRecipes()) { - InputRecipe recipe = (InputRecipe) (rec); - ItemStack recStack = recipe.getRecipeRepresentation(); - int runcount = fccf.getRunCount(recipe); - ItemUtils.addLore(recStack, "",ChatColor.AQUA + "Ran " + String.valueOf(runcount) + " times"); - if (rec == fccf.getCurrentRecipe()) { - ItemUtils.addLore(recStack, ChatColor.GREEN + "Currently selected"); - ItemUtils.addGlow(recStack); - } - if (recipe instanceof ProductionRecipe) { - ProductionRecipe prod = (ProductionRecipe) recipe; - if (prod.getModifier() != null) { - ItemUtils.addLore(recStack, ChatColor.BOLD + " " + ChatColor.GOLD - + fccf.getRecipeLevel(recipe) + " ★"); - ItemUtils.addLore(recStack, ChatColor.GREEN + "Current output multiplier: " + decimalFormatting - .format(prod.getModifier().getFactor(fccf.getRecipeLevel(recipe), runcount))); - } - } - Clickable c = new Clickable(recStack) { - - @Override - public void clicked(Player p) { - if (fccf.isActive()) { - p.sendMessage(ChatColor.RED + "You can't switch recipes while the factory is running"); - } else { - fccf.setRecipe(recipe); - p.sendMessage(ChatColor.GREEN + "Switched recipe to " + recipe.getName()); - } - } - }; - recipeClickList.add(c); - } - Scrollbar recipeScroller = new Scrollbar(recipeClickList, 27); - recipeScroller.setBackwardsClickSlot(8); - compInv.addComponent(recipeScroller, SlotPredicates.offsetRectangle(3, 9, 0, 0)); - - ItemStack autoSelectStack = new ItemStack(Material.REDSTONE_BLOCK); - ItemUtils.setDisplayName(autoSelectStack, "Toggle auto select"); - ItemUtils.addLore(autoSelectStack, - ChatColor.GOLD + "Make the factory automatically select any", - ChatColor.GOLD + "recipe it can run whenever you activate it", - ChatColor.AQUA + "Click to turn it " + (fccf.isAutoSelect() ? "off" : "on")); - Clickable autoClick = new Clickable(autoSelectStack) { - - @Override - public void clicked(Player p) { - p.sendMessage(ChatColor.GREEN + "Turned auto select " + (fccf.isAutoSelect() ? "off" : "on") - + " for " + fccf.getName()); - fccf.setAutoSelect(!fccf.isAutoSelect()); - } - }; - - ItemStack menuStack = new ItemStack(Material.PAINTING); - ItemUtils.setDisplayName(menuStack, "Open menu"); - ItemUtils.addLore(menuStack, ChatColor.LIGHT_PURPLE + "Click to open a detailed menu"); - Clickable menuC = new Clickable(menuStack) { - @Override - public void clicked(Player p) { - FactoryModGUI gui = new FactoryModGUI(p); - gui.showForFactory((FurnCraftChestEgg)FactoryMod.getInstance().getManager().getEgg(fccf.getName())); - } - }; - - Block fblock = fccf.getFurnace(); - if (fblock.getType() == Material.FURNACE) { - Furnace fstate = (Furnace) fblock.getState(); - org.bukkit.block.data.type.Furnace fdata = (org.bukkit.block.data.type.Furnace) fstate.getBlockData(); - BlockFace facing = fdata.getFacing(); - IOConfigSection furnaceConfigSection = new IOConfigSection( - fccf.getFurnaceIOSelector(), - Material.FURNACE, - fblock, - facing); - IOConfigSection tableConfigSection = new IOConfigSection( - fccf.getTableIOSelector(), - Material.CRAFTING_TABLE, - ((FurnCraftChestStructure) fccf.getMultiBlockStructure()).getCraftingTable(), - facing); - compInv.addComponent(furnaceConfigSection, SlotPredicates.offsetRectangle(3, 3, 3, 0)); - compInv.addComponent(tableConfigSection, SlotPredicates.offsetRectangle(3, 3, 3, 4)); - } - Clickable[] buddons = new Clickable[] { autoClick, menuC }; - StaticDisplaySection lowerSection = new StaticDisplaySection(buddons); - compInv.addComponent(lowerSection, SlotPredicates.offsetRectangle(3, 1, 3, 8)); + ComponableInventory compInv = buildRecipeInventory(p); compInv.update(); compInv.updatePlayerView(); return; @@ -297,6 +212,168 @@ public void clicked(Player p) { } } + private ComponableInventory buildRecipeInventory(Player p) { + ComponableInventory compInv = new ComponableInventory("Select a recipe", 6, p); + + Clickable autoClick = buildAutoSelectToggle(); + Clickable menuC = buildMenuClickable(); + Clickable menuModeButton = buildMenuModeCycleButton(p); + Clickable[] buddons = new Clickable[] { autoClick, menuC, menuModeButton }; + StaticDisplaySection lowerSection = new StaticDisplaySection(buddons); + + Block fblock = fccf.getFurnace(); + switch (fccf.getUiMenuMode()) { + case IOCONFIG: { + Scrollbar recipeScroller = buildRecipeScrollbar(3); + compInv.addComponent(recipeScroller, SlotPredicates.offsetRectangle(3, 9, 0, 0)); + if (fblock.getType() == Material.FURNACE) { + Furnace fstate = (Furnace) fblock.getState(); + org.bukkit.block.data.type.Furnace fdata = (org.bukkit.block.data.type.Furnace) fstate.getBlockData(); + BlockFace facing = fdata.getFacing(); + IOConfigSection furnaceConfigSection = new IOConfigSection( + p, + fccf.getFurnaceIOSelector(), + Material.FURNACE, + fblock, + facing); + IOConfigSection tableConfigSection = new IOConfigSection( + p, + fccf.getTableIOSelector(), + Material.CRAFTING_TABLE, + ((FurnCraftChestStructure) fccf.getMultiBlockStructure()).getCraftingTable(), + facing); + compInv.addComponent(furnaceConfigSection, SlotPredicates.offsetRectangle(3, 3, 3, 0)); + compInv.addComponent(tableConfigSection, SlotPredicates.offsetRectangle(3, 3, 3, 4)); + } + compInv.addComponent(lowerSection, SlotPredicates.offsetRectangle(3, 1, 3, 8)); + break; + } + default: { + Scrollbar recipeScroller = buildRecipeScrollbar(5); + compInv.addComponent(recipeScroller, SlotPredicates.offsetRectangle(5, 9, 0, 0)); + compInv.addComponent(lowerSection, SlotPredicates.offsetRectangle(1, 3, 5, 6)); + } + } + return compInv; + } + + private Scrollbar buildRecipeScrollbar(int rows) { + rows = Math.max(1, Math.min(5, rows)); + List recipeList = fccf.getRecipes(); + List recipeClickList = new ArrayList<>(recipeList.size()); + for (IRecipe rec : fccf.getRecipes()) { + InputRecipe recipe = (InputRecipe) (rec); + ItemStack recStack = recipe.getRecipeRepresentation(); + int runcount = fccf.getRunCount(recipe); + ItemUtils.addLore(recStack, "",ChatColor.AQUA + "Ran " + String.valueOf(runcount) + " times"); + if (rec == fccf.getCurrentRecipe()) { + ItemUtils.addLore(recStack, ChatColor.GREEN + "Currently selected"); + ItemUtils.addGlow(recStack); + } + if (recipe instanceof ProductionRecipe) { + ProductionRecipe prod = (ProductionRecipe) recipe; + if (prod.getModifier() != null) { + ItemUtils.addLore(recStack, ChatColor.BOLD + " " + ChatColor.GOLD + + fccf.getRecipeLevel(recipe) + " ★"); + ItemUtils.addLore(recStack, ChatColor.GREEN + "Current output multiplier: " + decimalFormatting + .format(prod.getModifier().getFactor(fccf.getRecipeLevel(recipe), runcount))); + } + } + Clickable c = new Clickable(recStack) { + + @Override + public void clicked(Player p) { + if (fccf.isActive()) { + p.sendMessage(ChatColor.RED + "You can't switch recipes while the factory is running"); + } else { + fccf.setRecipe(recipe); + p.sendMessage(ChatColor.GREEN + "Switched recipe to " + recipe.getName()); + } + } + }; + recipeClickList.add(c); + } + Scrollbar recipeScroller = new Scrollbar(recipeClickList, rows * 9); + recipeScroller.setBackwardsClickSlot(rows == 1 ? 0 : 8); + return recipeScroller; + } + + private Clickable buildAutoSelectToggle() { + ItemStack autoSelectStack = new ItemStack(Material.REDSTONE_BLOCK); + ItemUtils.setDisplayName(autoSelectStack, "Toggle auto select"); + ItemUtils.addLore(autoSelectStack, + ChatColor.GOLD + "Make the factory automatically select any", + ChatColor.GOLD + "recipe it can run whenever you activate it", + ChatColor.AQUA + "Click to turn it " + (fccf.isAutoSelect() ? "off" : "on")); + Clickable autoClick = new Clickable(autoSelectStack) { + + @Override + public void clicked(Player p) { + p.sendMessage(ChatColor.GREEN + "Turned auto select " + (fccf.isAutoSelect() ? "off" : "on") + + " for " + fccf.getName()); + fccf.setAutoSelect(!fccf.isAutoSelect()); + } + }; + return autoClick; + } + + private Clickable buildMenuClickable() { + ItemStack menuStack = new ItemStack(Material.PAINTING); + ItemUtils.setDisplayName(menuStack, "Open menu"); + ItemUtils.addLore(menuStack, ChatColor.LIGHT_PURPLE + "Click to open a detailed menu"); + Clickable menuC = new Clickable(menuStack) { + @Override + public void clicked(Player p) { + FactoryModGUI gui = new FactoryModGUI(p); + gui.showForFactory((FurnCraftChestEgg)FactoryMod.getInstance().getManager().getEgg(fccf.getName())); + } + }; + return menuC; + } + + private Clickable buildMenuModeCycleButton(Player p) { + FurnCraftChestFactory.UiMenuMode[] modes = FurnCraftChestFactory.UiMenuMode.values(); + FurnCraftChestFactory.UiMenuMode curMode = fccf.getUiMenuMode(); + FurnCraftChestFactory.UiMenuMode nextMode = modes[(curMode.ordinal() + 1) % modes.length]; + ItemStack display = new ItemStack(nextMode.uiMaterial); + ItemUtils.setComponentDisplayName(display, Component.text(nextMode.uiDescription)); + + Clickable menuModeButton = new Clickable(display) { + private ClickableInventory inventory; + private int slot; + + @Override + protected void clicked(Player player) { + cycleMenuMode(); + ComponableInventory compInv = buildRecipeInventory(p); + compInv.update(); + compInv.updatePlayerView(); + } + + @Override + public void addedToInventory(ClickableInventory inv, int slot) { + this.inventory = inv; + this.slot = slot; + } + + private void cycleMenuMode() { + FurnCraftChestFactory.UiMenuMode innerCurMode = fccf.getUiMenuMode(); + innerCurMode = modes[(innerCurMode.ordinal() + 1) % modes.length]; + fccf.setUiMenuMode(innerCurMode); + + ItemStack innerCurStack = getItemStack(); + FurnCraftChestFactory.UiMenuMode innerNextMode = modes[(innerCurMode.ordinal() + 1) % modes.length]; + innerCurStack.setType(innerNextMode.uiMaterial); + ItemUtils.setComponentDisplayName(innerCurStack, Component.text(innerNextMode.uiDescription)); + + if (inventory != null && inventory.getSlot(slot) == this) { + inventory.setSlot(this, slot); + } + } + }; + return menuModeButton; + } + @Override public void rightClick(Player p, Block b, BlockFace bf) { // Nothing to do here, every block already has a right click diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java index 5bc6624b..7b2d2558 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java @@ -101,6 +101,7 @@ public void save(Collection factories) { } config.set(current + ".furnace-io-mask", fccf.getFurnaceIOSelector().toShortMask()); config.set(current + ".table-io-mask", fccf.getTableIOSelector().toShortMask()); + config.set(current + ".ui-menu-mode", fccf.getUiMenuMode().name()); } else if (f instanceof Pipe) { Pipe p = (Pipe) f; config.set(current + ".type", "PIPE"); @@ -319,6 +320,18 @@ private void loadFromFile(File f, Map eggs) { } } } + String menuModeRaw = current.getString("ui-menu-mode"); + FurnCraftChestFactory.UiMenuMode menuMode; + if (menuModeRaw == null) { + menuMode = FurnCraftChestFactory.UiMenuMode.SIMPLE; + } else { + try { + menuMode = FurnCraftChestFactory.UiMenuMode.valueOf(menuModeRaw); + } catch (IllegalArgumentException iae) { + menuMode = FurnCraftChestFactory.UiMenuMode.SIMPLE; + } + } + fac.setUiMenuMode(menuMode); manager.addFactory(fac); counter++; break; From c70c397e5e5c57e4d624c3e8f4eda94dfdceb674 Mon Sep 17 00:00:00 2001 From: caucow Date: Fri, 11 Jun 2021 00:13:15 -0500 Subject: [PATCH 12/21] Fix NPE - Initialize default UiMenuMode --- .../igotyou/FactoryMod/factories/FurnCraftChestFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java index 8ed68e11..0fe4b83a 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java @@ -76,6 +76,7 @@ public FurnCraftChestFactory(IInteractionManager im, IRepairManager rm, IPowerMa this.autoSelect = false; this.furnaceIoSelector = new IOSelector(); this.tableIoSelector = new IOSelector(); + this.uiMenuMode = UiMenuMode.SIMPLE; for (IRecipe rec : recipes) { addRecipe(rec); } From 5f108305480c006e88f632317fcee40466cd584c Mon Sep 17 00:00:00 2001 From: caucow Date: Fri, 11 Jun 2021 00:21:38 -0500 Subject: [PATCH 13/21] Properly init default IO config +lazy init since getBlock called Default IO was only being initialized for old factories loaded from file, not new factories. --- .../factories/FurnCraftChestFactory.java | 28 +++++++++++++------ .../FactoryMod/utility/FileHandler.java | 9 +----- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java index 0fe4b83a..798c11cb 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java @@ -15,6 +15,7 @@ import com.github.igotyou.FactoryMod.repairManager.IRepairManager; import com.github.igotyou.FactoryMod.repairManager.PercentageHealthRepairManager; import com.github.igotyou.FactoryMod.structures.FurnCraftChestStructure; +import com.github.igotyou.FactoryMod.utility.DirectionMask; import com.github.igotyou.FactoryMod.utility.IOSelector; import com.github.igotyou.FactoryMod.utility.LoggingUtils; import java.util.ArrayList; @@ -58,8 +59,8 @@ public class FurnCraftChestFactory extends Factory { private UUID activator; private double citadelBreakReduction; private boolean autoSelect; - private IOSelector furnaceIoSelector; - private IOSelector tableIoSelector; + private @Nullable IOSelector furnaceIoSelector; + private @Nullable IOSelector tableIoSelector; private UiMenuMode uiMenuMode; private static HashSet pylonFactories; @@ -74,8 +75,7 @@ public FurnCraftChestFactory(IInteractionManager im, IRepairManager rm, IPowerMa this.recipes = new ArrayList<>(); this.citadelBreakReduction = citadelBreakReduction; this.autoSelect = false; - this.furnaceIoSelector = new IOSelector(); - this.tableIoSelector = new IOSelector(); + // TODO initialize furnace/table io selectors this.uiMenuMode = UiMenuMode.SIMPLE; for (IRecipe rec : recipes) { addRecipe(rec); @@ -108,14 +108,14 @@ public Inventory getInputInventory() { ArrayList invs = new ArrayList<>(12); Block fblock = getFurnace(); BlockFace facing = getFacing(); - for (BlockFace relativeFace : furnaceIoSelector.getInputs(facing)) { + for (BlockFace relativeFace : getFurnaceIOSelector().getInputs(facing)) { Block relBlock = fblock.getRelative(relativeFace); if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { invs.add(((Chest) relBlock.getState()).getInventory()); } } Block tblock = fccs.getCraftingTable(); - for (BlockFace relativeFace : tableIoSelector.getInputs(facing)) { + for (BlockFace relativeFace : getTableIOSelector().getInputs(facing)) { Block relBlock = tblock.getRelative(relativeFace); if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { invs.add(((Chest) relBlock.getState()).getInventory()); @@ -129,14 +129,14 @@ public Inventory getOutputInventory() { ArrayList invs = new ArrayList<>(12); Block fblock = getFurnace(); BlockFace facing = getFacing(); - for (BlockFace relativeFace : furnaceIoSelector.getOutputs(facing)) { + for (BlockFace relativeFace : getFurnaceIOSelector().getOutputs(facing)) { Block relBlock = fblock.getRelative(relativeFace); if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { invs.add(((Chest) relBlock.getState()).getInventory()); } } Block tblock = fccs.getCraftingTable(); - for (BlockFace relativeFace : tableIoSelector.getOutputs(facing)) { + for (BlockFace relativeFace : getTableIOSelector().getOutputs(facing)) { Block relBlock = tblock.getRelative(relativeFace); if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { invs.add(((Chest) relBlock.getState()).getInventory()); @@ -150,6 +150,9 @@ public void setFurnaceIOSelector(IOSelector ioSelector) { } public IOSelector getFurnaceIOSelector() { + if (furnaceIoSelector == null) { + furnaceIoSelector = new IOSelector(); + } return furnaceIoSelector; } @@ -158,6 +161,15 @@ public void setTableIOSelector(IOSelector ioSelector) { } public IOSelector getTableIOSelector() { + if (tableIoSelector == null) { + tableIoSelector = new IOSelector(); + BlockFace front = getFacing(); + BlockFace chestDir = getFurnace().getFace(getCraftingTable()); + if (chestDir != null && front != null) { + DirectionMask.Direction defaultDir = DirectionMask.Direction.getDirection(front, chestDir); + tableIoSelector.setState(defaultDir, IOSelector.IOState.BOTH); + } + } return tableIoSelector; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java index 7b2d2558..b3090911 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java @@ -310,14 +310,7 @@ private void loadFromFile(File f, Map eggs) { IOSelector tableIoSelector = IOSelector.fromShortMask((short) mask); fac.setTableIOSelector(tableIoSelector); } else { - BlockFace chestDir = fac.getFurnace().getFace(fac.getCraftingTable()); - BlockFace front = fac.getFacing(); - if (chestDir != null && front != null) { - IOSelector tableIoSelector = new IOSelector(); - DirectionMask.Direction defaultDir = DirectionMask.Direction.getDirection(front, chestDir); - tableIoSelector.setState(defaultDir, IOSelector.IOState.BOTH); - fac.setTableIOSelector(tableIoSelector); - } + // Default table-side IO moved to FCCF.getTableIoSelector() lazy init } } String menuModeRaw = current.getString("ui-menu-mode"); From a5506c849df3cc65fdb38e7a06c647f4ea7f297b Mon Sep 17 00:00:00 2001 From: caucow Date: Sat, 12 Jun 2021 19:51:11 -0500 Subject: [PATCH 14/21] Add configurable fuel chests + I/O/F/total chest limit --- .../igotyou/FactoryMod/ConfigParser.java | 7 +- .../igotyou/FactoryMod/FactoryModManager.java | 29 +++ .../factories/FurnCraftChestFactory.java | 47 ++++- .../FurnCraftChestInteractionManager.java | 6 +- .../powerManager/FurnacePowerManager.java | 33 ++++ .../FactoryMod/utility/FileHandler.java | 8 +- .../utility/IIOFInventoryProvider.java | 22 +++ .../FactoryMod/utility/IOConfigSection.java | 178 ++++++++---------- .../FactoryMod/utility/IOSelector.java | 106 +++++++++-- src/main/resources/config.yml | 7 + 10 files changed, 319 insertions(+), 124 deletions(-) create mode 100644 src/main/java/com/github/igotyou/FactoryMod/utility/IIOFInventoryProvider.java diff --git a/src/main/java/com/github/igotyou/FactoryMod/ConfigParser.java b/src/main/java/com/github/igotyou/FactoryMod/ConfigParser.java index a5cd5038..ae72cc7c 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/ConfigParser.java +++ b/src/main/java/com/github/igotyou/FactoryMod/ConfigParser.java @@ -143,9 +143,14 @@ public void run() { int globalPylonLimit = config.getInt("global_pylon_limit"); PylonRecipe.setGlobalLimit(globalPylonLimit); Map factoryRenames = parseRenames(config.getConfigurationSection("renames")); + int maxInputChests = config.getInt("max_input_chests", 10); + int maxOutputChests = config.getInt("max_output_chests", 10); + int maxFuelChests = config.getInt("max_fuel_chests", 10); + int maxTotalIOFChests = config.getInt("max_iof_chests", 15); manager = new FactoryModManager(plugin, factoryInteractionMaterial, citadelEnabled, nameLayerEnabled, - redstonePowerOn, redstoneRecipeChange, logInventories, factoryRenames); + redstonePowerOn, redstoneRecipeChange, logInventories, maxInputChests, maxOutputChests, maxFuelChests, + maxTotalIOFChests, factoryRenames); upgradeEggs = new HashMap<>(); recipeLists = new HashMap<>(); recipeScalingUpgradeMapping = new HashMap<>(); diff --git a/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java b/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java index d1a82aac..bcfbebc5 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java +++ b/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java @@ -53,18 +53,27 @@ public class FactoryModManager { private boolean logInventories; private int redstonePowerOn; private int redstoneRecipeChange; + private int maxInputChests; + private int maxOutputChests; + private int maxFuelChests; + private int maxTotalIOFChests; private Set compactLore; private Set forceInclude; private FactoryModPlayerSettings playerSettings; public FactoryModManager(FactoryMod plugin, Material factoryInteractionMaterial, boolean citadelEnabled, boolean nameLayerEnabled, int redstonePowerOn, int redstoneRecipeChange, boolean logInventories, + int maxInputChests, int maxOutputChests, int maxFuelChests, int maxTotalIOFChests, Map factoryRenames) { this.plugin = plugin; this.factoryInteractionMaterial = factoryInteractionMaterial; this.citadelEnabled = citadelEnabled; this.redstonePowerOn = redstonePowerOn; this.redstoneRecipeChange = redstoneRecipeChange; + this.maxInputChests = maxInputChests; + this.maxOutputChests = maxOutputChests; + this.maxFuelChests = maxFuelChests; + this.maxTotalIOFChests = maxTotalIOFChests; this.fileHandler = new FileHandler(this, factoryRenames); factoryCreationRecipes = new HashMap<>(); @@ -151,6 +160,26 @@ public boolean isCitadelEnabled() { return citadelEnabled; } + public int getMaxInputChests() { + return maxInputChests; + } + + public int getMaxOutputChests() { + return maxOutputChests; + } + + public int getMaxFuelChests() { + return maxFuelChests; + } + + /** + * @return The maximum total number of inputs, outputs, and fuel inputs a factory has. A chest with multiple IOF + * settings enabled is counted for each. + */ + public int getMaxTotalIOFChests() { + return maxTotalIOFChests; + } + /** * @return Which material is used to interact with factories, stick by default */ diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java index 798c11cb..45efe786 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java @@ -5,6 +5,7 @@ import com.github.igotyou.FactoryMod.events.RecipeExecuteEvent; import com.github.igotyou.FactoryMod.interactionManager.IInteractionManager; import com.github.igotyou.FactoryMod.powerManager.FurnacePowerManager; +import com.github.igotyou.FactoryMod.utility.IIOFInventoryProvider; import com.github.igotyou.FactoryMod.powerManager.IPowerManager; import com.github.igotyou.FactoryMod.recipes.IRecipe; import com.github.igotyou.FactoryMod.recipes.InputRecipe; @@ -50,7 +51,7 @@ * which is used as inventory holder * */ -public class FurnCraftChestFactory extends Factory { +public class FurnCraftChestFactory extends Factory implements IIOFInventoryProvider { protected int currentProductionTimer = 0; protected List recipes; protected IRecipe currentRecipe; @@ -69,13 +70,15 @@ public FurnCraftChestFactory(IInteractionManager im, IRepairManager rm, IPowerMa FurnCraftChestStructure mbs, int updateTime, String name, List recipes, double citadelBreakReduction) { super(im, rm, ipm, mbs, updateTime, name); + if (ipm instanceof FurnacePowerManager) { + ((FurnacePowerManager) ipm).setIofProvider(this); + } this.active = false; this.runCount = new HashMap<>(); this.recipeLevel = new HashMap<>(); this.recipes = new ArrayList<>(); this.citadelBreakReduction = citadelBreakReduction; this.autoSelect = false; - // TODO initialize furnace/table io selectors this.uiMenuMode = UiMenuMode.SIMPLE; for (IRecipe rec : recipes) { addRecipe(rec); @@ -145,6 +148,46 @@ public Inventory getOutputInventory() { return new MultiInventoryWrapper(invs); } + public Inventory getFuelInventory() { + if (!getFurnaceIOSelector().hasFuel() && !getTableIOSelector().hasFuel()) { + return getFurnaceInventory(); + } + FurnCraftChestStructure fccs = (FurnCraftChestStructure) getMultiBlockStructure(); + ArrayList invs = new ArrayList<>(13); + invs.add(getFurnaceInventory()); + Block fblock = getFurnace(); + BlockFace facing = getFacing(); + for (BlockFace relativeFace : getFurnaceIOSelector().getFuel(facing)) { + Block relBlock = fblock.getRelative(relativeFace); + if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { + invs.add(((Chest) relBlock.getState()).getInventory()); + } + } + Block tblock = fccs.getCraftingTable(); + for (BlockFace relativeFace : getTableIOSelector().getFuel(facing)) { + Block relBlock = tblock.getRelative(relativeFace); + if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { + invs.add(((Chest) relBlock.getState()).getInventory()); + } + } + return new MultiInventoryWrapper(invs); + } + + @Override + public int getInputCount() { + return furnaceIoSelector.getInputCount() + tableIoSelector.getInputCount(); + } + + @Override + public int getOutputCount() { + return furnaceIoSelector.getOutputCount() + tableIoSelector.getOutputCount(); + } + + @Override + public int getFuelCount() { + return furnaceIoSelector.getFuelCount() + tableIoSelector.getFuelCount(); + } + public void setFurnaceIOSelector(IOSelector ioSelector) { this.furnaceIoSelector = ioSelector; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java b/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java index 5865b0a1..9cd286c7 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java +++ b/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java @@ -235,13 +235,15 @@ private ComponableInventory buildRecipeInventory(Player p) { fccf.getFurnaceIOSelector(), Material.FURNACE, fblock, - facing); + facing, + fccf); IOConfigSection tableConfigSection = new IOConfigSection( p, fccf.getTableIOSelector(), Material.CRAFTING_TABLE, ((FurnCraftChestStructure) fccf.getMultiBlockStructure()).getCraftingTable(), - facing); + facing, + fccf); compInv.addComponent(furnaceConfigSection, SlotPredicates.offsetRectangle(3, 3, 3, 0)); compInv.addComponent(tableConfigSection, SlotPredicates.offsetRectangle(3, 3, 3, 4)); } diff --git a/src/main/java/com/github/igotyou/FactoryMod/powerManager/FurnacePowerManager.java b/src/main/java/com/github/igotyou/FactoryMod/powerManager/FurnacePowerManager.java index 4618e81c..b4c90e2e 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/powerManager/FurnacePowerManager.java +++ b/src/main/java/com/github/igotyou/FactoryMod/powerManager/FurnacePowerManager.java @@ -1,9 +1,11 @@ package com.github.igotyou.FactoryMod.powerManager; +import com.github.igotyou.FactoryMod.utility.IIOFInventoryProvider; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Furnace; import org.bukkit.inventory.FurnaceInventory; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import vg.civcraft.mc.civmodcore.itemHandling.ItemMap; @@ -17,6 +19,7 @@ public class FurnacePowerManager implements IPowerManager { private int powerCounter; private int fuelConsumptionIntervall; private Block furnace; + private IIOFInventoryProvider iofProvider; public FurnacePowerManager(Block furnace, ItemStack fuel, int fuelConsumptionIntervall) { @@ -30,11 +33,27 @@ public FurnacePowerManager(ItemStack fuel, int fuelConsumptionIntervall) { this.fuelConsumptionIntervall = fuelConsumptionIntervall; } + public void setIofProvider(IIOFInventoryProvider iofProvider) { + this.iofProvider = iofProvider; + } + + public IIOFInventoryProvider getIofProvider() { + return iofProvider; + } + public int getPowerCounter() { return powerCounter; } public boolean powerAvailable(int fuelCount) { + if (iofProvider != null) { + Inventory fuelInv = iofProvider.getFuelInventory(); + if (fuelInv != null) { + ItemMap im = new ItemMap(fuelInv); + return im.getAmount(fuel) >= fuelCount; + } + } + if (furnace.getType() != Material.FURNACE) { return false; } @@ -62,6 +81,13 @@ public void setPowerCounter(int amount) { } public void consumePower(int fuelCount) { + if (iofProvider != null) { + Inventory fuelInv = iofProvider.getFuelInventory(); + if (fuelInv != null) { + fuelInv.removeItem(fuel); + } + } + FurnaceInventory fi = ((Furnace) furnace.getState()).getInventory(); for(int i = 0; i < fuelCount; i++) @@ -69,6 +95,13 @@ public void consumePower(int fuelCount) { } public int getFuelAmountAvailable() { + if (iofProvider != null) { + Inventory fuelInv = iofProvider.getFuelInventory(); + if (fuelInv != null) { + ItemMap im = new ItemMap(fuelInv); + return im.getAmount(fuel); + } + } return new ItemMap(((Furnace) furnace.getState()).getInventory()).getAmount(fuel); } diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java index b3090911..7d4419bf 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java @@ -99,8 +99,8 @@ public void save(Collection factories) { config.set(current + ".runcounts." + i.getName(), fccf.getRunCount(i)); config.set(current + ".recipeLevels." + i.getName(), fccf.getRecipeLevel(i)); } - config.set(current + ".furnace-io-mask", fccf.getFurnaceIOSelector().toShortMask()); - config.set(current + ".table-io-mask", fccf.getTableIOSelector().toShortMask()); + config.set(current + ".furnace-io-mask", fccf.getFurnaceIOSelector().toIntMask()); + config.set(current + ".table-io-mask", fccf.getTableIOSelector().toIntMask()); config.set(current + ".ui-menu-mode", fccf.getUiMenuMode().name()); } else if (f instanceof Pipe) { Pipe p = (Pipe) f; @@ -300,14 +300,14 @@ private void loadFromFile(File f, Map eggs) { { int mask = current.getInt("furnace-io-mask", -1); if (mask != -1) { - IOSelector furnaceIoSelector = IOSelector.fromShortMask((short) mask); + IOSelector furnaceIoSelector = IOSelector.fromIntMask(mask); fac.setFurnaceIOSelector(furnaceIoSelector); } else { // Nothing I guess, the furnace has no default state. } mask = current.getInt("table-io-mask", -1); if (mask != -1) { - IOSelector tableIoSelector = IOSelector.fromShortMask((short) mask); + IOSelector tableIoSelector = IOSelector.fromIntMask(mask); fac.setTableIOSelector(tableIoSelector); } else { // Default table-side IO moved to FCCF.getTableIoSelector() lazy init diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IIOFInventoryProvider.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IIOFInventoryProvider.java new file mode 100644 index 00000000..362b7609 --- /dev/null +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IIOFInventoryProvider.java @@ -0,0 +1,22 @@ +package com.github.igotyou.FactoryMod.utility; + +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Nullable; + +/** + * Utility interface for classes that provide separate inventories for inputs, outputs, and fuel. + */ +public interface IIOFInventoryProvider { + + Inventory getInputInventory(); + Inventory getOutputInventory(); + @Nullable Inventory getFuelInventory(); + + int getInputCount(); + int getOutputCount(); + int getFuelCount(); + default int getTotalIOFCount() { + return getInputCount() + getOutputCount() + getFuelCount(); + } + +} diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java index ff0c061e..13cf035e 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java @@ -1,11 +1,13 @@ package com.github.igotyou.FactoryMod.utility; import com.github.igotyou.FactoryMod.FactoryMod; +import com.github.igotyou.FactoryMod.FactoryModManager; import com.github.igotyou.FactoryMod.FactoryModPlayerSettings; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; +import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -24,107 +26,43 @@ */ public class IOConfigSection extends StaticDisplaySection { - private UUID viewerId; + private final UUID viewerId; private final IOSelector ioSelector; private final Material centerDisplay; private final BlockFace front; private final Block centerBlock; + private final IIOFInventoryProvider iofProvider; private FactoryModPlayerSettings.IoConfigDirectionMode ioDirectionMode; - public IOConfigSection(Player viewer, IOSelector ioSelector, Material centerDisplay, Block centerBlock, BlockFace front) { + public IOConfigSection(Player viewer, IOSelector ioSelector, Material centerDisplay, Block centerBlock, + BlockFace front, IIOFInventoryProvider iofProvider) { super(9); this.viewerId = viewer.getUniqueId(); this.ioSelector = ioSelector; this.centerDisplay = centerDisplay; this.centerBlock = centerBlock; this.front = front; - + this.iofProvider = iofProvider; rebuild(); } - private Clickable getCycleButton(BlockFace dir) { - if (!ioSelector.hasInputs() && !ioSelector.hasOutputs()) { - // TODO short/optimized default UI (?) - } + private Clickable getIoButton(BlockFace dir) { Block relativeBlock = centerBlock.getRelative(dir); Material type = relativeBlock.getType(); DirectionMask.Direction relativeDir = DirectionMask.Direction.getDirection(front, dir); - IOSelector.IOState dirState = ioSelector.getState(relativeDir); - boolean hasChest = type != Material.CHEST && type != Material.TRAPPED_CHEST; - ItemStack display; - if (hasChest) { - display = new ItemStack(Material.BARRIER); - ItemUtils.addComponentLore(display, Component - .text("") - .style(Style.style(TextDecoration.BOLD)) - .color(TextColor.color(255, 0, 0))); - } else { - display = dirState.getUIVisual(); - } - if (ioDirectionMode != null) { - for (String descLine : ioDirectionMode.fullDescription) { - ItemUtils.addComponentLore(display, Component - .text(descLine) - .color(TextColor.color(255, 255, 192))); - } - } - ItemUtils.setComponentDisplayName(display, - Component.text("\u00a7r") - .append(Component.text(dir.name()).color(TextColor.color(192, 192, 192))) - .append(Component.text(": ")) - .append(Component.text(dirState.name()).color(TextColor.color(dirState.color))) - .asComponent()); - ItemUtils.addComponentLore(display, - Component.text("Click to cycle IO mode").color(TextColor.color(192, 192, 192))); - return new Clickable(display) { - private ClickableInventory inventory; - private int slot; - - @Override - protected void clicked(Player player) { - cycleIoState(relativeDir, false); - } - - @Override - protected void onRightClick(Player p) { - cycleIoState(relativeDir, true); - } - - @Override - protected void onDoubleClick(Player p) { } // nop - - @Override - public void addedToInventory(ClickableInventory inv, int slot) { - this.inventory = inv; - this.slot = slot; - } - - private void cycleIoState(DirectionMask.Direction dir, boolean backwards) { - IOSelector.IOState newState = ioSelector.cycleDirection(dir, backwards); - ItemStack cstack = getItemStack(); - cstack.setType(newState.getUIVisual().getType()); - ItemUtils.setComponentDisplayName(cstack, - Component.text("\u00a7r") - .append(Component.text(dir.name()).color(TextColor.color(192, 192, 192))) - .append(Component.text(": ")) - .append(Component.text(newState.name()).color(TextColor.color(newState.color))) - .asComponent()); - if (inventory != null && inventory.getSlot(slot) == this) { - inventory.setSlot(this, slot); - } - } - }; + return getIoClickable(type, relativeDir, dir.name()); } - private Clickable getCycleButton(DirectionMask.Direction dir) { - if (!ioSelector.hasInputs() && !ioSelector.hasOutputs()) { - // TODO short/optimized default UI (?) - } + private Clickable getIoButton(DirectionMask.Direction dir) { BlockFace relativeDir = dir.getBlockFacing(front); Block relativeBlock = centerBlock.getRelative(relativeDir); Material type = relativeBlock.getType(); + return getIoClickable(type, dir, dir.name()); + } + + private Clickable getIoClickable(Material adjacentType, DirectionMask.Direction dir, String dirLabel) { IOSelector.IOState dirState = ioSelector.getState(dir); - boolean hasChest = type != Material.CHEST && type != Material.TRAPPED_CHEST; + boolean hasChest = adjacentType != Material.CHEST && adjacentType != Material.TRAPPED_CHEST; ItemStack display; if (hasChest) { display = new ItemStack(Material.BARRIER); @@ -144,25 +82,63 @@ private Clickable getCycleButton(DirectionMask.Direction dir) { } ItemUtils.setComponentDisplayName(display, Component.text("\u00a7r") - .append(Component.text(dir.name()).color(TextColor.color(192, 192, 192))) + .append(Component.text(dirLabel).color(TextColor.color(192, 192, 192))) .append(Component.text(": ")) .append(Component.text(dirState.name()).color(TextColor.color(dirState.color))) .asComponent()); ItemUtils.addComponentLore(display, - Component.text("Click to cycle IO mode").color(TextColor.color(192, 192, 192))); - + Component.text("L/M/R click to toggle I/F/O").color(TextColor.color(192, 192, 192))); + FactoryModManager fmMgr = FactoryMod.getInstance().getManager(); return new Clickable(display) { private ClickableInventory inventory; private int slot; @Override protected void clicked(Player player) { - cycleIoState(dir, false); + if (!ioSelector.isInput(dir)) { + if (iofProvider.getInputCount() >= fmMgr.getMaxInputChests()) { + player.sendMessage(ChatColor.RED + "This factory is at the maximum number of inputs."); + return; + } + if (iofProvider.getTotalIOFCount() >= fmMgr.getMaxTotalIOFChests()) { + player.sendMessage(ChatColor.RED + "This factory is at the maximum number of total I/O/Fs."); + return; + } + } + ioSelector.toggleInput(dir); + updateItem(); + } + + @Override + protected void onRightClick(Player player) { + if (!ioSelector.isOutput(dir)) { + if (iofProvider.getOutputCount() >= fmMgr.getMaxOutputChests()) { + player.sendMessage(ChatColor.RED + "This factory is at the maximum number of outputs."); + return; + } + if (iofProvider.getTotalIOFCount() >= fmMgr.getMaxTotalIOFChests()) { + player.sendMessage(ChatColor.RED + "This factory is at the maximum number of total I/O/Fs."); + return; + } + } + ioSelector.toggleOutput(dir); + updateItem(); } @Override - protected void onRightClick(Player p) { - cycleIoState(dir, true); + protected void onMiddleClick(Player player) { + if (!ioSelector.isFuel(dir)) { + if (iofProvider.getFuelCount() >= fmMgr.getMaxFuelChests()) { + player.sendMessage(ChatColor.RED + "This factory is at the maximum number of fuel inputs."); + return; + } + if (iofProvider.getTotalIOFCount() >= fmMgr.getMaxTotalIOFChests()) { + player.sendMessage(ChatColor.RED + "This factory is at the maximum number of total I/O/Fs."); + return; + } + } + ioSelector.toggleFuel(dir); + updateItem(); } @Override @@ -174,13 +150,13 @@ public void addedToInventory(ClickableInventory inv, int slot) { this.slot = slot; } - private void cycleIoState(DirectionMask.Direction dir, boolean backwards) { - IOSelector.IOState newState = ioSelector.cycleDirection(dir, backwards); - ItemStack cstack = getItemStack(); - cstack.setType(newState.getUIVisual().getType()); - ItemUtils.setComponentDisplayName(cstack, + private void updateItem() { + IOSelector.IOState newState = ioSelector.getState(dir); + ItemStack curStack = getItemStack(); + curStack.setType(newState.getUIVisual().getType()); + ItemUtils.setComponentDisplayName(curStack, Component.text("\u00a7r") - .append(Component.text(dir.name()).color(TextColor.color(192, 192, 192))) + .append(Component.text(dirLabel).color(TextColor.color(192, 192, 192))) .append(Component.text(": ")) .append(Component.text(newState.name()).color(TextColor.color(newState.color))) .asComponent()); @@ -196,21 +172,21 @@ protected void rebuild() { ioDirectionMode = FactoryMod.getInstance().getManager().getPlayerSettings().getIoDirectionMode(viewerId); switch (ioDirectionMode) { case VISUAL_RELATIVE: { - set(getCycleButton(DirectionMask.Direction.TOP), 1); - set(getCycleButton(DirectionMask.Direction.FRONT), 2); - set(getCycleButton(DirectionMask.Direction.LEFT), 3); - set(getCycleButton(DirectionMask.Direction.RIGHT), 5); - set(getCycleButton(DirectionMask.Direction.BOTTOM), 7); - set(getCycleButton(DirectionMask.Direction.BACK), 8); + set(getIoButton(DirectionMask.Direction.TOP), 1); + set(getIoButton(DirectionMask.Direction.FRONT), 2); + set(getIoButton(DirectionMask.Direction.LEFT), 3); + set(getIoButton(DirectionMask.Direction.RIGHT), 5); + set(getIoButton(DirectionMask.Direction.BOTTOM), 7); + set(getIoButton(DirectionMask.Direction.BACK), 8); break; } case CARDINAL: { - set(getCycleButton(BlockFace.NORTH), 1); - set(getCycleButton(BlockFace.UP), 2); - set(getCycleButton(BlockFace.WEST), 3); - set(getCycleButton(BlockFace.EAST), 5); - set(getCycleButton(BlockFace.SOUTH), 7); - set(getCycleButton(BlockFace.DOWN), 8); + set(getIoButton(BlockFace.NORTH), 1); + set(getIoButton(BlockFace.UP), 2); + set(getIoButton(BlockFace.WEST), 3); + set(getIoButton(BlockFace.EAST), 5); + set(getIoButton(BlockFace.SOUTH), 7); + set(getIoButton(BlockFace.DOWN), 8); break; } } diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java index b2a4b45d..0ba579be 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java @@ -14,23 +14,72 @@ public class IOSelector { private final DirectionMask inputs; private final DirectionMask outputs; + private final DirectionMask fuel; - public IOSelector(byte inMask, byte outMask) { + public IOSelector(byte inMask, byte outMask, byte fuel) { this.inputs = new DirectionMask(inMask); this.outputs = new DirectionMask(outMask); + this.fuel = new DirectionMask(fuel); } public IOSelector() { - this((byte) 0, (byte) 0); + this((byte) 0, (byte) 0, (byte) 0); } public IOState getState(DirectionMask.Direction direction) { - return IOState.fromIO(inputs.isSet(direction), outputs.isSet(direction)); + return IOState.fromIO(inputs.isSet(direction), outputs.isSet(direction), fuel.isSet(direction)); } public void setState(DirectionMask.Direction direction, IOState state) { inputs.set(direction, state.isIn()); outputs.set(direction, state.isOut()); + fuel.set(direction, state.isFuel()); + } + + public int getInputCount() { + return Integer.bitCount(inputs.getMask()); + } + + public int getOutputCount() { + return Integer.bitCount(outputs.getMask()); + } + + public int getFuelCount() { + return Integer.bitCount(fuel.getMask()); + } + + public int getTotalIOFCount() { + return getInputCount() + getOutputCount() + getFuelCount(); + } + + public boolean toggleInput(DirectionMask.Direction direction) { + boolean newState = !inputs.isSet(direction); + inputs.set(direction, newState); + return newState; + } + + public boolean isInput(DirectionMask.Direction direction) { + return inputs.isSet(direction); + } + + public boolean toggleOutput(DirectionMask.Direction direction) { + boolean newState = !outputs.isSet(direction); + outputs.set(direction, newState); + return newState; + } + + public boolean isOutput(DirectionMask.Direction direction) { + return outputs.isSet(direction); + } + + public boolean toggleFuel(DirectionMask.Direction direction) { + boolean newState = !fuel.isSet(direction); + fuel.set(direction, newState); + return newState; + } + + public boolean isFuel(DirectionMask.Direction direction) { + return fuel.isSet(direction); } public boolean hasInputs() { @@ -63,6 +112,21 @@ public List getOutputs(BlockFace front) { return bfList; } + public boolean hasFuel() { + return fuel.getMask() != 0; + } + + public List getFuel(BlockFace front) { + DirectionMask.Direction[] values = DirectionMask.Direction.values(); + List bfList = new ArrayList<>(values.length); + for (DirectionMask.Direction dir : values) { + if (fuel.isSet(dir)) { + bfList.add(dir.getBlockFacing(front)); + } + } + return bfList; + } + public IOState cycleDirection(DirectionMask.Direction direction, boolean backwards) { IOState cur = getState(direction); if (backwards) { @@ -72,29 +136,39 @@ public IOState cycleDirection(DirectionMask.Direction direction, boolean backwar } inputs.set(direction, cur.isIn()); outputs.set(direction, cur.isOut()); + fuel.set(direction, cur.isFuel()); return cur; } /** - * @return a compact serialized form of the input and output bitmasks (high 8 bits => in; low 8 bits => out) + * @return a compact serialized form of the fuel/in/out bitmasks (high 8 bits unused, 8 bits fuel, 8 bits input, low + * 8 bits output) */ - public short toShortMask() { - return (short) ((short) inputs.getMask() << 8 | (short) outputs.getMask()); + public int toIntMask() { + return inputs.getMask() << 8 | outputs.getMask(); } /** - * @param IShOrO compact serialized form of the input and output bitmasks (high 8 bits => in; low 8 bits => out) - * @return IOSelector with input and output masks set + * @param fioCombinedMask compact serialized form of the input, output, and fuel bitmasks (high 8 bits unused, 8 + * bits fuel, 8 bits input, low 8 bits output) + * @return IOSelector with input, output, and fuel masks set */ - public static IOSelector fromShortMask(short IShOrO) { - return new IOSelector((byte) (IShOrO >>> 8 & 0xFF), (byte) (IShOrO & 0xFF)); + public static IOSelector fromIntMask(int fioCombinedMask) { + return new IOSelector( + (byte) (fioCombinedMask >>> 8 & 0xFF), + (byte) (fioCombinedMask & 0xFF), + (byte) (fioCombinedMask >>> 16 & 0xFF)); } public enum IOState { - IGNORED(new ItemStack(Material.WHITE_WOOL), 0x808080), + IGNORED(new ItemStack(Material.GRAY_WOOL), 0x808080), INPUT(new ItemStack(Material.BLUE_WOOL), 0x4040FF), OUTPUT(new ItemStack(Material.RED_WOOL), 0xFF4040), - BOTH(new ItemStack(Material.PURPLE_WOOL), 0xFF40FF); + BOTH(new ItemStack(Material.PURPLE_WOOL), 0xFF40FF), + FUEL(new ItemStack(Material.LIGHT_GRAY_WOOL), 0xA0A0A0), + INPUT_FUEL(new ItemStack(Material.CYAN_WOOL), 0x8060FF), + OUTPUT_FUEL(new ItemStack(Material.PINK_WOOL), 0xFF6080), + BOTH_FUEL(new ItemStack(Material.MAGENTA_WOOL), 0xFF60FF); private final ItemStack uiVisual; public final int color; @@ -116,6 +190,10 @@ public boolean isOut() { return (ordinal() & 2) != 0; } + public boolean isFuel() { + return (ordinal() & 4) != 0; + } + public IOState next() { IOState[] values = values(); return values[(ordinal() + values.length + 1) % values.length]; @@ -126,8 +204,8 @@ public IOState last() { return values[(ordinal() + values.length + values.length - 1) % values.length]; } - public static IOState fromIO(boolean in, boolean out) { - return IOState.values()[(in ? 1 : 0) | (out ? 2 : 0)]; + public static IOState fromIO(boolean in, boolean out, boolean fuel) { + return IOState.values()[(in ? 1 : 0) | (out ? 2 : 0) | (fuel ? 4 : 0)]; } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index ee39aa00..829d2334 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -194,6 +194,13 @@ use_recipe_yamlidentifiers: false #How often factory data is saved automatically. Recommended value and default is 15 minutes. Set to -1 to disable saving_intervall: 15m +# Maximum number of input, output, fuel, and total IOF chests. If a chest is used for multiple settings, it is counted +# multiple times. +max_input_chests: 10 +max_output_chests: 10 +max_fuel_chests: 10 +max_iof_chests: 15 + #---------------------------------------------------------------------------------------------------------------------- #Factories From 4e87c1fdb5a8e30248828d5cc0311873af246478 Mon Sep 17 00:00:00 2001 From: caucow Date: Wed, 16 Jun 2021 12:22:17 -0500 Subject: [PATCH 15/21] Accommodate mid-version api compatibility change (come on paper ffs) --- .../igotyou/FactoryMod/utility/MultiInventoryWrapper.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java b/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java index e345a1c5..cedfe5ec 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java @@ -63,6 +63,14 @@ private int getInventoryIndex(int combinedSlot) { + " is outside the bounds of the multi-inventory"); } + @Override + public int close() { + List viewers = getViewers(); + int num = viewers.size(); + viewers.forEach(HumanEntity::closeInventory); + return num; + } + @Override public int getSize() { return size; From a15ace087ab1fe448180c121000867ad10282960 Mon Sep 17 00:00:00 2001 From: caucow Date: Thu, 19 Aug 2021 14:53:22 -0500 Subject: [PATCH 16/21] Kleen up and tone down civtastic civtistic code (re: Max's reviews) --- .../factories/FurnCraftChestFactory.java | 60 ++----- .../igotyou/FactoryMod/utility/Direction.java | 86 ++++++++++ .../FactoryMod/utility/DirectionMask.java | 120 ------------- .../FactoryMod/utility/FileHandler.java | 16 +- .../FactoryMod/utility/IOConfigSection.java | 18 +- .../FactoryMod/utility/IOSelector.java | 158 ++++++++++-------- .../utility/MultiInventoryWrapper.java | 2 +- 7 files changed, 211 insertions(+), 249 deletions(-) create mode 100644 src/main/java/com/github/igotyou/FactoryMod/utility/Direction.java delete mode 100644 src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java index 45efe786..b934d7bf 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java @@ -5,6 +5,7 @@ import com.github.igotyou.FactoryMod.events.RecipeExecuteEvent; import com.github.igotyou.FactoryMod.interactionManager.IInteractionManager; import com.github.igotyou.FactoryMod.powerManager.FurnacePowerManager; +import com.github.igotyou.FactoryMod.utility.Direction; import com.github.igotyou.FactoryMod.utility.IIOFInventoryProvider; import com.github.igotyou.FactoryMod.powerManager.IPowerManager; import com.github.igotyou.FactoryMod.recipes.IRecipe; @@ -16,7 +17,6 @@ import com.github.igotyou.FactoryMod.repairManager.IRepairManager; import com.github.igotyou.FactoryMod.repairManager.PercentageHealthRepairManager; import com.github.igotyou.FactoryMod.structures.FurnCraftChestStructure; -import com.github.igotyou.FactoryMod.utility.DirectionMask; import com.github.igotyou.FactoryMod.utility.IOSelector; import com.github.igotyou.FactoryMod.utility.LoggingUtils; import java.util.ArrayList; @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.function.Function; import com.github.igotyou.FactoryMod.utility.MultiInventoryWrapper; import org.bukkit.Bukkit; @@ -107,44 +108,14 @@ public Inventory getInventory() { } public Inventory getInputInventory() { - FurnCraftChestStructure fccs = (FurnCraftChestStructure) getMultiBlockStructure(); - ArrayList invs = new ArrayList<>(12); - Block fblock = getFurnace(); - BlockFace facing = getFacing(); - for (BlockFace relativeFace : getFurnaceIOSelector().getInputs(facing)) { - Block relBlock = fblock.getRelative(relativeFace); - if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { - invs.add(((Chest) relBlock.getState()).getInventory()); - } - } - Block tblock = fccs.getCraftingTable(); - for (BlockFace relativeFace : getTableIOSelector().getInputs(facing)) { - Block relBlock = tblock.getRelative(relativeFace); - if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { - invs.add(((Chest) relBlock.getState()).getInventory()); - } - } + List invs = new ArrayList<>(12); + getInventoriesForIoType(invs, iosel -> iosel::getInputs); return new MultiInventoryWrapper(invs); } public Inventory getOutputInventory() { - FurnCraftChestStructure fccs = (FurnCraftChestStructure) getMultiBlockStructure(); - ArrayList invs = new ArrayList<>(12); - Block fblock = getFurnace(); - BlockFace facing = getFacing(); - for (BlockFace relativeFace : getFurnaceIOSelector().getOutputs(facing)) { - Block relBlock = fblock.getRelative(relativeFace); - if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { - invs.add(((Chest) relBlock.getState()).getInventory()); - } - } - Block tblock = fccs.getCraftingTable(); - for (BlockFace relativeFace : getTableIOSelector().getOutputs(facing)) { - Block relBlock = tblock.getRelative(relativeFace); - if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { - invs.add(((Chest) relBlock.getState()).getInventory()); - } - } + List invs = new ArrayList<>(12); + getInventoriesForIoType(invs, iosel -> iosel::getOutputs); return new MultiInventoryWrapper(invs); } @@ -152,25 +123,30 @@ public Inventory getFuelInventory() { if (!getFurnaceIOSelector().hasFuel() && !getTableIOSelector().hasFuel()) { return getFurnaceInventory(); } - FurnCraftChestStructure fccs = (FurnCraftChestStructure) getMultiBlockStructure(); ArrayList invs = new ArrayList<>(13); + getInventoriesForIoType(invs, iosel -> iosel::getFuel); invs.add(getFurnaceInventory()); + return new MultiInventoryWrapper(invs); + } + + private void getInventoriesForIoType(List combinedInvList, + Function>> ioTypeFunc) { + FurnCraftChestStructure fccs = (FurnCraftChestStructure) getMultiBlockStructure(); Block fblock = getFurnace(); BlockFace facing = getFacing(); - for (BlockFace relativeFace : getFurnaceIOSelector().getFuel(facing)) { + for (BlockFace relativeFace : ioTypeFunc.apply(getFurnaceIOSelector()).apply(facing)) { Block relBlock = fblock.getRelative(relativeFace); if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { - invs.add(((Chest) relBlock.getState()).getInventory()); + combinedInvList.add(((Chest) relBlock.getState()).getInventory()); } } Block tblock = fccs.getCraftingTable(); - for (BlockFace relativeFace : getTableIOSelector().getFuel(facing)) { + for (BlockFace relativeFace : ioTypeFunc.apply(getTableIOSelector()).apply(facing)) { Block relBlock = tblock.getRelative(relativeFace); if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) { - invs.add(((Chest) relBlock.getState()).getInventory()); + combinedInvList.add(((Chest) relBlock.getState()).getInventory()); } } - return new MultiInventoryWrapper(invs); } @Override @@ -209,7 +185,7 @@ public IOSelector getTableIOSelector() { BlockFace front = getFacing(); BlockFace chestDir = getFurnace().getFace(getCraftingTable()); if (chestDir != null && front != null) { - DirectionMask.Direction defaultDir = DirectionMask.Direction.getDirection(front, chestDir); + Direction defaultDir = Direction.getDirection(front, chestDir); tableIoSelector.setState(defaultDir, IOSelector.IOState.BOTH); } } diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/Direction.java b/src/main/java/com/github/igotyou/FactoryMod/utility/Direction.java new file mode 100644 index 00000000..2d3e33ed --- /dev/null +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/Direction.java @@ -0,0 +1,86 @@ +package com.github.igotyou.FactoryMod.utility; + +import org.bukkit.block.BlockFace; + +import java.util.function.Function; + +/** + * @author caucow + */ +public enum Direction { + TOP(bf -> BlockFace.UP), // 1 + BOTTOM(bf -> BlockFace.DOWN), // 2 + LEFT(bf -> { + switch (bf) { + case NORTH: + return BlockFace.EAST; + case EAST: + return BlockFace.SOUTH; + case SOUTH: + return BlockFace.WEST; + case WEST: + return BlockFace.NORTH; + default: + return bf; + } + }), // 4 + RIGHT(bf -> { + switch (bf) { + case NORTH: + return BlockFace.WEST; + case EAST: + return BlockFace.NORTH; + case SOUTH: + return BlockFace.EAST; + case WEST: + return BlockFace.SOUTH; + default: + return bf; + } + }), // 8 + FRONT(bf -> bf), // 16 + BACK(BlockFace::getOppositeFace); // 32 + + private final Function facingModifier; + + private Direction(Function facingModifier) { + this.facingModifier = facingModifier; + } + + /** + * @param front direction a block (such as a furnace) is facing. + * @return BlockFace in this direction, relative to the player's perspective when the player and block are + * facing each other. + */ + public BlockFace getBlockFacing(BlockFace front) { + return facingModifier.apply(front); + } + + public static Direction getDirection(BlockFace front, BlockFace axis) { + for (Direction dir : Direction.values()) { + // if dir's transformation of front == axis + if (dir.getBlockFacing(front) == axis) { + return dir; + } + } + throw new IllegalArgumentException("Direction can only be gotten from an axis-aligned BlockFace."); + } + + private static BlockFace getBlockFaceFromDirection(int dirx, int dirz) { + switch (dirz) { + case 1: + return BlockFace.SOUTH; + case -1: + return BlockFace.NORTH; + case 0: { + switch (dirx) { + case 1: + return BlockFace.EAST; + case -1: + return BlockFace.WEST; + } + } + } + throw new IllegalArgumentException("Not a horizontal ordinal: (" + dirx + "," + dirz + ")"); + } +} diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java b/src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java deleted file mode 100644 index 03b8c300..00000000 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/DirectionMask.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.github.igotyou.FactoryMod.utility; - -import org.bukkit.block.BlockFace; - -import java.util.function.Function; - -/** - * @author caucow - */ -public class DirectionMask { - - private byte mask; - - public DirectionMask(Direction... dirs) { - for (Direction dir : dirs) { - set(dir, true); - } - } - - public DirectionMask(byte mask) { - this.mask = mask; - } - - public void set(Direction dir, boolean set) { - if (set) { - mask |= dir.dmask; - } else { - mask &= ~dir.dmask; - } - } - - public boolean isSet(Direction dir) { - return (mask & dir.dmask) != 0; - } - - public byte getMask() { - return mask; - } - - public enum Direction { - TOP((byte) 0b0000_0001, bf -> BlockFace.UP), // 1 - BOTTOM((byte) 0b0000_0010, bf -> BlockFace.DOWN), // 2 - LEFT((byte) 0b0000_0100, bf -> { - switch (bf) { - case NORTH: - return BlockFace.EAST; - case EAST: - return BlockFace.SOUTH; - case SOUTH: - return BlockFace.WEST; - case WEST: - return BlockFace.NORTH; - default: - return bf; - } - }), // 4 - RIGHT((byte) 0b0000_1000, bf -> { - switch (bf) { - case NORTH: - return BlockFace.WEST; - case EAST: - return BlockFace.NORTH; - case SOUTH: - return BlockFace.EAST; - case WEST: - return BlockFace.SOUTH; - default: - return bf; - } - }), // 8 - FRONT((byte) 0b0001_0000, bf -> bf), // 16 - BACK((byte) 0b0010_0000, BlockFace::getOppositeFace); // 32 - - public final byte dmask; - private final Function facingModifier; - - private Direction(byte dmask, Function facingModifier) { - this.dmask = dmask; - this.facingModifier = facingModifier; - } - - /** - * @param front direction a block (such as a furnace) is facing. - * @return BlockFace in this direction, relative to the player's perspective when the player and block are - * facing each other. - */ - public BlockFace getBlockFacing(BlockFace front) { - return facingModifier.apply(front); - } - - public static Direction getDirection(BlockFace front, BlockFace axis) { - for (Direction dir : Direction.values()) { - // if dir's transformation of front == axis - if (dir.getBlockFacing(front) == axis) { - return dir; - } - } - throw new IllegalArgumentException("Direction can only be gotten from an axis-aligned BlockFace."); - } - - private static BlockFace getBlockFaceFromDirection(int dirx, int dirz) { - switch (dirz) { - case 1: - return BlockFace.SOUTH; - case -1: - return BlockFace.NORTH; - case 0: { - switch (dirx) { - case 1: - return BlockFace.EAST; - case -1: - return BlockFace.WEST; - } - } - } - throw new IllegalArgumentException("Not a horizontal ordinal: (" + dirx + "," + dirz + ")"); - } - } - -} diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java index 7d4419bf..8c4a11da 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java @@ -99,8 +99,8 @@ public void save(Collection factories) { config.set(current + ".runcounts." + i.getName(), fccf.getRunCount(i)); config.set(current + ".recipeLevels." + i.getName(), fccf.getRecipeLevel(i)); } - config.set(current + ".furnace-io-mask", fccf.getFurnaceIOSelector().toIntMask()); - config.set(current + ".table-io-mask", fccf.getTableIOSelector().toIntMask()); + config.set(current + ".furnace-io", fccf.getFurnaceIOSelector().toConfigSection()); + config.set(current + ".table-io", fccf.getTableIOSelector().toConfigSection()); config.set(current + ".ui-menu-mode", fccf.getUiMenuMode().name()); } else if (f instanceof Pipe) { Pipe p = (Pipe) f; @@ -298,16 +298,16 @@ private void loadFromFile(File f, Map eggs) { } fac.setAutoSelect(autoSelect); { - int mask = current.getInt("furnace-io-mask", -1); - if (mask != -1) { - IOSelector furnaceIoSelector = IOSelector.fromIntMask(mask); + ConfigurationSection iosec = current.getConfigurationSection("furnace-io"); + if (iosec != null) { + IOSelector furnaceIoSelector = IOSelector.fromConfigSection(iosec); fac.setFurnaceIOSelector(furnaceIoSelector); } else { // Nothing I guess, the furnace has no default state. } - mask = current.getInt("table-io-mask", -1); - if (mask != -1) { - IOSelector tableIoSelector = IOSelector.fromIntMask(mask); + iosec = current.getConfigurationSection("table-io"); + if (iosec != null) { + IOSelector tableIoSelector = IOSelector.fromConfigSection(iosec); fac.setTableIOSelector(tableIoSelector); } else { // Default table-side IO moved to FCCF.getTableIoSelector() lazy init diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java index 13cf035e..b6842a34 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java @@ -49,18 +49,18 @@ public IOConfigSection(Player viewer, IOSelector ioSelector, Material centerDisp private Clickable getIoButton(BlockFace dir) { Block relativeBlock = centerBlock.getRelative(dir); Material type = relativeBlock.getType(); - DirectionMask.Direction relativeDir = DirectionMask.Direction.getDirection(front, dir); + Direction relativeDir = Direction.getDirection(front, dir); return getIoClickable(type, relativeDir, dir.name()); } - private Clickable getIoButton(DirectionMask.Direction dir) { + private Clickable getIoButton(Direction dir) { BlockFace relativeDir = dir.getBlockFacing(front); Block relativeBlock = centerBlock.getRelative(relativeDir); Material type = relativeBlock.getType(); return getIoClickable(type, dir, dir.name()); } - private Clickable getIoClickable(Material adjacentType, DirectionMask.Direction dir, String dirLabel) { + private Clickable getIoClickable(Material adjacentType, Direction dir, String dirLabel) { IOSelector.IOState dirState = ioSelector.getState(dir); boolean hasChest = adjacentType != Material.CHEST && adjacentType != Material.TRAPPED_CHEST; ItemStack display; @@ -172,12 +172,12 @@ protected void rebuild() { ioDirectionMode = FactoryMod.getInstance().getManager().getPlayerSettings().getIoDirectionMode(viewerId); switch (ioDirectionMode) { case VISUAL_RELATIVE: { - set(getIoButton(DirectionMask.Direction.TOP), 1); - set(getIoButton(DirectionMask.Direction.FRONT), 2); - set(getIoButton(DirectionMask.Direction.LEFT), 3); - set(getIoButton(DirectionMask.Direction.RIGHT), 5); - set(getIoButton(DirectionMask.Direction.BOTTOM), 7); - set(getIoButton(DirectionMask.Direction.BACK), 8); + set(getIoButton(Direction.TOP), 1); + set(getIoButton(Direction.FRONT), 2); + set(getIoButton(Direction.LEFT), 3); + set(getIoButton(Direction.RIGHT), 5); + set(getIoButton(Direction.BOTTOM), 7); + set(getIoButton(Direction.BACK), 8); break; } case CARDINAL: { diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java index 0ba579be..306c0cb9 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java @@ -2,95 +2,122 @@ import org.bukkit.Material; import org.bukkit.block.BlockFace; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.inventory.ItemStack; import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumSet; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; /** * @author caucow */ public class IOSelector { - private final DirectionMask inputs; - private final DirectionMask outputs; - private final DirectionMask fuel; + private final EnumSet inputs; + private final EnumSet outputs; + private final EnumSet fuel; - public IOSelector(byte inMask, byte outMask, byte fuel) { - this.inputs = new DirectionMask(inMask); - this.outputs = new DirectionMask(outMask); - this.fuel = new DirectionMask(fuel); + public IOSelector(Collection inMask, Collection outMask, Collection fuel) { + this(); + this.inputs.addAll(inMask); + this.outputs.addAll(outMask); + this.fuel.addAll(fuel); } public IOSelector() { - this((byte) 0, (byte) 0, (byte) 0); + this.inputs = EnumSet.noneOf(Direction.class); + this.outputs = EnumSet.noneOf(Direction.class); + this.fuel = EnumSet.noneOf(Direction.class); } - public IOState getState(DirectionMask.Direction direction) { - return IOState.fromIO(inputs.isSet(direction), outputs.isSet(direction), fuel.isSet(direction)); + public IOState getState(Direction direction) { + return IOState.fromIO(inputs.contains(direction), outputs.contains(direction), fuel.contains(direction)); } - public void setState(DirectionMask.Direction direction, IOState state) { - inputs.set(direction, state.isIn()); - outputs.set(direction, state.isOut()); - fuel.set(direction, state.isFuel()); + public void setState(Direction direction, IOState state) { + if (state.isIn()) { + inputs.add(direction); + } else { + inputs.remove(direction); + } + if (state.isOut()) { + outputs.add(direction); + } else { + outputs.remove(direction); + } + if (state.isFuel()) { + fuel.add(direction); + } else { + fuel.remove(direction); + } } public int getInputCount() { - return Integer.bitCount(inputs.getMask()); + return inputs.size(); } public int getOutputCount() { - return Integer.bitCount(outputs.getMask()); + return outputs.size(); } public int getFuelCount() { - return Integer.bitCount(fuel.getMask()); + return fuel.size(); } public int getTotalIOFCount() { return getInputCount() + getOutputCount() + getFuelCount(); } - public boolean toggleInput(DirectionMask.Direction direction) { - boolean newState = !inputs.isSet(direction); - inputs.set(direction, newState); - return newState; + public boolean toggleInput(Direction direction) { + boolean added = inputs.add(direction); + if (!added) { + inputs.remove(direction); + } + return added; } - public boolean isInput(DirectionMask.Direction direction) { - return inputs.isSet(direction); + public boolean isInput(Direction direction) { + return inputs.contains(direction); } - public boolean toggleOutput(DirectionMask.Direction direction) { - boolean newState = !outputs.isSet(direction); - outputs.set(direction, newState); - return newState; + public boolean toggleOutput(Direction direction) { + boolean added = outputs.add(direction); + if (!added) { + outputs.remove(direction); + } + return added; } - public boolean isOutput(DirectionMask.Direction direction) { - return outputs.isSet(direction); + public boolean isOutput(Direction direction) { + return outputs.contains(direction); } - public boolean toggleFuel(DirectionMask.Direction direction) { - boolean newState = !fuel.isSet(direction); - fuel.set(direction, newState); - return newState; + public boolean toggleFuel(Direction direction) { + boolean added = fuel.add(direction); + if (!added) { + fuel.remove(direction); + } + return added; } - public boolean isFuel(DirectionMask.Direction direction) { - return fuel.isSet(direction); + public boolean isFuel(Direction direction) { + return fuel.contains(direction); } public boolean hasInputs() { - return inputs.getMask() != 0; + return !inputs.isEmpty(); } public List getInputs(BlockFace front) { - DirectionMask.Direction[] values = DirectionMask.Direction.values(); + Direction[] values = Direction.values(); List bfList = new ArrayList<>(values.length); - for (DirectionMask.Direction dir : values) { - if (inputs.isSet(dir)) { + for (Direction dir : values) { + if (inputs.contains(dir)) { bfList.add(dir.getBlockFacing(front)); } } @@ -98,14 +125,14 @@ public List getInputs(BlockFace front) { } public boolean hasOutputs() { - return outputs.getMask() != 0; + return !outputs.isEmpty(); } public List getOutputs(BlockFace front) { - DirectionMask.Direction[] values = DirectionMask.Direction.values(); + Direction[] values = Direction.values(); List bfList = new ArrayList<>(values.length); - for (DirectionMask.Direction dir : values) { - if (outputs.isSet(dir)) { + for (Direction dir : values) { + if (outputs.contains(dir)) { bfList.add(dir.getBlockFacing(front)); } } @@ -113,51 +140,44 @@ public List getOutputs(BlockFace front) { } public boolean hasFuel() { - return fuel.getMask() != 0; + return !fuel.isEmpty(); } public List getFuel(BlockFace front) { - DirectionMask.Direction[] values = DirectionMask.Direction.values(); + Direction[] values = Direction.values(); List bfList = new ArrayList<>(values.length); - for (DirectionMask.Direction dir : values) { - if (fuel.isSet(dir)) { + for (Direction dir : values) { + if (fuel.contains(dir)) { bfList.add(dir.getBlockFacing(front)); } } return bfList; } - public IOState cycleDirection(DirectionMask.Direction direction, boolean backwards) { + public IOState cycleDirection(Direction direction, boolean backwards) { IOState cur = getState(direction); if (backwards) { cur = cur.last(); } else { cur = cur.next(); } - inputs.set(direction, cur.isIn()); - outputs.set(direction, cur.isOut()); - fuel.set(direction, cur.isFuel()); + setState(direction, cur); return cur; } - /** - * @return a compact serialized form of the fuel/in/out bitmasks (high 8 bits unused, 8 bits fuel, 8 bits input, low - * 8 bits output) - */ - public int toIntMask() { - return inputs.getMask() << 8 | outputs.getMask(); - } - - /** - * @param fioCombinedMask compact serialized form of the input, output, and fuel bitmasks (high 8 bits unused, 8 - * bits fuel, 8 bits input, low 8 bits output) - * @return IOSelector with input, output, and fuel masks set - */ - public static IOSelector fromIntMask(int fioCombinedMask) { - return new IOSelector( - (byte) (fioCombinedMask >>> 8 & 0xFF), - (byte) (fioCombinedMask & 0xFF), - (byte) (fioCombinedMask >>> 16 & 0xFF)); + public ConfigurationSection toConfigSection() { + ConfigurationSection sec = new YamlConfiguration(); + sec.set("in", inputs.stream().map(Enum::name).collect(Collectors.toList())); + sec.set("out", outputs.stream().map(Enum::name).collect(Collectors.toList())); + sec.set("fuel", fuel.stream().map(Enum::name).collect(Collectors.toList())); + return sec; + } + + public static IOSelector fromConfigSection(ConfigurationSection conf) { + List inList = conf.getStringList("in").stream().map(Direction::valueOf).collect(Collectors.toList()); + List outList = conf.getStringList("out").stream().map(Direction::valueOf).collect(Collectors.toList()); + List fuelList = conf.getStringList("fuel").stream().map(Direction::valueOf).collect(Collectors.toList()); + return new IOSelector(inList, outList, fuelList); } public enum IOState { diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java b/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java index cedfe5ec..272fb1f8 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java @@ -33,7 +33,7 @@ public MultiInventoryWrapper(Inventory... wrapped) { this(new ArrayList<>(Arrays.asList(wrapped))); } - public MultiInventoryWrapper(ArrayList wrapped) { + public MultiInventoryWrapper(List wrapped) { Inventory[] wrappedArr = uniquify(wrapped); this.wrapped = wrappedArr; int lsize = 0; From a6d51f6cf2aad8a7caa6f01e7f559e6ab3fd8115 Mon Sep 17 00:00:00 2001 From: caucow Date: Thu, 19 Aug 2021 20:23:13 -0500 Subject: [PATCH 17/21] Fixes for potential fuel bug that hasn't presented yet --- .../igotyou/FactoryMod/powerManager/FurnacePowerManager.java | 5 ++++- .../igotyou/FactoryMod/utility/MultiInventoryWrapper.java | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/powerManager/FurnacePowerManager.java b/src/main/java/com/github/igotyou/FactoryMod/powerManager/FurnacePowerManager.java index b4c90e2e..cb7594b4 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/powerManager/FurnacePowerManager.java +++ b/src/main/java/com/github/igotyou/FactoryMod/powerManager/FurnacePowerManager.java @@ -84,7 +84,10 @@ public void consumePower(int fuelCount) { if (iofProvider != null) { Inventory fuelInv = iofProvider.getFuelInventory(); if (fuelInv != null) { - fuelInv.removeItem(fuel); + for (int i = 0; i < fuelCount; i++) { + fuelInv.removeItem(fuel); + } + return; } } diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java b/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java index 272fb1f8..3c6262bf 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java @@ -119,6 +119,9 @@ public void setItem(int i, @Nullable ItemStack itemStack) { HashMap result = null; for (int invi = 0; invi < wrapped.length; invi++) { result = wrapped[invi].removeItem(itemStacks); + if (result.isEmpty()) { + break; + } itemStacks = new ItemStack[result.size()]; int itemi = 0; Iterator> eit = result.entrySet().iterator(); From 2e24bc1d926669500d50f7463014ab4be485aa4f Mon Sep 17 00:00:00 2001 From: caucow Date: Thu, 19 Aug 2021 20:47:11 -0500 Subject: [PATCH 18/21] Fix furnace fuel level being reset a tick after consumption --- .../java/com/github/igotyou/FactoryMod/factories/Factory.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java index aa4da85a..9376974a 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java @@ -124,9 +124,9 @@ public void turnFurnaceOn(Block f) { if (f.getType() != Material.FURNACE) { return; } - Furnace furnace = (Furnace) f.getState(); Bukkit.getScheduler().runTask(FactoryMod.getInstance(), () -> { if (this.isActive()) { + Furnace furnace = (Furnace) f.getState(); furnace.setBurnTime(Short.MAX_VALUE); furnace.update(); } @@ -141,9 +141,9 @@ public void turnFurnaceOff(Block f) { if (f.getType() != Material.FURNACE) { return; } - Furnace furnace = (Furnace) f.getState(); Bukkit.getScheduler().runTask(FactoryMod.getInstance(), () -> { if (!this.isActive()) { + Furnace furnace = (Furnace) f.getState(); furnace.setBurnTime((short) 0); furnace.update(); } From 0f6a1e8d4f6d598bcccb47eb43a5916d3b129ce7 Mon Sep 17 00:00:00 2001 From: caucow Date: Thu, 19 Aug 2021 20:48:40 -0500 Subject: [PATCH 19/21] Fix scheduler exception when disabling furnaces while disabling plugin --- .../igotyou/FactoryMod/factories/Factory.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java index 9376974a..b15875a1 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java @@ -141,12 +141,19 @@ public void turnFurnaceOff(Block f) { if (f.getType() != Material.FURNACE) { return; } - Bukkit.getScheduler().runTask(FactoryMod.getInstance(), () -> { - if (!this.isActive()) { - Furnace furnace = (Furnace) f.getState(); - furnace.setBurnTime((short) 0); - furnace.update(); - } - }); + FactoryMod fmPlugin = FactoryMod.getInstance(); + if (fmPlugin.isEnabled()) { + Bukkit.getScheduler().runTask(FactoryMod.getInstance(), () -> { + if (!this.isActive()) { + Furnace furnace = (Furnace) f.getState(); + furnace.setBurnTime((short) 0); + furnace.update(); + } + }); + } else if (!this.isActive()) { + Furnace furnace = (Furnace) f.getState(); + furnace.setBurnTime((short) 0); + furnace.update(); + } } } From 72801df699521d4a77fdae52cbc5103130e25d85 Mon Sep 17 00:00:00 2001 From: caucow Date: Fri, 20 Aug 2021 12:25:28 -0500 Subject: [PATCH 20/21] Bug fixes and code cleanup (see desc) - Make text in ioconfig screen more clear and noticeable - Barriers for missing chests pop back after configuring - Fix for factories not auto-selecting a new recipe if ingredients run out mid-run - Fix for async-block-access on factory save - General minor code cleanup and renaming --- .../igotyou/FactoryMod/FactoryModManager.java | 2 ++ .../factories/FurnCraftChestFactory.java | 20 +++++++++---- .../listeners/FactoryModListener.java | 26 ++++++++-------- .../FactoryMod/utility/IOConfigSection.java | 30 ++++++++++++++----- .../FactoryMod/utility/IOSelector.java | 23 +++++++------- 5 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java b/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java index bcfbebc5..50cc6776 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java +++ b/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java @@ -270,6 +270,8 @@ public void attemptCreation(Block b, Player p) { if (egg != null) { Factory f = egg.hatch(fccs, p); if (f != null) { + // Trigger lazy-initialize default crafting table IOSelector + ((FurnCraftChestFactory)f).getTableIOSelector(); ((Chest) (fccs.getChest().getState())).getInventory().clear(); addFactory(f); p.sendMessage(ChatColor.GREEN + "Successfully created " + f.getName()); diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java index b934d7bf..7edf6591 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java @@ -151,17 +151,20 @@ private void getInventoriesForIoType(List combinedInvList, @Override public int getInputCount() { - return furnaceIoSelector.getInputCount() + tableIoSelector.getInputCount(); + return (furnaceIoSelector == null ? 0 : furnaceIoSelector.getInputCount()) + + (tableIoSelector == null ? 0 : tableIoSelector.getInputCount()); } @Override public int getOutputCount() { - return furnaceIoSelector.getOutputCount() + tableIoSelector.getOutputCount(); + return (furnaceIoSelector == null ? 0 : furnaceIoSelector.getOutputCount()) + + (tableIoSelector == null ? 0 : tableIoSelector.getOutputCount()); } @Override public int getFuelCount() { - return furnaceIoSelector.getFuelCount() + tableIoSelector.getFuelCount(); + return (furnaceIoSelector == null ? 0 : furnaceIoSelector.getFuelCount()) + + (tableIoSelector == null ? 0 : tableIoSelector.getFuelCount()); } public void setFurnaceIOSelector(IOSelector ioSelector) { @@ -210,8 +213,7 @@ public UiMenuMode getUiMenuMode() { } Furnace fstate = (Furnace) fblock.getState(); org.bukkit.block.data.type.Furnace fdata = (org.bukkit.block.data.type.Furnace) fstate.getBlockData(); - BlockFace facing = fdata.getFacing(); - return facing; + return fdata.getFacing(); } /** @@ -530,6 +532,14 @@ public void run() { deactivate(); } } + } else if (isAutoSelect()) { + IRecipe nextOne = getAutoSelectRecipe(); + if (nextOne != null) { + sendActivatorMessage(ChatColor.GREEN + name + " automatically switched to recipe " + nextOne.getName() + " and began running it"); + currentRecipe = nextOne; + scheduleUpdate(); + } + // don't setPowerCounter to 0, fuel has been consumed, let it be used for the new recipe } else { sendActivatorMessage(ChatColor.GOLD + name + " deactivated, because it ran out of required materials"); deactivate(); diff --git a/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java b/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java index 5fdb7f4d..d278663c 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java +++ b/src/main/java/com/github/igotyou/FactoryMod/listeners/FactoryModListener.java @@ -120,29 +120,29 @@ public void burnListener(BlockBurnEvent e) { } @EventHandler - public void playerInteract(PlayerInteractEvent e) { - Block block = e.getClickedBlock(); - Player player = e.getPlayer(); + public void playerInteract(PlayerInteractEvent evt) { + Block block = evt.getClickedBlock(); + Player player = evt.getPlayer(); if (block != null && manager.isPossibleInteractionBlock(block.getType())) { - BlockFace bf = e.getBlockFace(); - Factory c = manager.getFactoryAt(block); - if (e.getAction() == Action.RIGHT_CLICK_BLOCK) { - if (c != null) { - c.getInteractionManager().rightClick(player, block, bf); + BlockFace blockFace = evt.getBlockFace(); + Factory factory = manager.getFactoryAt(block); + if (evt.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (factory != null) { + factory.getInteractionManager().rightClick(player, block, blockFace); } else { // check if chest is other half of double chest if (block.getType() == Material.CHEST || block.getType() == Material.TRAPPED_CHEST) { for (Block b : MultiBlockStructure.searchForBlockOnSides(block, block.getType())) { Factory f = manager.getFactoryAt(b); if (f != null) { - f.getInteractionManager().rightClick(player, b, bf); + f.getInteractionManager().rightClick(player, b, blockFace); } } } } } - if (e.getAction() == Action.LEFT_CLICK_BLOCK) { - if (c == null) { + if (evt.getAction() == Action.LEFT_CLICK_BLOCK) { + if (factory == null) { if (manager.isPossibleCenterBlock(block.getType())) { if (player.getInventory().getItemInMainHand().getType() == manager .getFactoryInteractionMaterial()) { @@ -154,13 +154,13 @@ public void playerInteract(PlayerInteractEvent e) { for (Block b : MultiBlockStructure.searchForBlockOnAllSides(block, block.getType())) { Factory f = manager.getFactoryAt(b); if (f != null) { - f.getInteractionManager().leftClick(player, b, bf); + f.getInteractionManager().leftClick(player, b, blockFace); } } } } } else { - c.getInteractionManager().leftClick(player, block, bf); + factory.getInteractionManager().leftClick(player, block, blockFace); } } diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java index b6842a34..7c41c447 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java @@ -7,12 +7,14 @@ import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitTask; import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; import vg.civcraft.mc.civmodcore.inventorygui.Clickable; import vg.civcraft.mc.civmodcore.inventorygui.ClickableInventory; @@ -62,9 +64,9 @@ private Clickable getIoButton(Direction dir) { private Clickable getIoClickable(Material adjacentType, Direction dir, String dirLabel) { IOSelector.IOState dirState = ioSelector.getState(dir); - boolean hasChest = adjacentType != Material.CHEST && adjacentType != Material.TRAPPED_CHEST; + boolean chestMissing = adjacentType != Material.CHEST && adjacentType != Material.TRAPPED_CHEST; ItemStack display; - if (hasChest) { + if (chestMissing) { display = new ItemStack(Material.BARRIER); ItemUtils.addComponentLore(display, Component .text("") @@ -75,23 +77,25 @@ private Clickable getIoClickable(Material adjacentType, Direction dir, String di } if (ioDirectionMode != null) { for (String descLine : ioDirectionMode.fullDescription) { - ItemUtils.addComponentLore(display, Component - .text(descLine) - .color(TextColor.color(255, 255, 192))); + ItemUtils.addComponentLore(display, + Component.text(descLine).color(TextColor.color(255, 255, 192))); } } ItemUtils.setComponentDisplayName(display, Component.text("\u00a7r") .append(Component.text(dirLabel).color(TextColor.color(192, 192, 192))) .append(Component.text(": ")) - .append(Component.text(dirState.name()).color(TextColor.color(dirState.color))) + .append(Component.text(dirState.displayName).color(TextColor.color(dirState.color))) .asComponent()); ItemUtils.addComponentLore(display, - Component.text("L/M/R click to toggle I/F/O").color(TextColor.color(192, 192, 192))); + Component.text("L/M/R click to toggle I/F/O") + .style(Style.style(TextDecoration.BOLD)) + .color(TextColor.color(255, 255, 255))); FactoryModManager fmMgr = FactoryMod.getInstance().getManager(); return new Clickable(display) { private ClickableInventory inventory; private int slot; + private BukkitTask reBarrierTask; @Override protected void clicked(Player player) { @@ -158,11 +162,21 @@ private void updateItem() { Component.text("\u00a7r") .append(Component.text(dirLabel).color(TextColor.color(192, 192, 192))) .append(Component.text(": ")) - .append(Component.text(newState.name()).color(TextColor.color(newState.color))) + .append(Component.text(newState.displayName).color(TextColor.color(newState.color))) .asComponent()); if (inventory != null && inventory.getSlot(slot) == this) { inventory.setSlot(this, slot); } + if (chestMissing) { + if (reBarrierTask != null) { + reBarrierTask.cancel(); + } + reBarrierTask = Bukkit.getScheduler().runTaskLater(FactoryMod.getInstance(), () -> { + getItemStack().setType(Material.BARRIER); + inventory.setSlot(this, slot); + reBarrierTask = null; + }, 20); + } } }; } diff --git a/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java b/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java index 306c0cb9..c8148b24 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java +++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java @@ -10,7 +10,6 @@ import java.util.Collection; import java.util.EnumSet; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; /** @@ -181,19 +180,21 @@ public static IOSelector fromConfigSection(ConfigurationSection conf) { } public enum IOState { - IGNORED(new ItemStack(Material.GRAY_WOOL), 0x808080), - INPUT(new ItemStack(Material.BLUE_WOOL), 0x4040FF), - OUTPUT(new ItemStack(Material.RED_WOOL), 0xFF4040), - BOTH(new ItemStack(Material.PURPLE_WOOL), 0xFF40FF), - FUEL(new ItemStack(Material.LIGHT_GRAY_WOOL), 0xA0A0A0), - INPUT_FUEL(new ItemStack(Material.CYAN_WOOL), 0x8060FF), - OUTPUT_FUEL(new ItemStack(Material.PINK_WOOL), 0xFF6080), - BOTH_FUEL(new ItemStack(Material.MAGENTA_WOOL), 0xFF60FF); - + IGNORED("Ignored", new ItemStack(Material.GRAY_WOOL), 0x808080), + INPUT("Input", new ItemStack(Material.BLUE_WOOL), 0x4040FF), + OUTPUT("Output", new ItemStack(Material.RED_WOOL), 0xFF4040), + BOTH("Input+Output", new ItemStack(Material.PURPLE_WOOL), 0xFF40FF), + FUEL("Fuel", new ItemStack(Material.LIGHT_GRAY_WOOL), 0xA0A0A0), + INPUT_FUEL("Input+Fuel", new ItemStack(Material.CYAN_WOOL), 0x8060FF), + OUTPUT_FUEL("Output+Fuel", new ItemStack(Material.PINK_WOOL), 0xFF6080), + BOTH_FUEL("Input+Output+Fuel", new ItemStack(Material.MAGENTA_WOOL), 0xFF60FF); + + public final String displayName; private final ItemStack uiVisual; public final int color; - private IOState(ItemStack uiVisual, int color) { + IOState(String displayName, ItemStack uiVisual, int color) { + this.displayName = displayName; this.uiVisual = uiVisual; this.color = color; } From 2bd4f3ea3abe3c3bb18b268dc630ad94f04f41ec Mon Sep 17 00:00:00 2001 From: caucow Date: Sat, 21 Aug 2021 13:59:18 -0500 Subject: [PATCH 21/21] FIx fix for autoselect not disabling factories --- .../factories/FurnCraftChestFactory.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java index 7edf6591..0a6ec007 100644 --- a/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java +++ b/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java @@ -532,17 +532,17 @@ public void run() { deactivate(); } } - } else if (isAutoSelect()) { - IRecipe nextOne = getAutoSelectRecipe(); - if (nextOne != null) { + } else { + IRecipe nextOne; + if (isAutoSelect() && (nextOne = getAutoSelectRecipe()) != null) { sendActivatorMessage(ChatColor.GREEN + name + " automatically switched to recipe " + nextOne.getName() + " and began running it"); currentRecipe = nextOne; scheduleUpdate(); + // don't setPowerCounter to 0, fuel has been consumed, let it be used for the new recipe + } else { + sendActivatorMessage(ChatColor.GOLD + name + " deactivated, because it ran out of required materials"); + deactivate(); } - // don't setPowerCounter to 0, fuel has been consumed, let it be used for the new recipe - } else { - sendActivatorMessage(ChatColor.GOLD + name + " deactivated, because it ran out of required materials"); - deactivate(); } } else { sendActivatorMessage(ChatColor.GOLD + name + " deactivated, because the factory was destroyed");