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
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 ab631abe..50cc6776 100644
--- a/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java
+++ b/src/main/java/com/github/igotyou/FactoryMod/FactoryModManager.java
@@ -53,17 +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<>();
@@ -76,6 +86,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);
@@ -149,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
*/
@@ -239,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());
@@ -545,4 +578,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/factories/Factory.java b/src/main/java/com/github/igotyou/FactoryMod/factories/Factory.java
index 1742f6cd..b15875a1 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;
@@ -123,9 +124,13 @@ public void turnFurnaceOn(Block f) {
if (f.getType() != Material.FURNACE) {
return;
}
- Furnace furnace = (Furnace) f.getState();
- furnace.setBurnTime(Short.MAX_VALUE);
- furnace.update();
+ Bukkit.getScheduler().runTask(FactoryMod.getInstance(), () -> {
+ if (this.isActive()) {
+ Furnace furnace = (Furnace) f.getState();
+ furnace.setBurnTime(Short.MAX_VALUE);
+ furnace.update();
+ }
+ });
}
public String getLogData() {
@@ -136,8 +141,19 @@ public void turnFurnaceOff(Block f) {
if (f.getType() != Material.FURNACE) {
return;
}
- 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();
+ }
}
}
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..0a6ec007 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,8 @@
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;
import com.github.igotyou.FactoryMod.recipes.InputRecipe;
@@ -15,6 +17,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,16 +25,21 @@
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;
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;
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;
@@ -44,7 +52,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;
@@ -53,6 +61,9 @@ public class FurnCraftChestFactory extends Factory {
private UUID activator;
private double citadelBreakReduction;
private boolean autoSelect;
+ private @Nullable IOSelector furnaceIoSelector;
+ private @Nullable IOSelector tableIoSelector;
+ private UiMenuMode uiMenuMode;
private static HashSet pylonFactories;
@@ -60,12 +71,16 @@ 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;
+ this.uiMenuMode = UiMenuMode.SIMPLE;
for (IRecipe rec : recipes) {
addRecipe(rec);
}
@@ -92,6 +107,115 @@ public Inventory getInventory() {
return chestBlock.getInventory();
}
+ public Inventory getInputInventory() {
+ List invs = new ArrayList<>(12);
+ getInventoriesForIoType(invs, iosel -> iosel::getInputs);
+ return new MultiInventoryWrapper(invs);
+ }
+
+ public Inventory getOutputInventory() {
+ List invs = new ArrayList<>(12);
+ getInventoriesForIoType(invs, iosel -> iosel::getOutputs);
+ return new MultiInventoryWrapper(invs);
+ }
+
+ public Inventory getFuelInventory() {
+ if (!getFurnaceIOSelector().hasFuel() && !getTableIOSelector().hasFuel()) {
+ return getFurnaceInventory();
+ }
+ 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 : ioTypeFunc.apply(getFurnaceIOSelector()).apply(facing)) {
+ Block relBlock = fblock.getRelative(relativeFace);
+ if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) {
+ combinedInvList.add(((Chest) relBlock.getState()).getInventory());
+ }
+ }
+ Block tblock = fccs.getCraftingTable();
+ for (BlockFace relativeFace : ioTypeFunc.apply(getTableIOSelector()).apply(facing)) {
+ Block relBlock = tblock.getRelative(relativeFace);
+ if (relBlock.getType() == Material.CHEST || relBlock.getType() == Material.TRAPPED_CHEST) {
+ combinedInvList.add(((Chest) relBlock.getState()).getInventory());
+ }
+ }
+ }
+
+ @Override
+ public int getInputCount() {
+ return (furnaceIoSelector == null ? 0 : furnaceIoSelector.getInputCount())
+ + (tableIoSelector == null ? 0 : tableIoSelector.getInputCount());
+ }
+
+ @Override
+ public int getOutputCount() {
+ return (furnaceIoSelector == null ? 0 : furnaceIoSelector.getOutputCount())
+ + (tableIoSelector == null ? 0 : tableIoSelector.getOutputCount());
+ }
+
+ @Override
+ public int getFuelCount() {
+ return (furnaceIoSelector == null ? 0 : furnaceIoSelector.getFuelCount())
+ + (tableIoSelector == null ? 0 : tableIoSelector.getFuelCount());
+ }
+
+ public void setFurnaceIOSelector(IOSelector ioSelector) {
+ this.furnaceIoSelector = ioSelector;
+ }
+
+ public IOSelector getFurnaceIOSelector() {
+ if (furnaceIoSelector == null) {
+ furnaceIoSelector = new IOSelector();
+ }
+ return furnaceIoSelector;
+ }
+
+ public void setTableIOSelector(IOSelector ioSelector) {
+ this.tableIoSelector = ioSelector;
+ }
+
+ public IOSelector getTableIOSelector() {
+ if (tableIoSelector == null) {
+ tableIoSelector = new IOSelector();
+ BlockFace front = getFacing();
+ BlockFace chestDir = getFurnace().getFace(getCraftingTable());
+ if (chestDir != null && front != null) {
+ Direction defaultDir = Direction.getDirection(front, chestDir);
+ tableIoSelector.setState(defaultDir, IOSelector.IOState.BOTH);
+ }
+ }
+ 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.
+ */
+ 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();
+ return fdata.getFacing();
+ }
+
/**
* @return Inventory of the furnace or null if there is no furnace where one
* should be
@@ -258,6 +382,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
*/
@@ -362,11 +493,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");
@@ -402,8 +533,16 @@ public void run() {
}
}
} else {
- sendActivatorMessage(ChatColor.GOLD + name + " deactivated, because it ran out of required materials");
- deactivate();
+ 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();
+ }
}
} else {
sendActivatorMessage(ChatColor.GOLD + name + " deactivated, because the factory was destroyed");
@@ -506,12 +645,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;
}
}
@@ -555,4 +694,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 84a78a9e..9cd286c7 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,16 @@
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 net.kyori.adventure.text.Component;
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 +29,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 +42,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 +108,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 +138,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,88 +197,183 @@ 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;
+ ComponableInventory compInv = buildRecipeInventory(p);
+ compInv.update();
+ compInv.updatePlayerView();
+ return;
+ }
+ if (b.equals(fccf.getFurnace())) { // furnace interaction
+ if (fccf.isActive()) {
+ fccf.deactivate();
+ p.sendMessage(ChatColor.RED + "Deactivated " + fccf.getName());
+ } else {
+ fccf.attemptToActivate(p, false);
}
- ClickableInventory ci = new ClickableInventory(rows * 9, "Select a recipe");
- 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(recipes.get(this));
- p.sendMessage(ChatColor.GREEN + "Switched recipe to " + recipes.get(this).getName());
- }
+ private ComponableInventory buildRecipeInventory(Player p) {
+ ComponableInventory compInv = new ComponableInventory("Select a recipe", 6, p);
- }
- };
- recipes.put(c, recipe);
- ci.addSlot(c);
+ 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,
+ fccf);
+ IOConfigSection tableConfigSection = new IOConfigSection(
+ p,
+ fccf.getTableIOSelector(),
+ Material.CRAFTING_TABLE,
+ ((FurnCraftChestStructure) fccf.getMultiBlockStructure()).getCraftingTable(),
+ facing,
+ fccf);
+ 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));
}
- 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) {
+ }
+ return compInv;
+ }
- @Override
- public void clicked(Player p) {
- p.sendMessage(ChatColor.GREEN + "Turned auto select " + (fccf.isAutoSelect() ? "off" : "on")
- + " for " + fccf.getName());
- fccf.setAutoSelect(!fccf.isAutoSelect());
+ 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)));
}
- };
- 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");
- Clickable menuC = new Clickable(menuStack) {
+ }
+ Clickable c = new Clickable(recStack) {
+
@Override
public void clicked(Player p) {
- FactoryModGUI gui = new FactoryModGUI(p);
- gui.showForFactory((FurnCraftChestEgg)FactoryMod.getInstance().getManager().getEgg(fccf.getName()));
+ 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());
+ }
}
};
- ci.setSlot(menuC, (rows * 9) - 1);
-
- ci.showInventory(p);
- return;
+ recipeClickList.add(c);
}
- if (b.equals(fccf.getFurnace())) { // furnace interaction
- if (fccf.isActive()) {
- fccf.deactivate();
- p.sendMessage(ChatColor.RED + "Deactivated " + fccf.getName());
- } else {
- fccf.attemptToActivate(p, false);
+ 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
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..d278663c 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);
+ }
}
}
}
@@ -103,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()) {
@@ -137,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/powerManager/FurnacePowerManager.java b/src/main/java/com/github/igotyou/FactoryMod/powerManager/FurnacePowerManager.java
index 4618e81c..cb7594b4 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,16 @@ public void setPowerCounter(int amount) {
}
public void consumePower(int fuelCount) {
+ if (iofProvider != null) {
+ Inventory fuelInv = iofProvider.getFuelInventory();
+ if (fuelInv != null) {
+ for (int i = 0; i < fuelCount; i++) {
+ fuelInv.removeItem(fuel);
+ }
+ return;
+ }
+ }
+
FurnaceInventory fi = ((Furnace) furnace.getState()).getInventory();
for(int i = 0; i < fuelCount; i++)
@@ -69,6 +98,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/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/structures/FurnCraftChestStructure.java b/src/main/java/com/github/igotyou/FactoryMod/structures/FurnCraftChestStructure.java
index f121f502..17832767 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();
+ Block furnaceBlock = center.getRelative(furnaceFace);
+ if (furnaceBlock.getType() == Material.FURNACE) {
+ chest = b.getLocation();
+ furnace = furnaceBlock.getLocation();
break;
}
-
}
}
- if (chest != null && furnace != null) {
- complete = true;
- } else {
- complete = false;
- }
+ complete = chest != null && furnace != null;
}
public FurnCraftChestStructure(List blocks) {
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/FileHandler.java b/src/main/java/com/github/igotyou/FactoryMod/utility/FileHandler.java
index 5978f938..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,6 +99,9 @@ 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", 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;
config.set(current + ".type", "PIPE");
@@ -258,9 +261,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 +297,34 @@ private void loadFromFile(File f, Map eggs) {
}
}
fac.setAutoSelect(autoSelect);
+ {
+ 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.
+ }
+ 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
+ }
+ }
+ 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;
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
new file mode 100644
index 00000000..7c41c447
--- /dev/null
+++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOConfigSection.java
@@ -0,0 +1,209 @@
+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.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;
+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 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, 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 getIoButton(BlockFace dir) {
+ Block relativeBlock = centerBlock.getRelative(dir);
+ Material type = relativeBlock.getType();
+ Direction relativeDir = Direction.getDirection(front, dir);
+ return getIoClickable(type, relativeDir, dir.name());
+ }
+
+ 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, Direction dir, String dirLabel) {
+ IOSelector.IOState dirState = ioSelector.getState(dir);
+ boolean chestMissing = adjacentType != Material.CHEST && adjacentType != Material.TRAPPED_CHEST;
+ ItemStack display;
+ if (chestMissing) {
+ 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(dirLabel).color(TextColor.color(192, 192, 192)))
+ .append(Component.text(": "))
+ .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")
+ .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) {
+ 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 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
+ protected void onDoubleClick(Player p) { } // nop
+
+ @Override
+ public void addedToInventory(ClickableInventory inv, int slot) {
+ this.inventory = inv;
+ this.slot = slot;
+ }
+
+ 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(dirLabel).color(TextColor.color(192, 192, 192)))
+ .append(Component.text(": "))
+ .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);
+ }
+ }
+ };
+ }
+
+ @Override
+ protected void rebuild() {
+ ioDirectionMode = FactoryMod.getInstance().getManager().getPlayerSettings().getIoDirectionMode(viewerId);
+ switch (ioDirectionMode) {
+ case VISUAL_RELATIVE: {
+ 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: {
+ 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;
+ }
+ }
+ 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..c8148b24
--- /dev/null
+++ b/src/main/java/com/github/igotyou/FactoryMod/utility/IOSelector.java
@@ -0,0 +1,233 @@
+package com.github.igotyou.FactoryMod.utility;
+
+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.stream.Collectors;
+
+/**
+ * @author caucow
+ */
+public class IOSelector {
+
+ private final EnumSet inputs;
+ private final EnumSet outputs;
+ private final EnumSet 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.inputs = EnumSet.noneOf(Direction.class);
+ this.outputs = EnumSet.noneOf(Direction.class);
+ this.fuel = EnumSet.noneOf(Direction.class);
+ }
+
+ public IOState getState(Direction direction) {
+ return IOState.fromIO(inputs.contains(direction), outputs.contains(direction), fuel.contains(direction));
+ }
+
+ 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 inputs.size();
+ }
+
+ public int getOutputCount() {
+ return outputs.size();
+ }
+
+ public int getFuelCount() {
+ return fuel.size();
+ }
+
+ public int getTotalIOFCount() {
+ return getInputCount() + getOutputCount() + getFuelCount();
+ }
+
+ public boolean toggleInput(Direction direction) {
+ boolean added = inputs.add(direction);
+ if (!added) {
+ inputs.remove(direction);
+ }
+ return added;
+ }
+
+ public boolean isInput(Direction direction) {
+ return inputs.contains(direction);
+ }
+
+ public boolean toggleOutput(Direction direction) {
+ boolean added = outputs.add(direction);
+ if (!added) {
+ outputs.remove(direction);
+ }
+ return added;
+ }
+
+ public boolean isOutput(Direction direction) {
+ return outputs.contains(direction);
+ }
+
+ public boolean toggleFuel(Direction direction) {
+ boolean added = fuel.add(direction);
+ if (!added) {
+ fuel.remove(direction);
+ }
+ return added;
+ }
+
+ public boolean isFuel(Direction direction) {
+ return fuel.contains(direction);
+ }
+
+ public boolean hasInputs() {
+ return !inputs.isEmpty();
+ }
+
+ public List getInputs(BlockFace front) {
+ Direction[] values = Direction.values();
+ List bfList = new ArrayList<>(values.length);
+ for (Direction dir : values) {
+ if (inputs.contains(dir)) {
+ bfList.add(dir.getBlockFacing(front));
+ }
+ }
+ return bfList;
+ }
+
+ public boolean hasOutputs() {
+ return !outputs.isEmpty();
+ }
+
+ public List getOutputs(BlockFace front) {
+ Direction[] values = Direction.values();
+ List bfList = new ArrayList<>(values.length);
+ for (Direction dir : values) {
+ if (outputs.contains(dir)) {
+ bfList.add(dir.getBlockFacing(front));
+ }
+ }
+ return bfList;
+ }
+
+ public boolean hasFuel() {
+ return !fuel.isEmpty();
+ }
+
+ public List getFuel(BlockFace front) {
+ Direction[] values = Direction.values();
+ List bfList = new ArrayList<>(values.length);
+ for (Direction dir : values) {
+ if (fuel.contains(dir)) {
+ bfList.add(dir.getBlockFacing(front));
+ }
+ }
+ return bfList;
+ }
+
+ public IOState cycleDirection(Direction direction, boolean backwards) {
+ IOState cur = getState(direction);
+ if (backwards) {
+ cur = cur.last();
+ } else {
+ cur = cur.next();
+ }
+ setState(direction, cur);
+ return cur;
+ }
+
+ 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 {
+ 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;
+
+ IOState(String displayName, ItemStack uiVisual, int color) {
+ this.displayName = displayName;
+ 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 boolean isFuel() {
+ return (ordinal() & 4) != 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, boolean fuel) {
+ return IOState.values()[(in ? 1 : 0) | (out ? 2 : 0) | (fuel ? 4 : 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..3c6262bf
--- /dev/null
+++ b/src/main/java/com/github/igotyou/FactoryMod/utility/MultiInventoryWrapper.java
@@ -0,0 +1,387 @@
+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(List 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 close() {
+ List viewers = getViewers();
+ int num = viewers.size();
+ viewers.forEach(HumanEntity::closeInventory);
+ return num;
+ }
+
+ @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 invi = 0; invi < wrapped.length; invi++) {
+ result = wrapped[invi].addItem(itemStacks);
+ itemStacks = new ItemStack[result.size()];
+ int itemi = 0;
+ Iterator> eit = result.entrySet().iterator();
+ for (; eit.hasNext() && itemi < itemStacks.length; itemi++) {
+ Map.Entry entry = eit.next();
+ itemStacks[itemi] = entry.getValue();
+ }
+ }
+ return result == null ? new HashMap<>() : result;
+ }
+
+ @Override
+ public @NotNull HashMap removeItem(@NotNull ItemStack... itemStacks) throws IllegalArgumentException {
+ 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();
+ for (; eit.hasNext() && itemi < itemStacks.length; itemi++) {
+ Map.Entry entry = eit.next();
+ itemStacks[itemi] = 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;
+ }
+}
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