diff --git a/pom.xml b/pom.xml
index 21888c00..e745acf1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
net.Indyuce
MMOItems
- 5.5.1
+ 5.5.2
MMOItems
A great item solution for your RPG server.
diff --git a/src/main/java/net/Indyuce/mmoitems/MMOItems.java b/src/main/java/net/Indyuce/mmoitems/MMOItems.java
index 7c3ab0dd..f8f24814 100644
--- a/src/main/java/net/Indyuce/mmoitems/MMOItems.java
+++ b/src/main/java/net/Indyuce/mmoitems/MMOItems.java
@@ -10,10 +10,12 @@ import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
+import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import net.Indyuce.mmoitems.api.ConfigFile;
import net.Indyuce.mmoitems.api.SoulboundInfo;
+import net.Indyuce.mmoitems.api.item.MMOItem;
import net.Indyuce.mmoitems.api.player.PlayerData;
import net.Indyuce.mmoitems.command.MMOItemsCommand;
import net.Indyuce.mmoitems.command.UpdateItemCommand;
@@ -45,6 +47,7 @@ import net.Indyuce.mmoitems.comp.rpg.DefaultHook;
import net.Indyuce.mmoitems.comp.rpg.RPGHandler;
import net.Indyuce.mmoitems.gui.PluginInventory;
import net.Indyuce.mmoitems.gui.listener.GuiListener;
+import net.Indyuce.mmoitems.listener.CraftingListener;
import net.Indyuce.mmoitems.listener.CustomBlockListener;
import net.Indyuce.mmoitems.listener.CustomSoundListener;
import net.Indyuce.mmoitems.listener.DisableInteractions;
@@ -155,6 +158,7 @@ public class MMOItems extends JavaPlugin {
Bukkit.getPluginManager().registerEvents(new DisableInteractions(), this);
Bukkit.getPluginManager().registerEvents(new GuiListener(), this);
Bukkit.getPluginManager().registerEvents(new ElementListener(), this);
+ Bukkit.getPluginManager().registerEvents(new CraftingListener(), this);
if (MMOLib.plugin.getVersion().isStrictlyHigher(1, 12)) {
Bukkit.getPluginManager().registerEvents(new CustomBlockListener(), this);
Bukkit.getPluginManager().registerEvents(new Listener_v1_13(), this);
@@ -401,6 +405,45 @@ public class MMOItems extends JavaPlugin {
return getConfig().getStringList("block-blacklist").contains(material.name());
}
+ /***
+ * Parses an ItemStack from a string.
+ * Can be used to both get a vanilla material or
+ * an MMOItem. Used by the recipe manager.
+ */
+ public ItemStack parseStack(String parse) {
+ ItemStack stack = null;
+ String[] split = parse.split("\\:");
+ String input = split[0];
+
+ if (input.contains(".")) {
+ String[] typeId = input.split("\\.");
+ String typeFormat = typeId[0].toUpperCase().replace("-", "_").replace(" ", "_");
+ Validate.isTrue(getTypes().has(typeFormat), "Could not find type " + typeFormat);
+
+ MMOItem mmo = getItems().getMMOItem(MMOItems.plugin.getTypes().get(typeFormat), typeId[1]);
+ if(mmo != null) stack = mmo.newBuilder().build();
+ }
+ else {
+ Material mat = Material.AIR;
+ try {
+ mat = Material.valueOf(input.toUpperCase().replace("-", "_").replace(" ", "_"));
+ } catch (IllegalArgumentException e) {
+ getLogger().warning("Couldn't parse material from '" + parse + "'!");
+ }
+
+ if(mat != Material.AIR) stack = new ItemStack(mat);
+ }
+
+ try {
+ if(stack != null && split.length > 1)
+ stack.setAmount(Integer.parseInt(split[1]));
+ } catch (NumberFormatException e) {
+ getLogger().warning("Couldn't parse amount from '" + parse + "'!");
+ }
+
+ return stack;
+ }
+
public void debug(Object... message) {
if (!getConfig().getBoolean("debug"))
return;
diff --git a/src/main/java/net/Indyuce/mmoitems/api/recipe/MMORecipeChoice.java b/src/main/java/net/Indyuce/mmoitems/api/recipe/MMORecipeChoice.java
index 0a560c74..80fd033d 100644
--- a/src/main/java/net/Indyuce/mmoitems/api/recipe/MMORecipeChoice.java
+++ b/src/main/java/net/Indyuce/mmoitems/api/recipe/MMORecipeChoice.java
@@ -1,93 +1,41 @@
package net.Indyuce.mmoitems.api.recipe;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.lang.Validate;
-import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import net.Indyuce.mmoitems.MMOItems;
-import net.Indyuce.mmoitems.api.Type;
+import net.mmogroup.mmolib.api.item.NBTItem;
public class MMORecipeChoice {
- private final Material material;
- private final int data;
-
- private final Type type;
- private final String id;
-
- public MMORecipeChoice(Material material, int data) {
- this(material, data, null, null);
- }
-
- public MMORecipeChoice(Type type, String id) {
- this(null, 0, type, id);
- }
+ private final ItemStack item;
+ private final int amount;
+ private final boolean isVanilla;
public MMORecipeChoice(String input) {
- if (input.contains(".")) {
- String[] typeId = input.split("\\.");
- String typeFormat = typeId[0].toUpperCase().replace("-", "_").replace(" ", "_");
- Validate.isTrue(MMOItems.plugin.getTypes().has(typeFormat), "Could not find type " + typeFormat);
-
- type = MMOItems.plugin.getTypes().get(typeFormat);
- id = typeId[1];
-
- data = 0;
- material = null;
+ item = MMOItems.plugin.parseStack(input);
+
+ if(item != null) {
+ isVanilla = !NBTItem.get(item).hasType();
+ amount = item.getAmount();
}
-
else {
- String[] split = input.split("\\:");
-
- material = Material.valueOf(split[0].toUpperCase().replace("-", "_").replace(" ", "_"));
- data = split.length > 1 ? Integer.parseInt(split[1]) : 0;
-
- type = null;
- id = null;
+ amount = 1;
+ isVanilla = true;
}
}
- private MMORecipeChoice(Material material, int data, Type type, String id) {
- this.type = type;
- this.id = id;
- this.material = material;
- this.data = data;
+ public boolean isValid() {
+ return item != null;
+ }
+
+ public boolean isVanilla() {
+ return isVanilla;
}
- @SuppressWarnings("deprecation")
- public ItemStack generateStack() {
- return material != null ? (data > 0 ? new ItemStack(material, 1, (short) data) : new ItemStack(material)) : MMOItems.plugin.getItems().getItem(type, id);
+ public int getAmount() {
+ return amount;
}
- public boolean isAir() {
- return material == Material.AIR;
- }
-
- public Material getMaterial() {
- return material;
- }
-
- public Type getType() {
- return type;
- }
-
- public String getId() {
- return id;
- }
-
- public int getMeta() {
- return data;
- }
-
- public static List getFromShapedConfig(List list) {
- List choices = new ArrayList<>();
-
- for (String key : list)
- for (String subkey : key.split("\\ "))
- choices.add(new MMORecipeChoice(subkey));
-
- return choices;
+ public ItemStack getItem() {
+ return item;
}
}
diff --git a/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/CachedRecipe.java b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/CachedRecipe.java
new file mode 100644
index 00000000..089f715f
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/CachedRecipe.java
@@ -0,0 +1,56 @@
+package net.Indyuce.mmoitems.api.recipe.workbench;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.bukkit.inventory.ItemStack;
+
+public class CachedRecipe {
+ private Map amounts = new HashMap<>();
+ private ItemStack stack;
+
+ public boolean isValid(ItemStack[] matrix) {
+ boolean check = true;
+ for (int i = 0; i < matrix.length; i++) {
+ if (matrix[i] == null)
+ continue;
+ if (matrix[i].getAmount() < amounts.get(i))
+ check = false;
+ if (!check)
+ break;
+ }
+ return check;
+ }
+
+ public ItemStack[] generateMatrix(ItemStack[] matrix) {
+ ItemStack[] newMatrix = new ItemStack[9];
+ for (int i = 0; i < matrix.length; i++) {
+ ItemStack stack = matrix[i];
+ if (stack == null) {
+ newMatrix[i] = null;
+ continue;
+ }
+ int amountLeft = stack.getAmount() - amounts.get(i);
+ if (amountLeft < 1) {
+ newMatrix[i] = null;
+ continue;
+ }
+ stack.setAmount(amountLeft);
+ newMatrix[i] = stack;
+ }
+
+ return newMatrix;
+ }
+
+ public void add(int slot, int amount) {
+ amounts.put(slot, amount);
+ }
+
+ public void setResult(ItemStack result) {
+ stack = result;
+ }
+
+ public ItemStack getResult() {
+ return stack;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/CustomRecipe.java b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/CustomRecipe.java
new file mode 100644
index 00000000..512005c9
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/CustomRecipe.java
@@ -0,0 +1,81 @@
+package net.Indyuce.mmoitems.api.recipe.workbench;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+
+import net.Indyuce.mmoitems.MMOItems;
+import net.Indyuce.mmoitems.api.recipe.workbench.ingredients.AirIngredient;
+import net.Indyuce.mmoitems.api.recipe.workbench.ingredients.WorkbenchIngredient;
+import net.mmogroup.mmolib.api.item.NBTItem;
+
+public class CustomRecipe implements Comparable {
+ private final boolean shapeless;
+ private final ItemStack output;
+ private final Map ingredients = new HashMap<>(9);
+
+ public CustomRecipe(NBTItem output, List recipe, boolean isShapeless) {
+ this.shapeless = isShapeless;
+ this.output = output.toItem();
+ if (output.hasTag("MMOITEMS_CRAFTED_AMOUNT"))
+ this.output.setAmount(output.getInteger("MMOITEMS_CRAFTED_AMOUNT"));
+
+ if (shapeless) {
+ for (int i = 0; i < 9; i++) {
+ ItemStack stack = MMOItems.plugin.parseStack(recipe.get(i));
+ if (stack == null || stack.getType() == Material.AIR)
+ continue;
+ ingredients.put(i, WorkbenchIngredient.getAutomatically(stack));
+ }
+ }
+ else {
+ for (int i = 0; i < 9; i++) {
+ List line = Arrays.asList(recipe.get(i / 3).split("\\ "));
+ while (line.size() < 3)
+ line.add("AIR");
+
+ ItemStack stack = MMOItems.plugin.parseStack(line.get(i % 3));
+ if (stack == null || stack.getType() == Material.AIR)
+ ingredients.put(i, new AirIngredient());
+ else ingredients.put(i, WorkbenchIngredient.getAutomatically(stack));
+ }
+ }
+ }
+
+ public Set> getIngredients() {
+ return ingredients.entrySet();
+ }
+
+ public boolean fitsPlayerCrafting() {
+ boolean check = true;
+ for (int value : ingredients.keySet())
+ if (value > 3) {
+ check = false;
+ break;
+ }
+ return check;
+ }
+
+ public boolean isEmpty() {
+ return ingredients.isEmpty();
+ }
+
+ public boolean isShapeless() {
+ return shapeless;
+ }
+
+ public ItemStack getResult() {
+ return output;
+ }
+
+ @Override
+ public int compareTo(CustomRecipe o) {
+ return Boolean.compare(shapeless, o.shapeless);
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/AirIngredient.java b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/AirIngredient.java
new file mode 100644
index 00000000..9ee9b1ea
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/AirIngredient.java
@@ -0,0 +1,16 @@
+package net.Indyuce.mmoitems.api.recipe.workbench.ingredients;
+
+import org.bukkit.inventory.ItemStack;
+
+public class AirIngredient extends WorkbenchIngredient {
+ @Override
+ public boolean matches(ItemStack stack) {
+ if(stack == null) return true;
+ else return false;
+ }
+
+ @Override
+ public boolean matchStack(ItemStack stack) {
+ return true;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/MMOIngredient.java b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/MMOIngredient.java
new file mode 100644
index 00000000..0659d5b3
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/MMOIngredient.java
@@ -0,0 +1,26 @@
+package net.Indyuce.mmoitems.api.recipe.workbench.ingredients;
+
+import org.bukkit.inventory.ItemStack;
+
+import net.Indyuce.mmoitems.api.Type;
+import net.mmogroup.mmolib.api.item.NBTItem;
+
+public class MMOIngredient extends WorkbenchIngredient {
+ private final Type type;
+ private final String id;
+
+ public MMOIngredient(Type type, String id) {
+ this.type = type;
+ this.id = id;
+ }
+
+ @Override
+ public boolean matchStack(ItemStack stack) {
+ NBTItem nbt = NBTItem.get(stack);
+ if (!nbt.hasType())
+ return false;
+ return nbt.getType().equals(type) &&
+ nbt.getString("MMOITEMS_ITEM_ID").equalsIgnoreCase(id);
+ }
+
+}
diff --git a/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/VanillaIngredient.java b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/VanillaIngredient.java
new file mode 100644
index 00000000..894d4951
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/VanillaIngredient.java
@@ -0,0 +1,20 @@
+package net.Indyuce.mmoitems.api.recipe.workbench.ingredients;
+
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+
+import net.mmogroup.mmolib.api.item.NBTItem;
+
+public class VanillaIngredient extends WorkbenchIngredient {
+ private final Material mat;
+
+ public VanillaIngredient(Material mat) {
+ this.mat = mat;
+ }
+
+ @Override
+ public boolean matchStack(ItemStack stack) {
+ if(NBTItem.get(stack).hasType()) return false;
+ return stack.getType() == mat;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/WorkbenchIngredient.java b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/WorkbenchIngredient.java
new file mode 100644
index 00000000..1b39985a
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmoitems/api/recipe/workbench/ingredients/WorkbenchIngredient.java
@@ -0,0 +1,34 @@
+package net.Indyuce.mmoitems.api.recipe.workbench.ingredients;
+
+import org.bukkit.inventory.ItemStack;
+
+import net.mmogroup.mmolib.api.item.NBTItem;
+
+public abstract class WorkbenchIngredient {
+ private int amount;
+
+ public void setAmount(int value) {
+ amount = value;
+ }
+
+ public int getAmount() {
+ return amount;
+ }
+
+ public static WorkbenchIngredient getAutomatically(ItemStack stack) {
+ WorkbenchIngredient ingredient;
+ NBTItem nbt = NBTItem.get(stack);
+ if(nbt.hasType()) ingredient = new MMOIngredient(nbt.getType(), nbt.getString("MMOITEMS_ITEM_ID"));
+ else ingredient = new VanillaIngredient(stack.getType());
+ ingredient.setAmount(stack.getAmount());
+ return ingredient;
+ }
+
+ public boolean matches(ItemStack stack) {
+ if(stack == null) return false;
+ if(stack.getAmount() < amount) return false;
+ else return matchStack(stack);
+ }
+
+ public abstract boolean matchStack(ItemStack stack);
+}
diff --git a/src/main/java/net/Indyuce/mmoitems/command/MMOItemsCommand.java b/src/main/java/net/Indyuce/mmoitems/command/MMOItemsCommand.java
index b9c0fb38..ce9ceb56 100644
--- a/src/main/java/net/Indyuce/mmoitems/command/MMOItemsCommand.java
+++ b/src/main/java/net/Indyuce/mmoitems/command/MMOItemsCommand.java
@@ -522,12 +522,10 @@ public class MMOItemsCommand implements CommandExecutor {
* discoverRecipes must be called on the main thread.
*/
Bukkit.getScheduler().runTask(MMOItems.plugin, () -> {
- if (MMOLib.plugin.getVersion().isStrictlyHigher(1, 12) && MMOItems.plugin.getConfig().getBoolean("auto-recipe-book"))
- Bukkit.getOnlinePlayers().forEach(online -> online.discoverRecipes(MMOItems.plugin.getRecipes().getNamespacedKeys()));
-
sender.sendMessage(MMOItems.plugin.getPrefix() + "Successfully reloaded recipes.");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
- + MMOItems.plugin.getRecipes().getLoadedRecipes().size() + ChatColor.GRAY + " Recipes");
+ + (MMOItems.plugin.getRecipes().getLoadedRecipes().size()
+ + MMOItems.plugin.getRecipes().getCustomRecipes().size()) + ChatColor.GRAY + " Recipes");
});
});
}
diff --git a/src/main/java/net/Indyuce/mmoitems/gui/edition/RecipeEdition.java b/src/main/java/net/Indyuce/mmoitems/gui/edition/RecipeEdition.java
index 30242c6c..f523767f 100644
--- a/src/main/java/net/Indyuce/mmoitems/gui/edition/RecipeEdition.java
+++ b/src/main/java/net/Indyuce/mmoitems/gui/edition/RecipeEdition.java
@@ -6,6 +6,7 @@ import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
+import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
@@ -13,10 +14,10 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
+import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.ConfigFile;
import net.Indyuce.mmoitems.api.edition.StatEdition;
import net.Indyuce.mmoitems.api.item.MMOItem;
-import net.Indyuce.mmoitems.api.recipe.MMORecipeChoice;
import net.Indyuce.mmoitems.stat.type.ItemStat;
import net.mmogroup.mmolib.api.util.AltChar;
@@ -56,8 +57,11 @@ public class RecipeEdition extends EditionInventory {
while (line.size() < 3)
line.add("AIR");
- ItemStack element = new MMORecipeChoice(fixAir(line.get(j % 3))).generateStack();
+ ItemStack element = MMOItems.plugin.parseStack(line.get(j % 3));
+ if(element == null) element = new ItemStack(Material.BARRIER);
+ if(element.getType() == Material.AIR) element.setType(Material.BARRIER);
ItemMeta elementMeta = element.getItemMeta();
+ if(element.getType() == Material.BARRIER) elementMeta.setDisplayName(ChatColor.RED + "Empty");
List elementLore = new ArrayList<>();
elementLore.add("");
elementLore.add(ChatColor.YELLOW + AltChar.listDash + " Click to change this ingredient.");
@@ -76,34 +80,35 @@ public class RecipeEdition extends EditionInventory {
Inventory inv = Bukkit.createInventory(this, 54, ChatColor.UNDERLINE + "Recipe Editor: " + mmoitem.getId());
ConfigFile config = mmoitem.getType().getConfigFile();
if (!config.getConfig().contains(mmoitem.getId() + ".crafting.shapeless.1")) {
- for (int i = 1; i < 10; i++)
- config.getConfig().set(mmoitem.getId() + ".crafting.shapeless.1.item" + i, "AIR");
+ config.getConfig().set(mmoitem.getId() + ".crafting.shapeless.1",
+ Arrays.asList("AIR", "AIR", "AIR", "AIR", "AIR", "AIR", "AIR", "AIR", "AIR"));
registerItemEdition(config);
}
- for (int j = 0; j < 9; j++) {
- int slot = intToSlot(j);
+ List ingredients = config.getConfig().getStringList(mmoitem.getId() + ".crafting.shapeless.1");
+ if(ingredients.size() == 9)
+ for (int j = 0; j < 9; j++) {
+ int slot = intToSlot(j);
- ItemStack element = new MMORecipeChoice(fixAir(config.getConfig().getString(mmoitem.getId() + ".crafting.shapeless.1.item" + (j + 1))))
- .generateStack();
- ItemMeta elementMeta = element.getItemMeta();
- List elementLore = new ArrayList<>();
- elementLore.add("");
- elementLore.add(ChatColor.YELLOW + AltChar.listDash + " Click to change this ingredient.");
- elementLore.add(ChatColor.YELLOW + AltChar.listDash + " Right click to remove this ingredient.");
- elementMeta.setLore(elementLore);
- element.setItemMeta(elementMeta);
+ ItemStack element = MMOItems.plugin.parseStack(ingredients.get(j));
+ if(element == null) element = new ItemStack(Material.BARRIER);
+ if(element.getType() == Material.AIR) element.setType(Material.BARRIER);
+ ItemMeta elementMeta = element.getItemMeta();
+ if(element.getType() == Material.BARRIER) elementMeta.setDisplayName(ChatColor.RED + "Empty");
+ List elementLore = new ArrayList<>();
+ elementLore.add("");
+ elementLore.add(ChatColor.YELLOW + AltChar.listDash + " Click to change this ingredient.");
+ elementLore.add(ChatColor.YELLOW + AltChar.listDash + " Right click to remove this ingredient.");
+ elementMeta.setLore(elementLore);
+ element.setItemMeta(elementMeta);
- inv.setItem(slot, element);
- }
+ inv.setItem(slot, element);
+ }
+ else MMOItems.plugin.getLogger().warning("Couldn't load shapeless recipe for '" + mmoitem.getId() + "'!");
addEditionInventoryItems(inv, true);
return inv;
}
- private String fixAir(String string) {
- return string.equals("AIR") ? "BARRIER" : string;
- }
-
private int intToSlot(int i) {
return i >= 0 && i <= 2 ? 21 + i : (i >= 3 && i <= 5 ? 27 + i : (i >= 6 && i <= 8 ? 33 + i : 0));
}
@@ -122,7 +127,7 @@ public class RecipeEdition extends EditionInventory {
if (event.getAction() == InventoryAction.PICKUP_ALL) {
if (slotToInt(event.getRawSlot()) >= 0)
new StatEdition(this, ItemStat.CRAFTING, "recipe", (shapeless ? "shapeless" : "shaped"), slotToInt(event.getRawSlot()))
- .enable("Write in the chat the item you want.", "Format: '[MATERIAL]' or '[MATERIAL]:[DURABILITY]' or '[TYPE].[ID]'");
+ .enable("Write in the chat the item you want.", "Format: '[MATERIAL]' or '[TYPE].[ID]'");
} else if (event.getAction() == InventoryAction.PICKUP_HALF) {
if (shapeless)
@@ -146,8 +151,12 @@ public class RecipeEdition extends EditionInventory {
private void deleteShapeless(int slot) {
ConfigFile config = mmoitem.getType().getConfigFile();
- config.getConfig().set(mmoitem.getId() + ".crafting.shapeless.1.item" + (slot + 1), "AIR");
- registerItemEdition(config);
- open();
+ if(config.getConfig().contains(mmoitem.getId() + ".crafting.shapeless.1")) {
+ List newList = config.getConfig().getStringList(mmoitem.getId() + ".crafting.shapeless.1");
+ newList.set(slot, "AIR");
+ config.getConfig().set(mmoitem.getId() + ".crafting.shapeless.1", newList);
+ registerItemEdition(config);
+ open();
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/Indyuce/mmoitems/listener/CraftingListener.java b/src/main/java/net/Indyuce/mmoitems/listener/CraftingListener.java
new file mode 100644
index 00000000..9debae82
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmoitems/listener/CraftingListener.java
@@ -0,0 +1,140 @@
+package net.Indyuce.mmoitems.listener;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.ClickType;
+import org.bukkit.event.inventory.InventoryAction;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryType.SlotType;
+import org.bukkit.event.inventory.PrepareItemCraftEvent;
+import org.bukkit.inventory.CraftingInventory;
+import org.bukkit.inventory.ItemStack;
+
+import net.Indyuce.mmoitems.MMOItems;
+import net.Indyuce.mmoitems.api.recipe.workbench.CachedRecipe;
+import net.Indyuce.mmoitems.api.recipe.workbench.CustomRecipe;
+import net.Indyuce.mmoitems.api.recipe.workbench.ingredients.WorkbenchIngredient;
+
+public class CraftingListener implements Listener {
+ Map cachedRecipe = new HashMap<>();
+
+ @EventHandler
+ public void calculateCrafting(PrepareItemCraftEvent e) {
+ if (!(e.getView().getPlayer() instanceof Player))
+ return;
+ handleCustomCrafting(e.getInventory(), (Player) e.getView().getPlayer());
+ }
+
+ @EventHandler
+ public void getResult(InventoryClickEvent e) {
+ if (!(e.getView().getPlayer() instanceof Player)) return;
+ if (!(e.getInventory() instanceof CraftingInventory)) return;
+ if (e.getSlotType() == SlotType.CRAFTING && e.getAction() == InventoryAction.PLACE_ONE)
+ Bukkit.getScheduler().runTaskLater(MMOItems.plugin, new Runnable() {
+ @Override
+ public void run() {
+ handleCustomCrafting((CraftingInventory) e.getInventory(), (Player) e.getView().getPlayer());
+ }
+ }, 1);
+ else if (e.getSlotType() == SlotType.RESULT) {
+ CraftingInventory inv = (CraftingInventory) e.getInventory();
+ if (e.getCurrentItem() == null || !cachedRecipe.containsKey(e.getWhoClicked().getUniqueId()))
+ return;
+ if (e.getClick() != ClickType.LEFT) {
+ e.setCancelled(true);
+ return;
+ }
+ CachedRecipe cached = cachedRecipe.get(e.getWhoClicked().getUniqueId());
+ cachedRecipe.remove(e.getWhoClicked().getUniqueId());
+ if (!cached.isValid(inv.getMatrix())) {
+ e.setCancelled(true);
+ return;
+ }
+ ItemStack[] newMatrix = cached.generateMatrix(inv.getMatrix());
+ inv.setMatrix(new ItemStack[] { null, null, null, null, null, null, null, null, null });
+ Bukkit.getScheduler().runTaskLater(MMOItems.plugin, new Runnable() {
+ @Override
+ public void run() {
+ boolean check = true;
+ for (ItemStack stack : newMatrix)
+ if (stack != null)
+ check = false;
+ if (check) {
+ inv.setMatrix(new ItemStack[] { null, null, null, null, null, null, null, null, null });
+ ((Player) e.getView().getPlayer()).updateInventory();
+ } else
+ inv.setMatrix(newMatrix);
+ }
+ }, 1);
+ e.setCurrentItem(cached.getResult());
+ }
+ }
+
+ public void handleCustomCrafting(CraftingInventory inv, Player player) {
+ player.updateInventory();
+ cachedRecipe.remove(player.getUniqueId());
+ for (CustomRecipe recipe : MMOItems.plugin.getRecipes().getCustomRecipes()) {
+ if (!recipe.fitsPlayerCrafting() && inv.getMatrix().length == 4)
+ continue;
+
+ CachedRecipe cached = new CachedRecipe();
+ boolean matches = true;
+ List slotsChecked = new ArrayList<>();
+ for (Entry ingredients : recipe.getIngredients()) {
+ if (recipe.isShapeless()) {
+ boolean check = false;
+ int nonnullcount = 0;
+ for (int i = 0; i < inv.getMatrix().length; i++) {
+ if (slotsChecked.contains(i))
+ continue;
+ ItemStack item = inv.getMatrix()[i];
+ if (item == null) {
+ slotsChecked.add(i);
+ continue;
+ }
+ nonnullcount += 1;
+ if (ingredients.getValue().matches(item)) {
+ cached.add(i, ingredients.getValue().getAmount());
+ slotsChecked.add(i);
+ check = true;
+ }
+ if (nonnullcount > recipe.getIngredients().size()) {
+ check = false;
+ break;
+ }
+ }
+ if (!check)
+ matches = false;
+ } else {
+ if (!ingredients.getValue().matches(inv.getMatrix()[ingredients.getKey()]))
+ matches = false;
+ else cached.add(ingredients.getKey(), ingredients.getValue().getAmount());
+ }
+
+ if (!matches) break;
+ }
+
+ if (matches) {
+ cached.setResult(recipe.getResult());
+ cachedRecipe.put(player.getUniqueId(), cached);
+ inv.setResult(recipe.getResult());
+ Bukkit.getScheduler().runTaskLater(MMOItems.plugin, new Runnable() {
+ @Override
+ public void run() {
+ inv.setItem(0, recipe.getResult());
+ }
+ }, 1);
+ break;
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmoitems/listener/version/Listener_v1_13.java b/src/main/java/net/Indyuce/mmoitems/listener/version/Listener_v1_13.java
index 237d310b..19a4eddb 100644
--- a/src/main/java/net/Indyuce/mmoitems/listener/version/Listener_v1_13.java
+++ b/src/main/java/net/Indyuce/mmoitems/listener/version/Listener_v1_13.java
@@ -4,10 +4,8 @@ import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.entity.Trident;
import org.bukkit.event.EventHandler;
-import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileLaunchEvent;
-import org.bukkit.event.player.PlayerJoinEvent;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
@@ -18,8 +16,6 @@ import net.mmogroup.mmolib.MMOLib;
import net.mmogroup.mmolib.api.item.NBTItem;
public class Listener_v1_13 implements Listener {
- private final boolean autoRecipeBook = MMOItems.plugin.getConfig().getBoolean("auto-recipe-book");
-
@EventHandler
public void a(ProjectileLaunchEvent event) {
if (!(event.getEntity() instanceof Trident) || !(event.getEntity().getShooter() instanceof Player))
@@ -41,10 +37,4 @@ public class Listener_v1_13 implements Listener {
MMOItems.plugin.getEntities().registerCustomProjectile(nbtItem, playerData.getStats().newTemporary(), (Trident) event.getEntity(), type != null);
}
-
- @EventHandler(priority = EventPriority.LOW)
- public void b(PlayerJoinEvent event) {
- if (autoRecipeBook)
- event.getPlayer().discoverRecipes(MMOItems.plugin.getRecipes().getNamespacedKeys());
- }
}
diff --git a/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManager.java b/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManager.java
index 6c2d8c5f..e953aadf 100644
--- a/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManager.java
+++ b/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManager.java
@@ -1,5 +1,6 @@
package net.Indyuce.mmoitems.manager.recipe;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -10,58 +11,55 @@ import org.bukkit.Bukkit;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.inventory.Recipe;
-import org.bukkit.inventory.ShapedRecipe;
-import org.bukkit.inventory.ShapelessRecipe;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.recipe.MMORecipeChoice;
+import net.Indyuce.mmoitems.api.recipe.workbench.CustomRecipe;
public abstract class RecipeManager {
-
- /**
- * TODO When Bukkit changes their 'RecipeChoice.ExactChoice' API we can
- * remove the suppressed warnings, but right now it works despite being
- * marked as deprecated. It is just a
- */
+ private final Set craftingRecipes = new HashSet<>();
private final Set loadedRecipes = new HashSet<>();
public abstract void reload();
public abstract void registerFurnaceRecipe(Type type, String id, BurningRecipeInformation info, String number);
-
- public abstract void registerShapelessRecipe(Type type, String id, ConfigurationSection config, String number);
-
- public abstract void shapedIngredient(ShapedRecipe recipe, char slot, MMORecipeChoice choice);
-
- public abstract void registerShapedRecipe(Type type, String id, List list, String number);
-
- public abstract void shapelessIngredient(ShapelessRecipe recipe, MMORecipeChoice choice);
-
- /**
- * This method is purely for easily converting the AWB recipes.
- *
- * @deprecated Some day I want to get proper rid of the AWB but right now we
- * don't want to force players to update their recipes right off
- * the bat.
- */
- @Deprecated
- public abstract void setIngredientOrAir(ShapedRecipe recipe, char character, ConfigurationSection c);
+ public abstract void registerShapedRecipe(Type type, String id, List list);
+ public abstract void registerShapelessRecipe(Type type, String id, List ingredients);
public void registerRecipe(NamespacedKey key, Recipe recipe) {
loadedRecipes.add(new LoadedRecipe(key, recipe));
}
+ public void registerRecipe(CustomRecipe recipe) {
+ if(!recipe.isEmpty())
+ craftingRecipes.add(recipe);
+ }
+
public Set getLoadedRecipes() {
return loadedRecipes;
}
+
+ public Set getCustomRecipes() {
+ return craftingRecipes;
+ }
public Set getNamespacedKeys() {
return loadedRecipes.stream().map(recipe -> recipe.getKey()).collect(Collectors.toSet());
}
+ public void sortRecipes() {
+ List temporary = new ArrayList<>();
+ temporary.addAll(craftingRecipes);
+ craftingRecipes.clear();
+ craftingRecipes.addAll(temporary.stream().sorted().collect(Collectors.toList()));
+ }
+
+ public void clearCustomRecipes() {
+ craftingRecipes.clear();
+ }
+
public NamespacedKey getRecipeKey(Type type, String id, String recipeType, String number) {
return new NamespacedKey(MMOItems.plugin, recipeType + "_" + type.getId() + "_" + id + "_" + number);
}
@@ -81,28 +79,6 @@ public abstract class RecipeManager {
});
}
- /**
- * @deprecated Some day I want to get proper rid of the AWB but right now we
- * don't want to force players to update their recipes right off
- * the bat.
- */
- public void registerAdvancedWorkbenchRecipe(Type type, String id, FileConfiguration config) {
- MMOItems.plugin.getLogger().warning("Found deprecated adv. recipe for " + id + ". Converting it to the new system...");
- MMOItems.plugin.getLogger().warning("It is recommended to update your recipes!");
-
- NamespacedKey key = getRecipeKey(type, id, "advanced", "deprecated");
- ShapedRecipe recipe = new ShapedRecipe(key, MMOItems.plugin.getItems().getItem(type, id));
- recipe.shape("012", "345", "678");
-
- for (int j = 0; j < 9; j++) {
- ConfigurationSection section = config.getConfigurationSection(id + ".advanced-craft." + j);
- if (section != null)
- setIngredientOrAir(recipe, ("" + j).charAt(0), section);
- }
-
- registerRecipe(key, recipe);
- }
-
/*
* used because spigot API does not let us access namespaced key of a Recipe
* instance.
@@ -120,7 +96,7 @@ public abstract class RecipeManager {
return key;
}
- public Recipe toBukkit() {
+ public Recipe getRecipe() {
return recipe;
}
}
diff --git a/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManagerDefault.java b/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManagerDefault.java
index b6e834e5..23df1189 100644
--- a/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManagerDefault.java
+++ b/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManagerDefault.java
@@ -3,53 +3,44 @@ package net.Indyuce.mmoitems.manager.recipe;
import java.util.List;
import java.util.logging.Level;
-import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
-import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.inventory.BlastingRecipe;
import org.bukkit.inventory.CampfireRecipe;
import org.bukkit.inventory.FurnaceRecipe;
-import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.RecipeChoice;
-import org.bukkit.inventory.ShapedRecipe;
-import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.inventory.SmokingRecipe;
-import org.bukkit.inventory.meta.ItemMeta;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.recipe.MMORecipeChoice;
-import net.asangarin.hexcolors.ColorParse;
+import net.Indyuce.mmoitems.api.recipe.workbench.CustomRecipe;
public class RecipeManagerDefault extends RecipeManager {
-
public RecipeManagerDefault() {
reload();
}
@Override
- @SuppressWarnings("deprecation")
public void reload() {
+ clearCustomRecipes();
+
for (Type type : MMOItems.plugin.getTypes().getAll()) {
FileConfiguration config = type.getConfigFile().getConfig();
for (String id : config.getKeys(false))
try {
- if (config.getConfigurationSection(id).contains("advanced-craft"))
- registerAdvancedWorkbenchRecipe(type, id, config);
-
if (config.getConfigurationSection(id).contains("crafting")) {
ConfigurationSection section = config.getConfigurationSection(id + ".crafting");
if (section.contains("shaped"))
section.getConfigurationSection("shaped").getKeys(false)
- .forEach(recipe -> registerShapedRecipe(type, id, section.getStringList("shaped." + recipe), recipe));
+ .forEach(recipe -> registerShapedRecipe(type, id, section.getStringList("shaped." + recipe)));
if (section.contains("shapeless"))
section.getConfigurationSection("shapeless").getKeys(false).forEach(
- recipe -> registerShapelessRecipe(type, id, section.getConfigurationSection("shapeless." + recipe), recipe));
+ recipe -> registerShapelessRecipe(type, id, section.getStringList("shapeless." + recipe)));
if (section.contains("furnace"))
section.getConfigurationSection("furnace").getKeys(false).forEach(recipe -> registerFurnaceRecipe(type, id,
new BurningRecipeInformation(section.getConfigurationSection("furnace." + recipe)), recipe));
@@ -68,16 +59,17 @@ public class RecipeManagerDefault extends RecipeManager {
}
}
- // registerCampfireRecipe(MMOItems.plugin.getItems().getItem(Type.SWORD,
- // "SILVER_SWORD"), new
- // RecipeChoice.ExactChoice(MMOItems.plugin.getItems().getItem(Type.get("MATERIAL"),
- // "SILVER_INGOT")));
-
- Bukkit.getScheduler().runTask(MMOItems.plugin, () -> getLoadedRecipes().forEach(recipe -> Bukkit.addRecipe(recipe.toBukkit())));
+ sortRecipes();
+ Bukkit.getScheduler().runTask(MMOItems.plugin,
+ () -> getLoadedRecipes().forEach(recipe -> Bukkit.addRecipe(recipe.getRecipe())));
}
@Override
public void registerFurnaceRecipe(Type type, String id, BurningRecipeInformation info, String number) {
+ if(!info.getChoice().isValid()) {
+ MMOItems.plugin.getLogger().warning("Couldn't load furnace recipe for '" + type.getId() + "." + id + "'");
+ return;
+ }
NamespacedKey key = getRecipeKey(type, id, "furnace", number);
FurnaceRecipe recipe = new FurnaceRecipe(key, MMOItems.plugin.getItems().getItem(type, id), toBukkit(info.getChoice()), info.getExp(),
info.getBurnTime());
@@ -85,6 +77,10 @@ public class RecipeManagerDefault extends RecipeManager {
}
public void registerBlastRecipe(Type type, String id, BurningRecipeInformation info, String number) {
+ if(!info.getChoice().isValid()) {
+ MMOItems.plugin.getLogger().warning("Couldn't load blast furnace recipe for '" + type.getId() + "." + id + "'");
+ return;
+ }
NamespacedKey key = getRecipeKey(type, id, "blast", number);
BlastingRecipe recipe = new BlastingRecipe(key, MMOItems.plugin.getItems().getItem(type, id), toBukkit(info.getChoice()), info.getExp(),
info.getBurnTime());
@@ -92,6 +88,10 @@ public class RecipeManagerDefault extends RecipeManager {
}
public void registerSmokerRecipe(Type type, String id, BurningRecipeInformation info, String number) {
+ if(!info.getChoice().isValid()) {
+ MMOItems.plugin.getLogger().warning("Couldn't load smoker recipe for '" + type.getId() + "." + id + "'");
+ return;
+ }
NamespacedKey key = getRecipeKey(type, id, "smoker", number);
SmokingRecipe recipe = new SmokingRecipe(key, MMOItems.plugin.getItems().getItem(type, id), toBukkit(info.getChoice()), info.getExp(),
info.getBurnTime());
@@ -99,6 +99,10 @@ public class RecipeManagerDefault extends RecipeManager {
}
public void registerCampfireRecipe(Type type, String id, BurningRecipeInformation info, String number) {
+ if(!info.getChoice().isValid()) {
+ MMOItems.plugin.getLogger().warning("Couldn't load campfire recipe for '" + type.getId() + "." + id + "'");
+ return;
+ }
NamespacedKey key = getRecipeKey(type, id, "campfire", number);
CampfireRecipe recipe = new CampfireRecipe(key, MMOItems.plugin.getItems().getItem(type, id), toBukkit(info.getChoice()), info.getExp(),
info.getBurnTime());
@@ -106,94 +110,23 @@ public class RecipeManagerDefault extends RecipeManager {
}
@Override
- public void registerShapedRecipe(Type type, String id, List list, String number) {
- NamespacedKey key = getRecipeKey(type, id, "shaped", number);
- ShapedRecipe recipe = new ShapedRecipe(key, MMOItems.plugin.getItems().getItem(type, id));
-
- List choices = MMORecipeChoice.getFromShapedConfig(list);
- if (choices.isEmpty())
- return;
-
- recipe.shape("ABC", "DEF", "GHI");
-
- shapedIngredient(recipe, 'A', choices.get(0));
- shapedIngredient(recipe, 'B', choices.get(1));
- shapedIngredient(recipe, 'C', choices.get(2));
- shapedIngredient(recipe, 'D', choices.get(3));
- shapedIngredient(recipe, 'E', choices.get(4));
- shapedIngredient(recipe, 'F', choices.get(5));
- shapedIngredient(recipe, 'G', choices.get(6));
- shapedIngredient(recipe, 'H', choices.get(7));
- shapedIngredient(recipe, 'I', choices.get(8));
-
- registerRecipe(key, recipe);
+ public void registerShapedRecipe(Type type, String id, List list) {
+ registerRecipe(new CustomRecipe(MMOItems.plugin.getItems().getMMOItem(type, id).newBuilder().buildNBT(), list, false));
}
@Override
- public void shapedIngredient(ShapedRecipe recipe, char slot, MMORecipeChoice choice) {
- if (choice.isAir())
- recipe.setIngredient(slot, Material.AIR);
- else
- recipe.setIngredient(slot, toBukkit(choice));
- }
-
- @Override
- public void registerShapelessRecipe(Type type, String id, ConfigurationSection config, String number) {
- NamespacedKey key = getRecipeKey(type, id, "shapeless", number);
- ShapelessRecipe recipe = new ShapelessRecipe(key, MMOItems.plugin.getItems().getItem(type, id));
-
- for (int i = 1; i < 10; i++)
- if (config.contains("item" + i))
- shapelessIngredient(recipe, new MMORecipeChoice(config.getString("item" + i)));
-
- if (!recipe.getIngredientList().isEmpty())
- registerRecipe(key, recipe);
- }
-
- @Override
- public void shapelessIngredient(ShapelessRecipe recipe, MMORecipeChoice choice) {
- if (!choice.isAir())
- recipe.addIngredient(toBukkit(choice));
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public void setIngredientOrAir(ShapedRecipe recipe, char character, ConfigurationSection config) {
- if (config.contains("type")) {
- String typeFormat = config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_");
- Validate.notNull(MMOItems.plugin.getTypes().has(typeFormat), "Could not find item type");
-
- String id = config.getString("id");
- Validate.notNull(id, "Could not find item ID");
-
- ItemStack item = MMOItems.plugin.getItems().getItem(MMOItems.plugin.getTypes().get(typeFormat), id);
- Validate.isTrue(item != null, "Could not load item with ID: " + id);
-
- item.setAmount(config.getInt("amount", 1));
- recipe.setIngredient(character, item.getType());
-
- } else if (config.contains("material")) {
- Material material = Material.valueOf(config.getString("material").toUpperCase().replace("-", "_").replace(" ", "_"));
- int amount = config.getInt("amount", 1);
- String name = config.getString("name", "");
- if (amount == 1)
- recipe.setIngredient(character, material);
- else {
- ItemStack item = new ItemStack(material);
- item.setAmount(amount);
- if (!name.isEmpty()) {
- ItemMeta meta = item.getItemMeta();
- meta.setDisplayName(new ColorParse('&', name).toChatColor());
- item.setItemMeta(meta);
- }
- recipe.setIngredient(character, new RecipeChoice.ExactChoice(item));
- }
- }
+ public void registerShapelessRecipe(Type type, String id, List list) {
+ registerRecipe(new CustomRecipe(MMOItems.plugin.getItems().getMMOItem(type, id).newBuilder().buildNBT(), list, true));
}
+ /*
+ * TODO When Bukkit changes their 'RecipeChoice.ExactChoice' API we can
+ * remove the suppressed warnings, but right now it works despite being
+ * marked as deprecated. It is just draft API and probably subject to change.
+ */
@SuppressWarnings("deprecation")
public RecipeChoice toBukkit(MMORecipeChoice choice) {
- return choice.getMaterial() != null ? new RecipeChoice.MaterialChoice(choice.getMaterial())
- : new RecipeChoice.ExactChoice(MMOItems.plugin.getItems().getItem(choice.getType(), choice.getId()));
+ return choice.isVanilla() ? new RecipeChoice.MaterialChoice(choice.getItem().getType())
+ : new RecipeChoice.ExactChoice(choice.getItem());
}
}
diff --git a/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManagerLegacy.java b/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManagerLegacy.java
index 1b3b2dad..f053c2f6 100644
--- a/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManagerLegacy.java
+++ b/src/main/java/net/Indyuce/mmoitems/manager/recipe/RecipeManagerLegacy.java
@@ -3,144 +3,75 @@ package net.Indyuce.mmoitems.manager.recipe;
import java.util.List;
import java.util.logging.Level;
-import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
-import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.inventory.FurnaceRecipe;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.ShapedRecipe;
-import org.bukkit.inventory.ShapelessRecipe;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
-import net.Indyuce.mmoitems.api.recipe.MMORecipeChoice;
+import net.Indyuce.mmoitems.api.recipe.workbench.CustomRecipe;
-/** One day I'll get rid of 1.12 for real >:) */
+/** One day we'll get rid of 1.12 for real >:) */
public class RecipeManagerLegacy extends RecipeManager {
-
public RecipeManagerLegacy() {
reload();
}
@Override
- @SuppressWarnings("deprecation")
public void reload() {
+ clearCustomRecipes();
+
for (Type type : MMOItems.plugin.getTypes().getAll()) {
FileConfiguration config = type.getConfigFile().getConfig();
for (String id : config.getKeys(false))
try {
- if (config.getConfigurationSection(id).contains("advanced-craft"))
- registerAdvancedWorkbenchRecipe(type, id, config);
-
if (config.getConfigurationSection(id).contains("crafting")) {
ConfigurationSection section = config.getConfigurationSection(id + ".crafting");
if (section.contains("shaped"))
section.getConfigurationSection("shaped").getKeys(false)
- .forEach(recipe -> registerShapedRecipe(type, id, section.getStringList("shaped." + recipe), recipe));
+ .forEach(recipe -> registerShapedRecipe(type, id, section.getStringList("shaped." + recipe)));
if (section.contains("shapeless"))
- section.getConfigurationSection("shapeless").getKeys(false).forEach(
- recipe -> registerShapelessRecipe(type, id, section.getConfigurationSection("shapeless." + recipe), recipe));
+ section.getConfigurationSection("shapeless").getKeys(false)
+ .forEach(recipe -> registerShapelessRecipe(type, id, section.getStringList("shapeless." + recipe)));
if (section.contains("furnace"))
- section.getConfigurationSection("furnace").getKeys(false).forEach(recipe -> registerFurnaceRecipe(type, id,
- new BurningRecipeInformation(section.getConfigurationSection("furnace." + recipe)), recipe));
+ section.getConfigurationSection("furnace").getKeys(false)
+ .forEach(recipe -> registerFurnaceRecipe(type, id,
+ new BurningRecipeInformation(section.getConfigurationSection("furnace." + recipe)), recipe));
}
} catch (IllegalArgumentException exception) {
- MMOItems.plugin.getLogger().log(Level.WARNING, "Could not load recipe of " + id + ": " + exception.getMessage());
+ MMOItems.plugin.getLogger().log(Level.WARNING,
+ "Could not load recipe of " + id + ": " + exception.getMessage());
}
}
- // registerCampfireRecipe(MMOItems.plugin.getItems().getItem(Type.SWORD,
- // "SILVER_SWORD"), new
- // RecipeChoice.ExactChoice(MMOItems.plugin.getItems().getItem(Type.get("MATERIAL"),
- // "SILVER_INGOT")));
-
- Bukkit.getScheduler().runTask(MMOItems.plugin, () ->
-
- getLoadedRecipes().forEach(recipe -> Bukkit.addRecipe(recipe.toBukkit())));
+ sortRecipes();
+ Bukkit.getScheduler().runTask(MMOItems.plugin,
+ () -> getLoadedRecipes().forEach(recipe -> Bukkit.addRecipe(recipe.getRecipe())));
}
@Override
public void registerFurnaceRecipe(Type type, String id, BurningRecipeInformation info, String number) {
- NamespacedKey key = getRecipeKey(type, id, "furnace", number);
- FurnaceRecipe recipe = new FurnaceRecipe(key, MMOItems.plugin.getItems().getItem(type, id), info.getChoice().getMaterial(), info.getExp(),
- info.getBurnTime());
- registerRecipe(key, recipe);
- }
-
- @Override
- public void registerShapedRecipe(Type type, String id, List list, String number) {
- NamespacedKey key = getRecipeKey(type, id, "shaped", number);
- ShapedRecipe recipe = new ShapedRecipe(key, MMOItems.plugin.getItems().getItem(type, id));
-
- List rcList = MMORecipeChoice.getFromShapedConfig(list);
- if (rcList == null)
+ if (!info.getChoice().isValid()) {
+ MMOItems.plugin.getLogger().warning("Couldn't load furnace recipe for '" + type.getId() + "." + id + "'");
return;
-
- recipe.shape("ABC", "DEF", "GHI");
-
- shapedIngredient(recipe, 'A', rcList.get(0));
- shapedIngredient(recipe, 'B', rcList.get(1));
- shapedIngredient(recipe, 'C', rcList.get(2));
- shapedIngredient(recipe, 'D', rcList.get(3));
- shapedIngredient(recipe, 'E', rcList.get(4));
- shapedIngredient(recipe, 'F', rcList.get(5));
- shapedIngredient(recipe, 'G', rcList.get(6));
- shapedIngredient(recipe, 'H', rcList.get(7));
- shapedIngredient(recipe, 'I', rcList.get(8));
-
+ }
+ NamespacedKey key = getRecipeKey(type, id, "furnace", number);
+ FurnaceRecipe recipe = new FurnaceRecipe(key, MMOItems.plugin.getItems().getItem(type, id),
+ info.getChoice().getItem().getType(), info.getExp(), info.getBurnTime());
registerRecipe(key, recipe);
}
@Override
- public void shapedIngredient(ShapedRecipe recipe, char c, MMORecipeChoice rc) {
- if (rc.isAir())
- recipe.setIngredient(c, Material.AIR);
- else
- recipe.setIngredient(c, rc.generateStack().getType());
+ public void registerShapedRecipe(Type type, String id, List list) {
+ registerRecipe(new CustomRecipe(MMOItems.plugin.getItems().getMMOItem(type, id).newBuilder().buildNBT(), list, false));
}
@Override
- public void registerShapelessRecipe(Type type, String id, ConfigurationSection config, String number) {
- NamespacedKey key = getRecipeKey(type, id, "shapeless", number);
- ShapelessRecipe recipe = new ShapelessRecipe(key, MMOItems.plugin.getItems().getItem(type, id));
-
- for (int i = 1; i < 10; i++)
- if (config.contains("item" + i))
- shapelessIngredient(recipe, new MMORecipeChoice(config.getString("item" + i)));
-
- if (!recipe.getIngredientList().isEmpty())
- registerRecipe(key, recipe);
- }
-
- @Override
- public void shapelessIngredient(ShapelessRecipe recipe, MMORecipeChoice rc) {
- if (!rc.isAir())
- recipe.addIngredient(rc.getMaterial());
- }
-
- @Override
- public void setIngredientOrAir(ShapedRecipe recipe, char character, ConfigurationSection config) {
- if (config.contains("type")) {
- String typeFormat = config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_");
- Validate.notNull(MMOItems.plugin.getTypes().has(typeFormat), "Could not find item type");
-
- String id = config.getString("id");
- Validate.notNull(id, "Could not find item ID");
-
- ItemStack item = MMOItems.plugin.getItems().getItem(MMOItems.plugin.getTypes().get(typeFormat), id);
- Validate.isTrue(item != null, "Could not load item with ID: " + id);
-
- item.setAmount(config.getInt("amount", 1));
- recipe.setIngredient(character, item.getType());
-
- } else if (config.contains("material")) {
- Material material = Material.valueOf(config.getString("material").toUpperCase().replace("-", "_").replace(" ", "_"));
- recipe.setIngredient(character, material);
- }
+ public void registerShapelessRecipe(Type type, String id, List list) {
+ registerRecipe(new CustomRecipe(MMOItems.plugin.getItems().getMMOItem(type, id).newBuilder().buildNBT(), list, true));
}
}
diff --git a/src/main/java/net/Indyuce/mmoitems/stat/Crafting.java b/src/main/java/net/Indyuce/mmoitems/stat/Crafting.java
index 9aa164ae..139c26a6 100644
--- a/src/main/java/net/Indyuce/mmoitems/stat/Crafting.java
+++ b/src/main/java/net/Indyuce/mmoitems/stat/Crafting.java
@@ -71,7 +71,9 @@ public class Crafting extends ItemStat {
config.getConfig().set(inv.getEdited().getId() + ".crafting.shaped.1", newList);
inv.registerItemEdition(config);
} else {
- config.getConfig().set(inv.getEdited().getId() + ".crafting.shapeless.1.item" + (slot + 1), message);
+ List newList = config.getConfig().getStringList(inv.getEdited().getId() + ".crafting.shapeless.1");
+ newList.set(slot, message);
+ config.getConfig().set(inv.getEdited().getId() + ".crafting.shapeless.1", newList);
inv.registerItemEdition(config);
}
}
@@ -128,6 +130,23 @@ public class Crafting extends ItemStat {
}
private boolean validate(Player player, String input) {
+ if (input.contains(":")) {
+ String[] count = input.split("\\:");
+
+ if (count.length != 2) {
+ player.sendMessage(MMOItems.plugin.getPrefix() + "Invalid format.");
+ return false;
+ }
+
+ try {
+ Integer.parseInt(count[1]);
+ } catch (NumberFormatException exception) {
+ player.sendMessage(MMOItems.plugin.getPrefix() + "'" + count[1] + "' isn't a valid number.");
+ return false;
+ }
+
+ input = count[0];
+ }
if (input.contains(".")) {
String[] typeid = input.split("\\.");
if (typeid.length != 2) {
@@ -149,27 +168,6 @@ public class Crafting extends ItemStat {
return true;
}
- if (input.contains(":")) {
- String[] matmeta = input.split("\\:");
- if (matmeta.length != 2) {
- player.sendMessage(MMOItems.plugin.getPrefix() + "Invalid format.");
- return false;
- }
- try {
- Material.valueOf(matmeta[0].toUpperCase().replace("-", "_"));
- } catch (IllegalArgumentException exception) {
- player.sendMessage(MMOItems.plugin.getPrefix() + "'" + matmeta[0].toUpperCase().replace("-", "_") + "' isn't a valid material.");
- return false;
- }
- try {
- Integer.parseInt(matmeta[1]);
- } catch (NumberFormatException exception) {
- player.sendMessage(MMOItems.plugin.getPrefix() + "'" + matmeta[1] + "' isn't a valid number.");
- return false;
- }
-
- return true;
- }
try {
Material.valueOf(input.toUpperCase().replace("-", "_"));
} catch (Exception e) {
diff --git a/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java b/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java
index c70236b0..a78866b6 100644
--- a/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java
+++ b/src/main/java/net/Indyuce/mmoitems/stat/type/ItemStat.java
@@ -77,177 +77,227 @@ import net.mmogroup.mmolib.version.VersionMaterial;
public abstract class ItemStat {
public static final ItemStat MATERIAL = new MaterialStat(),
- DURABILITY = MMOLib.plugin.getVersion().isBelowOrEqual(1, 12) ? new LegacyDurability() : new DefaultDurability(),
- CUSTOM_MODEL_DATA = new CustomModelData(), MAX_DURABILITY = new MaximumDurability(), WILL_BREAK = new LostWhenBroken();
+ DURABILITY = MMOLib.plugin.getVersion().isBelowOrEqual(1, 12) ? new LegacyDurability()
+ : new DefaultDurability(),
+ CUSTOM_MODEL_DATA = new CustomModelData(), MAX_DURABILITY = new MaximumDurability(),
+ WILL_BREAK = new LostWhenBroken();
public static final ItemStat NAME = new DisplayName(), LORE = new Lore(), NBT_TAGS = new NBTTags();
- public static final ItemStat DISPLAYED_TYPE = new StringStat("DISPLAYED_TYPE", VersionMaterial.OAK_SIGN.toItem(), "Displayed Type",
- new String[] { "This option will only affect the", "type displayed on the item lore." }, new String[] { "all" });
- public static final ItemStat ENCHANTS = new Enchants(), HIDE_ENCHANTS = new HideEnchants(), PERMISSION = new Permission(),
- ITEM_PARTICLES = new ItemParticles(), ARROW_PARTICLES = new ArrowParticles();
- public static final ItemStat DISABLE_INTERACTION = new DisableStat("INTERACTION", VersionMaterial.GRASS_BLOCK.toMaterial(), "Disable Interaction",
- "Disable any unwanted interaction:", "block placement, item use...");
- public static final ItemStat DISABLE_CRAFTING = new DisableStat("CRAFTING", VersionMaterial.CRAFTING_TABLE.toMaterial(), "Disable Crafting",
+ public static final ItemStat DISPLAYED_TYPE = new StringStat("DISPLAYED_TYPE", VersionMaterial.OAK_SIGN.toItem(),
+ "Displayed Type", new String[] { "This option will only affect the", "type displayed on the item lore." },
+ new String[] { "all" });
+ public static final ItemStat ENCHANTS = new Enchants(), HIDE_ENCHANTS = new HideEnchants(),
+ PERMISSION = new Permission(), ITEM_PARTICLES = new ItemParticles(), ARROW_PARTICLES = new ArrowParticles();
+ public static final ItemStat DISABLE_INTERACTION = new DisableStat("INTERACTION",
+ VersionMaterial.GRASS_BLOCK.toMaterial(), "Disable Interaction", "Disable any unwanted interaction:",
+ "block placement, item use...");
+ public static final ItemStat DISABLE_CRAFTING = new DisableStat("CRAFTING",
+ VersionMaterial.CRAFTING_TABLE.toMaterial(), "Disable Crafting",
"Players can't use this item while crafting.");
- public static final ItemStat DISABLE_SMELTING = new DisableStat("SMELTING", Material.FURNACE, "Disable Smelting",
- "Players can't use this item in furnaces.");
- public static final ItemStat DISABLE_SMITHING = new DisableStat("SMITHING", Material.DAMAGED_ANVIL, "Disable Smithing",
- "Players can't smith this item in smithing tables.");
- public static final ItemStat DISABLE_ENCHANTING = new DisableStat("ENCHANTING", VersionMaterial.ENCHANTING_TABLE.toMaterial(),
- "Disable Enchanting", "Players can't enchant this item."), DISABLE_ADVANCED_ENCHANTS = new DisableAdvancedEnchantments();
+ public static final ItemStat DISABLE_SMELTING = new DisableStat("SMELTING", Material.FURNACE, "Disable Smelting",
+ "Players can't use this item in furnaces.");
+ public static final ItemStat DISABLE_SMITHING = new DisableStat("SMITHING", Material.DAMAGED_ANVIL,
+ "Disable Smithing", "Players can't smith this item in smithing tables.");
+ public static final ItemStat DISABLE_ENCHANTING = new DisableStat("ENCHANTING",
+ VersionMaterial.ENCHANTING_TABLE.toMaterial(), "Disable Enchanting", "Players can't enchant this item."),
+ DISABLE_ADVANCED_ENCHANTS = new DisableAdvancedEnchantments();
public static final ItemStat DISABLE_REPAIRING = new DisableStat("REPAIRING", Material.ANVIL, "Disable Repairing",
"Players can't use this item in anvils.");
- public static final ItemStat DISABLE_ARROW_SHOOTING = new DisableStat("ARROW_SHOOTING", Material.ARROW, "Disable Arrow Shooting",
- new Material[] { Material.ARROW }, "Players can't shoot this", "item using a bow.");
- public static final ItemStat DISABLE_ATTACK_PASSIVE = new DisableStat("ATTACK_PASSIVE", Material.BARRIER, "Disable Attack Passive",
- new String[] { "piercing", "slashing", "blunt" }, "Disables the blunt/slashing/piercing", "passive effects on attacks.");
- public static final ItemStat DISABLE_RIGHT_CLICK_CONSUME = new DisableStat("RIGHT_CLICK_CONSUME", Material.BARRIER, "Disable Right Click Consume",
- new String[] { "consumable" }, "This item will not be consumed", "when eaten by players.");
+ public static final ItemStat DISABLE_ARROW_SHOOTING = new DisableStat("ARROW_SHOOTING", Material.ARROW,
+ "Disable Arrow Shooting", new Material[] { Material.ARROW }, "Players can't shoot this",
+ "item using a bow.");
+ public static final ItemStat DISABLE_ATTACK_PASSIVE = new DisableStat("ATTACK_PASSIVE", Material.BARRIER,
+ "Disable Attack Passive", new String[] { "piercing", "slashing", "blunt" },
+ "Disables the blunt/slashing/piercing", "passive effects on attacks.");
+ public static final ItemStat DISABLE_RIGHT_CLICK_CONSUME = new DisableStat("RIGHT_CLICK_CONSUME", Material.BARRIER,
+ "Disable Right Click Consume", new String[] { "consumable" }, "This item will not be consumed",
+ "when eaten by players.");
- public static final ItemStat REQUIRED_LEVEL = new RequiredLevel(), REQUIRED_CLASS = new RequiredClass(), ATTACK_DAMAGE = new AttackDamage(),
- ATTACK_SPEED = new AttackSpeed();
- public static final ItemStat CRITICAL_STRIKE_CHANCE = new DoubleStat("CRITICAL_STRIKE_CHANCE", new ItemStack(Material.NETHER_STAR),
- "Critical Strike Chance", new String[] { "Critical Strikes deal more damage.", "In % chance." },
+ public static final ItemStat REQUIRED_LEVEL = new RequiredLevel(), REQUIRED_CLASS = new RequiredClass(),
+ ATTACK_DAMAGE = new AttackDamage(), ATTACK_SPEED = new AttackSpeed();
+ public static final ItemStat CRITICAL_STRIKE_CHANCE = new DoubleStat("CRITICAL_STRIKE_CHANCE",
+ new ItemStack(Material.NETHER_STAR), "Critical Strike Chance",
+ new String[] { "Critical Strikes deal more damage.", "In % chance." },
new String[] { "!miscellaneous", "all" });
- public static final ItemStat CRITICAL_STRIKE_POWER = new DoubleStat("CRITICAL_STRIKE_POWER", new ItemStack(Material.NETHER_STAR),
- "Critical Strike Power", new String[] { "The extra damage weapon crits deals.", "(Stacks with default value)", "In %." },
+ public static final ItemStat CRITICAL_STRIKE_POWER = new DoubleStat("CRITICAL_STRIKE_POWER",
+ new ItemStack(Material.NETHER_STAR), "Critical Strike Power",
+ new String[] { "The extra damage weapon crits deals.", "(Stacks with default value)", "In %." },
new String[] { "!miscellaneous", "all" });
- public static final ItemStat BLOCK_POWER = new DoubleStat("BLOCK_POWER", new ItemStack(Material.IRON_HELMET), "Block Power",
- new String[] { "The % of the damage your", "armor/shield can block.", "Default: 25%" }, new String[] { "!miscellaneous", "all" });
- public static final ItemStat BLOCK_RATING = new DoubleStat("BLOCK_RATING", new ItemStack(Material.IRON_HELMET), "Block Rating",
- new String[] { "The chance your piece of armor", "has to block any entity attack." }, new String[] { "!miscellaneous", "all" });
- public static final ItemStat BLOCK_COOLDOWN_REDUCTION = new DoubleStat("BLOCK_COOLDOWN_REDUCTION", new ItemStack(Material.IRON_HELMET),
- "Block Cooldown Reduction", new String[] { "Reduces the blocking cooldown (%)." }, new String[] { "!miscellaneous", "all" });
- public static final ItemStat DODGE_RATING = new DoubleStat("DODGE_RATING", new ItemStack(Material.FEATHER), "Dodge Rating",
+ public static final ItemStat BLOCK_POWER = new DoubleStat("BLOCK_POWER", new ItemStack(Material.IRON_HELMET),
+ "Block Power", new String[] { "The % of the damage your", "armor/shield can block.", "Default: 25%" },
+ new String[] { "!miscellaneous", "all" });
+ public static final ItemStat BLOCK_RATING = new DoubleStat("BLOCK_RATING", new ItemStack(Material.IRON_HELMET),
+ "Block Rating", new String[] { "The chance your piece of armor", "has to block any entity attack." },
+ new String[] { "!miscellaneous", "all" });
+ public static final ItemStat BLOCK_COOLDOWN_REDUCTION = new DoubleStat("BLOCK_COOLDOWN_REDUCTION",
+ new ItemStack(Material.IRON_HELMET), "Block Cooldown Reduction",
+ new String[] { "Reduces the blocking cooldown (%)." }, new String[] { "!miscellaneous", "all" });
+ public static final ItemStat DODGE_RATING = new DoubleStat("DODGE_RATING", new ItemStack(Material.FEATHER),
+ "Dodge Rating",
new String[] { "The chance to dodge an attack.", "Dodging completely negates", "the attack damage." },
new String[] { "!miscellaneous", "all" });
- public static final ItemStat DODGE_COOLDOWN_REDUCTION = new DoubleStat("DODGE_COOLDOWN_REDUCTION", new ItemStack(Material.FEATHER),
- "Dodge Cooldown Reduction", new String[] { "Reduces the dodging cooldown (%)." }, new String[] { "!miscellaneous", "all" });
- public static final ItemStat PARRY_RATING = new DoubleStat("PARRY_RATING", new ItemStack(Material.BUCKET), "Parry Rating",
- new String[] { "The chance to parry an attack.", "Parrying negates the damage", "and knocks the attacker back." },
+ public static final ItemStat DODGE_COOLDOWN_REDUCTION = new DoubleStat("DODGE_COOLDOWN_REDUCTION",
+ new ItemStack(Material.FEATHER), "Dodge Cooldown Reduction",
+ new String[] { "Reduces the dodging cooldown (%)." }, new String[] { "!miscellaneous", "all" });
+ public static final ItemStat PARRY_RATING = new DoubleStat(
+ "PARRY_RATING", new ItemStack(Material.BUCKET), "Parry Rating", new String[] {
+ "The chance to parry an attack.", "Parrying negates the damage", "and knocks the attacker back." },
new String[] { "!miscellaneous", "all" });
- public static final ItemStat PARRY_COOLDOWN_REDUCTION = new DoubleStat("PARRY_COOLDOWN_REDUCTION", new ItemStack(Material.BUCKET),
- "Parry Cooldown Reduction", new String[] { "Reduces the parrying cooldown (%)." }, new String[] { "!miscellaneous", "all" });
- public static final ItemStat COOLDOWN_REDUCTION = new DoubleStat("COOLDOWN_REDUCTION", new ItemStack(Material.BOOK), "Cooldown Reduction",
- new String[] { "Reduces cooldowns of item skills (%)." });
+ public static final ItemStat PARRY_COOLDOWN_REDUCTION = new DoubleStat("PARRY_COOLDOWN_REDUCTION",
+ new ItemStack(Material.BUCKET), "Parry Cooldown Reduction",
+ new String[] { "Reduces the parrying cooldown (%)." }, new String[] { "!miscellaneous", "all" });
+ public static final ItemStat COOLDOWN_REDUCTION = new DoubleStat("COOLDOWN_REDUCTION", new ItemStack(Material.BOOK),
+ "Cooldown Reduction", new String[] { "Reduces cooldowns of item skills (%)." });
public static final ItemStat RANGE = new DoubleStat("RANGE", new ItemStack(Material.STICK), "Range",
new String[] { "The range of your item attacks." }, new String[] { "staff", "whip", "wand", "musket" });
- public static final ItemStat MANA_COST = new DoubleStat("MANA_COST", VersionMaterial.LAPIS_LAZULI.toItem(), "Mana Cost",
- new String[] { "Mana spent by your weapon to be used." }, new String[] { "piercing", "slashing", "blunt", "range" });
- public static final ItemStat STAMINA_COST = new DoubleStat("STAMINA_COST", VersionMaterial.LIGHT_GRAY_DYE.toItem(), "Stamina Cost",
- new String[] { "Stamina spent by your weapon to be used." }, new String[] { "piercing", "slashing", "blunt", "range" });
- public static final ItemStat ARROW_VELOCITY = new DoubleStat("ARROW_VELOCITY", new ItemStack(Material.ARROW), "Arrow Velocity",
- new String[] { "Determins how far your", "crossbow can shoot.", "Default: 1.0" }, new String[] { "bow", "crossbow" });
- public static final ItemStat PVE_DAMAGE = new DoubleStat("PVE_DAMAGE", VersionMaterial.PORKCHOP.toItem(), "PvE Damage",
- new String[] { "Additional damage against", "non human entities in %." },
- new String[] { "piercing", "slashing", "blunt", "offhand", "range", "tool", "armor", "gem_stone", "accessory" });
- public static final ItemStat PVP_DAMAGE = new DoubleStat("PVP_DAMAGE", VersionMaterial.SKELETON_SKULL.toItem(), "PvP Damage",
- new String[] { "Additional damage", "against players in %." },
- new String[] { "piercing", "slashing", "blunt", "offhand", "range", "tool", "armor", "gem_stone", "accessory" });
- public static final ItemStat BLUNT_POWER = new DoubleStat("BLUNT_POWER", new ItemStack(Material.IRON_AXE), "Blunt Power",
- new String[] { "The radius of the AoE attack.", "If set to 2.0, enemies within 2 blocks", "around your target will take damage." },
+ public static final ItemStat MANA_COST = new DoubleStat("MANA_COST", VersionMaterial.LAPIS_LAZULI.toItem(),
+ "Mana Cost", new String[] { "Mana spent by your weapon to be used." },
+ new String[] { "piercing", "slashing", "blunt", "range" });
+ public static final ItemStat STAMINA_COST = new DoubleStat("STAMINA_COST", VersionMaterial.LIGHT_GRAY_DYE.toItem(),
+ "Stamina Cost", new String[] { "Stamina spent by your weapon to be used." },
+ new String[] { "piercing", "slashing", "blunt", "range" });
+ public static final ItemStat ARROW_VELOCITY = new DoubleStat("ARROW_VELOCITY", new ItemStack(Material.ARROW),
+ "Arrow Velocity", new String[] { "Determins how far your", "crossbow can shoot.", "Default: 1.0" },
+ new String[] { "bow", "crossbow" });
+ public static final ItemStat PVE_DAMAGE = new DoubleStat("PVE_DAMAGE", VersionMaterial.PORKCHOP.toItem(),
+ "PvE Damage", new String[] { "Additional damage against", "non human entities in %." }, new String[] {
+ "piercing", "slashing", "blunt", "offhand", "range", "tool", "armor", "gem_stone", "accessory" });
+ public static final ItemStat PVP_DAMAGE = new DoubleStat("PVP_DAMAGE", VersionMaterial.SKELETON_SKULL.toItem(),
+ "PvP Damage", new String[] { "Additional damage", "against players in %." }, new String[] { "piercing",
+ "slashing", "blunt", "offhand", "range", "tool", "armor", "gem_stone", "accessory" });
+ public static final ItemStat BLUNT_POWER = new DoubleStat("BLUNT_POWER", new ItemStack(Material.IRON_AXE),
+ "Blunt Power", new String[] { "The radius of the AoE attack.", "If set to 2.0, enemies within 2 blocks",
+ "around your target will take damage." },
new String[] { "blunt", "gem_stone" });
- public static final ItemStat BLUNT_RATING = new DoubleStat("BLUNT_RATING", new ItemStack(Material.BRICK), "Blunt Rating",
- new String[] { "The force of the blunt attack.", "If set to 50%, enemies hit by the attack", "will take 50% of the initial damage." },
+ public static final ItemStat BLUNT_RATING = new DoubleStat("BLUNT_RATING", new ItemStack(Material.BRICK),
+ "Blunt Rating", new String[] { "The force of the blunt attack.", "If set to 50%, enemies hit by the attack",
+ "will take 50% of the initial damage." },
new String[] { "blunt", "gem_stone" });
- public static final ItemStat WEAPON_DAMAGE = new DoubleStat("WEAPON_DAMAGE", new ItemStack(Material.IRON_SWORD), "Weapon Damage",
- new String[] { "Additional on-hit weapon damage in %." });
- public static final ItemStat SKILL_DAMAGE = new DoubleStat("SKILL_DAMAGE", new ItemStack(Material.BOOK), "Skill Damage",
- new String[] { "Additional ability damage in %." });
- public static final ItemStat PROJECTILE_DAMAGE = new DoubleStat("PROJECTILE_DAMAGE", new ItemStack(Material.ARROW), "Projectile Damage",
- new String[] { "Additional skill/weapon projectile damage." });
- public static final ItemStat MAGIC_DAMAGE = new DoubleStat("MAGIC_DAMAGE", new ItemStack(Material.MAGMA_CREAM), "Magic Damage",
- new String[] { "Additional magic skill damage in %." });
- public static final ItemStat PHYSICAL_DAMAGE = new DoubleStat("PHYSICAL_DAMAGE", new ItemStack(Material.IRON_AXE), "Physical Damage",
- new String[] { "Additional skill/weapon physical damage." });
- public static final ItemStat DAMAGE_REDUCTION = new DoubleStat("DAMAGE_REDUCTION", new ItemStack(Material.IRON_CHESTPLATE), "Damage Reduction",
+ public static final ItemStat WEAPON_DAMAGE = new DoubleStat("WEAPON_DAMAGE", new ItemStack(Material.IRON_SWORD),
+ "Weapon Damage", new String[] { "Additional on-hit weapon damage in %." });
+ public static final ItemStat SKILL_DAMAGE = new DoubleStat("SKILL_DAMAGE", new ItemStack(Material.BOOK),
+ "Skill Damage", new String[] { "Additional ability damage in %." });
+ public static final ItemStat PROJECTILE_DAMAGE = new DoubleStat("PROJECTILE_DAMAGE", new ItemStack(Material.ARROW),
+ "Projectile Damage", new String[] { "Additional skill/weapon projectile damage." });
+ public static final ItemStat MAGIC_DAMAGE = new DoubleStat("MAGIC_DAMAGE", new ItemStack(Material.MAGMA_CREAM),
+ "Magic Damage", new String[] { "Additional magic skill damage in %." });
+ public static final ItemStat PHYSICAL_DAMAGE = new DoubleStat("PHYSICAL_DAMAGE", new ItemStack(Material.IRON_AXE),
+ "Physical Damage", new String[] { "Additional skill/weapon physical damage." });
+ public static final ItemStat DAMAGE_REDUCTION = new DoubleStat("DAMAGE_REDUCTION",
+ new ItemStack(Material.IRON_CHESTPLATE), "Damage Reduction",
new String[] { "Reduces damage from any source.", "In %." });
- public static final ItemStat FALL_DAMAGE_REDUCTION = new DoubleStat("FALL_DAMAGE_REDUCTION", new ItemStack(Material.FEATHER),
- "Fall Damage Reduction", new String[] { "Reduces fall damage.", "In %." });
- public static final ItemStat PROJECTILE_DAMAGE_REDUCTION = new DoubleStat("PROJECTILE_DAMAGE_REDUCTION", VersionMaterial.SNOWBALL.toItem(),
- "Projectile Damage Reduction", new String[] { "Reduces projectile damage.", "In %." });
- public static final ItemStat PHYSICAL_DAMAGE_REDUCTION = new DoubleStat("PHYSICAL_DAMAGE_REDUCTION", new ItemStack(Material.LEATHER_CHESTPLATE),
- "Physical Damage Reduction", new String[] { "Reduces physical damage.", "In %." });
- public static final ItemStat FIRE_DAMAGE_REDUCTION = new DoubleStat("FIRE_DAMAGE_REDUCTION", new ItemStack(Material.BLAZE_POWDER),
- "Fire Damage Reduction", new String[] { "Reduces fire damage.", "In %." });
- public static final ItemStat MAGIC_DAMAGE_REDUCTION = new DoubleStat("MAGIC_DAMAGE_REDUCTION", new ItemStack(Material.POTION),
- "Magic Damage Reduction", new String[] { "Reduce magic damage dealt by potions.", "In %." });
- public static final ItemStat PVE_DAMAGE_REDUCTION = new DoubleStat("PVE_DAMAGE_REDUCTION", VersionMaterial.PORKCHOP.toItem(),
- "PvE Damage Reduction", new String[] { "Reduces damage dealt by mobs.", "In %." });
- public static final ItemStat PVP_DAMAGE_REDUCTION = new DoubleStat("PVP_DAMAGE_REDUCTION", VersionMaterial.SKELETON_SKULL.toItem(),
- "PvP Damage Reduction", new String[] { "Reduces damage dealt by players", "In %." });
- public static final ItemStat UNDEAD_DAMAGE = new DoubleStat("UNDEAD_DAMAGE", VersionMaterial.SKELETON_SKULL.toItem(), "Undead Damage",
+ public static final ItemStat FALL_DAMAGE_REDUCTION = new DoubleStat("FALL_DAMAGE_REDUCTION",
+ new ItemStack(Material.FEATHER), "Fall Damage Reduction", new String[] { "Reduces fall damage.", "In %." });
+ public static final ItemStat PROJECTILE_DAMAGE_REDUCTION = new DoubleStat("PROJECTILE_DAMAGE_REDUCTION",
+ VersionMaterial.SNOWBALL.toItem(), "Projectile Damage Reduction",
+ new String[] { "Reduces projectile damage.", "In %." });
+ public static final ItemStat PHYSICAL_DAMAGE_REDUCTION = new DoubleStat("PHYSICAL_DAMAGE_REDUCTION",
+ new ItemStack(Material.LEATHER_CHESTPLATE), "Physical Damage Reduction",
+ new String[] { "Reduces physical damage.", "In %." });
+ public static final ItemStat FIRE_DAMAGE_REDUCTION = new DoubleStat("FIRE_DAMAGE_REDUCTION",
+ new ItemStack(Material.BLAZE_POWDER), "Fire Damage Reduction",
+ new String[] { "Reduces fire damage.", "In %." });
+ public static final ItemStat MAGIC_DAMAGE_REDUCTION = new DoubleStat("MAGIC_DAMAGE_REDUCTION",
+ new ItemStack(Material.POTION), "Magic Damage Reduction",
+ new String[] { "Reduce magic damage dealt by potions.", "In %." });
+ public static final ItemStat PVE_DAMAGE_REDUCTION = new DoubleStat("PVE_DAMAGE_REDUCTION",
+ VersionMaterial.PORKCHOP.toItem(), "PvE Damage Reduction",
+ new String[] { "Reduces damage dealt by mobs.", "In %." });
+ public static final ItemStat PVP_DAMAGE_REDUCTION = new DoubleStat("PVP_DAMAGE_REDUCTION",
+ VersionMaterial.SKELETON_SKULL.toItem(), "PvP Damage Reduction",
+ new String[] { "Reduces damage dealt by players", "In %." });
+ public static final ItemStat UNDEAD_DAMAGE = new DoubleStat("UNDEAD_DAMAGE",
+ VersionMaterial.SKELETON_SKULL.toItem(), "Undead Damage",
new String[] { "Deals additional damage to undead.", "In %." });
- public static final ItemStat UNBREAKABLE = new Unbreakable(), TIER = new ItemTierStat(), SET = new ItemSetStat(), ARMOR = new Armor(),
- ARMOR_TOUGHNESS = new ArmorToughness(), MAX_HEALTH = new MaxHealth();
- public static final ItemStat MAX_MANA = new DoubleStat("MAX_MANA", VersionMaterial.LAPIS_LAZULI.toItem(), "Max Mana",
- new String[] { "Adds mana to your max mana bar." });
+ public static final ItemStat UNBREAKABLE = new Unbreakable(), TIER = new ItemTierStat(), SET = new ItemSetStat(),
+ ARMOR = new Armor(), ARMOR_TOUGHNESS = new ArmorToughness(), MAX_HEALTH = new MaxHealth();
+ public static final ItemStat MAX_MANA = new DoubleStat("MAX_MANA", VersionMaterial.LAPIS_LAZULI.toItem(),
+ "Max Mana", new String[] { "Adds mana to your max mana bar." });
public static final ItemStat KNOCKBACK_RESISTANCE = new KnockbackResistance(), MOVEMENT_SPEED = new MovementSpeed();
- public static final ItemStat TWO_HANDED = new BooleanStat("TWO_HANDED", new ItemStack(Material.IRON_INGOT), "Two Handed",
- new String[] { "If set to true, a player will be", "significantly slower if holding two", "items, one being Two Handed." },
+ public static final ItemStat TWO_HANDED = new BooleanStat("TWO_HANDED", new ItemStack(Material.IRON_INGOT),
+ "Two Handed",
+ new String[] { "If set to true, a player will be", "significantly slower if holding two",
+ "items, one being Two Handed." },
new String[] { "piercing", "slashing", "blunt", "offhand", "range", "tool" });
public static final ItemStat RESTORE = new Restore();
- public static final ItemStat RESTORE_MANA = new DoubleStat("RESTORE_MANA", VersionMaterial.LAPIS_LAZULI.toItem(), "Restore Mana",
- new String[] { "The amount of mana", "your consumable restores." }, new String[] { "consumable" });
- public static final ItemStat RESTORE_STAMINA = new DoubleStat("RESTORE_STAMINA", VersionMaterial.LIGHT_GRAY_DYE.toItem(), "Restore Stamina",
+ public static final ItemStat RESTORE_MANA = new DoubleStat("RESTORE_MANA", VersionMaterial.LAPIS_LAZULI.toItem(),
+ "Restore Mana", new String[] { "The amount of mana", "your consumable restores." },
+ new String[] { "consumable" });
+ public static final ItemStat RESTORE_STAMINA = new DoubleStat("RESTORE_STAMINA",
+ VersionMaterial.LIGHT_GRAY_DYE.toItem(), "Restore Stamina",
new String[] { "The amount of stamina/power", "your consumable restores." }, new String[] { "consumable" });
- public static final ItemStat CAN_IDENTIFY = new BooleanStat("CAN_IDENTIFY", new ItemStack(Material.PAPER), "Can Identify?",
- new String[] { "Players can identify & make their", "item usable using this consumable." }, new String[] { "consumable" });
- public static final ItemStat CAN_DECONSTRUCT = new BooleanStat("CAN_DECONSTRUCT", new ItemStack(Material.PAPER), "Can Deconstruct?",
- new String[] { "Players can deconstruct their item", "using this consumable, creating", "another random item." },
+ public static final ItemStat CAN_IDENTIFY = new BooleanStat("CAN_IDENTIFY", new ItemStack(Material.PAPER),
+ "Can Identify?", new String[] { "Players can identify & make their", "item usable using this consumable." },
+ new String[] { "consumable" });
+ public static final ItemStat CAN_DECONSTRUCT = new BooleanStat(
+ "CAN_DECONSTRUCT", new ItemStack(Material.PAPER), "Can Deconstruct?", new String[] {
+ "Players can deconstruct their item", "using this consumable, creating", "another random item." },
new String[] { "consumable" });
public static final ItemStat EFFECTS = new Effects(), PERM_EFFECTS = new PermanentEffects();
- public static final ItemStat SOULBINDING_CHANCE = new DoubleStat("SOULBINDING_CHANCE", VersionMaterial.ENDER_EYE.toItem(), "Soulbinding Chance",
- new String[] { "Defines the chance your item has to", "link another item to your soul,", "preventing other players from using it." },
+ public static final ItemStat SOULBINDING_CHANCE = new DoubleStat("SOULBINDING_CHANCE",
+ VersionMaterial.ENDER_EYE.toItem(), "Soulbinding Chance",
+ new String[] { "Defines the chance your item has to", "link another item to your soul,",
+ "preventing other players from using it." },
new String[] { "consumable" });
- public static final ItemStat SOULBOUND_BREAK_CHANCE = new DoubleStat(
- "SOULBOUND_BREAK_CHANCE", VersionMaterial.ENDER_EYE.toItem(), "Soulbound Break Chance", new String[] { "The chance of breaking an item's",
- "soulbound when drag & drop'd on it.", "This chance is lowered depending", "on the soulbound's level." },
+ public static final ItemStat SOULBOUND_BREAK_CHANCE = new DoubleStat("SOULBOUND_BREAK_CHANCE",
+ VersionMaterial.ENDER_EYE.toItem(), "Soulbound Break Chance",
+ new String[] { "The chance of breaking an item's", "soulbound when drag & drop'd on it.",
+ "This chance is lowered depending", "on the soulbound's level." },
new String[] { "consumable" });
public static final ItemStat SOULBOUND_LEVEL = new SoulboundLevel();
- public static final ItemStat ITEM_COOLDOWN = new DoubleStat("ITEM_COOLDOWN", new ItemStack(Material.COOKED_CHICKEN), "Item Cooldown",
- new String[] { "This cooldown applies for consumables", "as well as for item commands." },
+ public static final ItemStat ITEM_COOLDOWN = new DoubleStat("ITEM_COOLDOWN", new ItemStack(Material.COOKED_CHICKEN),
+ "Item Cooldown", new String[] { "This cooldown applies for consumables", "as well as for item commands." },
new String[] { "!armor", "!gem_stone", "all" });
- public static final ItemStat VANILLA_EATING_ANIMATION = new VanillaEatingAnimation(), INEDIBLE = new Inedible(), GEM_COLOR = new GemColor(),
- ITEM_TYPE_RESTRICTION = new ItemTypeRestriction();
- public static final ItemStat MAX_CONSUME = new DoubleStat("MAX_CONSUME", new ItemStack(Material.BLAZE_POWDER), "Max Consume",
- new String[] { "Max amount of usage before", "item disappears." }, new String[] { "consumable" });
+ public static final ItemStat VANILLA_EATING_ANIMATION = new VanillaEatingAnimation(), INEDIBLE = new Inedible(),
+ GEM_COLOR = new GemColor(), ITEM_TYPE_RESTRICTION = new ItemTypeRestriction();
+ public static final ItemStat MAX_CONSUME = new DoubleStat("MAX_CONSUME", new ItemStack(Material.BLAZE_POWDER),
+ "Max Consume", new String[] { "Max amount of usage before", "item disappears." },
+ new String[] { "consumable" });
public static final ItemStat SUCCESS_RATE = new SuccessRate();
public static final ItemStat COMPATIBLE_TYPES = new CompatibleTypes();
- public static final ItemStat CRAFTING = new Crafting(), CRAFT_PERMISSION = new CraftingPermission();
+ public static final ItemStat CRAFTING = new Crafting(), CRAFT_PERMISSION = new CraftingPermission(),
+ CRAFT_AMOUNT = new DoubleStat("CRAFTED_AMOUNT", new ItemStack(Material.WOODEN_AXE), "Crafted Amount",
+ new String[] { "The stack count for", "this item when crafted." }, new String[] { "all" });
public static final ItemStat AUTOSMELT = new BooleanStat("AUTOSMELT", new ItemStack(Material.COAL), "Autosmelt",
- new String[] { "If set to true, your tool will", "automaticaly smelt mined ores." }, new String[] { "tool" });
- public static final ItemStat BOUNCING_CRACK = new BooleanStat("BOUNCING_CRACK", VersionMaterial.COBBLESTONE_WALL.toItem(), "Bouncing Crack",
+ new String[] { "If set to true, your tool will", "automaticaly smelt mined ores." },
+ new String[] { "tool" });
+ public static final ItemStat BOUNCING_CRACK = new BooleanStat("BOUNCING_CRACK",
+ VersionMaterial.COBBLESTONE_WALL.toItem(), "Bouncing Crack",
new String[] { "If set to true, your tool will", "also break nearby blocks." }, new String[] { "tool" });
public static final ItemStat PICKAXE_POWER = new PickaxePower();
public static final ItemStat CUSTOM_SOUNDS = new CustomSounds();
public static final ItemStat ELEMENTS = new Elements();
- public static final ItemStat COMMANDS = new Commands(), STAFF_SPIRIT = new StaffSpiritStat(), LUTE_ATTACK_SOUND = new LuteAttackSoundStat(),
- LUTE_ATTACK_EFFECT = new LuteAttackEffectStat();
- public static final ItemStat NOTE_WEIGHT = new DoubleStat("NOTE_WEIGHT", VersionMaterial.MUSIC_DISC_MALL.toItem(), "Note Weight",
- new String[] { "Defines how the projectile cast", "by your lute tilts downwards." }, new String[] { "lute" });
- public static final ItemStat REMOVE_ON_CRAFT = new BooleanStat("REMOVE_ON_CRAFT", new ItemStack(Material.GLASS_BOTTLE), "Remove on Craft",
- new String[] { "If the item should be completely", "removed when used in a recipe,", "or if it should become an",
- "empty bottle or bucket." },
- new String[] { "all" }, Material.POTION, Material.SPLASH_POTION, Material.LINGERING_POTION, Material.MILK_BUCKET, Material.LAVA_BUCKET,
- Material.WATER_BUCKET);
+ public static final ItemStat COMMANDS = new Commands(), STAFF_SPIRIT = new StaffSpiritStat(),
+ LUTE_ATTACK_SOUND = new LuteAttackSoundStat(), LUTE_ATTACK_EFFECT = new LuteAttackEffectStat();
+ public static final ItemStat NOTE_WEIGHT = new DoubleStat("NOTE_WEIGHT", VersionMaterial.MUSIC_DISC_MALL.toItem(),
+ "Note Weight", new String[] { "Defines how the projectile cast", "by your lute tilts downwards." },
+ new String[] { "lute" });
+ public static final ItemStat REMOVE_ON_CRAFT = new BooleanStat("REMOVE_ON_CRAFT",
+ new ItemStack(Material.GLASS_BOTTLE), "Remove on Craft",
+ new String[] { "If the item should be completely", "removed when used in a recipe,",
+ "or if it should become an", "empty bottle or bucket." },
+ new String[] { "all" }, Material.POTION, Material.SPLASH_POTION, Material.LINGERING_POTION,
+ Material.MILK_BUCKET, Material.LAVA_BUCKET, Material.WATER_BUCKET);
public static final ItemStat GEM_SOCKETS = new GemSockets();
public static final ItemStat REPAIR = new DoubleStat("REPAIR", new ItemStack(Material.ANVIL), "Repair",
- new String[] { "The amount of durability your item", "can repair when set an item." }, new String[] { "consumable" });
+ new String[] { "The amount of durability your item", "can repair when set an item." },
+ new String[] { "consumable" });
// public static final ItemStat REPAIR_MATERIAL = new RepairMaterial();
- public static final ItemStat KNOCKBACK = new DoubleStat("KNOCKBACK", VersionMaterial.IRON_HORSE_ARMOR.toItem(), "Knockback",
- new String[] { "Using this musket will knock", "the user back if positive." }, new String[] { "musket" });
+ public static final ItemStat KNOCKBACK = new DoubleStat("KNOCKBACK", VersionMaterial.IRON_HORSE_ARMOR.toItem(),
+ "Knockback", new String[] { "Using this musket will knock", "the user back if positive." },
+ new String[] { "musket" });
public static final ItemStat RECOIL = new DoubleStat("RECOIL", VersionMaterial.IRON_HORSE_ARMOR.toItem(), "Recoil",
new String[] { "Corresponds to the shooting innacuracy." }, new String[] { "musket" });
public static final ItemStat ABILITIES = new Abilities(), UPGRADE = new UpgradeStat();
- public static final ItemStat SKULL_TEXTURE = new SkullTextureStat(), DYE_COLOR = new DyeColor(), POTION_EFFECTS = new PotionEffects(),
- POTION_COLOR = new PotionColor(), SHIELD_PATTERN = new ShieldPatternStat(), HIDE_POTION_EFFECTS = new HidePotionEffects();
+ public static final ItemStat SKULL_TEXTURE = new SkullTextureStat(), DYE_COLOR = new DyeColor(),
+ POTION_EFFECTS = new PotionEffects(), POTION_COLOR = new PotionColor(),
+ SHIELD_PATTERN = new ShieldPatternStat(), HIDE_POTION_EFFECTS = new HidePotionEffects();
/*
* internal stats
@@ -262,8 +312,8 @@ public abstract class ItemStat {
private final List compatibleMaterials;
/*
- * the stat can be enabled or not, depending on the server version to
- * prevent from displaying useless editable stats in the edition menu.
+ * the stat can be enabled or not, depending on the server version to prevent
+ * from displaying useless editable stats in the edition menu.
*/
private boolean enabled = true;
@@ -277,15 +327,14 @@ public abstract class ItemStat {
}
/*
- * reads stat data from a configuration section and applies it to the item
- * stack after having generated the corresponding stat data class instance
+ * reads stat data from a configuration section and applies it to the item stack
+ * after having generated the corresponding stat data class instance
*/
public abstract StatData whenInitialized(Object object);
/*
- * any item stat which can be used in the item generator. this method reads
- * from a config file stat data which is cached to later generate a random
- * item
+ * any item stat which can be used in the item generator. this method reads from
+ * a config file stat data which is cached to later generate a random item
*/
public abstract RandomStatData whenInitializedGeneration(Object object);
@@ -300,8 +349,7 @@ public abstract class ItemStat {
public abstract boolean whenClicked(EditionInventory inv, InventoryClickEvent event);
/*
- * when entering input using the chat edition feature from the item edition
- * menu
+ * when entering input using the chat edition feature from the item edition menu
*/
public abstract boolean whenInput(EditionInventory inv, ConfigFile config, String message, Object... info);
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 92d015b0..29462798 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -130,10 +130,6 @@ cooldown-progress-bar-char: █
# When toggled off, players can't damage each other using item abilities.
ability-player-damage: true
-# When enabled, all custom recipes will be in the recipe book on join.
-# If toggled off they will have to use to recipe once to add it to their book.
-auto-recipe-book: true
-
# Displays a message on the action bar instead of on the chat.
# Can be used to reduce chat spam.
# Might interfere with other action bar plugins.
diff --git a/src/main/resources/default/item/consumable.yml b/src/main/resources/default/item/consumable.yml
index 7f6fbb5e..46ae7a87 100644
--- a/src/main/resources/default/item/consumable.yml
+++ b/src/main/resources/default/item/consumable.yml
@@ -299,15 +299,15 @@ EGGNOG:
crafting:
shapeless:
'1':
- item1: EGG
- item2: SUGAR
- item3: AIR
- item4: AIR
- item5: AIR
- item6: AIR
- item7: AIR
- item8: AIR
- item9: AIR
+ - EGG
+ - SUGAR
+ - AIR
+ - AIR
+ - AIR
+ - AIR
+ - AIR
+ - AIR
+ - AIR
MANGO:
material: PLAYER_HEAD
name: '&fMango'
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index d70eb149..b8e1fcfe 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -13,6 +13,8 @@ commands:
updateitem:
description: Update the item you are holding.
aliases: [upitem,itemup]
+ recipes:
+ description: Opens the recipe book for viewing all custom recipes.
permissions:
mmoitems.admin:
description: Access to admin commands.
@@ -41,3 +43,6 @@ permissions:
mmoitems.soulbound:
description: Allows to use /soulbound.
default: op
+ mmoitems.recipes:
+ description: Allows to use /recipes.
+ default: true
\ No newline at end of file