!Added comments to the station API + small cleanups

This commit is contained in:
Indyuce 2020-12-22 14:48:52 +01:00
parent 537cff02d4
commit 57b20fa97d
15 changed files with 289 additions and 191 deletions

View File

@ -4,7 +4,7 @@ import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe;
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe.RecipeOption;
import net.Indyuce.mmoitems.api.crafting.recipe.RecipeInfo;
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
import net.Indyuce.mmoitems.api.crafting.recipe.UpgradingRecipe;
import net.Indyuce.mmoitems.api.player.PlayerData;
import net.mmogroup.mmolib.MMOLib;
@ -110,11 +110,11 @@ public class CraftingStation extends PostLoadObject {
return maxQueueSize;
}
public List<RecipeInfo> getAvailableRecipes(PlayerData data, IngredientInventory inv) {
List<RecipeInfo> infos = new ArrayList<>();
public List<CheckedRecipe> getAvailableRecipes(PlayerData data, IngredientInventory inv) {
List<CheckedRecipe> infos = new ArrayList<>();
for (Recipe recipe : getRecipes()) {
RecipeInfo info = recipe.getRecipeInfo(data, inv);
CheckedRecipe info = recipe.evaluateRecipe(data, inv);
if ((info.areConditionsMet() || !info.getRecipe().hasOption(RecipeOption.HIDE_WHEN_LOCKED))
&& (info.allIngredientsHad() || !info.getRecipe().hasOption(RecipeOption.HIDE_WHEN_NO_INGREDIENTS)))
infos.add(info);

View File

@ -7,6 +7,12 @@ import net.Indyuce.mmoitems.api.player.PlayerData;
public abstract class Condition {
private final String id;
/**
* Instanciated for every condition in a crafting recipe when loading a
* crafting station from the config file.
*
* @param id The condition id
*/
public Condition(String id) {
this.id = id;
}
@ -16,20 +22,38 @@ public abstract class Condition {
}
/*
* shortcut to RecipeManager map lookup, may throw a stream lookup error if
* Shortcut to RecipeManager map lookup, may throw a stream lookup error if
* the condition has not been registered.
*/
public ConditionalDisplay getDisplay() {
return MMOItems.plugin.getCrafting().getConditions().stream().filter(type -> type.getId().equals(id)).findAny().orElse(null).getDisplay();
}
/**
* @param data The player opening the crafting station
* @return If the condition is met by the player
*/
public abstract boolean isMet(PlayerData data);
/**
* Apply specific placeholders to display the condition in the item lore.
*
* @param string String with unparsed placeholders
* @return String with parsed placeholders
*/
public abstract String formatDisplay(String string);
/**
* Conditions like mana or stamina costs may behave like triggers ie they
* can perform an action if the recipe is used by the player. This method is
* called when the player crafts the item (not when he opens the station
* inventory)
*
* @param data The player crafting the item
*/
public abstract void whenCrafting(PlayerData data);
public CheckedCondition newConditionInfo(PlayerData data) {
public CheckedCondition evaluateCondition(PlayerData data) {
return new CheckedCondition(this, isMet(data));
}
@ -37,6 +61,14 @@ public abstract class Condition {
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;

View File

@ -1,5 +1,7 @@
package net.Indyuce.mmoitems.api.crafting.ingredient;
import org.bukkit.inventory.ItemStack;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
import net.Indyuce.mmoitems.api.crafting.IngredientInventory;
@ -7,7 +9,6 @@ import net.Indyuce.mmoitems.api.crafting.IngredientInventory.IngredientLookupMod
import net.Indyuce.mmoitems.api.crafting.IngredientInventory.PlayerIngredient;
import net.Indyuce.mmoitems.api.player.RPGPlayer;
import net.mmogroup.mmolib.api.MMOLineConfig;
import org.bukkit.inventory.ItemStack;
public abstract class Ingredient {
private final String id;
@ -38,34 +39,42 @@ public abstract class Ingredient {
return MMOItems.plugin.getCrafting().getIngredients().stream().filter(type -> type.getId().equals(id)).findAny().orElse(null).getDisplay();
}
/*
* ingredient key is used internally by plugin to check if two ingredients
* are of the same nature. name is the actual piece of string displayed
/**
* @return The ingredient key which is used internally by MMOItems to check
* if two ingredients are of the same nature.
*/
public abstract String getKey();
/*
* apply specific placeholders to display the ingredient in the item lore.
/**
* Apply specific placeholders to display the ingredient in the item lore.
*
* @param string String with unparsed placeholders
* @return String with parsed placeholders
*/
public abstract String formatLoreDisplay(String string);
public abstract String formatDisplay(String string);
public abstract ItemStack generateItemStack(RPGPlayer player);
public CheckedIngredient newIngredientInfo(IngredientInventory inv) {
public CheckedIngredient evaluateIngredient(IngredientInventory inv) {
return new CheckedIngredient(this, inv.getIngredient(this, IngredientLookupMode.BASIC));
}
/*
* used to reduce calculations when the player has opened the crafting
* station. ingredientInfo instances must be updated everytime the player's
* inventory updates.
*/
public static class CheckedIngredient {
private final Ingredient inventory;
private final Ingredient ingredient;
private final PlayerIngredient found;
private CheckedIngredient(Ingredient inventory, PlayerIngredient found) {
this.inventory = inventory;
/**
* Instanciated 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(Ingredient ingredient, PlayerIngredient found) {
this.ingredient = ingredient;
this.found = found;
}
@ -73,11 +82,11 @@ public abstract class Ingredient {
* checks if the player has a specific item or not
*/
public boolean isHad() {
return found != null && found.getAmount() >= inventory.getAmount();
return found != null && found.getAmount() >= ingredient.getAmount();
}
public Ingredient getIngredient() {
return inventory;
return ingredient;
}
public PlayerIngredient getPlayerIngredient() {
@ -85,7 +94,7 @@ public abstract class Ingredient {
}
public String format() {
return inventory.formatLoreDisplay(isHad() ? inventory.getDisplay().getPositive() : inventory.getDisplay().getNegative());
return ingredient.formatDisplay(isHad() ? ingredient.getDisplay().getPositive() : ingredient.getDisplay().getNegative());
}
}
}

View File

@ -48,7 +48,7 @@ public class MMOItemIngredient extends Ingredient {
}
@Override
public String formatLoreDisplay(String string) {
public String formatDisplay(String string) {
return string.replace("#item#", display).replace("#level#", level != 0 ? "lvl." + level + " " : "").replace("#amount#", "" + getAmount());
}

View File

@ -12,9 +12,9 @@ import net.mmogroup.mmolib.api.MMOLineConfig;
public class VanillaIngredient extends Ingredient {
private final Material material;
/*
* display display is the item's meta display display, display corresponds
* to how the ingredient displays in the crafting recipe GUI item lores
/**
* displayName is the itemMeta display name; display corresponds to how the
* ingredient displays in the crafting recipe GUI item lore
*/
private final String displayName, display;
@ -35,7 +35,7 @@ public class VanillaIngredient extends Ingredient {
}
@Override
public String formatLoreDisplay(String string) {
public String formatDisplay(String string) {
return string.replace("#item#", display).replace("#amount#", "" + getAmount());
}

View File

@ -13,7 +13,7 @@ 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 RecipeInfo {
public class CheckedRecipe {
private final Recipe recipe;
private final Set<CheckedCondition> conditions = new LinkedHashSet<>();
@ -21,27 +21,32 @@ public class RecipeInfo {
private boolean ingredientsHad = true, conditionsMet = true;
/*
* once the recipe is loaded, this class is used to reduce checkups for
* ingredients and conditions
/**
* An instance of CheckedRecipe is created, for every recipe in a crafting
* station whenever a player opens a crafting station. This class calculates
* the ingredients the player is missing and the conditions which he does
* not meet. It is used to display the missing ingredients on the GUI recipe
* items.
*
* @param recipe The corresponding crafting recipe
* @param data The player opening the crafting station
* @param inv The player's ingredients
*/
public RecipeInfo(Recipe recipe, PlayerData data, IngredientInventory inv) {
public CheckedRecipe(Recipe recipe, PlayerData data, IngredientInventory inv) {
this.recipe = recipe;
for (Ingredient ingredient : recipe.getIngredients()) {
CheckedIngredient info = ingredient.newIngredientInfo(inv);
CheckedIngredient info = ingredient.evaluateIngredient(inv);
ingredients.add(info);
if (!info.isHad()) {
if (!info.isHad())
ingredientsHad = false;
}
}
for (Condition condition : recipe.getConditions()) {
CheckedCondition info = condition.newConditionInfo(data);
CheckedCondition info = condition.evaluateCondition(data);
conditions.add(info);
if (!info.isMet()) {
if (!info.isMet())
conditionsMet = false;
}
}
}
@ -71,8 +76,7 @@ public class RecipeInfo {
}
public Set<CheckedCondition> getDisplayableConditions() {
return conditions.stream().filter(condition -> condition.getCondition().getDisplay() != null)
.collect(Collectors.toSet());
return conditions.stream().filter(condition -> condition.getCondition().getDisplay() != null).collect(Collectors.toSet());
}
public Set<CheckedIngredient> getIngredients() {

View File

@ -1,5 +1,11 @@
package net.Indyuce.mmoitems.api.crafting.recipe;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import net.Indyuce.mmoitems.api.crafting.ConfigMMOItem;
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue;
@ -9,11 +15,6 @@ import net.Indyuce.mmoitems.api.item.util.ConfigItems;
import net.Indyuce.mmoitems.api.player.PlayerData;
import net.Indyuce.mmoitems.api.util.message.Message;
import net.mmogroup.mmolib.api.util.SmartGive;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
public class CraftingRecipe extends Recipe {
private final ConfigMMOItem output;
@ -29,9 +30,7 @@ public class CraftingRecipe extends Recipe {
craftingTime = config.getDouble("crafting-time");
/*
* load recipe output
*/
// load recipe output
output = new ConfigMMOItem(config.getConfigurationSection("output"));
}
@ -48,14 +47,20 @@ public class CraftingRecipe extends Recipe {
}
@Override
public void whenUsed(PlayerData data, IngredientInventory inv, RecipeInfo recipe, CraftingStation station) {
if(!data.isOnline()) return;
public void whenUsed(PlayerData data, IngredientInventory inv, CheckedRecipe recipe, CraftingStation station) {
if (!data.isOnline())
return;
if (!hasOption(RecipeOption.SILENT_CRAFT))
data.getPlayer().playSound(data.getPlayer().getLocation(), station.getSound(), 1, 1);
/*
* if the recipe is an instant recipe, just take off the ingredients add
* directly add the ingredients to the player inventory
* If the recipe is instant, take the ingredients off and directly add
* the output to the player's inventory
*/
if (isInstant()) {
PlayerUseCraftingStationEvent event = new PlayerUseCraftingStationEvent(data, station, recipe, PlayerUseCraftingStationEvent.StationAction.INSTANT_RECIPE);
PlayerUseCraftingStationEvent event = new PlayerUseCraftingStationEvent(data, station, recipe,
PlayerUseCraftingStationEvent.StationAction.INSTANT_RECIPE);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled())
return;
@ -63,27 +68,24 @@ public class CraftingRecipe extends Recipe {
if (hasOption(RecipeOption.OUTPUT_ITEM))
new SmartGive(data.getPlayer()).give(getOutput().generate(data.getRPG()));
recipe.getRecipe().getTriggers().forEach(trigger -> trigger.whenCrafting(data));
if (!hasOption(RecipeOption.SILENT_CRAFT))
data.getPlayer().playSound(data.getPlayer().getLocation(), station.getSound(), 1, 1);
/*
* if recipe not instant, add item to crafting queue, either way
* RELOAD inventory data and reopen inventory!
* If the recipe is not instant, add the item to the crafting queue
*/
} else
data.getCrafting().getQueue(station).add(this);
if (!isInstant())
data.getPlayer().playSound(data.getPlayer().getLocation(), station.getSound(), 1, 1);
}
@Override
public boolean canUse(PlayerData data, IngredientInventory inv, RecipeInfo recipe, CraftingStation station) {
public boolean canUse(PlayerData data, IngredientInventory inv, CheckedRecipe recipe, CraftingStation station) {
if (isInstant())
return true;
CraftingQueue queue = data.getCrafting().getQueue(station);
if (queue.isFull(station)) {
if(!data.isOnline()) return false;
if (!data.isOnline())
return false;
Message.CRAFTING_QUEUE_FULL.format(ChatColor.RED).send(data.getPlayer());
data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1);
return false;
@ -92,7 +94,7 @@ public class CraftingRecipe extends Recipe {
}
@Override
public ItemStack display(RecipeInfo recipe) {
public ItemStack display(CheckedRecipe recipe) {
return ConfigItems.CRAFTING_RECIPE_DISPLAY.newBuilder(recipe).build();
}
}

View File

@ -1,5 +1,14 @@
package net.Indyuce.mmoitems.api.crafting.recipe;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
import net.Indyuce.mmoitems.api.crafting.IngredientInventory;
@ -8,14 +17,6 @@ import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient;
import net.Indyuce.mmoitems.api.crafting.trigger.Trigger;
import net.Indyuce.mmoitems.api.player.PlayerData;
import net.mmogroup.mmolib.api.MMOLineConfig;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@SuppressWarnings("unused")
public abstract class Recipe {
@ -26,6 +27,14 @@ public abstract class Recipe {
private final Set<Condition> conditions = new LinkedHashSet<>();
private final Set<Trigger> triggers = new LinkedHashSet<>();
/**
* Stores the information about a specific recipe setup in a crafting
* station. When a player opens a crafting station GUI, a CheckedRecipe
* instance is created to evaluate the conditions which are not met/the
* ingredients he is missing.
*
* @param config Config section to load data from
*/
public Recipe(ConfigurationSection config) {
this(config.getName());
@ -46,11 +55,9 @@ public abstract class Recipe {
Validate.notNull(ingredient, "Could not match ingredient");
ingredients.add(ingredient);
} catch (IllegalArgumentException exception) {
throw new IllegalArgumentException(
"Could not load ingredient '" + format + "': " + exception.getMessage());
throw new IllegalArgumentException("Could not load ingredient '" + format + "': " + exception.getMessage());
}
/*
* load conditions
*/
@ -60,8 +67,7 @@ public abstract class Recipe {
Validate.notNull(condition, "Could not match condition");
conditions.add(condition);
} catch (IllegalArgumentException exception) {
throw new IllegalArgumentException(
"Could not load condition '" + format + "': " + exception.getMessage());
throw new IllegalArgumentException("Could not load condition '" + format + "': " + exception.getMessage());
}
if (conditions.isEmpty() && ingredients.isEmpty()) {
@ -77,8 +83,7 @@ public abstract class Recipe {
Validate.notNull(trigger, "Could not match trigger");
triggers.add(trigger);
} catch (IllegalArgumentException exception) {
throw new IllegalArgumentException(
"Could not load trigger '" + format + "': " + exception.getMessage());
throw new IllegalArgumentException("Could not load trigger '" + format + "': " + exception.getMessage());
}
}
@ -127,8 +132,8 @@ public abstract class Recipe {
options.put(option, value);
}
public RecipeInfo getRecipeInfo(PlayerData data, IngredientInventory inv) {
return new RecipeInfo(this, data, inv);
public CheckedRecipe evaluateRecipe(PlayerData data, IngredientInventory inv) {
return new CheckedRecipe(this, data, inv);
}
@Override
@ -136,33 +141,56 @@ public abstract class Recipe {
return obj instanceof Recipe && ((Recipe) obj).id.equals(id);
}
/*
* when the recipe is claimed once in the crafting queue. if it returns true,
* the conditions are applied and the ingredients are taken off the player's
* inventory
/**
* Called when all the recipe conditions are to true and when the player
* eventually starts crafting OR when the player claims the item in the
* crafting queue once the delay is over.
*
* @param data Player crafting the item
* @param inv The player's ingredients
* @param recipe The recipe used to craft the item
* @param station The station used to craft the item
*/
public abstract void whenUsed(PlayerData data, IngredientInventory inv, RecipeInfo recipe, CraftingStation station);
public abstract void whenUsed(PlayerData data, IngredientInventory inv, CheckedRecipe recipe, CraftingStation station);
/*
* extra conditions when trying to use the recipe.
/**
* Applies extra conditions when a player has just clicked on a recipe item
* in the GUI. This method is called after checking for the recipe
* conditions and ingredients.
*
* @param data The player crafting the item
* @param inv The player's ingredients
* @param recipe The recipe used to craft the item
* @param station The station used to craft the item
* @return If the player can use the recipe
*/
public abstract boolean canUse(PlayerData data, IngredientInventory inv, RecipeInfo recipe,
CraftingStation station);
public abstract boolean canUse(PlayerData data, IngredientInventory inv, CheckedRecipe recipe, CraftingStation station);
public abstract ItemStack display(RecipeInfo recipe);
public abstract ItemStack display(CheckedRecipe recipe);
public enum RecipeOption {
// hide crafting recipe when conditions are not met
/**
* Hide the crafting recipe when one of the condition is not met
*/
HIDE_WHEN_LOCKED(false),
// hide crafting recipe when insufficient ingredients
/**
* Hide the crafting recipe when the player does not have all the
* ingredients
*/
HIDE_WHEN_NO_INGREDIENTS(false),
// set to false not to output any item when used
/**
* If set to false (default is true), no output item will be given to
* the player crafting the item. That option is made to have recipes
* which entirely rely on triggers.
*/
OUTPUT_ITEM(true),
// removes crafting sound when used
/**
* Disables crafting sound
*/
SILENT_CRAFT(false);
private final boolean def;

View File

@ -1,5 +1,12 @@
package net.Indyuce.mmoitems.api.crafting.recipe;
import java.util.Random;
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.MMOUtils;
import net.Indyuce.mmoitems.api.crafting.ConfigMMOItem;
@ -15,12 +22,6 @@ import net.Indyuce.mmoitems.api.player.PlayerData;
import net.Indyuce.mmoitems.api.util.message.Message;
import net.Indyuce.mmoitems.stat.data.UpgradeData;
import net.mmogroup.mmolib.MMOLib;
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 {
private final ConfigMMOItem item;
@ -43,19 +44,21 @@ public class UpgradingRecipe extends Recipe {
}
@Override
public void whenUsed(PlayerData data, IngredientInventory inv, RecipeInfo uncastRecipe, CraftingStation station) {
public void whenUsed(PlayerData data, IngredientInventory inv, CheckedRecipe uncastRecipe, CraftingStation station) {
UpgradingRecipeInfo recipe = (UpgradingRecipeInfo) uncastRecipe;
recipe.getUpgradeData().upgrade(recipe.getMMOItem());
recipe.getUpgraded().setItemMeta(recipe.getMMOItem().newBuilder().build().getItemMeta());
uncastRecipe.getRecipe().getTriggers().forEach(trigger -> trigger.whenCrafting(data));
if(!data.isOnline()) return;
if (!data.isOnline())
return;
Message.UPGRADE_SUCCESS.format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(recipe.getUpgraded())).send(data.getPlayer());
data.getPlayer().playSound(data.getPlayer().getLocation(), station.getSound(), 1, 1);
}
@Override
public boolean canUse(PlayerData data, IngredientInventory inv, RecipeInfo uncastRecipe, CraftingStation station) {
public boolean canUse(PlayerData data, IngredientInventory inv, CheckedRecipe uncastRecipe, CraftingStation station) {
/*
* try to find the item which is meant to be updated. null check is
@ -65,18 +68,23 @@ public class UpgradingRecipe extends Recipe {
*/
PlayerIngredient upgraded = inv.getIngredient(ingredient, IngredientLookupMode.IGNORE_ITEM_LEVEL);
if (upgraded == null) {
if(!data.isOnline()) return false;
if (!data.isOnline())
return false;
Message.NOT_HAVE_ITEM_UPGRADE.format(ChatColor.RED).send(data.getPlayer());
data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return false;
}
UpgradingRecipeInfo recipe = (UpgradingRecipeInfo) uncastRecipe;
if (!(recipe.mmoitem = new LiveMMOItem(MMOLib.plugin.getVersion().getWrapper().getNBTItem(upgraded.getFirstItem()))).hasData(ItemStats.UPGRADE))
if (!(recipe.mmoitem = new LiveMMOItem(MMOLib.plugin.getVersion().getWrapper().getNBTItem(upgraded.getFirstItem())))
.hasData(ItemStats.UPGRADE))
return false;
if (!(recipe.upgradeData = (UpgradeData) recipe.getMMOItem().getData(ItemStats.UPGRADE)).canLevelUp()) {
if(!data.isOnline()) return false;
if (!data.isOnline())
return false;
Message.MAX_UPGRADES_HIT.format(ChatColor.RED).send(data.getPlayer());
data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return false;
@ -87,7 +95,9 @@ public class UpgradingRecipe extends Recipe {
recipe.getUpgraded().setAmount(recipe.getUpgraded().getAmount() - 1);
recipe.getIngredients().forEach(ingredient -> ingredient.getPlayerIngredient().reduceItem(ingredient.getIngredient().getAmount()));
if(!data.isOnline()) return false;
if (!data.isOnline())
return false;
Message.UPGRADE_FAIL_STATION.format(ChatColor.RED).send(data.getPlayer());
data.getPlayer().playSound(data.getPlayer().getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 2);
return false;
@ -97,16 +107,16 @@ public class UpgradingRecipe extends Recipe {
}
@Override
public ItemStack display(RecipeInfo recipe) {
public ItemStack display(CheckedRecipe recipe) {
return ConfigItems.UPGRADING_RECIPE_DISPLAY.newBuilder(recipe).build();
}
@Override
public RecipeInfo getRecipeInfo(PlayerData data, IngredientInventory inv) {
public CheckedRecipe evaluateRecipe(PlayerData data, IngredientInventory inv) {
return new UpgradingRecipeInfo(this, data, inv);
}
public static class UpgradingRecipeInfo extends RecipeInfo {
public static class UpgradingRecipeInfo extends CheckedRecipe {
private LiveMMOItem mmoitem;
private UpgradeData upgradeData;

View File

@ -3,14 +3,14 @@ package net.Indyuce.mmoitems.api.event;
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe;
import net.Indyuce.mmoitems.api.crafting.recipe.RecipeInfo;
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
import net.Indyuce.mmoitems.api.player.PlayerData;
import org.apache.commons.lang.Validate;
import org.bukkit.event.HandlerList;
public class PlayerUseCraftingStationEvent extends PlayerDataEvent {
private final Recipe recipe;
private final RecipeInfo recipeInfo;
private final CheckedRecipe recipeInfo;
private final CraftingStation station;
private final StationAction action;
@ -21,33 +21,27 @@ public class PlayerUseCraftingStationEvent extends PlayerDataEvent {
* station GUI. The recipe is either instant and the item is given
* instaneously, or the item is sent in the crafting queue
*
* @param playerData
* The player interacting with the crafting station
* @param station
* The crafting station being used
* @param recipeInfo
* The recipe being used to craft the item
* @param playerData The player interacting with the crafting station
* @param station The crafting station being used
* @param recipeInfo The recipe being used to craft the item
*/
public PlayerUseCraftingStationEvent(PlayerData playerData, CraftingStation station, RecipeInfo recipeInfo, StationAction action) {
public PlayerUseCraftingStationEvent(PlayerData playerData, CraftingStation station, CheckedRecipe recipeInfo, StationAction action) {
this(playerData, station, recipeInfo, recipeInfo.getRecipe(), action);
}
/**
* Called when a player claims an item from the crafting queue.
*
* @param playerData
* The player interacting with the crafting station
* @param station
* The crafting station being used
* @param recipe
* The recipe being used to craft the item
* @param playerData The player interacting with the crafting station
* @param station The crafting station being used
* @param recipe The recipe being used to craft the item
*/
public PlayerUseCraftingStationEvent(PlayerData playerData, CraftingStation station, Recipe recipe, StationAction action) {
this(playerData, station, null, recipe, action);
}
private PlayerUseCraftingStationEvent(PlayerData playerData, CraftingStation station, RecipeInfo recipeInfo, Recipe recipe, StationAction action) {
private PlayerUseCraftingStationEvent(PlayerData playerData, CraftingStation station, CheckedRecipe recipeInfo, Recipe recipe,
StationAction action) {
super(playerData);
this.recipeInfo = recipeInfo;
@ -65,7 +59,7 @@ public class PlayerUseCraftingStationEvent extends PlayerDataEvent {
* interacting with a recipe. This method cannot be used when a
* player claims an item from the crafting queue.
*/
public RecipeInfo getRecipeInfo() {
public CheckedRecipe getRecipeInfo() {
Validate.notNull(recipeInfo, "No recipe info is provided when a player claims an item in the crafting queue");
return recipeInfo;
}

View File

@ -17,7 +17,7 @@ import net.Indyuce.mmoitems.MMOUtils;
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
import net.Indyuce.mmoitems.api.crafting.condition.Condition.CheckedCondition;
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
import net.Indyuce.mmoitems.api.crafting.recipe.RecipeInfo;
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
import net.Indyuce.mmoitems.api.item.util.ConfigItem;
import net.Indyuce.mmoitems.api.util.message.Message;
import net.mmogroup.mmolib.MMOLib;
@ -33,7 +33,7 @@ public class CraftingRecipeDisplay extends ConfigItem {
"&eRight-Click to preview!");
}
public ItemBuilder newBuilder(RecipeInfo recipe) {
public ItemBuilder newBuilder(CheckedRecipe recipe) {
return new ItemBuilder(recipe);
}
@ -41,13 +41,13 @@ public class CraftingRecipeDisplay extends ConfigItem {
* allows to build an unidentified item based on the given NBTItem.
*/
public class ItemBuilder {
private final RecipeInfo recipe;
private final CheckedRecipe recipe;
private final CraftingRecipe craftingRecipe;
private final String name = getName();
private final List<String> lore = new ArrayList<>(getLore());
public ItemBuilder(RecipeInfo recipe) {
public ItemBuilder(CheckedRecipe recipe) {
this.recipe = recipe;
craftingRecipe = (CraftingRecipe) recipe.getRecipe();
}

View File

@ -14,7 +14,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import net.Indyuce.mmoitems.MMOUtils;
import net.Indyuce.mmoitems.api.crafting.ConditionalDisplay;
import net.Indyuce.mmoitems.api.crafting.condition.Condition.CheckedCondition;
import net.Indyuce.mmoitems.api.crafting.recipe.RecipeInfo;
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
import net.Indyuce.mmoitems.api.crafting.recipe.UpgradingRecipe;
import net.Indyuce.mmoitems.api.item.util.ConfigItem;
import net.mmogroup.mmolib.MMOLib;
@ -26,7 +26,7 @@ public class UpgradingRecipeDisplay extends ConfigItem {
"#ingredients#", "", "&eLeft-Click to craft!", "&eRight-Click to preview!");
}
public ItemBuilder newBuilder(RecipeInfo recipe) {
public ItemBuilder newBuilder(CheckedRecipe recipe) {
return new ItemBuilder(recipe);
}
@ -34,13 +34,13 @@ public class UpgradingRecipeDisplay extends ConfigItem {
* allows to build an unidentified item based on the given NBTItem.
*/
public class ItemBuilder {
private final RecipeInfo recipe;
private final CheckedRecipe recipe;
private final UpgradingRecipe upgradingRecipe;
private final String name = getName();
private final List<String> lore = new ArrayList<>(getLore());
public ItemBuilder(RecipeInfo recipe) {
public ItemBuilder(CheckedRecipe recipe) {
this.recipe = recipe;
this.upgradingRecipe = (UpgradingRecipe) recipe.getRecipe();
}

View File

@ -34,7 +34,7 @@ public class MythicItemIngredient extends Ingredient {
}
@Override
public String formatLoreDisplay(String string) {
public String formatDisplay(String string) {
return string.replace("#item#", display).replace("#amount#", "" + getAmount());
}

View File

@ -16,7 +16,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import net.Indyuce.mmoitems.MMOUtils;
import net.Indyuce.mmoitems.api.crafting.ingredient.Ingredient.CheckedIngredient;
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
import net.Indyuce.mmoitems.api.crafting.recipe.RecipeInfo;
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
import net.Indyuce.mmoitems.api.crafting.recipe.UpgradingRecipe;
import net.Indyuce.mmoitems.api.util.message.Message;
import net.mmogroup.mmolib.MMOLib;
@ -24,14 +24,14 @@ import net.mmogroup.mmolib.api.item.NBTItem;
public class CraftingStationPreview extends PluginInventory {
private final CraftingStationView previous;
private final RecipeInfo recipe;
private final CheckedRecipe recipe;
private final List<ItemStack> ingredients = new ArrayList<>();
private static final int[] slots = { 12, 13, 14, 21, 22, 23, 30, 31, 32 },
fill = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 15, 17, 18, 19, 25, 26, 27, 29, 33, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44 };
public CraftingStationPreview(CraftingStationView previous, RecipeInfo recipe) {
public CraftingStationPreview(CraftingStationView previous, CheckedRecipe recipe) {
super(previous.getPlayer());
this.previous = previous;

View File

@ -1,24 +1,8 @@
package net.Indyuce.mmoitems.gui;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.MMOUtils;
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue;
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.ingredient.Ingredient;
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe;
import net.Indyuce.mmoitems.api.crafting.recipe.RecipeInfo;
import net.Indyuce.mmoitems.api.event.PlayerUseCraftingStationEvent;
import net.Indyuce.mmoitems.api.item.util.ConfigItems;
import net.Indyuce.mmoitems.api.player.PlayerData;
import net.Indyuce.mmoitems.api.util.message.Message;
import net.Indyuce.mmoitems.listener.CustomSoundListener;
import net.mmogroup.mmolib.MMOLib;
import net.mmogroup.mmolib.api.item.NBTItem;
import net.mmogroup.mmolib.api.util.SmartGive;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@ -29,16 +13,32 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.List;
import java.util.UUID;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.MMOUtils;
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue;
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.ingredient.Ingredient;
import net.Indyuce.mmoitems.api.crafting.recipe.CheckedRecipe;
import net.Indyuce.mmoitems.api.crafting.recipe.CraftingRecipe;
import net.Indyuce.mmoitems.api.crafting.recipe.Recipe;
import net.Indyuce.mmoitems.api.event.PlayerUseCraftingStationEvent;
import net.Indyuce.mmoitems.api.item.util.ConfigItems;
import net.Indyuce.mmoitems.api.player.PlayerData;
import net.Indyuce.mmoitems.api.util.message.Message;
import net.Indyuce.mmoitems.listener.CustomSoundListener;
import net.mmogroup.mmolib.MMOLib;
import net.mmogroup.mmolib.api.item.NBTItem;
import net.mmogroup.mmolib.api.util.SmartGive;
public class CraftingStationView extends PluginInventory {
private final CraftingStation station;
private final Layout layout;
private final PlayerData data;
private List<RecipeInfo> recipes;
private List<CheckedRecipe> recipes;
private IngredientInventory ingredients;
private int queueOffset;
@ -65,7 +65,8 @@ public class CraftingStationView extends PluginInventory {
@Override
public Inventory getInventory() {
Inventory inv = Bukkit.createInventory(this, layout.getSize(), station.getName().replace("#page#", "" + page).replace("#max#", "" + station.getMaxPage()));
Inventory inv = Bukkit.createInventory(this, layout.getSize(),
station.getName().replace("#page#", "" + page).replace("#max#", "" + station.getMaxPage()));
int min = (page - 1) * layout.getRecipeSlots().size(), max = page * layout.getRecipeSlots().size();
for (int j = min; j < max; j++) {
if (j >= recipes.size()) {
@ -90,7 +91,8 @@ public class CraftingStationView extends PluginInventory {
continue;
}
inv.setItem(layout.getQueueSlots().get(j - queueOffset), ConfigItems.QUEUE_ITEM_DISPLAY.newBuilder(queue.getCrafts().get(j), j + 1).build());
inv.setItem(layout.getQueueSlots().get(j - queueOffset),
ConfigItems.QUEUE_ITEM_DISPLAY.newBuilder(queue.getCrafts().get(j), j + 1).build());
}
if (queueOffset + layout.getQueueSlots().size() < queue.getCrafts().size())
inv.setItem(layout.getQueueNextSlot(), ConfigItems.NEXT_IN_QUEUE.getItem());
@ -115,7 +117,8 @@ public class CraftingStationView extends PluginInventory {
inv.setItem(layout.getQueueSlots().get(j - queueOffset),
station.getItemOptions().hasNoQueueItem() ? station.getItemOptions().getNoQueueItem() : null);
else
inv.setItem(layout.getQueueSlots().get(j - queueOffset), ConfigItems.QUEUE_ITEM_DISPLAY.newBuilder(queue.getCrafts().get(j), j + 1).build());
inv.setItem(layout.getQueueSlots().get(j - queueOffset),
ConfigItems.QUEUE_ITEM_DISPLAY.newBuilder(queue.getCrafts().get(j), j + 1).build());
}
}.runTaskTimerAsynchronously(MMOItems.plugin, 0, 20);
if (station.getItemOptions().hasFill())
@ -128,7 +131,8 @@ public class CraftingStationView extends PluginInventory {
@Override
public void whenClicked(InventoryClickEvent event) {
if(!data.isOnline()) return;
if (!data.isOnline())
return;
event.setCancelled(true);
if (!MMOUtils.isMetaItem(event.getCurrentItem(), false))
return;
@ -161,7 +165,7 @@ public class CraftingStationView extends PluginInventory {
NBTItem item = MMOLib.plugin.getVersion().getWrapper().getNBTItem(event.getCurrentItem());
String tag = item.getString("recipeId");
if (!tag.equals("")) {
RecipeInfo recipe = getRecipe(tag);
CheckedRecipe recipe = getRecipe(tag);
if (event.isRightClick()) {
new CraftingStationPreview(this, recipe).open();
return;
@ -173,29 +177,43 @@ public class CraftingStationView extends PluginInventory {
if (!(tag = item.getString("queueId")).equals("")) {
UUID uuid = UUID.fromString(tag);
CraftingInfo craft = data.getCrafting().getQueue(station).getCraft(uuid);
data.getCrafting().getQueue(station).remove(craft);
CraftingInfo recipeInfo = data.getCrafting().getQueue(station).getCraft(uuid);
CraftingRecipe recipe = recipeInfo.getRecipe();
CraftingRecipe recipe = craft.getRecipe();
if (craft.isReady()) {
PlayerUseCraftingStationEvent called = new PlayerUseCraftingStationEvent(data, station, recipe, PlayerUseCraftingStationEvent.StationAction.CRAFTING_QUEUE);
/*
* If the crafting recipe is ready, give the player the output item
* to the player and remove the recipe from the queue
*/
if (recipeInfo.isReady()) {
PlayerUseCraftingStationEvent called = new PlayerUseCraftingStationEvent(data, station, recipe,
PlayerUseCraftingStationEvent.StationAction.CRAFTING_QUEUE);
Bukkit.getPluginManager().callEvent(called);
if (!called.isCancelled()) {
recipe.getTriggers().forEach(trigger -> trigger.whenCrafting(data));
ItemStack craftedItem = recipe.getOutput().generate(playerData.getRPG());
CustomSoundListener.stationCrafting(craftedItem, getPlayer());
if (!recipe.hasOption(Recipe.RecipeOption.SILENT_CRAFT))
getPlayer().playSound(getPlayer().getLocation(), station.getSound(), 1, 1);
if (recipe.hasOption(Recipe.RecipeOption.OUTPUT_ITEM))
new SmartGive(getPlayer()).give(craftedItem);
}
if (!called.isCancelled())
return;
data.getCrafting().getQueue(station).remove(recipeInfo);
recipe.getTriggers().forEach(trigger -> trigger.whenCrafting(data));
ItemStack craftedItem = recipe.getOutput().generate(playerData.getRPG());
CustomSoundListener.stationCrafting(craftedItem, getPlayer());
if (!recipe.hasOption(Recipe.RecipeOption.SILENT_CRAFT))
getPlayer().playSound(getPlayer().getLocation(), station.getSound(), 1, 1);
if (recipe.hasOption(Recipe.RecipeOption.OUTPUT_ITEM))
new SmartGive(getPlayer()).give(craftedItem);
/**
* If the recipe is not ready, cancel the recipe and give the
* ingredients back to the player
*/
} else {
PlayerUseCraftingStationEvent called = new PlayerUseCraftingStationEvent(data, station, recipe, PlayerUseCraftingStationEvent.StationAction.CANCEL_QUEUE);
PlayerUseCraftingStationEvent called = new PlayerUseCraftingStationEvent(data, station, recipe,
PlayerUseCraftingStationEvent.StationAction.CANCEL_QUEUE);
Bukkit.getPluginManager().callEvent(called);
if (called.isCancelled())
return;
data.getCrafting().getQueue(station).remove(recipeInfo);
getPlayer().playSound(getPlayer().getLocation(), station.getSound(), 1, 1);
for (Ingredient ingredient : craft.getRecipe().getIngredients())
for (Ingredient ingredient : recipeInfo.getRecipe().getIngredients())
new SmartGive(getPlayer()).give(ingredient.generateItemStack(playerData.getRPG()));
}
@ -204,7 +222,7 @@ public class CraftingStationView extends PluginInventory {
}
}
public void processRecipe(RecipeInfo recipe) {
public void processRecipe(CheckedRecipe recipe) {
if (!recipe.areConditionsMet()) {
Message.CONDITIONS_NOT_MET.format(ChatColor.RED).send(getPlayer());
getPlayer().playSound(getPlayer().getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1);
@ -222,7 +240,8 @@ public class CraftingStationView extends PluginInventory {
return;
}
PlayerUseCraftingStationEvent called = new PlayerUseCraftingStationEvent(data, station, recipe, PlayerUseCraftingStationEvent.StationAction.INTERACT_WITH_RECIPE);
PlayerUseCraftingStationEvent called = new PlayerUseCraftingStationEvent(data, station, recipe,
PlayerUseCraftingStationEvent.StationAction.INTERACT_WITH_RECIPE);
Bukkit.getPluginManager().callEvent(called);
if (called.isCancelled())
return;
@ -234,8 +253,8 @@ public class CraftingStationView extends PluginInventory {
updateData();
}
private RecipeInfo getRecipe(String id) {
for (RecipeInfo info : recipes)
private CheckedRecipe getRecipe(String id) {
for (CheckedRecipe info : recipes)
if (info.getRecipe().getId().equals(id))
return info;
return null;