MMORecipeChoice refactor

This commit is contained in:
Indyuce 2020-08-20 13:21:13 +02:00
parent cdc7b32edb
commit 649c16f9c6
10 changed files with 144 additions and 183 deletions

View File

@ -1,33 +0,0 @@
package net.Indyuce.mmoitems.api.recipe;
import org.apache.commons.lang.Validate;
import org.bukkit.inventory.ItemStack;
import net.Indyuce.mmoitems.MMOItems;
import net.mmogroup.mmolib.api.item.NBTItem;
public class MMORecipeChoice {
private final ItemStack item;
private final int amount;
private final boolean isVanilla;
public MMORecipeChoice(String input) {
item = MMOItems.plugin.getRecipes().parseStack(input);
Validate.notNull(item, "Could not parse recipe choice");
isVanilla = !NBTItem.get(item).hasType();
amount = item.getAmount();
}
public ItemStack getItem() {
return item;
}
public int getAmount() {
return amount;
}
public boolean isVanilla() {
return isVanilla;
}
}

View File

@ -7,7 +7,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.bukkit.Material;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.Permission;
@ -27,7 +27,7 @@ public class CustomRecipe implements Comparable<CustomRecipe> {
private final String id;
private final boolean shapeless;
private final Map<Integer, WorkbenchIngredient> ingredients = new HashMap<>(9);
private Permission perm = null;
private Permission permission;
public CustomRecipe(Type type, String id, List<String> recipe, boolean isShapeless) {
this.shapeless = isShapeless;
@ -35,31 +35,22 @@ public class CustomRecipe implements Comparable<CustomRecipe> {
this.id = id;
if (shapeless) {
if (recipe.size() != 9) {
MMOItems.plugin.getLogger()
.warning("Invalid shapeless recipe for '" + type.getId() + "." + id + "'");
recipe = Arrays.asList("AIR", "AIR", "AIR", "AIR", "AIR", "AIR", "AIR", "AIR", "AIR");
}
Validate.isTrue(recipe.size() == 9, "Invalid shapeless recipe");
for (int i = 0; i < 9; i++) {
ItemStack stack = MMOItems.plugin.getRecipes().parseStack(recipe.get(i));
if (stack != null && stack.getType() != Material.AIR)
ingredients.put(i, WorkbenchIngredient.getAutomatically(stack));
WorkbenchIngredient ingredient = MMOItems.plugin.getRecipes().getWorkbenchIngredient(recipe.get(i));
if (!(ingredient instanceof AirIngredient))
ingredients.put(i, ingredient);
}
} else {
if (recipe.size() != 3) {
MMOItems.plugin.getLogger()
.warning("Invalid shaped recipe for '" + type.getId() + "." + id + "'");
recipe = Arrays.asList("AIR AIR AIR", "AIR AIR AIR", "AIR AIR AIR");
}
for (int i = 0; i < 9; i++) {
List<String> line = Arrays.asList(recipe.get(i / 3).split("\\ "));
while (line.size() < 3)
line.add("AIR");
return;
}
ItemStack stack = MMOItems.plugin.getRecipes().parseStack(line.get(i % 3));
ingredients.put(i,
stack == null || stack.getType() == Material.AIR ? new AirIngredient() : WorkbenchIngredient.getAutomatically(stack));
}
Validate.isTrue(recipe.size() == 3, "Invalid shaped recipe");
for (int i = 0; i < 9; i++) {
List<String> line = Arrays.asList(recipe.get(i / 3).split("\\ "));
while (line.size() < 3)
line.add("AIR");
ingredients.put(i, MMOItems.plugin.getRecipes().getWorkbenchIngredient(line.get(i % 3)));
}
}
@ -81,20 +72,19 @@ public class CustomRecipe implements Comparable<CustomRecipe> {
public boolean isShapeless() {
return shapeless;
}
public boolean permCheck(Player player) {
if(perm == null) return true;
else return player.hasPermission(perm);
public boolean checkPermission(Player player) {
return permission == null || player.hasPermission(permission);
}
public ItemStack getResult(Player p) {
PlayerData player = PlayerData.get(p);
MMOItem mmo = MMOItems.plugin.getMMOItem(type, id, player);
ItemStack stack = mmo.newBuilder().build();
if(mmo.hasData(ItemStat.CRAFT_AMOUNT))
if (mmo.hasData(ItemStat.CRAFT_AMOUNT))
stack.setAmount((int) ((DoubleData) mmo.getData(ItemStat.CRAFT_AMOUNT)).getValue());
if(mmo.hasData(ItemStat.CRAFT_PERMISSION))
perm = new Permission(mmo.getData(ItemStat.CRAFT_PERMISSION).toString(), PermissionDefault.FALSE);
if (mmo.hasData(ItemStat.CRAFT_PERMISSION))
permission = new Permission(mmo.getData(ItemStat.CRAFT_PERMISSION).toString(), PermissionDefault.FALSE);
return stack;
}

View File

@ -1,16 +1,31 @@
package net.Indyuce.mmoitems.api.recipe.workbench.ingredients;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.RecipeChoice;
public class AirIngredient extends WorkbenchIngredient {
public AirIngredient() {
super(0);
}
@Override
public boolean matches(ItemStack stack) {
if(stack == null) return true;
else return false;
return stack == null || stack.getType() == Material.AIR;
}
@Override
public boolean matchStack(ItemStack stack) {
public boolean corresponds(ItemStack stack) {
return true;
}
@Override
public ItemStack generateItem() {
return new ItemStack(Material.AIR);
}
@Override
public RecipeChoice toBukkit() {
return new RecipeChoice.MaterialChoice(Material.AIR);
}
}

View File

@ -1,26 +0,0 @@
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);
}
}

View File

@ -0,0 +1,37 @@
package net.Indyuce.mmoitems.api.recipe.workbench.ingredients;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.RecipeChoice;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.mmogroup.mmolib.api.item.NBTItem;
public class MMOItemIngredient extends WorkbenchIngredient {
private final Type type;
private final String id;
public MMOItemIngredient(Type type, String id, int amount) {
super(amount);
this.type = type;
this.id = id;
}
@Override
public boolean corresponds(ItemStack stack) {
NBTItem nbt = NBTItem.get(stack);
return type.equals(nbt.getType()) && nbt.getString("MMOITEMS_ITEM_ID").equalsIgnoreCase(id);
}
@Override
public ItemStack generateItem() {
return MMOItems.plugin.getItem(type, id);
}
@SuppressWarnings("deprecation")
@Override
public RecipeChoice toBukkit() {
return new RecipeChoice.ExactChoice(generateItem());
}
}

View File

@ -2,19 +2,31 @@ package net.Indyuce.mmoitems.api.recipe.workbench.ingredients;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.RecipeChoice;
import net.mmogroup.mmolib.api.item.NBTItem;
public class VanillaIngredient extends WorkbenchIngredient {
private final Material mat;
public VanillaIngredient(Material mat) {
this.mat = mat;
private final Material material;
public VanillaIngredient(Material material, int amount) {
super(amount);
this.material = material;
}
@Override
public boolean matchStack(ItemStack stack) {
if(NBTItem.get(stack).hasType()) return false;
return stack.getType() == mat;
public boolean corresponds(ItemStack stack) {
return !NBTItem.get(stack).hasType() && stack.getType() == material;
}
@Override
public ItemStack generateItem() {
return new ItemStack(material);
}
@Override
public RecipeChoice toBukkit() {
return new RecipeChoice.MaterialChoice(material);
}
}

View File

@ -1,34 +1,26 @@
package net.Indyuce.mmoitems.api.recipe.workbench.ingredients;
import org.bukkit.inventory.ItemStack;
import net.mmogroup.mmolib.api.item.NBTItem;
import org.bukkit.inventory.RecipeChoice;
public abstract class WorkbenchIngredient {
private int amount;
public void setAmount(int value) {
amount = value;
private final int amount;
public WorkbenchIngredient(int amount) {
this.amount = amount;
}
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);
return stack != null && stack.getAmount() >= amount && corresponds(stack);
}
public abstract boolean matchStack(ItemStack stack);
public abstract RecipeChoice toBukkit();
public abstract ItemStack generateItem();
protected abstract boolean corresponds(ItemStack stack);
}

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@ -55,11 +56,13 @@ public class RecipeEdition extends EditionInventory {
while (line.size() < 3)
line.add("AIR");
ItemStack element = MMOItems.plugin.getRecipes().parseStack(line.get(j % 3));
if (element == null)
ItemStack element;
try {
element = MMOItems.plugin.getRecipes().getWorkbenchIngredient(line.get(j % 3)).generateItem();
Validate.isTrue(element != null && element.getType() != Material.AIR);
} catch (IllegalArgumentException exception) {
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");
@ -88,11 +91,13 @@ public class RecipeEdition extends EditionInventory {
for (int j = 0; j < 9; j++) {
int slot = intToSlot(j);
ItemStack element = MMOItems.plugin.getRecipes().parseStack(ingredients.get(j));
if (element == null)
ItemStack element;
try {
element = MMOItems.plugin.getRecipes().getWorkbenchIngredient(ingredients.get(j)).generateItem();
Validate.isTrue(element != null && element.getType() != Material.AIR);
} catch (IllegalArgumentException exception) {
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");

View File

@ -96,7 +96,7 @@ public class CraftingListener implements Listener {
public Optional<CachedRecipe> checkRecipes(Player player, ItemStack[] matrix) {
for (CustomRecipe recipe : MMOItems.plugin.getRecipes().getCustomRecipes()) {
if ((!recipe.fitsPlayerCrafting() && matrix.length == 4) || !recipe.permCheck(player))
if ((!recipe.fitsPlayerCrafting() && matrix.length == 4) || !recipe.checkPermission(player))
continue;
boolean empty = true;

View File

@ -8,7 +8,6 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Keyed;
import org.bukkit.Material;
@ -25,10 +24,12 @@ import org.bukkit.inventory.SmokingRecipe;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
import net.Indyuce.mmoitems.api.recipe.MMORecipeChoice;
import net.Indyuce.mmoitems.api.recipe.workbench.CustomRecipe;
import net.Indyuce.mmoitems.api.recipe.workbench.ingredients.AirIngredient;
import net.Indyuce.mmoitems.api.recipe.workbench.ingredients.MMOItemIngredient;
import net.Indyuce.mmoitems.api.recipe.workbench.ingredients.VanillaIngredient;
import net.Indyuce.mmoitems.api.recipe.workbench.ingredients.WorkbenchIngredient;
public class RecipeManager {
@ -87,7 +88,7 @@ public class RecipeManager {
public void registerBurningRecipe(BurningRecipeType recipeType, Type type, String id, BurningRecipeInformation info, String recipeId) {
NamespacedKey key = getRecipeKey(type, id, recipeType.getPath(), recipeId);
Recipe recipe = recipeType.provideRecipe(key, MMOItems.plugin.getItem(type, id), toBukkit(info.getChoice()), info.getExp(),
Recipe recipe = recipeType.provideRecipe(key, MMOItems.plugin.getItem(type, id), info.getChoice().toBukkit(), info.getExp(),
info.getBurnTime());
loadedRecipes.add(recipe);
}
@ -100,17 +101,6 @@ public class RecipeManager {
registerRecipe(new CustomRecipe(type, id, 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.isVanilla() ? new RecipeChoice.MaterialChoice(choice.getItem().getType()) : new RecipeChoice.ExactChoice(choice.getItem());
}
public void registerRecipe(CustomRecipe recipe) {
if (!recipe.isEmpty())
craftingRecipes.add(recipe);
@ -157,43 +147,22 @@ public class RecipeManager {
});
}
/***
* Parses an ItemStack from a string. Can be used to both get a vanilla
* material or an MMOItem
*/
public ItemStack parseStack(String parse) {
ItemStack stack = null;
String[] split = parse.split("\\:");
String input = split[0];
public WorkbenchIngredient getWorkbenchIngredient(String input) {
String[] split = input.split("\\:");
int amount = split.length > 1 ? Integer.parseInt(split[1]) : 1;
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);
MMOItem mmo = MMOItems.plugin.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) {
MMOItems.plugin.getLogger().warning("Couldn't parse material from '" + parse + "'!");
}
if (mat != Material.AIR)
stack = new ItemStack(mat);
if (split[0].contains(".")) {
String[] split1 = split[0].split("\\.");
Type type = MMOItems.plugin.getTypes().getOrThrow(split1[0].toUpperCase().replace("-", "_").replace(" ", "_"));
MMOItemTemplate template = MMOItems.plugin.getTemplates().getTemplateOrThrow(type,
split1[1].toUpperCase().replace("-", "_").replace(" ", "_"));
return new MMOItemIngredient(type, template.getId(), amount);
}
try {
if (stack != null && split.length > 1)
stack.setAmount(Integer.parseInt(split[1]));
} catch (NumberFormatException e) {
MMOItems.plugin.getLogger().warning("Couldn't parse amount from '" + parse + "'!");
}
if (split[0].equalsIgnoreCase("air"))
return new AirIngredient();
return stack;
return new VanillaIngredient(Material.valueOf(input.toUpperCase().replace("-", "_").replace(" ", "_")), amount);
}
/**
@ -235,12 +204,12 @@ public class RecipeManager {
* @author ASangarin
*/
public class BurningRecipeInformation {
private final MMORecipeChoice choice;
private final WorkbenchIngredient choice;
private final float exp;
private final int burnTime;
protected BurningRecipeInformation(ConfigurationSection config) {
choice = new MMORecipeChoice(config.getString("item"));
public BurningRecipeInformation(ConfigurationSection config) {
choice = getWorkbenchIngredient(config.getString("item"));
exp = (float) config.getDouble("exp", 0.35);
burnTime = config.getInt("time", 200);
}
@ -249,7 +218,7 @@ public class RecipeManager {
return burnTime;
}
public MMORecipeChoice getChoice() {
public WorkbenchIngredient getChoice() {
return choice;
}