Removed unused legacy custom recipes

This commit is contained in:
Indyuce 2022-11-05 12:45:00 +01:00
parent 29e38bd4a0
commit 1471923a2c
7 changed files with 469 additions and 857 deletions

View File

@ -39,7 +39,6 @@ import net.Indyuce.mmoitems.comp.rpg.McMMOHook;
import net.Indyuce.mmoitems.comp.rpg.RPGHandler;
import net.Indyuce.mmoitems.gui.PluginInventory;
import net.Indyuce.mmoitems.gui.edition.recipe.RecipeBrowserGUI;
import net.Indyuce.mmoitems.listener.CraftingListener;
import net.Indyuce.mmoitems.manager.*;
import net.Indyuce.mmoitems.util.PluginUtils;
import org.apache.commons.lang.Validate;
@ -250,20 +249,6 @@ public class MMOItems extends JavaPlugin {
// Compatibility with /reload
Bukkit.getScheduler().runTask(this, () -> Bukkit.getOnlinePlayers().forEach(PlayerData::load));
boolean book = getConfig().getBoolean("recipes.use-recipe-book");
boolean amounts = getConfig().getBoolean("recipes.recipe-amounts");
if (book && amounts) {
getLogger().warning("Tried to enable recipe book while amounts are active!");
getLogger().warning("Please use only ONE of these options!");
getLogger().warning("Disabling both options for now...");
book = false;
amounts = false;
}
recipeManager.load(book, amounts);
if (amounts) Bukkit.getPluginManager().registerEvents(new CraftingListener(), this);
// Amount and bukkit recipes
getLogger().log(Level.INFO, "Loading recipes, please wait...");
recipeManager.loadRecipes();

View File

@ -1,71 +0,0 @@
package net.Indyuce.mmoitems.api.recipe.workbench;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
public class CachedRecipe {
private final Map<Integer, Integer> amounts = new HashMap<>();
private ItemStack stack;
public boolean isValid(ItemStack[] matrix) {
//System.out.println("Checking validity");
boolean check = true;
for (int i = 0; i < matrix.length; i++) {
if (matrix[i] == null || matrix[i].getType() == Material.AIR) {
//System.out.printf("[%d] is null or air%n", i);
continue;
}
if (matrix[i].getAmount() < amounts.get(i)) {
//System.out.printf("[%d] did not have correct amounts (%d < %d)%n", i, matrix[i].getAmount(), amounts.get(i));
check = false;
}
if (!check) {
//System.out.println("Failed the check");
break;
}
}
//System.out.println("Succeeded the check");
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 || stack.getType() == Material.AIR) {
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;
}
public void clean() {
for (int i = 0; i < 9; i++)
if(!amounts.containsKey(i))
amounts.put(i, 0);
}
}

View File

@ -1,159 +0,0 @@
package net.Indyuce.mmoitems.api.recipe.workbench;
import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import net.Indyuce.mmoitems.api.player.PlayerData;
import net.Indyuce.mmoitems.api.recipe.workbench.ingredients.AirIngredient;
import net.Indyuce.mmoitems.api.recipe.workbench.ingredients.WorkbenchIngredient;
import org.apache.commons.lang.Validate;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import javax.annotation.Nullable;
import java.util.*;
import java.util.Map.Entry;
public class CustomRecipe implements Comparable<CustomRecipe> {
private final Type type;
private final String id;
private final boolean shapeless;
private final Map<Integer, WorkbenchIngredient> ingredients = new HashMap<>(9);
private Permission permission;
public CustomRecipe(Type type, String id, List<String> recipe, boolean isShapeless) {
this.shapeless = isShapeless;
this.type = type;
this.id = id;
if (shapeless) {
Validate.isTrue(recipe.size() == 9, "Invalid shapeless recipe");
for (int i = 0; i < 9; i++) {
WorkbenchIngredient ingredient = MMOItems.plugin.getRecipes().getWorkbenchIngredient(recipe.get(i));
// Only add AirIngredients if the amount system is enabled
if (MMOItems.plugin.getRecipes().isAmounts() || !(ingredient instanceof AirIngredient))
ingredients.put(i, ingredient);
}
return;
}
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");
WorkbenchIngredient ingredient = MMOItems.plugin.getRecipes().getWorkbenchIngredient(line.get(i % 3));
if (!(ingredient instanceof AirIngredient))
ingredients.put(i, ingredient);
}
}
public Set<Entry<Integer, WorkbenchIngredient>> getIngredients() {
return ingredients.entrySet();
}
public boolean isOneRow() {
for (int value : ingredients.keySet())
if (value > 2)
return false;
return true;
}
public boolean isTwoRows() {
for (int value : ingredients.keySet())
if (value > 5)
return false;
return true;
}
public boolean fitsPlayerCrafting() {
for (int value : ingredients.keySet())
if (value > 4 || value == 2)
return false;
return true;
}
public boolean isEmpty() {
return ingredients.isEmpty();
}
public boolean isShapeless() {
return shapeless;
}
public Type getType() {
return type;
}
public String getId() {
return id;
}
public boolean checkPermission(Player player) {
return permission == null || player.hasPermission(permission);
}
public ItemStack getResult(@Nullable Player p) {
MMOItem mmo = p == null ? MMOItems.plugin.getMMOItem(type, id)
: MMOItems.plugin.getMMOItem(type, id, PlayerData.get(p));
ItemStack stack = mmo.newBuilder().build();
/*if (mmo.hasData(ItemStats.CRAFT_AMOUNT))
stack.setAmount((int) ((DoubleData) mmo.getData(ItemStats.CRAFT_AMOUNT)).getValue());*/
if (mmo.hasData(ItemStats.CRAFT_PERMISSION))
permission = new Permission(mmo.getData(ItemStats.CRAFT_PERMISSION).toString(), PermissionDefault.FALSE);
return stack;
}
@Override
public int compareTo(CustomRecipe o) {
return Boolean.compare(shapeless, o.shapeless);
}
public Recipe asBukkit(NamespacedKey key) {
Recipe recipe;
if (shapeless) {
org.bukkit.inventory.ShapelessRecipe r = new org.bukkit.inventory.ShapelessRecipe(key, getResult(null));
for (WorkbenchIngredient ingredient : ingredients.values())
if (!(ingredient instanceof AirIngredient))
r.addIngredient(ingredient.toBukkit());
recipe = r;
} else {
org.bukkit.inventory.ShapedRecipe r = new org.bukkit.inventory.ShapedRecipe(key, getResult(null));
char[] characters = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'};
List<Integer> list = new ArrayList<>(ingredients.keySet());
StringBuilder firstRow = new StringBuilder();
firstRow.append(list.contains(0) ? "A" : " ");
firstRow.append(list.contains(1) ? "B" : " ");
firstRow.append(list.contains(2) ? "C" : " ");
if(!isOneRow()) {
StringBuilder secondRow = new StringBuilder();
secondRow.append(list.contains(3) ? "D" : " ");
secondRow.append(list.contains(4) ? "E" : " ");
secondRow.append(list.contains(5) ? "F" : " ");
if(!isTwoRows()) {
r.shape(firstRow.toString(), secondRow.toString(),
(list.contains(6) ? "G" : " ") +
(list.contains(7) ? "H" : " ") +
(list.contains(8) ? "I" : " "));
}
else r.shape(firstRow.toString(), secondRow.toString());
}
else r.shape(firstRow.toString());
for (Entry<Integer, WorkbenchIngredient> ingredient : getIngredients()) {
if (ingredient.getValue() instanceof AirIngredient) continue;
char c = characters[ingredient.getKey()];
r.setIngredient(c, ingredient.getValue().toBukkit());
}
recipe = r;
}
return recipe;
}
}

