mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2024-12-23 04:47:34 +01:00
!Rewrote crafting station player ingredients
This commit is contained in:
parent
2ecaf4572c
commit
2f73a572ea
@ -3,6 +3,7 @@ package net.Indyuce.mmoitems.api.crafting;
|
|||||||
import io.lumine.mythic.lib.MythicLib;
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
import io.lumine.mythic.lib.api.util.PostLoadObject;
|
import io.lumine.mythic.lib.api.util.PostLoadObject;
|
||||||
import net.Indyuce.mmoitems.MMOItems;
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.IngredientInventory;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe;
|
||||||
|
@ -1,19 +1,14 @@
|
|||||||
package net.Indyuce.mmoitems.api.crafting;
|
package net.Indyuce.mmoitems.api.crafting;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
|
|
||||||
import net.Indyuce.mmoitems.MMOItems;
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue.CraftingInfo;
|
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue.CraftingInfo;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe;
|
||||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class CraftingStatus {
|
public class CraftingStatus {
|
||||||
|
|
||||||
@ -170,103 +165,4 @@ public class CraftingStatus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* instant craft: the progress bar is displayed on the subtitle and players
|
|
||||||
* must stay around their initial position or the craft will be cancelled
|
|
||||||
*/
|
|
||||||
// private InstantCraftingInfo instant;
|
|
||||||
//
|
|
||||||
// public InstantCraftingInfo getInstant() {
|
|
||||||
// return instant;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public
|
|
||||||
// public class InstantCraftingInfo extends CraftingInfo {
|
|
||||||
// private final PlayerDataManager data;
|
|
||||||
// private boolean timedOut;
|
|
||||||
//
|
|
||||||
// public InstantCraftingInfo(PlayerDataManager data, Recipe recipe) {
|
|
||||||
// super(recipe);
|
|
||||||
// this.data = data;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void start() {
|
|
||||||
// data.getPlayer().closeInventory();
|
|
||||||
//
|
|
||||||
// new BukkitRunnable() {
|
|
||||||
// int t = 0;
|
|
||||||
// final String format =
|
|
||||||
// Message.CRAFTING_SUBTITLE.formatRaw(ChatColor.GREEN);
|
|
||||||
// final Location loc = data.getPlayer().getLocation().clone();
|
|
||||||
//
|
|
||||||
// public void run() {
|
|
||||||
// t++;
|
|
||||||
//
|
|
||||||
// if (data.getPlayer() == null || !data.getPlayer().isOnline() ||
|
|
||||||
// data.getPlayer().isDead() ||
|
|
||||||
// !data.getPlayer().getWorld().equals(loc.getWorld()) ||
|
|
||||||
// loc.distanceSquared(data.getPlayer().getLocation()) > 15) {
|
|
||||||
// timedOut = true;
|
|
||||||
// cancel();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if ((double) t / 10 > recipe.getRecipe().getCraftingTime()) {
|
|
||||||
// timedOut = true;
|
|
||||||
//
|
|
||||||
// recipe = recipe.getRecipe().getRecipeInfo(data, new
|
|
||||||
// IngredientInventory(data.getPlayer()));
|
|
||||||
// if (!recipe.areConditionsMet()) {
|
|
||||||
// Message.CONDITIONS_NOT_MET.format(ChatColor.RED).send(data.getPlayer());
|
|
||||||
// data.getPlayer().playSound(data.getPlayer().getLocation(),
|
|
||||||
// Sound.ENTITY_VILLAGER_NO, 1, 1);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (!recipe.allIngredientsHad()) {
|
|
||||||
// Message.NOT_ENOUGH_MATERIALS.format(ChatColor.RED).send(data.getPlayer());
|
|
||||||
// data.getPlayer().playSound(data.getPlayer().getLocation(),
|
|
||||||
// Sound.ENTITY_VILLAGER_NO, 1, 1);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// craft();
|
|
||||||
//
|
|
||||||
// cancel();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// double left = recipe.getRecipe().getCraftingTime() - (double) t / 10;
|
|
||||||
// double r = (double) t / 10 / recipe.getRecipe().getCraftingTime();
|
|
||||||
// data.getPlayer().sendTitle("", format.replace("#left#",
|
|
||||||
// formatDelay(left)).replace("#bar#", MMOUtils.getProgressBar(r, 10,
|
|
||||||
// AltChar.square)), 0, 20, 10);
|
|
||||||
// }
|
|
||||||
// }.runTaskTimer(MMOItems.plugin, 0, 2);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void craft() {
|
|
||||||
// timedOut = true;
|
|
||||||
//
|
|
||||||
// for (CheckedIngredient ingredient : recipe.getIngredients())
|
|
||||||
// ingredient.getPlayerIngredient().reduceItem(ingredient.getIngredient().getAmount(),
|
|
||||||
// ingredient.getIngredient());
|
|
||||||
//
|
|
||||||
// data.getPlayer().playSound(data.getPlayer().getLocation(),
|
|
||||||
// Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1);
|
|
||||||
// for (ItemStack drop :
|
|
||||||
// data.getPlayer().getInventory().addItem(recipe.getRecipe().getOutput().generate()).values())
|
|
||||||
// data.getPlayer().getWorld().dropItem(data.getPlayer().getLocation(),
|
|
||||||
// drop);
|
|
||||||
//
|
|
||||||
// updateData();
|
|
||||||
// open();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public boolean isTimedOut() {
|
|
||||||
// return timedOut || (System.currentTimeMillis() - started >
|
|
||||||
// recipe.getRecipe().getCraftingTime());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
@ -1,193 +0,0 @@
|
|||||||
package net.Indyuce.mmoitems.api.crafting;
|
|
||||||
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
|
||||||
import io.lumine.mythic.lib.api.util.ui.QuickNumberRange;
|
|
||||||
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
|
|
||||||
import net.Indyuce.mmoitems.MMOItems;
|
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
|
||||||
import net.Indyuce.mmoitems.manager.CraftingManager.IngredientType;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class IngredientInventory {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ingredients in the map are not stored using class instances as keys but
|
|
||||||
* using a unique string which is an unique ingredient identifier. allows
|
|
||||||
* for faster map check ups and fixes the >64 amount and ingredient
|
|
||||||
* splitting glitches
|
|
||||||
*/
|
|
||||||
private final Map<String, PlayerIngredient> ingredients = new HashMap<>();
|
|
||||||
|
|
||||||
public IngredientInventory(Player player) { this(player.getInventory()); }
|
|
||||||
|
|
||||||
public IngredientInventory(Inventory inv) {
|
|
||||||
loop: for (ItemStack item : inv.getContents())
|
|
||||||
if (item != null && item.getType() != Material.AIR) {
|
|
||||||
NBTItem nbt = MythicLib.plugin.getVersion().getWrapper().getNBTItem(item);
|
|
||||||
for (IngredientType ingredient : MMOItems.plugin.getCrafting().getIngredients()) {
|
|
||||||
if (ingredient.check(nbt)) {
|
|
||||||
addIngredient(nbt, ingredient);
|
|
||||||
continue loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addIngredient(NBTItem item, IngredientType ingredient) {
|
|
||||||
String key = ingredient.getId() + ":" + ingredient.readKey(item);
|
|
||||||
|
|
||||||
if (ingredients.containsKey(key))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* add to current ingredient a specific amount.
|
|
||||||
*/
|
|
||||||
ingredients.get(key).add(item.getItem());
|
|
||||||
else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* load an item stack and turn it into an ingredient which makes
|
|
||||||
* checking ingredients later much faster.
|
|
||||||
*/
|
|
||||||
ingredients.put(key, new PlayerIngredient(item.getItem()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public PlayerIngredient getIngredient(@NotNull Ingredient ingredient, @NotNull IngredientLookupMode lookupMode) {
|
|
||||||
String key = ingredient.getKey();
|
|
||||||
|
|
||||||
// Find level
|
|
||||||
QuickNumberRange lvl = null;
|
|
||||||
int dsh = key.indexOf('-');
|
|
||||||
if (dsh > 0) {
|
|
||||||
|
|
||||||
// Get lvl
|
|
||||||
String itemCrop = key.substring(dsh + 1);
|
|
||||||
String itemLevel = itemCrop.substring(0, itemCrop.indexOf('_'));
|
|
||||||
lvl = QuickNumberRange.getFromString(itemLevel);
|
|
||||||
key = key.substring(0, dsh) + key.substring(dsh + 1 + itemLevel.length()); }
|
|
||||||
|
|
||||||
// Remove lvl
|
|
||||||
//ING//MMOItems.log("\u00a7a>\u00a78>\u00a77 Reading ingredient\u00a7a " + key + "\u00a77 (of level \u00a7a" + lvl + "\u00a77)");
|
|
||||||
|
|
||||||
for (String invKey : ingredients.keySet()) {
|
|
||||||
|
|
||||||
int dash = invKey.indexOf('-');
|
|
||||||
Integer itemLvl = null;
|
|
||||||
String ingredientKey = invKey;
|
|
||||||
if (dash > 0) {
|
|
||||||
|
|
||||||
// Get lvl
|
|
||||||
String itemCrop = invKey.substring(dash + 1);
|
|
||||||
String itemLevel = itemCrop.substring(0, itemCrop.indexOf('_'));
|
|
||||||
itemLvl = SilentNumbers.IntegerParse(itemLevel);
|
|
||||||
ingredientKey = invKey.substring(0, dash) + invKey.substring(dash + 1 + itemLevel.length()); }
|
|
||||||
|
|
||||||
|
|
||||||
// Compare removing level
|
|
||||||
//ING//MMOItems.log(" \u00a7a>\u00a77 Comparing to \u00a7b" + invKey + "\u00a77 (\u00a73" + ingredientKey + "\u00a77)");
|
|
||||||
|
|
||||||
if (ingredientKey.equals(key)) {
|
|
||||||
|
|
||||||
// Get level
|
|
||||||
boolean levelMet = true;
|
|
||||||
if (lookupMode != IngredientLookupMode.IGNORE_ITEM_LEVEL && lvl != null) {
|
|
||||||
|
|
||||||
// Parse
|
|
||||||
if (itemLvl == null) { itemLvl = 0; }
|
|
||||||
levelMet = lvl.inRange(itemLvl);
|
|
||||||
//ING//MMOItems.log(" \u00a7a>\u00a77 Was level \u00a7e" + invKey + "\u00a77 (\u00a76" + levelMet + "\u00a77)");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (levelMet) { return ingredients.get(invKey); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public boolean hasIngredient(Ingredient ingredient) {
|
|
||||||
PlayerIngredient found = getIngredient(ingredient, IngredientLookupMode.IGNORE_ITEM_LEVEL);
|
|
||||||
return found != null && found.getAmount() >= ingredient.getAmount();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class PlayerIngredient {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* stores items which correspond to a specific ingredient. when the
|
|
||||||
* ingredient is taken off the player inventory, the itemstack amounts
|
|
||||||
* get lowered. these POINT towards the player inventory itemStacks.
|
|
||||||
*/
|
|
||||||
private final List<ItemStack> items = new ArrayList<>();
|
|
||||||
|
|
||||||
public PlayerIngredient(ItemStack item) {
|
|
||||||
items.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAmount() {
|
|
||||||
int t = 0;
|
|
||||||
for (ItemStack item : items)
|
|
||||||
t += item.getAmount();
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(ItemStack item) {
|
|
||||||
items.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
// used for upgrading recipes
|
|
||||||
public ItemStack getFirstItem() {
|
|
||||||
return items.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* algorythm which takes away a certain amount of items. used to consume
|
|
||||||
* ingredients when using recipes
|
|
||||||
*/
|
|
||||||
public void reduceItem(int amount) {
|
|
||||||
|
|
||||||
Iterator<ItemStack> iterator = items.iterator();
|
|
||||||
while (iterator.hasNext() && amount > 0) {
|
|
||||||
ItemStack item = iterator.next();
|
|
||||||
|
|
||||||
// remove itemStack from list if amount <= 0
|
|
||||||
if (item.getAmount() < 1) {
|
|
||||||
iterator.remove();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// amount of items it can take from this particular ItemStack
|
|
||||||
int take = Math.min(item.getAmount(), amount);
|
|
||||||
|
|
||||||
amount -= take;
|
|
||||||
item.setAmount(item.getAmount() - take);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* could use a boolean because there are only two states possible, but makes
|
|
||||||
* things clearer.
|
|
||||||
*/
|
|
||||||
public enum IngredientLookupMode {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* item level must be ignored when the player is using an upgrading
|
|
||||||
* recipe, otherwise recipe cannot identify right item
|
|
||||||
*/
|
|
||||||
IGNORE_ITEM_LEVEL,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* scans ingredient inventory considering item levels
|
|
||||||
*/
|
|
||||||
BASIC
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,47 @@
|
|||||||
|
package net.Indyuce.mmoitems.api.crafting;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to handle both ingredients and conditions because they share the same
|
||||||
|
* properties:
|
||||||
|
* - a way to display them in the recipe item lore.
|
||||||
|
* - some string identifier
|
||||||
|
* - a function which takes as input a line config and returns a loaded ingredient/condition
|
||||||
|
*
|
||||||
|
* @param <C> Either Condition or Ingredient
|
||||||
|
*/
|
||||||
|
public class LoadedCraftingObject<C> {
|
||||||
|
private final String id;
|
||||||
|
private final Function<MMOLineConfig, C> function;
|
||||||
|
|
||||||
|
private ConditionalDisplay display;
|
||||||
|
|
||||||
|
public LoadedCraftingObject(String id, Function<MMOLineConfig, C> function, ConditionalDisplay display) {
|
||||||
|
this.id = id;
|
||||||
|
this.function = function;
|
||||||
|
this.display = display;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplay(ConditionalDisplay display) {
|
||||||
|
this.display = display;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasDisplay() {
|
||||||
|
return display != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConditionalDisplay getDisplay() {
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
|
||||||
|
public C load(MMOLineConfig config) {
|
||||||
|
return function.apply(config);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package net.Indyuce.mmoitems.api.crafting.condition;
|
||||||
|
|
||||||
|
public class CheckedCondition {
|
||||||
|
private final Condition condition;
|
||||||
|
private final boolean met;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instanciated everytime a condition needs to be evaluated for a player
|
||||||
|
* when evaluating a CheckedRecipe (when a player is opening a crafting
|
||||||
|
* station)
|
||||||
|
*
|
||||||
|
* @param condition Condition being evaluated
|
||||||
|
* @param met If the condition is met or not
|
||||||
|
*/
|
||||||
|
public CheckedCondition(Condition condition, boolean met) {
|
||||||
|
this.condition = condition;
|
||||||
|
this.met = met;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMet() {
|
||||||
|
return met;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Condition getCondition() {
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String format() {
|
||||||
|
return condition.formatDisplay(isMet() ? condition.getDisplay().getPositive() : condition.getDisplay().getNegative());
|
||||||
|
}
|
||||||
|
}
|
@ -56,34 +56,4 @@ public abstract class Condition {
|
|||||||
public CheckedCondition evaluateCondition(PlayerData data) {
|
public CheckedCondition evaluateCondition(PlayerData data) {
|
||||||
return new CheckedCondition(this, isMet(data));
|
return new CheckedCondition(this, isMet(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CheckedCondition {
|
|
||||||
private final Condition condition;
|
|
||||||
private final boolean met;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instanciated everytime a condition needs to be evaluated for a player
|
|
||||||
* when evaluating a CheckedRecipe (when a player is opening a crafting
|
|
||||||
* station)
|
|
||||||
*
|
|
||||||
* @param condition Condition being evaluated
|
|
||||||
* @param met If the condition is met or not
|
|
||||||
*/
|
|
||||||
public CheckedCondition(Condition condition, boolean met) {
|
|
||||||
this.condition = condition;
|
|
||||||
this.met = met;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMet() {
|
|
||||||
return met;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Condition getCondition() {
|
|
||||||
return condition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String format() {
|
|
||||||
return condition.formatDisplay(isMet() ? condition.getDisplay().getPositive() : condition.getDisplay().getNegative());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,95 @@
|
|||||||
|
package net.Indyuce.mmoitems.api.crafting.ingredient;
|
||||||
|
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.PlayerIngredient;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class CheckedIngredient {
|
||||||
|
@NotNull
|
||||||
|
private final Ingredient ingredient;
|
||||||
|
@Nullable
|
||||||
|
private final Set<PlayerIngredient> found;
|
||||||
|
private final boolean isHad;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiated everytime an ingredient is evaluated for a player when a
|
||||||
|
* CheckedRecipe is being created (when a player is opening a crafting
|
||||||
|
* station). This helps greatly reducing ingredient checkups by caching
|
||||||
|
* the items the plugin will need to take off the player's ingredient
|
||||||
|
*
|
||||||
|
* @param ingredient The ingredient being evaluated
|
||||||
|
* @param found The corresponding ingredient found in the player's
|
||||||
|
* ingredient
|
||||||
|
*/
|
||||||
|
public CheckedIngredient(@NotNull Ingredient ingredient, @Nullable Set<PlayerIngredient> found) {
|
||||||
|
this.ingredient = ingredient;
|
||||||
|
this.found = found;
|
||||||
|
this.isHad = getTotalAmount() >= ingredient.getAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return If the player has enough of the specific item or not
|
||||||
|
*/
|
||||||
|
public boolean isHad() {
|
||||||
|
return isHad;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalAmount() {
|
||||||
|
int total = 0;
|
||||||
|
for (PlayerIngredient ing : this.found)
|
||||||
|
total += ing.getAmount();
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes off the required amount of ingredients from a player's inventory.
|
||||||
|
*/
|
||||||
|
public void takeAway() {
|
||||||
|
reduceItem(ingredient.getAmount());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes off a specific amount of ingredients from a player's inventory.
|
||||||
|
*
|
||||||
|
* @param amount Amount to take off the player's inventory.
|
||||||
|
* It most likely matches ingredient.getAmount()
|
||||||
|
*/
|
||||||
|
public void reduceItem(int amount) {
|
||||||
|
|
||||||
|
Iterator<PlayerIngredient> iterator = found.iterator();
|
||||||
|
while (iterator.hasNext() && amount > 0) {
|
||||||
|
ItemStack item = iterator.next().getItem();
|
||||||
|
|
||||||
|
// Remove itemStack from list if amount <= 0
|
||||||
|
if (item.getAmount() <= 0) {
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Amount of items it can take from this particular ItemStack
|
||||||
|
int take = Math.min(item.getAmount(), amount);
|
||||||
|
|
||||||
|
amount -= take;
|
||||||
|
item.setAmount(item.getAmount() - take);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Ingredient getIngredient() {
|
||||||
|
return ingredient;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Set<PlayerIngredient> getFound() {
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String format() {
|
||||||
|
return ingredient.formatDisplay(isHad() ? ingredient.getDisplay().getPositive() : ingredient.getDisplay().getNegative());
|
||||||
|
}
|
||||||
|
}
|
@ -3,15 +3,18 @@ package net.Indyuce.mmoitems.api.crafting.ingredient;
|
|||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
import net.Indyuce.mmoitems.MMOItems;
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
|
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
|
||||||
import net.Indyuce.mmoitems.api.crafting.IngredientInventory;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.IngredientInventory;
|
||||||
import net.Indyuce.mmoitems.api.crafting.IngredientInventory.IngredientLookupMode;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.PlayerIngredient;
|
||||||
import net.Indyuce.mmoitems.api.crafting.IngredientInventory.PlayerIngredient;
|
|
||||||
import net.Indyuce.mmoitems.api.player.RPGPlayer;
|
import net.Indyuce.mmoitems.api.player.RPGPlayer;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public abstract class Ingredient {
|
/**
|
||||||
|
* An ingredient from a crafting station recipe.
|
||||||
|
* <p>
|
||||||
|
* See {@link PlayerIngredient} for more information.
|
||||||
|
*/
|
||||||
|
public abstract class Ingredient<C extends PlayerIngredient> {
|
||||||
private final String id;
|
private final String id;
|
||||||
private final int amount;
|
private final int amount;
|
||||||
|
|
||||||
@ -24,6 +27,10 @@ public abstract class Ingredient {
|
|||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The ingredient type id i.e the string placed
|
||||||
|
* at the beginning of the line config
|
||||||
|
*/
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -43,7 +50,9 @@ public abstract class Ingredient {
|
|||||||
/**
|
/**
|
||||||
* @return The ingredient key which is used internally by MMOItems to check
|
* @return The ingredient key which is used internally by MMOItems to check
|
||||||
* if two ingredients are of the same nature.
|
* if two ingredients are of the same nature.
|
||||||
|
* @deprecated Apart from ingredient type keys, keys are not used anymore.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public abstract String getKey();
|
public abstract String getKey();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,49 +63,20 @@ public abstract class Ingredient {
|
|||||||
*/
|
*/
|
||||||
public abstract String formatDisplay(String s);
|
public abstract String formatDisplay(String s);
|
||||||
|
|
||||||
|
public abstract boolean matches(C playerIngredient);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the player right-clicks one of the items in a station, they can
|
* When the player right-clicks one of the items in a station, they can
|
||||||
* preview the stats if itself and the components it is made of. This
|
* preview the stats if itself and the components it is made of. This
|
||||||
* is called to displace those preview elements.
|
* is called to displace those preview elements.
|
||||||
*
|
*
|
||||||
* @param player Player looking at the recipe
|
* @param player Player looking at the recipe
|
||||||
*
|
|
||||||
* @return The ItemStack to display to the player
|
* @return The ItemStack to display to the player
|
||||||
*/
|
*/
|
||||||
@NotNull public abstract ItemStack generateItemStack(@NotNull RPGPlayer player);
|
@NotNull
|
||||||
|
public abstract ItemStack generateItemStack(@NotNull RPGPlayer player);
|
||||||
|
|
||||||
public CheckedIngredient evaluateIngredient(@NotNull IngredientInventory inv) {
|
public CheckedIngredient evaluateIngredient(@NotNull IngredientInventory inv) {
|
||||||
return new CheckedIngredient(this, inv.getIngredient(this, IngredientLookupMode.BASIC));
|
return inv.findMatching(this);
|
||||||
}
|
|
||||||
|
|
||||||
public static class CheckedIngredient {
|
|
||||||
@NotNull private final Ingredient ingredient;
|
|
||||||
@Nullable private final PlayerIngredient found;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiated everytime an ingredient is evaluated for a player when a
|
|
||||||
* CheckedRecipe is being created (when a player is opening a crafting
|
|
||||||
* station). This helps greatly reducing ingredient checkups by caching
|
|
||||||
* the items the plugin will need to take off the player's ingredient
|
|
||||||
*
|
|
||||||
* @param ingredient The ingredient being evaluated
|
|
||||||
* @param found The corresponding ingredient found in the player's
|
|
||||||
* ingredient
|
|
||||||
*/
|
|
||||||
private CheckedIngredient(@NotNull Ingredient ingredient, @Nullable PlayerIngredient found) {
|
|
||||||
this.ingredient = ingredient;
|
|
||||||
this.found = found;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return If the player has enough of the specific item or not
|
|
||||||
*/
|
|
||||||
public boolean isHad() { return found != null && found.getAmount() >= ingredient.getAmount(); }
|
|
||||||
|
|
||||||
@NotNull public Ingredient getIngredient() { return ingredient; }
|
|
||||||
|
|
||||||
@Nullable public PlayerIngredient getPlayerIngredient() { return found; }
|
|
||||||
|
|
||||||
@NotNull public String format() { return ingredient.formatDisplay(isHad() ? ingredient.getDisplay().getPositive() : ingredient.getDisplay().getNegative()); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
package net.Indyuce.mmoitems.api.crafting.ingredient;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.LoadedCraftingObject;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.PlayerIngredient;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type of ingredient, like a vanilla ingredient or a MMOItems ingredient.
|
||||||
|
* <p>
|
||||||
|
* See {@link PlayerIngredient} for more information.
|
||||||
|
*/
|
||||||
|
public class IngredientType extends LoadedCraftingObject<Ingredient> {
|
||||||
|
private final Predicate<NBTItem> check;
|
||||||
|
private final Function<NBTItem, PlayerIngredient> readIngredient;
|
||||||
|
|
||||||
|
public IngredientType(String id, Function<MMOLineConfig, Ingredient> function, ConditionalDisplay display, Predicate<NBTItem> check, Function<NBTItem, PlayerIngredient> readIngredient) {
|
||||||
|
super(id, function, display);
|
||||||
|
|
||||||
|
this.check = check;
|
||||||
|
this.readIngredient = readIngredient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return If the checked item can be handled by this ingredient
|
||||||
|
*/
|
||||||
|
public boolean check(NBTItem item) {
|
||||||
|
return check.test(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the ingredient from an NBTItem, called after checking
|
||||||
|
* that this ingredient type can handle this NBTItem
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public PlayerIngredient readPlayerIngredient(NBTItem item) {
|
||||||
|
return readIngredient.apply(item);
|
||||||
|
}
|
||||||
|
}
|
@ -1,28 +1,29 @@
|
|||||||
package net.Indyuce.mmoitems.api.crafting.ingredient;
|
package net.Indyuce.mmoitems.api.crafting.ingredient;
|
||||||
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
import io.lumine.mythic.lib.api.util.ui.QuickNumberRange;
|
import io.lumine.mythic.lib.api.util.ui.QuickNumberRange;
|
||||||
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
|
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
|
||||||
import net.Indyuce.mmoitems.ItemStats;
|
import net.Indyuce.mmoitems.ItemStats;
|
||||||
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
|
|
||||||
import net.Indyuce.mmoitems.stat.DisplayName;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import net.Indyuce.mmoitems.MMOItems;
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
import net.Indyuce.mmoitems.MMOUtils;
|
import net.Indyuce.mmoitems.MMOUtils;
|
||||||
import net.Indyuce.mmoitems.api.Type;
|
import net.Indyuce.mmoitems.api.Type;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ConfigMMOItem;
|
import net.Indyuce.mmoitems.api.crafting.ConfigMMOItem;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.MMOItemPlayerIngredient;
|
||||||
|
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
|
||||||
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
|
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
|
||||||
import net.Indyuce.mmoitems.api.player.RPGPlayer;
|
import net.Indyuce.mmoitems.api.player.RPGPlayer;
|
||||||
|
import net.Indyuce.mmoitems.stat.DisplayName;
|
||||||
import net.Indyuce.mmoitems.stat.data.MaterialData;
|
import net.Indyuce.mmoitems.stat.data.MaterialData;
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class MMOItemIngredient extends Ingredient {
|
public class MMOItemIngredient extends Ingredient<MMOItemPlayerIngredient> {
|
||||||
private final MMOItemTemplate template;
|
private final MMOItemTemplate template;
|
||||||
|
|
||||||
@NotNull private final QuickNumberRange level;
|
@NotNull
|
||||||
|
private final QuickNumberRange level;
|
||||||
private final String display;
|
private final String display;
|
||||||
|
|
||||||
public MMOItemIngredient(MMOLineConfig config) {
|
public MMOItemIngredient(MMOLineConfig config) {
|
||||||
@ -64,7 +65,28 @@ public class MMOItemIngredient extends Ingredient {
|
|||||||
return s.replace("#item#", display).replace("#level#", (level.hasMax() || level.hasMax()) ? "lvl." + level.toString() + " " : "").replace("#amount#", String.valueOf(getAmount()));
|
return s.replace("#item#", display).replace("#level#", (level.hasMax() || level.hasMax()) ? "lvl." + level.toString() + " " : "").replace("#amount#", String.valueOf(getAmount()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull @Override public ItemStack generateItemStack(@NotNull RPGPlayer player) {
|
@Override
|
||||||
|
public boolean matches(MMOItemPlayerIngredient playerIngredient) {
|
||||||
|
|
||||||
|
// Check for item type
|
||||||
|
if (!playerIngredient.getType().equals(template.getType().getId()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check for item id
|
||||||
|
if (!playerIngredient.getId().equals(template.getId()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Checks for level range
|
||||||
|
if (SilentNumbers.floor(level.getAsDouble(0)) != 0 && !level.inRange(playerIngredient.getUpgradeLevel()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Yuss
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public ItemStack generateItemStack(@NotNull RPGPlayer player) {
|
||||||
|
|
||||||
// Generate fresh from the template
|
// Generate fresh from the template
|
||||||
MMOItem mmo = template.newBuilder(player).build();
|
MMOItem mmo = template.newBuilder(player).build();
|
||||||
@ -93,17 +115,22 @@ public class MMOItemIngredient extends Ingredient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String findName() {
|
private String findName() {
|
||||||
String name = null;
|
String name;
|
||||||
|
|
||||||
|
// By default, take item display name
|
||||||
if (template.getBaseItemData().containsKey(ItemStats.NAME))
|
if (template.getBaseItemData().containsKey(ItemStats.NAME))
|
||||||
name = template.getBaseItemData().get(ItemStats.NAME).toString().replace("<tier-color>", "").replace("<tier-name>", "").replace("<tier-color-cleaned>", "");
|
name = template.getBaseItemData().get(ItemStats.NAME).toString().replace("<tier-color>", "").replace("<tier-name>", "").replace("<tier-color-cleaned>", "");
|
||||||
|
|
||||||
if (template.getBaseItemData().containsKey(ItemStats.MATERIAL) && name == null)
|
// Try and take the material name
|
||||||
|
else if (template.getBaseItemData().containsKey(ItemStats.MATERIAL))
|
||||||
name = MMOUtils.caseOnWords(((MaterialData) template.getBaseItemData().get(ItemStats.MATERIAL)).getMaterial().name().toLowerCase().replace("_", " "));
|
name = MMOUtils.caseOnWords(((MaterialData) template.getBaseItemData().get(ItemStats.MATERIAL)).getMaterial().name().toLowerCase().replace("_", " "));
|
||||||
|
|
||||||
if (name == null) { name = "Unrecognized Item"; }
|
// Ultra rare case to avoid a NPE
|
||||||
|
else name = "Unrecognized Item";
|
||||||
|
|
||||||
// Append upgrade level
|
// Append upgrade level
|
||||||
if (SilentNumbers.floor(level.getAsDouble(0)) != 0) { return DisplayName.appendUpgradeLevel(name, SilentNumbers.floor(level.getAsDouble(0))); }
|
if (SilentNumbers.floor(level.getAsDouble(0)) != 0)
|
||||||
|
return DisplayName.appendUpgradeLevel(name, SilentNumbers.floor(level.getAsDouble(0)));
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package net.Indyuce.mmoitems.api.crafting.ingredient;
|
package net.Indyuce.mmoitems.api.crafting.ingredient;
|
||||||
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
import io.lumine.mythic.lib.api.util.LegacyComponent;
|
import io.lumine.mythic.lib.api.util.LegacyComponent;
|
||||||
import net.Indyuce.mmoitems.MMOUtils;
|
import net.Indyuce.mmoitems.MMOUtils;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.VanillaPlayerIngredient;
|
||||||
import net.Indyuce.mmoitems.api.player.RPGPlayer;
|
import net.Indyuce.mmoitems.api.player.RPGPlayer;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class VanillaIngredient extends Ingredient {
|
public class VanillaIngredient extends Ingredient<VanillaPlayerIngredient> {
|
||||||
private final Material material;
|
private final Material material;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,6 +40,17 @@ public class VanillaIngredient extends Ingredient {
|
|||||||
return s.replace("#item#", display).replace("#amount#", "" + getAmount());
|
return s.replace("#item#", display).replace("#amount#", "" + getAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(VanillaPlayerIngredient ing) {
|
||||||
|
|
||||||
|
// Check for material
|
||||||
|
if (ing.getType() != material)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check for display name
|
||||||
|
return ing.getDisplayName() != null ? ing.getDisplayName().equals(displayName) : displayName == null;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ItemStack generateItemStack(@NotNull RPGPlayer player) {
|
public ItemStack generateItemStack(@NotNull RPGPlayer player) {
|
||||||
|
@ -0,0 +1,111 @@
|
|||||||
|
package net.Indyuce.mmoitems.api.crafting.ingredient.inventory;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.CheckedIngredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.IngredientType;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class IngredientInventory {
|
||||||
|
private final Map<String, Set<PlayerIngredient>> ingredients = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads all the possible crafting station ingredients from a player's inventory
|
||||||
|
*/
|
||||||
|
public IngredientInventory(Player player) {
|
||||||
|
this(player.getInventory());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads all the possible crafting station ingredients from an inventory
|
||||||
|
*/
|
||||||
|
public IngredientInventory(Inventory inv) {
|
||||||
|
loop:
|
||||||
|
for (ItemStack item : inv.getContents())
|
||||||
|
if (item != null && item.getType() != Material.AIR && item.getAmount() > 0) {
|
||||||
|
NBTItem nbt = MythicLib.plugin.getVersion().getWrapper().getNBTItem(item);
|
||||||
|
for (IngredientType ingredient : MMOItems.plugin.getCrafting().getIngredients()) {
|
||||||
|
if (ingredient.check(nbt)) {
|
||||||
|
addIngredient(nbt, ingredient);
|
||||||
|
continue loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers an ingredient.
|
||||||
|
*
|
||||||
|
* @param item The actual item in the inventory
|
||||||
|
* @param ingredient The type of the ingredient added
|
||||||
|
*/
|
||||||
|
public void addIngredient(NBTItem item, IngredientType ingredient) {
|
||||||
|
String key = ingredient.getId();
|
||||||
|
|
||||||
|
// Add to existing set
|
||||||
|
if (ingredients.containsKey(key))
|
||||||
|
ingredients.get(key).add(ingredient.readPlayerIngredient(item));
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
else {
|
||||||
|
Set<PlayerIngredient> ingredients = new HashSet<>();
|
||||||
|
ingredients.add(ingredient.readPlayerIngredient(item));
|
||||||
|
this.ingredients.put(key, ingredients);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public CheckedIngredient findMatching(@NotNull Ingredient ingredient) {
|
||||||
|
Set<PlayerIngredient> found = new HashSet<>();
|
||||||
|
if (!ingredients.containsKey(ingredient.getId()))
|
||||||
|
return new CheckedIngredient(ingredient, found);
|
||||||
|
|
||||||
|
for (PlayerIngredient checked : ingredients.get(ingredient.getId()))
|
||||||
|
if (ingredient.matches(checked))
|
||||||
|
found.add(checked);
|
||||||
|
|
||||||
|
return new CheckedIngredient(ingredient, found);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated First use {@link #findMatching(Ingredient)} and cache its
|
||||||
|
* result to use the isHad() method of returned class instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public boolean hasIngredient(Ingredient ingredient) {
|
||||||
|
return findMatching(ingredient).isHad();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Could use a boolean because there are only two
|
||||||
|
* states possible, but makes things clearer.
|
||||||
|
*
|
||||||
|
* @deprecated Since 6.6 where ingredients were recoded.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public enum IngredientLookupMode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item level must be ignored when the player is using an upgrading
|
||||||
|
* recipe, otherwise recipe cannot identify right item
|
||||||
|
*/
|
||||||
|
IGNORE_ITEM_LEVEL,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans ingredient inventory considering item levels
|
||||||
|
*/
|
||||||
|
BASIC
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package net.Indyuce.mmoitems.api.crafting.ingredient.inventory;
|
||||||
|
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
|
|
||||||
|
public class MMOItemPlayerIngredient extends PlayerIngredient {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No need to save as MMOItemTemplate or Type instances. Just need the string,
|
||||||
|
* because if they don't exist the recipe ingredients won't load anyways.
|
||||||
|
* And it's better for performance yes
|
||||||
|
*/
|
||||||
|
private final String type, id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to check if the level of the player's item matches
|
||||||
|
* the level range given by the recipe ingredient.
|
||||||
|
*/
|
||||||
|
private final int upgradeLevel;
|
||||||
|
|
||||||
|
// TODO also add support for item level range? Quite easy to implement with the new PlayerIngredient interface.
|
||||||
|
|
||||||
|
public MMOItemPlayerIngredient(NBTItem item) {
|
||||||
|
super(item);
|
||||||
|
|
||||||
|
this.type = item.getString("MMOITEMS_ITEM_TYPE");
|
||||||
|
this.id = item.getString("MMOITEMS_ITEM_ID");
|
||||||
|
|
||||||
|
String upgradeString = item.getString("MMOITEMS_UPGRADE");
|
||||||
|
this.upgradeLevel = !upgradeString.isEmpty() ? new JsonParser().parse(upgradeString).getAsJsonObject().get("Level").getAsInt() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUpgradeLevel() {
|
||||||
|
return upgradeLevel;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package net.Indyuce.mmoitems.api.crafting.ingredient.inventory;
|
||||||
|
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.CheckedIngredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.IngredientType;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
|
||||||
|
import net.Indyuce.mmoitems.manager.CraftingManager;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code architecture for all the classes concerning Ingredients.
|
||||||
|
* <p>
|
||||||
|
* MMOItems based ingredients / vanilla based ingredients are called IngredientTypes.
|
||||||
|
* One {@link IngredientType} is loaded for every type of ingredient there exists.
|
||||||
|
* External plugins can register other types of ingredients using
|
||||||
|
* {@link CraftingManager#registerIngredient(String, Function, ConditionalDisplay, Predicate, Function)}.
|
||||||
|
* <p>
|
||||||
|
* Once all the ingredient types are loaded, stations are loaded from the config files.
|
||||||
|
* That means loading the ingredients from the recipes which is what {@link Ingredient} is used for.
|
||||||
|
* <p>
|
||||||
|
* When a player opens a crafting station, MMOItems must first calculate all the ingredients
|
||||||
|
* they have in their inventory. A {@link IngredientInventory} is created, calculating all
|
||||||
|
* the ingredients the player has using the {@link PlayerIngredient} interface.
|
||||||
|
* <p>
|
||||||
|
* The second step when opening a crafting station is comparing the ingredients required for one
|
||||||
|
* crafting recipe to the current player's ingredients, which is done using {@link CheckedIngredient}
|
||||||
|
* when creating {@link CheckedRecipe}.
|
||||||
|
*
|
||||||
|
* @author indyuce
|
||||||
|
*/
|
||||||
|
public abstract class PlayerIngredient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirects to the player's item in his inventory. This can be
|
||||||
|
* used later by MMOItems to reduce the amount of items in his inventory
|
||||||
|
* to take off ingredients from him.
|
||||||
|
*/
|
||||||
|
private final ItemStack item;
|
||||||
|
|
||||||
|
public PlayerIngredient(NBTItem item) {
|
||||||
|
|
||||||
|
// Throw NBTItem to garbage collector because no longer needed
|
||||||
|
this.item = item.getItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAmount() {
|
||||||
|
return item.getAmount();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package net.Indyuce.mmoitems.api.crafting.ingredient.inventory;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class VanillaPlayerIngredient extends PlayerIngredient {
|
||||||
|
private final Material material;
|
||||||
|
@Nullable
|
||||||
|
private final String displayName;
|
||||||
|
|
||||||
|
public VanillaPlayerIngredient(NBTItem item) {
|
||||||
|
super(item);
|
||||||
|
|
||||||
|
this.material = item.getItem().getType();
|
||||||
|
|
||||||
|
ItemMeta meta = item.getItem().getItemMeta();
|
||||||
|
this.displayName = meta.hasDisplayName() ? meta.getDisplayName() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material getType() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,17 @@
|
|||||||
package net.Indyuce.mmoitems.api.crafting.recipe;
|
package net.Indyuce.mmoitems.api.crafting.recipe;
|
||||||
|
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.condition.CheckedCondition;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.condition.Condition;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.CheckedIngredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.IngredientInventory;
|
||||||
|
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import net.Indyuce.mmoitems.api.crafting.IngredientInventory;
|
|
||||||
import net.Indyuce.mmoitems.api.crafting.condition.Condition;
|
|
||||||
import net.Indyuce.mmoitems.api.crafting.condition.Condition.CheckedCondition;
|
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient.CheckedIngredient;
|
|
||||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
|
||||||
|
|
||||||
public class CheckedRecipe {
|
public class CheckedRecipe {
|
||||||
private final Recipe recipe;
|
private final Recipe recipe;
|
||||||
|
|
||||||
@ -54,6 +53,10 @@ public class CheckedRecipe {
|
|||||||
return recipe;
|
return recipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if both conditions are met and ingredients are gathered
|
||||||
|
* @deprecated Not used internally anymore
|
||||||
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public boolean isUnlocked() {
|
public boolean isUnlocked() {
|
||||||
return ingredientsHad && conditionsMet;
|
return ingredientsHad && conditionsMet;
|
||||||
|
@ -4,7 +4,7 @@ import io.lumine.mythic.lib.api.util.SmartGive;
|
|||||||
import net.Indyuce.mmoitems.api.crafting.ConfigMMOItem;
|
import net.Indyuce.mmoitems.api.crafting.ConfigMMOItem;
|
||||||
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
|
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
|
||||||
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue;
|
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue;
|
||||||
import net.Indyuce.mmoitems.api.crafting.IngredientInventory;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.IngredientInventory;
|
||||||
import net.Indyuce.mmoitems.api.event.PlayerUseCraftingStationEvent;
|
import net.Indyuce.mmoitems.api.event.PlayerUseCraftingStationEvent;
|
||||||
import net.Indyuce.mmoitems.api.item.util.ConfigItems;
|
import net.Indyuce.mmoitems.api.item.util.ConfigItems;
|
||||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||||
@ -19,7 +19,7 @@ public class CraftingRecipe extends Recipe {
|
|||||||
private final ConfigMMOItem output;
|
private final ConfigMMOItem output;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* there can't be any crafting time for upgrading recipes since there is no
|
* There can't be any crafting time for upgrading recipes since there is no
|
||||||
* way to save an MMOItem in the config file TODO save as ItemStack
|
* way to save an MMOItem in the config file TODO save as ItemStack
|
||||||
*/
|
*/
|
||||||
private final double craftingTime;
|
private final double craftingTime;
|
||||||
@ -96,4 +96,9 @@ public class CraftingRecipe extends Recipe {
|
|||||||
public ItemStack display(CheckedRecipe recipe) {
|
public ItemStack display(CheckedRecipe recipe) {
|
||||||
return ConfigItems.CRAFTING_RECIPE_DISPLAY.newBuilder(recipe).build();
|
return ConfigItems.CRAFTING_RECIPE_DISPLAY.newBuilder(recipe).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckedRecipe evaluateRecipe(PlayerData data, IngredientInventory inv) {
|
||||||
|
return new CheckedRecipe(this, data, inv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,9 @@ package net.Indyuce.mmoitems.api.crafting.recipe;
|
|||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
import net.Indyuce.mmoitems.MMOItems;
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
|
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
|
||||||
import net.Indyuce.mmoitems.api.crafting.IngredientInventory;
|
|
||||||
import net.Indyuce.mmoitems.api.crafting.condition.Condition;
|
import net.Indyuce.mmoitems.api.crafting.condition.Condition;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.IngredientInventory;
|
||||||
import net.Indyuce.mmoitems.api.crafting.trigger.Trigger;
|
import net.Indyuce.mmoitems.api.crafting.trigger.Trigger;
|
||||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
@ -51,7 +51,6 @@ public abstract class Recipe {
|
|||||||
for (String format : config.getStringList("ingredients"))
|
for (String format : config.getStringList("ingredients"))
|
||||||
try {
|
try {
|
||||||
Ingredient ingredient = MMOItems.plugin.getCrafting().getIngredient(new MMOLineConfig(format));
|
Ingredient ingredient = MMOItems.plugin.getCrafting().getIngredient(new MMOLineConfig(format));
|
||||||
Validate.notNull(ingredient, "Could not match ingredient");
|
|
||||||
ingredients.add(ingredient);
|
ingredients.add(ingredient);
|
||||||
} catch (IllegalArgumentException exception) {
|
} catch (IllegalArgumentException exception) {
|
||||||
throw new IllegalArgumentException("Could not load ingredient '" + format + "': " + exception.getMessage());
|
throw new IllegalArgumentException("Could not load ingredient '" + format + "': " + exception.getMessage());
|
||||||
@ -63,7 +62,6 @@ public abstract class Recipe {
|
|||||||
for (String format : config.getStringList("conditions"))
|
for (String format : config.getStringList("conditions"))
|
||||||
try {
|
try {
|
||||||
Condition condition = MMOItems.plugin.getCrafting().getCondition(new MMOLineConfig(format));
|
Condition condition = MMOItems.plugin.getCrafting().getCondition(new MMOLineConfig(format));
|
||||||
Validate.notNull(condition, "Could not match condition");
|
|
||||||
conditions.add(condition);
|
conditions.add(condition);
|
||||||
} catch (IllegalArgumentException exception) {
|
} catch (IllegalArgumentException exception) {
|
||||||
throw new IllegalArgumentException("Could not load condition '" + format + "': " + exception.getMessage());
|
throw new IllegalArgumentException("Could not load condition '" + format + "': " + exception.getMessage());
|
||||||
@ -131,14 +129,16 @@ public abstract class Recipe {
|
|||||||
options.put(option, value);
|
options.put(option, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CheckedRecipe evaluateRecipe(PlayerData data, IngredientInventory inv) {
|
/**
|
||||||
return new CheckedRecipe(this, data, inv);
|
* THE method that checks if a player can use a recipe or not. This checks for
|
||||||
}
|
* conditions and ingredients and saves all the info needed to display everything
|
||||||
|
* in the item lore.
|
||||||
@Override
|
*
|
||||||
public boolean equals(Object obj) {
|
* @param data Player trying to use the recipe
|
||||||
return obj instanceof Recipe && ((Recipe) obj).id.equals(id);
|
* @param inv The ingredients of the player
|
||||||
}
|
* @return Class that knows if the player can use the recipe
|
||||||
|
*/
|
||||||
|
public abstract CheckedRecipe evaluateRecipe(PlayerData data, IngredientInventory inv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when all the recipe conditions are to true and when the player
|
* Called when all the recipe conditions are to true and when the player
|
||||||
@ -167,7 +167,12 @@ public abstract class Recipe {
|
|||||||
|
|
||||||
public abstract ItemStack display(CheckedRecipe recipe);
|
public abstract ItemStack display(CheckedRecipe recipe);
|
||||||
|
|
||||||
public enum RecipeOption {
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof Recipe && ((Recipe) obj).id.equals(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum RecipeOption {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hide the crafting recipe when one of the condition is not met
|
* Hide the crafting recipe when one of the condition is not met
|
||||||
|
@ -1,27 +1,25 @@
|
|||||||
package net.Indyuce.mmoitems.api.crafting.recipe;
|
package net.Indyuce.mmoitems.api.crafting.recipe;
|
||||||
|
|
||||||
import java.util.Random;
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import net.Indyuce.mmoitems.ItemStats;
|
import net.Indyuce.mmoitems.ItemStats;
|
||||||
import net.Indyuce.mmoitems.MMOUtils;
|
import net.Indyuce.mmoitems.MMOUtils;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ConfigMMOItem;
|
import net.Indyuce.mmoitems.api.crafting.ConfigMMOItem;
|
||||||
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
|
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
|
||||||
import net.Indyuce.mmoitems.api.crafting.IngredientInventory;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.CheckedIngredient;
|
||||||
import net.Indyuce.mmoitems.api.crafting.IngredientInventory.IngredientLookupMode;
|
|
||||||
import net.Indyuce.mmoitems.api.crafting.IngredientInventory.PlayerIngredient;
|
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.MMOItemIngredient;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.MMOItemIngredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.IngredientInventory;
|
||||||
import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem;
|
import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem;
|
||||||
import net.Indyuce.mmoitems.api.item.util.ConfigItems;
|
import net.Indyuce.mmoitems.api.item.util.ConfigItems;
|
||||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||||
import net.Indyuce.mmoitems.api.util.message.Message;
|
import net.Indyuce.mmoitems.api.util.message.Message;
|
||||||
import net.Indyuce.mmoitems.stat.data.UpgradeData;
|
import net.Indyuce.mmoitems.stat.data.UpgradeData;
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
public class UpgradingRecipe extends Recipe {
|
public class UpgradingRecipe extends Recipe {
|
||||||
private final ConfigMMOItem item;
|
private final ConfigMMOItem item;
|
||||||
@ -32,9 +30,7 @@ public class UpgradingRecipe extends Recipe {
|
|||||||
public UpgradingRecipe(ConfigurationSection config) {
|
public UpgradingRecipe(ConfigurationSection config) {
|
||||||
super(config);
|
super(config);
|
||||||
|
|
||||||
/*
|
// load item being upgraded.
|
||||||
* load item being upgraded.
|
|
||||||
*/
|
|
||||||
item = new ConfigMMOItem(config.getConfigurationSection("item"));
|
item = new ConfigMMOItem(config.getConfigurationSection("item"));
|
||||||
ingredient = new MMOItemIngredient(item);
|
ingredient = new MMOItemIngredient(item);
|
||||||
}
|
}
|
||||||
@ -44,12 +40,12 @@ public class UpgradingRecipe extends Recipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void whenUsed(PlayerData data, IngredientInventory inv, CheckedRecipe uncastRecipe, CraftingStation station) {
|
public void whenUsed(PlayerData data, IngredientInventory inv, CheckedRecipe castRecipe, CraftingStation station) {
|
||||||
UpgradingRecipeInfo recipe = (UpgradingRecipeInfo) uncastRecipe;
|
CheckedUpgradingRecipe recipe = (CheckedUpgradingRecipe) castRecipe;
|
||||||
recipe.getUpgradeData().upgrade(recipe.getMMOItem());
|
recipe.getUpgradeData().upgrade(recipe.getMMOItem());
|
||||||
recipe.getUpgraded().setItemMeta(recipe.getMMOItem().newBuilder().build().getItemMeta());
|
recipe.getUpgraded().setItemMeta(recipe.getMMOItem().newBuilder().build().getItemMeta());
|
||||||
|
|
||||||
uncastRecipe.getRecipe().getTriggers().forEach(trigger -> trigger.whenCrafting(data));
|
castRecipe.getRecipe().getTriggers().forEach(trigger -> trigger.whenCrafting(data));
|
||||||
if (!data.isOnline())
|
if (!data.isOnline())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -60,14 +56,9 @@ public class UpgradingRecipe extends Recipe {
|
|||||||
@Override
|
@Override
|
||||||
public boolean canUse(PlayerData data, IngredientInventory inv, CheckedRecipe uncastRecipe, CraftingStation station) {
|
public boolean canUse(PlayerData data, IngredientInventory inv, CheckedRecipe uncastRecipe, CraftingStation station) {
|
||||||
|
|
||||||
/*
|
// Find the item which should be upgraded
|
||||||
* try to find the item which is meant to be updated. null check is
|
CheckedIngredient upgraded = inv.findMatching(ingredient);
|
||||||
* ugly, BUT it does halve calculations done because it does not calls
|
if (!upgraded.isHad()) {
|
||||||
* two map lookups. it is not needed to check for the amount because
|
|
||||||
* only one item is upgraded.
|
|
||||||
*/
|
|
||||||
PlayerIngredient upgraded = inv.getIngredient(ingredient, IngredientLookupMode.IGNORE_ITEM_LEVEL);
|
|
||||||
if (upgraded == null) {
|
|
||||||
if (!data.isOnline())
|
if (!data.isOnline())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -76,11 +67,15 @@ public class UpgradingRecipe extends Recipe {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpgradingRecipeInfo recipe = (UpgradingRecipeInfo) uncastRecipe;
|
// Finds the item that will be upgraded
|
||||||
if (!(recipe.mmoitem = new LiveMMOItem(MythicLib.plugin.getVersion().getWrapper().getNBTItem(upgraded.getFirstItem())))
|
NBTItem firstItem = NBTItem.get(upgraded.getFound().stream().findFirst().get().getItem());
|
||||||
.hasData(ItemStats.UPGRADE))
|
|
||||||
|
// Checks if upgraded item DOES has an upgrade template
|
||||||
|
CheckedUpgradingRecipe recipe = (CheckedUpgradingRecipe) uncastRecipe;
|
||||||
|
if (!(recipe.mmoitem = new LiveMMOItem(firstItem)).hasData(ItemStats.UPGRADE))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Checks for max upgrade level
|
||||||
if (!(recipe.upgradeData = (UpgradeData) recipe.getMMOItem().getData(ItemStats.UPGRADE)).canLevelUp()) {
|
if (!(recipe.upgradeData = (UpgradeData) recipe.getMMOItem().getData(ItemStats.UPGRADE)).canLevelUp()) {
|
||||||
if (!data.isOnline())
|
if (!data.isOnline())
|
||||||
return false;
|
return false;
|
||||||
@ -90,11 +85,16 @@ public class UpgradingRecipe extends Recipe {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks for failure
|
||||||
if (random.nextDouble() > recipe.getUpgradeData().getSuccess()) {
|
if (random.nextDouble() > recipe.getUpgradeData().getSuccess()) {
|
||||||
|
|
||||||
|
// Should the item be destroyed when failing to upgrade
|
||||||
if (recipe.getUpgradeData().destroysOnFail())
|
if (recipe.getUpgradeData().destroysOnFail())
|
||||||
recipe.getUpgraded().setAmount(recipe.getUpgraded().getAmount() - 1);
|
recipe.getUpgraded().setAmount(recipe.getUpgraded().getAmount() - 1);
|
||||||
|
|
||||||
recipe.getIngredients().forEach(ingredient -> ingredient.getPlayerIngredient().reduceItem(ingredient.getIngredient().getAmount()));
|
// Take away ingredients
|
||||||
|
recipe.getIngredients().forEach(ingredient -> ingredient.takeAway());
|
||||||
|
|
||||||
if (!data.isOnline())
|
if (!data.isOnline())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -113,14 +113,18 @@ public class UpgradingRecipe extends Recipe {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CheckedRecipe evaluateRecipe(PlayerData data, IngredientInventory inv) {
|
public CheckedRecipe evaluateRecipe(PlayerData data, IngredientInventory inv) {
|
||||||
return new UpgradingRecipeInfo(this, data, inv);
|
return new CheckedUpgradingRecipe(this, data, inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class UpgradingRecipeInfo extends CheckedRecipe {
|
/**
|
||||||
|
* Used to cache the LiveMMOItem instance and UpgradeData
|
||||||
|
* which take a little performance to calculate.
|
||||||
|
*/
|
||||||
|
public class CheckedUpgradingRecipe extends CheckedRecipe {
|
||||||
private LiveMMOItem mmoitem;
|
private LiveMMOItem mmoitem;
|
||||||
private UpgradeData upgradeData;
|
private UpgradeData upgradeData;
|
||||||
|
|
||||||
public UpgradingRecipeInfo(Recipe recipe, PlayerData data, IngredientInventory inv) {
|
public CheckedUpgradingRecipe(Recipe recipe, PlayerData data, IngredientInventory inv) {
|
||||||
super(recipe, data, inv);
|
super(recipe, data, inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,25 +3,19 @@ package net.Indyuce.mmoitems.api.item.template;
|
|||||||
import io.lumine.mythic.lib.api.util.PostLoadObject;
|
import io.lumine.mythic.lib.api.util.PostLoadObject;
|
||||||
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackCategory;
|
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackCategory;
|
||||||
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider;
|
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider;
|
||||||
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
|
|
||||||
import net.Indyuce.mmoitems.ItemStats;
|
|
||||||
import net.Indyuce.mmoitems.MMOItems;
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
import net.Indyuce.mmoitems.api.ItemTier;
|
import net.Indyuce.mmoitems.api.ItemTier;
|
||||||
import net.Indyuce.mmoitems.api.Type;
|
import net.Indyuce.mmoitems.api.Type;
|
||||||
import net.Indyuce.mmoitems.api.item.ItemReference;
|
import net.Indyuce.mmoitems.api.item.ItemReference;
|
||||||
import net.Indyuce.mmoitems.api.item.build.MMOItemBuilder;
|
import net.Indyuce.mmoitems.api.item.build.MMOItemBuilder;
|
||||||
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
|
|
||||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||||
import net.Indyuce.mmoitems.api.player.RPGPlayer;
|
import net.Indyuce.mmoitems.api.player.RPGPlayer;
|
||||||
import net.Indyuce.mmoitems.api.util.NumericStatFormula;
|
|
||||||
import net.Indyuce.mmoitems.api.util.message.FFPMMOItems;
|
import net.Indyuce.mmoitems.api.util.message.FFPMMOItems;
|
||||||
import net.Indyuce.mmoitems.stat.data.random.RandomStatData;
|
import net.Indyuce.mmoitems.stat.data.random.RandomStatData;
|
||||||
import net.Indyuce.mmoitems.stat.type.ItemStat;
|
import net.Indyuce.mmoitems.stat.type.ItemStat;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -149,7 +143,6 @@ public class MMOItemTemplate extends PostLoadObject implements ItemReference {
|
|||||||
return options.contains(option);
|
return options.contains(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public MMOItemBuilder newBuilder(@Nullable Player player) {
|
public MMOItemBuilder newBuilder(@Nullable Player player) {
|
||||||
if (player != null) { return newBuilder(PlayerData.get(player).getRPG()); }
|
if (player != null) { return newBuilder(PlayerData.get(player).getRPG()); }
|
||||||
return newBuilder((RPGPlayer) null);
|
return newBuilder((RPGPlayer) null);
|
||||||
|
@ -7,7 +7,7 @@ import io.lumine.mythic.lib.api.util.LegacyComponent;
|
|||||||
import io.lumine.mythic.utils.adventure.text.Component;
|
import io.lumine.mythic.utils.adventure.text.Component;
|
||||||
import net.Indyuce.mmoitems.MMOUtils;
|
import net.Indyuce.mmoitems.MMOUtils;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
|
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
|
||||||
import net.Indyuce.mmoitems.api.crafting.condition.Condition.CheckedCondition;
|
import net.Indyuce.mmoitems.api.crafting.condition.CheckedCondition;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
|
||||||
import net.Indyuce.mmoitems.api.item.util.ConfigItem;
|
import net.Indyuce.mmoitems.api.item.util.ConfigItem;
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package net.Indyuce.mmoitems.api.item.util.crafting;
|
package net.Indyuce.mmoitems.api.item.util.crafting;
|
||||||
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
|
||||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
import io.lumine.mythic.lib.api.util.LegacyComponent;
|
import io.lumine.mythic.lib.api.util.LegacyComponent;
|
||||||
import io.lumine.mythic.utils.adventure.text.Component;
|
import io.lumine.mythic.utils.adventure.text.Component;
|
||||||
import net.Indyuce.mmoitems.MMOUtils;
|
import net.Indyuce.mmoitems.MMOUtils;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
|
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
|
||||||
import net.Indyuce.mmoitems.api.crafting.condition.Condition.CheckedCondition;
|
import net.Indyuce.mmoitems.api.crafting.condition.CheckedCondition;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.UpgradingRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.UpgradingRecipe;
|
||||||
import net.Indyuce.mmoitems.api.item.util.ConfigItem;
|
import net.Indyuce.mmoitems.api.item.util.ConfigItem;
|
||||||
@ -16,11 +15,7 @@ import org.bukkit.inventory.ItemFlag;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ListIterator;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class UpgradingRecipeDisplay extends ConfigItem {
|
public class UpgradingRecipeDisplay extends ConfigItem {
|
||||||
public UpgradingRecipeDisplay() {
|
public UpgradingRecipeDisplay() {
|
||||||
|
@ -1,19 +1,25 @@
|
|||||||
package net.Indyuce.mmoitems.comp.mythicmobs.crafting;
|
package net.Indyuce.mmoitems.comp.mythicmobs.crafting;
|
||||||
|
|
||||||
import java.util.Optional;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import io.lumine.xikage.mythicmobs.MythicMobs;
|
import io.lumine.xikage.mythicmobs.MythicMobs;
|
||||||
import io.lumine.xikage.mythicmobs.adapters.bukkit.BukkitAdapter;
|
import io.lumine.xikage.mythicmobs.adapters.bukkit.BukkitAdapter;
|
||||||
import io.lumine.xikage.mythicmobs.items.MythicItem;
|
import io.lumine.xikage.mythicmobs.items.MythicItem;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
||||||
import net.Indyuce.mmoitems.api.player.RPGPlayer;
|
import net.Indyuce.mmoitems.api.player.RPGPlayer;
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class MythicItemIngredient extends Ingredient {
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No way of checking if an item was generated using MythicMobs? There does
|
||||||
|
* not seem to be any NBTTag for that using the latest dev build
|
||||||
|
*
|
||||||
|
* @deprecated Not implemented yet
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public class MythicItemIngredient extends Ingredient<MythicItemPlayerIngredient> {
|
||||||
private final MythicItem mythicitem;
|
private final MythicItem mythicitem;
|
||||||
|
|
||||||
private final String display;
|
private final String display;
|
||||||
@ -39,6 +45,11 @@ public class MythicItemIngredient extends Ingredient {
|
|||||||
return s.replace("#item#", display).replace("#amount#", "" + getAmount());
|
return s.replace("#item#", display).replace("#amount#", "" + getAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(MythicItemPlayerIngredient playerIngredient) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ItemStack generateItemStack(@NotNull RPGPlayer player) {
|
public ItemStack generateItemStack(@NotNull RPGPlayer player) {
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package net.Indyuce.mmoitems.comp.mythicmobs.crafting;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.PlayerIngredient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Not implemented yet
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public class MythicItemPlayerIngredient extends PlayerIngredient {
|
||||||
|
private final String type, id;
|
||||||
|
|
||||||
|
public MythicItemPlayerIngredient(NBTItem item) {
|
||||||
|
super(item);
|
||||||
|
|
||||||
|
type = item.getString("MYTHIC_TYPE").toLowerCase();
|
||||||
|
|
||||||
|
// No idea what to use here
|
||||||
|
id = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@ import io.lumine.mythic.lib.api.util.LegacyComponent;
|
|||||||
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
|
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
|
||||||
import io.lumine.mythic.utils.adventure.text.Component;
|
import io.lumine.mythic.utils.adventure.text.Component;
|
||||||
import net.Indyuce.mmoitems.MMOUtils;
|
import net.Indyuce.mmoitems.MMOUtils;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient.CheckedIngredient;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.CheckedIngredient;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.UpgradingRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.UpgradingRecipe;
|
||||||
|
@ -8,9 +8,9 @@ import net.Indyuce.mmoitems.MMOUtils;
|
|||||||
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
|
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
|
||||||
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue;
|
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue;
|
||||||
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue.CraftingInfo;
|
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue.CraftingInfo;
|
||||||
import net.Indyuce.mmoitems.api.crafting.IngredientInventory;
|
|
||||||
import net.Indyuce.mmoitems.api.crafting.Layout;
|
import net.Indyuce.mmoitems.api.crafting.Layout;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.IngredientInventory;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
|
||||||
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe;
|
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe;
|
||||||
@ -34,6 +34,7 @@ import java.util.UUID;
|
|||||||
public class CraftingStationView extends PluginInventory {
|
public class CraftingStationView extends PluginInventory {
|
||||||
private final CraftingStation station;
|
private final CraftingStation station;
|
||||||
private final Layout layout;
|
private final Layout layout;
|
||||||
|
|
||||||
private List<CheckedRecipe> recipes;
|
private List<CheckedRecipe> recipes;
|
||||||
private IngredientInventory ingredients;
|
private IngredientInventory ingredients;
|
||||||
|
|
||||||
@ -128,6 +129,7 @@ public class CraftingStationView extends PluginInventory {
|
|||||||
public void whenClicked(InventoryClickEvent event) {
|
public void whenClicked(InventoryClickEvent event) {
|
||||||
if (!playerData.isOnline())
|
if (!playerData.isOnline())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
if (!MMOUtils.isMetaItem(event.getCurrentItem(), false))
|
if (!MMOUtils.isMetaItem(event.getCurrentItem(), false))
|
||||||
return;
|
return;
|
||||||
@ -159,18 +161,17 @@ public class CraftingStationView extends PluginInventory {
|
|||||||
|
|
||||||
NBTItem item = MythicLib.plugin.getVersion().getWrapper().getNBTItem(event.getCurrentItem());
|
NBTItem item = MythicLib.plugin.getVersion().getWrapper().getNBTItem(event.getCurrentItem());
|
||||||
String tag = item.getString("recipeId");
|
String tag = item.getString("recipeId");
|
||||||
if (!tag.equals("")) {
|
if (!tag.isEmpty()) {
|
||||||
CheckedRecipe recipe = getRecipe(tag);
|
CheckedRecipe recipe = getRecipe(tag);
|
||||||
if (event.isRightClick()) {
|
if (event.isRightClick())
|
||||||
new CraftingStationPreview(this, recipe).open();
|
new CraftingStationPreview(this, recipe).open();
|
||||||
return;
|
else {
|
||||||
}
|
|
||||||
|
|
||||||
processRecipe(recipe);
|
processRecipe(recipe);
|
||||||
open();
|
open();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(tag = item.getString("queueId")).equals("")) {
|
if (!(tag = item.getString("queueId")).isEmpty()) {
|
||||||
UUID uuid = UUID.fromString(tag);
|
UUID uuid = UUID.fromString(tag);
|
||||||
CraftingInfo recipeInfo = playerData.getCrafting().getQueue(station).getCraft(uuid);
|
CraftingInfo recipeInfo = playerData.getCrafting().getQueue(station).getCraft(uuid);
|
||||||
CraftingRecipe recipe = recipeInfo.getRecipe();
|
CraftingRecipe recipe = recipeInfo.getRecipe();
|
||||||
@ -247,7 +248,7 @@ public class CraftingStationView extends PluginInventory {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
recipe.getRecipe().whenUsed(playerData, ingredients, recipe, station);
|
recipe.getRecipe().whenUsed(playerData, ingredients, recipe, station);
|
||||||
recipe.getIngredients().forEach(ingredient -> ingredient.getPlayerIngredient().reduceItem(ingredient.getIngredient().getAmount()));
|
recipe.getIngredients().forEach(ingredient -> ingredient.takeAway());
|
||||||
recipe.getConditions().forEach(condition -> condition.getCondition().whenCrafting(playerData));
|
recipe.getConditions().forEach(condition -> condition.getCondition().whenCrafting(playerData));
|
||||||
|
|
||||||
updateData();
|
updateData();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package net.Indyuce.mmoitems.manager;
|
package net.Indyuce.mmoitems.manager;
|
||||||
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
import io.lumine.mythic.lib.api.util.AltChar;
|
import io.lumine.mythic.lib.api.util.AltChar;
|
||||||
@ -8,16 +7,22 @@ import net.Indyuce.mmoitems.MMOItems;
|
|||||||
import net.Indyuce.mmoitems.api.ConfigFile;
|
import net.Indyuce.mmoitems.api.ConfigFile;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
|
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
|
||||||
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
|
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.LoadedCraftingObject;
|
||||||
import net.Indyuce.mmoitems.api.crafting.condition.*;
|
import net.Indyuce.mmoitems.api.crafting.condition.*;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.IngredientType;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.MMOItemIngredient;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.MMOItemIngredient;
|
||||||
import net.Indyuce.mmoitems.api.crafting.ingredient.VanillaIngredient;
|
import net.Indyuce.mmoitems.api.crafting.ingredient.VanillaIngredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.MMOItemPlayerIngredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.PlayerIngredient;
|
||||||
|
import net.Indyuce.mmoitems.api.crafting.ingredient.inventory.VanillaPlayerIngredient;
|
||||||
import net.Indyuce.mmoitems.api.crafting.trigger.*;
|
import net.Indyuce.mmoitems.api.crafting.trigger.*;
|
||||||
import net.Indyuce.mmoitems.comp.mythicmobs.crafting.MythicItemIngredient;
|
|
||||||
import net.Indyuce.mmoitems.comp.mythicmobs.crafting.MythicMobsSkillTrigger;
|
import net.Indyuce.mmoitems.comp.mythicmobs.crafting.MythicMobsSkillTrigger;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -26,18 +31,19 @@ import java.util.logging.Level;
|
|||||||
|
|
||||||
public class CraftingManager implements Reloadable {
|
public class CraftingManager implements Reloadable {
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* order matters when trying to recognize an ingredient type: if none
|
* Order matters when trying to recognize an ingredient type: if none
|
||||||
* ingredient matches, the item is considered as a vanilla item.
|
* ingredient matches, the item is considered as a vanilla item.
|
||||||
*/
|
*/
|
||||||
private final List<IngredientType> ingredients = new ArrayList<>();
|
private final List<IngredientType> ingredients = new ArrayList<>();
|
||||||
private final Set<LoadedObject<Condition>> conditions = new HashSet<>();
|
private final Set<LoadedCraftingObject<Condition>> conditions = new HashSet<>();
|
||||||
private final Set<LoadedObject<Trigger>> triggers = new HashSet<>();
|
private final Set<LoadedCraftingObject<Trigger>> triggers = new HashSet<>();
|
||||||
|
|
||||||
private final Map<String, CraftingStation> stations = new HashMap<>();
|
private final Map<String, CraftingStation> stations = new HashMap<>();
|
||||||
|
|
||||||
public CraftingManager() {
|
public CraftingManager() {
|
||||||
// conditions
|
|
||||||
|
// Conditions
|
||||||
registerCondition("level", LevelCondition::new, new ConditionalDisplay("&a" + AltChar.check + " Requires Level #level#", "&c" + AltChar.cross + " Requires Level #level#"));
|
registerCondition("level", LevelCondition::new, new ConditionalDisplay("&a" + AltChar.check + " Requires Level #level#", "&c" + AltChar.cross + " Requires Level #level#"));
|
||||||
registerCondition("permission", PermissionCondition::new, null);
|
registerCondition("permission", PermissionCondition::new, null);
|
||||||
registerCondition("placeholder", PlaceholderCondition::new, null);
|
registerCondition("placeholder", PlaceholderCondition::new, null);
|
||||||
@ -46,26 +52,22 @@ public class CraftingManager implements Reloadable {
|
|||||||
registerCondition("food", FoodCondition::new, new ConditionalDisplay("&a" + AltChar.check + " Requires #food# Food", "&c" + AltChar.cross + " Requires #food# Food"));
|
registerCondition("food", FoodCondition::new, new ConditionalDisplay("&a" + AltChar.check + " Requires #food# Food", "&c" + AltChar.cross + " Requires #food# Food"));
|
||||||
registerCondition("class", ClassCondition::new, new ConditionalDisplay("&a" + AltChar.check + " Required Class: #class#", "&c" + AltChar.cross + " Required Class: #class#"));
|
registerCondition("class", ClassCondition::new, new ConditionalDisplay("&a" + AltChar.check + " Required Class: #class#", "&c" + AltChar.cross + " Required Class: #class#"));
|
||||||
|
|
||||||
// triggers
|
// Triggers
|
||||||
registerTrigger("command", CommandTrigger::new);
|
registerTrigger("command", CommandTrigger::new);
|
||||||
registerTrigger("message", MessageTrigger::new);
|
registerTrigger("message", MessageTrigger::new);
|
||||||
registerTrigger("sound", SoundTrigger::new);
|
registerTrigger("sound", SoundTrigger::new);
|
||||||
registerTrigger("vanilla", VanillaTrigger::new);
|
registerTrigger("vanilla", VanillaTrigger::new);
|
||||||
registerTrigger("mmoitem", MMOItemTrigger::new);
|
registerTrigger("mmoitem", MMOItemTrigger::new);
|
||||||
|
|
||||||
// ingredients
|
// Ingredients
|
||||||
registerIngredient("vanilla", VanillaIngredient::new, new ConditionalDisplay("&8" + AltChar.check + " &7#amount# #item#", "&c" + AltChar.cross + " &7#amount# #item#"), nbt -> true, item -> item.getItem().getType().name().toLowerCase() + "_" + (item.getItem().hasItemMeta() ? item.getItem().getItemMeta().getDisplayName() : null));
|
registerIngredient("vanilla", VanillaIngredient::new, new ConditionalDisplay("&8" + AltChar.check + " &7#amount# #item#", "&c" + AltChar.cross + " &7#amount# #item#"), nbt -> true, VanillaPlayerIngredient::new);
|
||||||
registerIngredient("mmoitem", MMOItemIngredient::new, new ConditionalDisplay("&8" + AltChar.check + " &7#amount# #level##item#", "&c" + AltChar.cross + " &7#amount# #level##item#"), NBTItem::hasType, item -> {
|
registerIngredient("mmoitem", MMOItemIngredient::new, new ConditionalDisplay("&8" + AltChar.check + " &7#amount# #level##item#", "&c" + AltChar.cross + " &7#amount# #level##item#"), NBTItem::hasType, MMOItemPlayerIngredient::new);
|
||||||
String upgradeString = item.getString("MMOITEMS_UPGRADE");
|
|
||||||
int level = !upgradeString.isEmpty() ? new JsonParser().parse(upgradeString).getAsJsonObject().get("Level").getAsInt() : 0;
|
|
||||||
return item.getString("MMOITEMS_ITEM_TYPE").toLowerCase() + (level != 0 ? "-" + level : "") + "_" + item.getString("MMOITEMS_ITEM_ID").toLowerCase();
|
|
||||||
});
|
|
||||||
|
|
||||||
// mm comp
|
// MythicMobs native compatibility
|
||||||
if (Bukkit.getPluginManager().getPlugin("MythicMobs") != null) {
|
if (Bukkit.getPluginManager().getPlugin("MythicMobs") != null) {
|
||||||
registerIngredient("mythicitem", MythicItemIngredient::new,
|
/*registerIngredient("mythicitem", MythicItemIngredient::new,
|
||||||
new ConditionalDisplay("&8" + AltChar.check + " &7#amount# #item#", "&c" + AltChar.cross + " &7#amount# #item#"),
|
new ConditionalDisplay("&8" + AltChar.check + " &7#amount# #item#", "&c" + AltChar.cross + " &7#amount# #item#"),
|
||||||
nbt -> nbt.hasTag("MYTHIC_TYPE"), nbt -> nbt.getString("MYTHIC_TYPE").toLowerCase());
|
nbt -> nbt.hasTag("MYTHIC_TYPE"), MythicItemPlayerIngredient::new);*/
|
||||||
registerTrigger("mmskill", MythicMobsSkillTrigger::new);
|
registerTrigger("mmskill", MythicMobsSkillTrigger::new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +77,7 @@ public class CraftingManager implements Reloadable {
|
|||||||
|
|
||||||
ConfigFile language = new ConfigFile("/language", "crafting-stations");
|
ConfigFile language = new ConfigFile("/language", "crafting-stations");
|
||||||
|
|
||||||
for (LoadedObject<Condition> condition : getConditions())
|
for (LoadedCraftingObject<Condition> condition : getConditions())
|
||||||
if (condition.hasDisplay()) {
|
if (condition.hasDisplay()) {
|
||||||
String path = "condition." + condition.getId();
|
String path = "condition." + condition.getId();
|
||||||
if (!language.getConfig().contains(path)) {
|
if (!language.getConfig().contains(path)) {
|
||||||
@ -134,6 +136,11 @@ public class CraftingManager implements Reloadable {
|
|||||||
return stations.get(id);
|
return stations.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the corresponding ingredient type, and from there
|
||||||
|
* load the corresponding ingredient from the line config
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
public Ingredient getIngredient(MMOLineConfig config) {
|
public Ingredient getIngredient(MMOLineConfig config) {
|
||||||
String key = config.getKey();
|
String key = config.getKey();
|
||||||
|
|
||||||
@ -141,113 +148,91 @@ public class CraftingManager implements Reloadable {
|
|||||||
if (ingredient.getId().equals(key))
|
if (ingredient.getId().equals(key))
|
||||||
return ingredient.load(config);
|
return ingredient.load(config);
|
||||||
|
|
||||||
return null;
|
throw new IllegalArgumentException("Could not match ingredient");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the corresponding condition type, and from there
|
||||||
|
* load the corresponding condition from the line config
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
public Condition getCondition(MMOLineConfig config) {
|
public Condition getCondition(MMOLineConfig config) {
|
||||||
String key = config.getKey();
|
String key = config.getKey();
|
||||||
|
|
||||||
for (LoadedObject<Condition> condition : conditions)
|
for (LoadedCraftingObject<Condition> condition : conditions)
|
||||||
if (condition.getId().equalsIgnoreCase(key))
|
if (condition.getId().equalsIgnoreCase(key))
|
||||||
return condition.load(config);
|
return condition.load(config);
|
||||||
|
|
||||||
return null;
|
throw new IllegalArgumentException("Could not match condition");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the corresponding trigger type, and from there
|
||||||
|
* load the corresponding trigger from the line config
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
public Trigger getTrigger(MMOLineConfig config) {
|
public Trigger getTrigger(MMOLineConfig config) {
|
||||||
String key = config.getKey();
|
String key = config.getKey();
|
||||||
|
|
||||||
for (LoadedObject<Trigger> trigger : triggers)
|
for (LoadedCraftingObject<Trigger> trigger : triggers)
|
||||||
if (trigger.getId().equalsIgnoreCase(key))
|
if (trigger.getId().equalsIgnoreCase(key))
|
||||||
return trigger.load(config);
|
return trigger.load(config);
|
||||||
|
|
||||||
return null;
|
throw new IllegalArgumentException("Could not match trigger");
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IngredientType> getIngredients() {
|
public List<IngredientType> getIngredients() {
|
||||||
return ingredients;
|
return ingredients;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<LoadedObject<Condition>> getConditions() {
|
public Set<LoadedCraftingObject<Condition>> getConditions() {
|
||||||
return conditions;
|
return conditions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<LoadedObject<Trigger>> getTriggers() {
|
public Set<LoadedCraftingObject<Trigger>> getTriggers() {
|
||||||
return triggers;
|
return triggers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerIngredient(String id, Function<MMOLineConfig, Ingredient> function, ConditionalDisplay display, Predicate<NBTItem> check, Function<NBTItem, String> read) {
|
/**
|
||||||
ingredients.add(0, new IngredientType(id, function, display, check, read));
|
* Registers a type of ingredient in MMOItems crafting stations
|
||||||
|
* <p>
|
||||||
|
* See {@link IngredientType} for more information.
|
||||||
|
*
|
||||||
|
* @param id The ingredient id
|
||||||
|
* @param function Function that loads an ingredient from a line config
|
||||||
|
* @param display How it displays in the item lore
|
||||||
|
* @param check Should return true if an item can be handled by this ingredient type
|
||||||
|
* @param readIngredient After checking if this ingredient type can handle an item,
|
||||||
|
* method called to provide the corresponding PlayerIngredient
|
||||||
|
*/
|
||||||
|
public void registerIngredient(String id, Function<MMOLineConfig, Ingredient> function, ConditionalDisplay display, Predicate<NBTItem> check, Function<NBTItem, PlayerIngredient> readIngredient) {
|
||||||
|
ingredients.add(0, new IngredientType(id, function, display, check, readIngredient));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerCondition(String id, Function<MMOLineConfig, Condition> function, ConditionalDisplay display) {
|
/**
|
||||||
conditions.add(new LoadedObject<>(id, function, display));
|
* Registers a type of condition in MMOItems crafting stations
|
||||||
|
*
|
||||||
|
* @param id Condition ID
|
||||||
|
* @param function Function that loads a condition from a line conf
|
||||||
|
* @param display How it displays in the item lore, null if it should not
|
||||||
|
*/
|
||||||
|
public void registerCondition(String id, Function<MMOLineConfig, Condition> function, @Nullable ConditionalDisplay display) {
|
||||||
|
conditions.add(new LoadedCraftingObject<>(id, function, display));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a type of trigger in MMOItems crafting stations. Unlike
|
||||||
|
* conditions or ingredients, triggers don't need to be displayed
|
||||||
|
* in the item lore therefore no 'display' argument is required.
|
||||||
|
*
|
||||||
|
* @param id Trigger ID
|
||||||
|
* @param function Function that loads that type of trigger from a line configuration
|
||||||
|
*/
|
||||||
public void registerTrigger(String id, Function<MMOLineConfig, Trigger> function) {
|
public void registerTrigger(String id, Function<MMOLineConfig, Trigger> function) {
|
||||||
triggers.add(new LoadedObject<>(id, function, null));
|
triggers.add(new LoadedCraftingObject<Trigger>(id, function, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<CraftingStation> getAll() {
|
public Collection<CraftingStation> getAll() {
|
||||||
return stations.values();
|
return stations.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LoadedObject<C> {
|
|
||||||
private final String id;
|
|
||||||
private final Function<MMOLineConfig, C> function;
|
|
||||||
|
|
||||||
private ConditionalDisplay display;
|
|
||||||
|
|
||||||
public LoadedObject(String id, Function<MMOLineConfig, C> function, ConditionalDisplay display) {
|
|
||||||
this.id = id;
|
|
||||||
this.function = function;
|
|
||||||
this.display = display;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDisplay(ConditionalDisplay display) {
|
|
||||||
this.display = display;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasDisplay() {
|
|
||||||
return display != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConditionalDisplay getDisplay() {
|
|
||||||
return display;
|
|
||||||
}
|
|
||||||
|
|
||||||
public C load(MMOLineConfig config) {
|
|
||||||
return function.apply(config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class IngredientType extends LoadedObject<Ingredient> {
|
|
||||||
private final Predicate<NBTItem> check;
|
|
||||||
private final Function<NBTItem, String> read;
|
|
||||||
|
|
||||||
public IngredientType(String id, Function<MMOLineConfig, Ingredient> function, ConditionalDisplay display, Predicate<NBTItem> check, Function<NBTItem, String> read) {
|
|
||||||
super(id, function, display);
|
|
||||||
|
|
||||||
this.check = check;
|
|
||||||
this.read = read;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* returns true if the checked item can be handled by this ingredient
|
|
||||||
*/
|
|
||||||
public boolean check(NBTItem item) {
|
|
||||||
return check.test(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* reads the ingredient read from an NBTItem
|
|
||||||
*/
|
|
||||||
public String readKey(NBTItem item) {
|
|
||||||
return read.apply(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user