View File

@ -11,95 +11,93 @@ import org.bukkit.command.CommandSender;
import java.util.function.Consumer;
public class ReloadCommandTreeNode extends CommandTreeNode {
public ReloadCommandTreeNode(CommandTreeNode parent) {
super(parent, "reload");
public ReloadCommandTreeNode(CommandTreeNode parent) {
super(parent, "reload");
addChild(new SubReloadCommandTreeNode("recipes", this, this::reloadRecipes));
addChild(new SubReloadCommandTreeNode("stations", this, this::reloadStations));
addChild(new SubReloadCommandTreeNode("skills", this, this::reloadSkills));
addChild(new SubReloadCommandTreeNode("all", this, (sender) -> {
reloadMain(sender);
reloadRecipes(sender);
reloadStations(sender);
reloadSkills(sender);
}));
}
addChild(new SubReloadCommandTreeNode("recipes", this, this::reloadRecipes));
addChild(new SubReloadCommandTreeNode("stations", this, this::reloadStations));
addChild(new SubReloadCommandTreeNode("skills", this, this::reloadSkills));
addChild(new SubReloadCommandTreeNode("all", this, (sender) -> {
reloadMain(sender);
reloadRecipes(sender);
reloadStations(sender);
reloadSkills(sender);
}));
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
reloadMain(sender);
return CommandResult.SUCCESS;
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
reloadMain(sender);
return CommandResult.SUCCESS;
}
public class SubReloadCommandTreeNode extends CommandTreeNode {
private final Consumer<CommandSender> action;
public class SubReloadCommandTreeNode extends CommandTreeNode {
private final Consumer<CommandSender> action;
public SubReloadCommandTreeNode(String sub, CommandTreeNode parent, Consumer<CommandSender> action) {
super(parent, sub);
this.action = action;
}
public SubReloadCommandTreeNode(String sub, CommandTreeNode parent, Consumer<CommandSender> action) {
super(parent, sub);
this.action = action;
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
action.accept(sender);
return CommandResult.SUCCESS;
}
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
action.accept(sender);
return CommandResult.SUCCESS;
}
}
public void reloadSkills(CommandSender sender) {
MythicLib.plugin.getSkills().initialize(true);
MMOItems.plugin.getSkills().initialize(true);
sender.sendMessage(MMOItems.plugin.getPrefix() + "Successfully reloaded " + MMOItems.plugin.getSkills().getAll().size() + " skills.");
}
public void reloadSkills(CommandSender sender) {
MythicLib.plugin.getSkills().initialize(true);
MMOItems.plugin.getSkills().initialize(true);
sender.sendMessage(MMOItems.plugin.getPrefix() + "Successfully reloaded " + MMOItems.plugin.getSkills().getAll().size() + " skills.");
}
public void reloadMain(CommandSender sender) {
MMOItems.plugin.getLanguage().reload();
MMOItems.plugin.getDropTables().reload();
MMOItems.plugin.getTypes().reload();
MMOItems.plugin.getTiers().reload();
MMOItems.plugin.getSets().reload();
MMOItems.plugin.getUpgrades().reload();
MMOItems.plugin.getWorldGen().reload();
MMOItems.plugin.getCustomBlocks().reload();
MMOItems.plugin.getLayouts().reload();
MMOItems.plugin.getFormats().reload();
MMOItems.plugin.getTemplates().reload();
MMOItems.plugin.getStats().reload(true);
sender.sendMessage(MMOItems.plugin.getPrefix() + MMOItems.plugin.getName() + " "
+ MMOItems.plugin.getDescription().getVersion() + " reloaded.");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getTypes().getAll().size() + ChatColor.GRAY + " Item Types");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getTiers().getAll().size() + ChatColor.GRAY + " Item Tiers");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getSets().getAll().size() + ChatColor.GRAY + " Item Sets");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getUpgrades().getAll().size() + ChatColor.GRAY + " Upgrade Templates");
public void reloadMain(CommandSender sender) {
MMOItems.plugin.getLanguage().reload();
MMOItems.plugin.getDropTables().reload();
MMOItems.plugin.getTypes().reload();
MMOItems.plugin.getTiers().reload();
MMOItems.plugin.getSets().reload();
MMOItems.plugin.getUpgrades().reload();
MMOItems.plugin.getWorldGen().reload();
MMOItems.plugin.getCustomBlocks().reload();
MMOItems.plugin.getLayouts().reload();
MMOItems.plugin.getFormats().reload();
MMOItems.plugin.getTemplates().reload();
MMOItems.plugin.getStats().reload(true);
sender.sendMessage(MMOItems.plugin.getPrefix() + MMOItems.plugin.getName() + " "
+ MMOItems.plugin.getDescription().getVersion() + " reloaded.");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getTypes().getAll().size() + ChatColor.GRAY + " Item Types");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getTiers().getAll().size() + ChatColor.GRAY + " Item Tiers");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getSets().getAll().size() + ChatColor.GRAY + " Item Sets");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getUpgrades().getAll().size() + ChatColor.GRAY + " Upgrade Templates");
// This one is not implementing Reloadable
NumericStatFormula.reload();
MMOItemReforger.reload();
}
// *This one is not implementing Reloadable
NumericStatFormula.reload();
MMOItemReforger.reload();
}
public void reloadRecipes(CommandSender sender) {
MMOItems.plugin.getRecipes().reload();
sender.sendMessage(MMOItems.plugin.getPrefix() + "Successfully reloaded recipes.");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ (MMOItems.plugin.getRecipes().getLoadedLegacyRecipes().size()
+ MMOItems.plugin.getRecipes().getBooklessRecipes().size()
+ MMOItems.plugin.getRecipes().getCustomRecipes().size())
+ ChatColor.GRAY + " Recipes");
}
public void reloadRecipes(CommandSender sender) {
MMOItems.plugin.getRecipes().reload();
sender.sendMessage(MMOItems.plugin.getPrefix() + "Successfully reloaded recipes.");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ (MMOItems.plugin.getRecipes().getLoadedLegacyRecipes().size()
+ MMOItems.plugin.getRecipes().getLegacyCustomRecipes().size()
+ MMOItems.plugin.getRecipes().getBooklessRecipes().size()
+ MMOItems.plugin.getRecipes().getCustomRecipes().size())
+ ChatColor.GRAY + " Recipes");
}
public void reloadStations(CommandSender sender) {
MMOItems.plugin.getLayouts().reload();
MMOItems.plugin.getCrafting().reload();
sender.sendMessage(MMOItems.plugin.getPrefix() + "Successfully reloaded the crafting stations..");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getCrafting().getAll().size() + ChatColor.GRAY + " Crafting Stations");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getCrafting().countRecipes() + ChatColor.GRAY + " Recipes");
}
public void reloadStations(CommandSender sender) {
MMOItems.plugin.getLayouts().reload();
MMOItems.plugin.getCrafting().reload();
sender.sendMessage(MMOItems.plugin.getPrefix() + "Successfully reloaded the crafting stations..");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getCrafting().getAll().size() + ChatColor.GRAY + " Crafting Stations");
sender.sendMessage(MMOItems.plugin.getPrefix() + "- " + ChatColor.RED
+ MMOItems.plugin.getCrafting().countRecipes() + ChatColor.GRAY + " Recipes");
}
}

View File

@ -1,160 +0,0 @@
package net.Indyuce.mmoitems.listener;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.event.CraftMMOItemEvent;
import net.Indyuce.mmoitems.api.player.PlayerData;
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;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
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 java.util.*;
import java.util.Map.Entry;
public class CraftingListener implements Listener {
final Map<UUID, CachedRecipe> 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) || !(e.getInventory() instanceof CraftingInventory))
return;
Player player = (Player) e.getView().getPlayer();
if (e.getSlotType() == SlotType.CRAFTING && e.getAction() == InventoryAction.PLACE_ONE)
Bukkit.getScheduler().runTaskLater(MMOItems.plugin, () ->
handleCustomCrafting((CraftingInventory) e.getInventory(), player), 1);
else if (e.getSlotType() == SlotType.RESULT) {
CraftingInventory inv = (CraftingInventory) e.getInventory();
if (e.getCurrentItem() == null || !cachedRecipe.containsKey(e.getWhoClicked().getUniqueId()))
return;
if (e.getAction() != InventoryAction.PICKUP_ALL) {
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;
}
CraftMMOItemEvent event = new CraftMMOItemEvent(PlayerData.get(player),
cached.getResult());
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
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, () -> {
boolean check = true;
for (ItemStack stack : newMatrix)
if (stack != null) {
check = false;
break;
}
if (check) {
inv.setMatrix(new ItemStack[]{null, null, null, null, null, null, null, null, null});
} else
inv.setMatrix(newMatrix);
}, 1);
e.setCurrentItem(event.getResult());
Bukkit.getScheduler().runTaskLater(MMOItems.plugin, player::updateInventory, 1);
}
}
public void handleCustomCrafting(CraftingInventory inv, Player player) {
cachedRecipe.remove(player.getUniqueId());
Optional<CachedRecipe> recipe = checkRecipes(player, inv.getMatrix());
if (recipe.isPresent()) {
cachedRecipe.put(player.getUniqueId(), recipe.get());
inv.setResult(recipe.get().getResult());
Bukkit.getScheduler().runTaskLater(MMOItems.plugin, () -> {
inv.setItem(0, recipe.get().getResult());
player.updateInventory();
}, 1);
}
}
public Optional<CachedRecipe> checkRecipes(Player player, ItemStack[] matrix) {
for (CustomRecipe recipe : MMOItems.plugin.getRecipes().getLegacyCustomRecipes()) {
if ((!recipe.fitsPlayerCrafting() && matrix.length == 4) || !recipe.checkPermission(player))
continue;
boolean empty = true;
for (ItemStack itemStack : matrix) {
if (itemStack != null) {
empty = false;
break;
}
}
if (empty) return Optional.empty();
CachedRecipe cached = new CachedRecipe();
boolean matches = true;
List<Integer> slotsChecked = new ArrayList<>();
for (Entry<Integer, WorkbenchIngredient> ingredients : recipe.getIngredients()) {
if (recipe.isShapeless()) {
boolean check = false;
int nonnullcount = 0;
for (int i = 0; i < matrix.length; i++) {
if (slotsChecked.contains(i))
continue;
ItemStack item = matrix[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;
}
cached.clean();
if (nonnullcount > recipe.getIngredients().size()) {
check = false;
break;
}
}
if (!check)
matches = false;
} else {
if (!ingredients.getValue().matches(matrix[ingredients.getKey()]))
matches = false;
else
cached.add(ingredients.getKey(), ingredients.getValue().getAmount());
}
if (!matches)
break;
}
if (matches) {
cached.setResult(recipe.getResult(player));
return Optional.of(cached);
}
}
return Optional.empty();
}
}

View File

@ -1,8 +1,6 @@
package net.Indyuce.mmoitems.manager;
import java.util.*;
import java.util.stream.Collectors;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.crafting.recipes.MythicRecipeBlueprint;
import io.lumine.mythic.lib.api.crafting.uifilters.VanillaUIFilter;
import io.lumine.mythic.lib.api.crafting.uimanager.ProvidedUIFilter;
@ -11,7 +9,15 @@ import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackCategory;
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackMessage;
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider;
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.crafting.MMOItemUIFilter;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
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;
import net.Indyuce.mmoitems.api.util.message.FFPMMOItems;
import net.Indyuce.mmoitems.gui.edition.recipe.RecipeBrowserGUI;
import net.Indyuce.mmoitems.gui.edition.recipe.recipes.RecipeMakerGUI;
@ -24,28 +30,16 @@ import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.BlastingRecipe;
import org.bukkit.inventory.CampfireRecipe;
import org.bukkit.inventory.CookingRecipe;
import org.bukkit.inventory.FurnaceRecipe;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.RecipeChoice;
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.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;
import io.lumine.mythic.lib.MythicLib;
import org.bukkit.inventory.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Manages the custom crafting of MMOItem components and stuff.
*
@ -53,367 +47,399 @@ import org.jetbrains.annotations.Nullable;
*/
public class RecipeManager implements Reloadable {
/**
* Custom recipes which are handled by MMOItems
*/
final HashSet<CustomRecipe> legacyCraftingRecipes = new HashSet<>();
/**
* Recipes which are handled by the vanilla spigot API. All recipes
* registered here are Keyed
*/
final HashSet<Recipe> loadedLegacyRecipes = new HashSet<>();
/**
* Recipes which are handled by the vanilla spigot API.
* All recipes registered here are Keyed
*/
final HashSet<Recipe> loadedLegacyRecipes = new HashSet<>();
/**
* All the custom recipes loaded by MMOItems.
* <p></p>
* <b>Except that for the time being, only Workbench recipes are supported
* by mythic lib so for any other kind use the legacy array.</b>
*/
final HashMap<NamespacedKey, MythicRecipeBlueprint> customRecipes = new HashMap<>();
final ArrayList<MythicRecipeBlueprint> booklessRecipes = new ArrayList<>();
@NotNull ArrayList<NamespacedKey> blacklistedFromAutomaticDiscovery = new ArrayList<>();
/**
* All the custom recipes loaded by MMOItems.
* <p></p>
* <b>Except that for the time being, only Workbench recipes are supported
* by mythic lib so for any other kind use the legacy array.</b>
*/
final HashMap<NamespacedKey, MythicRecipeBlueprint> customRecipes = new HashMap<>();
final ArrayList<MythicRecipeBlueprint> booklessRecipes = new ArrayList<>();
private boolean book, amounts;
@NotNull
ArrayList<NamespacedKey> blacklistedFromAutomaticDiscovery = new ArrayList<>();
/**
* @param book Vanilla knowledge book support.
*
* @param amounts If the recipe system should support glitchy multi amount
* recipes. Ignored by MythicLib recipes.
*/
public void load(boolean book, boolean amounts) {
this.book = book;
this.amounts = amounts; }
private boolean book;
public boolean isAmounts() { return amounts; }
public void loadRecipes() {
this.book = MMOItems.plugin.getConfig().getBoolean("recipes.use-recipe-book");
public void loadRecipes() {
legacyCraftingRecipes.clear();
// For logging
FriendlyFeedbackProvider ffp = new FriendlyFeedbackProvider(FFPMMOItems.get());
ffp.activatePrefix(true, "Custom Crafting");
// For logging
FriendlyFeedbackProvider ffp = new FriendlyFeedbackProvider(FFPMMOItems.get());
ffp.activatePrefix(true, "Custom Crafting");
// Every single type yes
for (Type type : MMOItems.plugin.getTypes().getAll()) {
// Every single type yes
for (Type type : MMOItems.plugin.getTypes().getAll()) {
// Find their config
FileConfiguration config = type.getConfigFile().getConfig();
// Find their config
FileConfiguration config = type.getConfigFile().getConfig();
// For every template of those types
for (MMOItemTemplate template : MMOItems.plugin.getTemplates().getTemplates(type)) {
// For every template of those types
for (MMOItemTemplate template : MMOItems.plugin.getTemplates().getTemplates(type)) {
// Does it have a crafting recipe?
if (config.contains(template.getId() + ".base.crafting")) {
// Does it have a crafting recipe?
if (config.contains(template.getId() + ".base.crafting")) {
// Get section containing the crafting recipes
ConfigurationSection section = RecipeMakerGUI.getSection(config, template.getId() + ".base.crafting");
// Get section containing the crafting recipes
ConfigurationSection section = RecipeMakerGUI.getSection(config, template.getId() + ".base.crafting");
// All loaded recipes
for (String recipeType : RecipeBrowserGUI.getRegisteredRecipes()) {
// All loaded recipes
for (String recipeType : RecipeBrowserGUI.getRegisteredRecipes()) {
// Is it in-yo?
if (section.contains(recipeType)) {
// Is it in-yo?
if (section.contains(recipeType)) {
// Get Registry
RecipeRegistry rr = RecipeBrowserGUI.getRegisteredRecipe(recipeType);
// Get Registry
RecipeRegistry rr = RecipeBrowserGUI.getRegisteredRecipe(recipeType);
// Get recipe type section
ConfigurationSection typeSection = RecipeMakerGUI.getSection(section, recipeType);
// Get recipe type section
ConfigurationSection typeSection = RecipeMakerGUI.getSection(section, recipeType);
// Register dem
for (String recipeName : typeSection.getKeys(false)) {
// Register dem
for (String recipeName : typeSection.getKeys(false)) {
// Generate its key
NamespacedKey nk = getRecipeKey(template.getType(), template.getId(), recipeType, recipeName);
// Generate its key
NamespacedKey nk = getRecipeKey(template.getType(), template.getId(), recipeType, recipeName);
// Wrap
Ref<NamespacedKey> nkRef = new Ref<>(nk);
// Wrap
Ref<NamespacedKey> nkRef = new Ref<>(nk);
// Error yes
FriendlyFeedbackProvider ffpMinor = new FriendlyFeedbackProvider(FFPMMOItems.get());
ffpMinor.activatePrefix(true, "Recipe of $u" + template.getType() + " " + template.getId());
// Send to mythiclib
try {
// The result of sending to MythicLib
MythicRecipeBlueprint blueprint = rr.sendToMythicLib(template, typeSection, recipeName, nkRef, ffpMinor);
// Was it registered in the book, then?
if (nkRef.getValue() != null) {
customRecipes.put(nkRef.getValue(), blueprint);
// Bookless, include in the other list.
} else { booklessRecipes.add(blueprint); }
// Well something went wrong...
} catch (IllegalArgumentException error) {
// Empty message? Snooze that
if (!error.getMessage().isEmpty()) {
// Log error
MMOItems.print(null, "Cannot register custom recipe '$u{2}$b' for $e{0} {1}$b;$f {3}", "Custom Crafting", type.getId(), template.getId(), recipeName, error.getMessage());
// Include failures in the report
ffpMinor.sendTo(FriendlyFeedbackCategory.ERROR, MMOItems.getConsole());
ffpMinor.sendTo(FriendlyFeedbackCategory.FAILURE, MMOItems.getConsole());
}
}
}
}
}
}
}
}
// Error yes
FriendlyFeedbackProvider ffpMinor = new FriendlyFeedbackProvider(FFPMMOItems.get());
ffpMinor.activatePrefix(true, "Recipe of $u" + template.getType() + " " + template.getId());
// Log relevant messages
ffp.sendTo(FriendlyFeedbackCategory.ERROR, MMOItems.getConsole());
ffp.sendTo(FriendlyFeedbackCategory.FAILURE, MMOItems.getConsole());
// Send to mythiclib
try {
// Sort recipes
sortRecipes();
// The result of sending to MythicLib
MythicRecipeBlueprint blueprint = rr.sendToMythicLib(template, typeSection, recipeName, nkRef, ffpMinor);
// Load legacy recipes onto Bukkit System
Bukkit.getScheduler().runTask(MMOItems.plugin, () -> getLoadedLegacyRecipes().forEach(Bukkit::addRecipe));
}
// Was it registered in the book, then?
if (nkRef.getValue() != null) {
customRecipes.put(nkRef.getValue(), blueprint);
public void registerBurningRecipe(@NotNull BurningRecipeType recipeType, @NotNull MMOItem mmo, @NotNull BurningRecipeInformation info, int amount, @NotNull NamespacedKey key, boolean hidden) {
// Build its item stacc
ItemStack stack = mmo.newBuilder().build();
stack.setAmount(amount);
// Do whatever this is / I just wont touch it
CookingRecipe<?> recipe = recipeType.provideRecipe(key, stack, info.getChoice().toBukkit(), info.getExp(), info.getBurnTime());
// Register that recipe lets goo
loadedLegacyRecipes.add(recipe);
if (hidden) { blacklistedFromAutomaticDiscovery.add(key); }
}
public void registerRecipeAsCustom(CustomRecipe recipe) {
if (!recipe.isEmpty())
legacyCraftingRecipes.add(recipe);
}
public void registerRecipeAsBukkit(CustomRecipe recipe, String number) {
NamespacedKey key = getRecipeKey(recipe.getType(), recipe.getId(), recipe.isShapeless() ? "shapeless" : "shaped", number);
if (!recipe.isEmpty())
loadedLegacyRecipes.add(recipe.asBukkit(key));
}
public Set<Recipe> getLoadedLegacyRecipes() {
return loadedLegacyRecipes;
}
public Set<CustomRecipe> getLegacyCustomRecipes() {
return legacyCraftingRecipes;
}
public HashMap<NamespacedKey, MythicRecipeBlueprint> getCustomRecipes() { return customRecipes; }
public ArrayList<MythicRecipeBlueprint> getBooklessRecipes() { return booklessRecipes; }
@Nullable
ArrayList<NamespacedKey> generatedNKs;
public ArrayList<NamespacedKey> getNamespacedKeys() {
if (generatedNKs != null) { return generatedNKs; }
// Collect all Namespaces
ArrayList<NamespacedKey> nkMythic = new ArrayList<>(customRecipes.keySet());
ArrayList<NamespacedKey> nkLegacy = loadedLegacyRecipes.stream().map(recipe -> ((Keyed) recipe).getKey()).distinct().collect(Collectors.toCollection(ArrayList::new));
nkMythic.addAll(nkLegacy);
generatedNKs = new ArrayList<>();
for (NamespacedKey nk : nkMythic) { if (nk != null) { generatedNKs.add(nk); }}
return generatedNKs;
}
public void sortRecipes() {
List<CustomRecipe> temporary = new ArrayList<>(legacyCraftingRecipes);
legacyCraftingRecipes.clear();
legacyCraftingRecipes.addAll(temporary.stream().sorted().collect(Collectors.toList()));
}
@NotNull public NamespacedKey getRecipeKey(@NotNull Type type, @NotNull String id, @NotNull String recipeType, @NotNull String number) {
return new NamespacedKey(MMOItems.plugin, recipeType + "_" + type.getId() + "_" + id + "_" + number);
}
/**
* Unregisters bukkit and MythicLib recipes and loads everything again.
*/
public void reload() {
Bukkit.getScheduler().runTask(MMOItems.plugin, () -> {
// Remove all recipes
for (NamespacedKey recipe : getNamespacedKeys()) {
if (recipe == null) { continue; }
try { Bukkit.removeRecipe(recipe); }
catch (Throwable e) { MMOItems.print(null, "Could not register crafting book recipe for $r{0}$b:$f {1}", "MMOItems Custom Crafting", recipe.getKey(), e.getMessage()); }
}
// Clear loaded recipes
loadedLegacyRecipes.clear();
blacklistedFromAutomaticDiscovery.clear();
// Disable and forget all blueprints
for (NamespacedKey b : customRecipes.keySet()) {
if (b == null) { continue; }
customRecipes.get(b).disable();
try { Bukkit.removeRecipe(b); }
catch (Throwable e) { MMOItems.print(null, "Could not register crafting book recipe for $r{0}$b:$f {1}", "MMOItems Custom Crafting", b.getKey(), e.getMessage()); } }
customRecipes.clear();
for (MythicRecipeBlueprint b : booklessRecipes) { b.disable(); }
booklessRecipes.clear();
// Load all recipes
generatedNKs = null;
loadRecipes();
// Refresh the book I suppose
if (book) { for (Player player : Bukkit.getOnlinePlayers()) { refreshRecipeBook(player); } }
});
}
public void refreshRecipeBook(Player player) {
/*
* todo For some reason, we have to refresh the book every time
* the player joins the server or something; the thing is
* that recipes that are hidden from the book are lost when
* doing this (if they had unlocked them somehow).
* -
* Kind of need to somehow remember what recipes have been
* unlocked by who so that they don't get lost...
*/
// Book disabled?
if (!book) {
// Hide all recipes
for (NamespacedKey key : player.getDiscoveredRecipes()) { if ("mmoitems".equals(key.getNamespace())) { player.undiscoverRecipe(key); } }
// Done woah
return;
}
if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 16)) {
// Undiscovers the recipes apparently
for (NamespacedKey key : player.getDiscoveredRecipes()) {
if ("mmoitems".equals(key.getNamespace()) && !getNamespacedKeys().contains(key)) { player.undiscoverRecipe(key); } }
// And discovers them again
for (NamespacedKey recipe : getNamespacedKeys()) {
if (recipe == null) { continue; }
// Not blacklisted right
boolean blacklisted = false;
for (NamespacedKey black : blacklistedFromAutomaticDiscovery) {
if (recipe.equals(black)) { blacklisted = true; break; } }
if (blacklisted) { continue; }
try { if (!player.hasDiscoveredRecipe(recipe)) { player.discoverRecipe(recipe); } }
catch (Throwable e) { MMOItems.print(null, "Could not register crafting book recipe for $r{0}$b:$f {1}", "MMOItems Custom Crafting", recipe.getKey(), e.getMessage()); }
}
// Done woah
return;
}
// Discovers all recipes
for (NamespacedKey recipe : getNamespacedKeys()) {
if (recipe == null) { continue; }
// Not blacklisted aight
boolean blacklisted = false;
for (NamespacedKey black : blacklistedFromAutomaticDiscovery) {
if (recipe.equals(black)) { blacklisted = true; break; } }
if (blacklisted) { continue; }
try { player.discoverRecipe(recipe); }
catch (Throwable e) { MMOItems.print(null, "Could not register crafting book recipe for $r{0}$b:$f {1}", "MMOItems Custom Crafting", recipe.getKey(), e.getMessage()); }
}
}
@NotNull public static WorkbenchIngredient getWorkbenchIngredient(@NotNull String input) throws IllegalArgumentException {
// Read it this other way ~
ProvidedUIFilter poof = ProvidedUIFilter.getFromString(RecipeMakerGUI.poofFromLegacy(input), null);
// Air is AIR
if (poof == null) { return new AirIngredient(); }
// With class, obviously - no need for prefix tho
FriendlyFeedbackProvider ffp = new FriendlyFeedbackProvider(FFPMMOItems.get());
// Valid right
if (!poof.isValid(ffp)) {
// Snooze that
//noinspection ConstantConditions
throw new IllegalArgumentException(SilentNumbers.collapseList(SilentNumbers.transcribeList(ffp.getFeedbackOf(FriendlyFeedbackCategory.ERROR), s -> ((FriendlyFeedbackMessage) s).forConsole(FFPMMOItems.get())), ". "));
}
// Get amount
int amount = poof.getAmount(0);
// MMOItem?
if (poof.getParent() instanceof MMOItemUIFilter) {
// Get those
Type miType = MMOItems.plugin.getTypes().getOrThrow(poof.getArgument());
// Find template
MMOItemTemplate mmo = MMOItems.plugin.getTemplates().getTemplateOrThrow(miType, poof.getData());
// Treat is as MMOItem :pogyoo:
return new MMOItemIngredient(miType, mmo.getId(), amount);
// Must be vanilla
} else if (poof.getParent() instanceof VanillaUIFilter) {
return new VanillaIngredient(Material.valueOf(poof.getArgument().toUpperCase().replace("-", "_").replace(" ", "_")), amount);
}
throw new IllegalArgumentException("Unsupported ingredient, you may only specify vanilla or mmoitems.");
}
/**
* Easier control of furnace, smoker, campfire and blast recipes so there is
* no need to have four time the same method to register this type of recipe
*
* @author cympe
*/
public enum BurningRecipeType {
FURNACE(FurnaceRecipe::new),
SMOKER(SmokingRecipe::new),
CAMPFIRE(CampfireRecipe::new),
BLAST(BlastingRecipe::new);
private final RecipeProvider provider;
BurningRecipeType(RecipeProvider provider) {
this.provider = provider;
}
public CookingRecipe<?> provideRecipe(NamespacedKey key, ItemStack result, RecipeChoice source, float experience, int cookTime) {
return provider.provide(key, result, source, experience, cookTime);
}
public String getPath() {
return name().toLowerCase();
}
}
@FunctionalInterface
public interface RecipeProvider { CookingRecipe<?> provide(NamespacedKey key, ItemStack result, RecipeChoice source, float experience, int cookTime);}
// Bookless, include in the other list.
} else {
booklessRecipes.add(blueprint);
}
// Well something went wrong...
} catch (IllegalArgumentException error) {
// Empty message? Snooze that
if (!error.getMessage().isEmpty()) {
// Log error
MMOItems.print(null, "Cannot register custom recipe '$u{2}$b' for $e{0} {1}$b;$f {3}", "Custom Crafting", type.getId(), template.getId(), recipeName, error.getMessage());
// Include failures in the report
ffpMinor.sendTo(FriendlyFeedbackCategory.ERROR, MMOItems.getConsole());
ffpMinor.sendTo(FriendlyFeedbackCategory.FAILURE, MMOItems.getConsole());
}
}
}
}
}
}
}
}
// Log relevant messages
ffp.sendTo(FriendlyFeedbackCategory.ERROR, MMOItems.getConsole());
ffp.sendTo(FriendlyFeedbackCategory.FAILURE, MMOItems.getConsole());
// Load legacy recipes onto Bukkit System
Bukkit.getScheduler().runTask(MMOItems.plugin, () -> getLoadedLegacyRecipes().forEach(Bukkit::addRecipe));
}
public void registerBurningRecipe(@NotNull BurningRecipeType recipeType, @NotNull MMOItem mmo, @NotNull BurningRecipeInformation info, int amount, @NotNull NamespacedKey key, boolean hidden) {
// Build its item stacc
ItemStack stack = mmo.newBuilder().build();
stack.setAmount(amount);
// Do whatever this is / I just wont touch it
CookingRecipe<?> recipe = recipeType.provideRecipe(key, stack, info.getChoice().toBukkit(), info.getExp(), info.getBurnTime());
// Register that recipe lets goo
loadedLegacyRecipes.add(recipe);
if (hidden) {
blacklistedFromAutomaticDiscovery.add(key);
}
}
public Set<Recipe> getLoadedLegacyRecipes() {
return loadedLegacyRecipes;
}
public HashMap<NamespacedKey, MythicRecipeBlueprint> getCustomRecipes() {
return customRecipes;
}
public ArrayList<MythicRecipeBlueprint> getBooklessRecipes() {
return booklessRecipes;
}
@Nullable
ArrayList<NamespacedKey> generatedNKs;
public ArrayList<NamespacedKey> getNamespacedKeys() {
if (generatedNKs != null) {
return generatedNKs;
}
// Collect all Namespaces
ArrayList<NamespacedKey> nkMythic = new ArrayList<>(customRecipes.keySet());
ArrayList<NamespacedKey> nkLegacy = loadedLegacyRecipes.stream().map(recipe -> ((Keyed) recipe).getKey()).distinct().collect(Collectors.toCollection(ArrayList::new));
nkMythic.addAll(nkLegacy);
generatedNKs = new ArrayList<>();
for (NamespacedKey nk : nkMythic) {
if (nk != null) {
generatedNKs.add(nk);
}
}
return generatedNKs;
}
@NotNull
public NamespacedKey getRecipeKey(@NotNull Type type, @NotNull String id, @NotNull String recipeType, @NotNull String number) {
return new NamespacedKey(MMOItems.plugin, recipeType + "_" + type.getId() + "_" + id + "_" + number);
}
/**
* Unregisters bukkit and MythicLib recipes and loads everything again.
*/
public void reload() {
Bukkit.getScheduler().runTask(MMOItems.plugin, () -> {
// Remove all recipes
for (NamespacedKey recipe : getNamespacedKeys()) {
if (recipe == null) {
continue;
}
try {
Bukkit.removeRecipe(recipe);
} catch (Throwable e) {
MMOItems.print(null, "Could not register crafting book recipe for $r{0}$b:$f {1}", "MMOItems Custom Crafting", recipe.getKey(), e.getMessage());
}
}
// Clear loaded recipes
loadedLegacyRecipes.clear();
blacklistedFromAutomaticDiscovery.clear();
// Disable and forget all blueprints
for (NamespacedKey b : customRecipes.keySet()) {
if (b == null) {
continue;
}
customRecipes.get(b).disable();
try {
Bukkit.removeRecipe(b);
} catch (Throwable e) {
MMOItems.print(null, "Could not register crafting book recipe for $r{0}$b:$f {1}", "MMOItems Custom Crafting", b.getKey(), e.getMessage());
}
}
customRecipes.clear();
for (MythicRecipeBlueprint b : booklessRecipes) {
b.disable();
}
booklessRecipes.clear();
// Load all recipes
generatedNKs = null;
loadRecipes();
// Refresh the book I suppose
if (book) {
for (Player player : Bukkit.getOnlinePlayers()) {
refreshRecipeBook(player);
}
}
});
}
public void refreshRecipeBook(Player player) {
/*
* todo For some reason, we have to refresh the book every time
* the player joins the server or something; the thing is
* that recipes that are hidden from the book are lost when
* doing this (if they had unlocked them somehow).
* -
* Kind of need to somehow remember what recipes have been
* unlocked by who so that they don't get lost...
*/
// Book disabled?
if (!book) {
// Hide all recipes
for (NamespacedKey key : player.getDiscoveredRecipes()) {
if ("mmoitems".equals(key.getNamespace())) {
player.undiscoverRecipe(key);
}
}
// Done woah
return;
}
if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 16)) {
// Undiscovers the recipes apparently
for (NamespacedKey key : player.getDiscoveredRecipes()) {
if ("mmoitems".equals(key.getNamespace()) && !getNamespacedKeys().contains(key)) {
player.undiscoverRecipe(key);
}
}
// And discovers them again
for (NamespacedKey recipe : getNamespacedKeys()) {
if (recipe == null) {
continue;
}
// Not blacklisted right
boolean blacklisted = false;
for (NamespacedKey black : blacklistedFromAutomaticDiscovery) {
if (recipe.equals(black)) {
blacklisted = true;
break;
}
}
if (blacklisted) {
continue;
}
try {
if (!player.hasDiscoveredRecipe(recipe)) {
player.discoverRecipe(recipe);
}
} catch (Throwable e) {
MMOItems.print(null, "Could not register crafting book recipe for $r{0}$b:$f {1}", "MMOItems Custom Crafting", recipe.getKey(), e.getMessage());
}
}
// Done woah
return;
}
// Discovers all recipes
for (NamespacedKey recipe : getNamespacedKeys()) {
if (recipe == null) {
continue;
}
// Not blacklisted aight
boolean blacklisted = false;
for (NamespacedKey black : blacklistedFromAutomaticDiscovery) {
if (recipe.equals(black)) {
blacklisted = true;
break;
}
}
if (blacklisted) {
continue;
}
try {
player.discoverRecipe(recipe);
} catch (Throwable e) {
MMOItems.print(null, "Could not register crafting book recipe for $r{0}$b:$f {1}", "MMOItems Custom Crafting", recipe.getKey(), e.getMessage());
}
}
}
@NotNull
public static WorkbenchIngredient getWorkbenchIngredient(@NotNull String input) throws IllegalArgumentException {
// Read it this other way ~
ProvidedUIFilter poof = ProvidedUIFilter.getFromString(RecipeMakerGUI.poofFromLegacy(input), null);
// Air is AIR
if (poof == null) {
return new AirIngredient();
}
// With class, obviously - no need for prefix tho
FriendlyFeedbackProvider ffp = new FriendlyFeedbackProvider(FFPMMOItems.get());
// Valid right
if (!poof.isValid(ffp)) {
// Snooze that
//noinspection ConstantConditions
throw new IllegalArgumentException(SilentNumbers.collapseList(SilentNumbers.transcribeList(ffp.getFeedbackOf(FriendlyFeedbackCategory.ERROR), s -> ((FriendlyFeedbackMessage) s).forConsole(FFPMMOItems.get())), ". "));
}
// Get amount
int amount = poof.getAmount(0);
// MMOItem?
if (poof.getParent() instanceof MMOItemUIFilter) {
// Get those
Type miType = MMOItems.plugin.getTypes().getOrThrow(poof.getArgument());
// Find template
MMOItemTemplate mmo = MMOItems.plugin.getTemplates().getTemplateOrThrow(miType, poof.getData());
// Treat is as MMOItem :pogyoo:
return new MMOItemIngredient(miType, mmo.getId(), amount);
// Must be vanilla
} else if (poof.getParent() instanceof VanillaUIFilter) {
return new VanillaIngredient(Material.valueOf(poof.getArgument().toUpperCase().replace("-", "_").replace(" ", "_")), amount);
}
throw new IllegalArgumentException("Unsupported ingredient, you may only specify vanilla or mmoitems.");
}
/**
* Easier control of furnace, smoker, campfire and blast recipes so there is
* no need to have four time the same method to register this type of recipe
*
* @author cympe
*/
public enum BurningRecipeType {
FURNACE(FurnaceRecipe::new),
SMOKER(SmokingRecipe::new),
CAMPFIRE(CampfireRecipe::new),
BLAST(BlastingRecipe::new);
private final RecipeProvider provider;
BurningRecipeType(RecipeProvider provider) {
this.provider = provider;
}
public CookingRecipe<?> provideRecipe(NamespacedKey key, ItemStack result, RecipeChoice source, float experience, int cookTime) {
return provider.provide(key, result, source, experience, cookTime);
}
public String getPath() {
return name().toLowerCase();
}
}
@FunctionalInterface
public interface RecipeProvider {
CookingRecipe<?> provide(NamespacedKey key, ItemStack result, RecipeChoice source, float experience, int cookTime);
}
}

View File

@ -181,15 +181,8 @@ action-bar-display:
item-break: false
recipes:
# Allows you to use stack amounts for recipe ingredients.
# This will enable a custom crafting system which
# can cause lots of trouble. If you don't need specific
# ingredient amounts then DO NOT enable this!
recipe-amounts: false
# Enables the vanilla recipe book for MMOItem recipes!
# THIS IS NOT COMPATIBLE WITH RECIPE AMOUNTS!
# Enables the vanilla recipe book for MMOItems recipes
use-recipe-book: true
# "repair" prevents players from repairing MMOItems.