From 3f1458285ae6081ecaf8940829b1f945667129cb Mon Sep 17 00:00:00 2001 From: Gunging <48371009+Gunging@users.noreply.github.com> Date: Sun, 30 Jan 2022 20:02:00 -0600 Subject: [PATCH] Restores the `CRAFT_PERMISSION` stat for crafting recipes. Requires most up-to-date MythicLib --- pom.xml | 2 +- .../java/net/Indyuce/mmoitems/MMOItems.java | 4 +- .../mmoitems/api/item/build/LoreBuilder.java | 8 +- .../mythicmobs/MythicMobsCompatibility.java | 8 ++ .../edition/recipe/registry/RMGRR_Shaped.java | 13 +++ .../recipe/registry/RMGRR_Shapeless.java | 13 +++ .../recipe/registry/RMGRR_SuperShaped.java | 15 +++ .../mmoitems/manager/SkillManager.java | 101 +++++++++++++----- .../mmoitems/skill/RegisteredSkill.java | 19 ++-- .../mmoitems/stat/data/AbilityData.java | 3 + 10 files changed, 144 insertions(+), 42 deletions(-) diff --git a/pom.xml b/pom.xml index 684814c9..52e79a0b 100644 --- a/pom.xml +++ b/pom.xml @@ -141,7 +141,7 @@ io.lumine MythicLib-dist - 1.3-R21-SNAPSHOT + 1.3-R22-SNAPSHOT provided diff --git a/src/main/java/net/Indyuce/mmoitems/MMOItems.java b/src/main/java/net/Indyuce/mmoitems/MMOItems.java index 34a4c44c..65e1ab08 100644 --- a/src/main/java/net/Indyuce/mmoitems/MMOItems.java +++ b/src/main/java/net/Indyuce/mmoitems/MMOItems.java @@ -97,7 +97,7 @@ public class MMOItems extends LuminePlugin { private VaultSupport vaultSupport; private RPGHandler rpgPlugin; - private static final int MYTHICLIB_COMPATIBILITY_INDEX = 4; + private static final int MYTHICLIB_COMPATIBILITY_INDEX = 5; public MMOItems() { plugin = this; } @@ -122,7 +122,7 @@ public class MMOItems extends LuminePlugin { saveDefaultConfig(); configManager = new ConfigManager(); - /** + /* * Stat manager must be initialized before MMOCore compatibility * initializes so that MMOCore can register its stats */ diff --git a/src/main/java/net/Indyuce/mmoitems/api/item/build/LoreBuilder.java b/src/main/java/net/Indyuce/mmoitems/api/item/build/LoreBuilder.java index 3a4e02ae..2fd1d8ba 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/item/build/LoreBuilder.java +++ b/src/main/java/net/Indyuce/mmoitems/api/item/build/LoreBuilder.java @@ -157,7 +157,13 @@ public class LoreBuilder { if (match == null) continue; - String result = MythicLib.plugin.getMMOConfig().decimals.format(new EvaluatedFormula(match).evaluate()); + String result; + try { + result = MythicLib.plugin.getMMOConfig().decimals.format(new EvaluatedFormula(match).evaluate()); + + } catch (RuntimeException ignored) { + result = "FORMULA_INVALID"; + } lore.set(index, string.replaceAll("MATH\\%[^%]*\\%", result)); } diff --git a/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsCompatibility.java b/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsCompatibility.java index b2a992b4..1e7d04b8 100644 --- a/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsCompatibility.java +++ b/src/main/java/net/Indyuce/mmoitems/comp/mythicmobs/MythicMobsCompatibility.java @@ -4,8 +4,11 @@ import io.lumine.xikage.mythicmobs.MythicMobs; import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicReloadedEvent; import io.lumine.xikage.mythicmobs.mobs.MythicMob; import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem; +import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.comp.mythicmobs.stat.FactionDamage; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -35,6 +38,11 @@ public class MythicMobsCompatibility implements Listener { // Update skills MMOItems.plugin.getSkills().initialize(true); + + // Reload the abilities of online players... + for (Player p : Bukkit.getOnlinePlayers()) { + PlayerData data = PlayerData.get(p); + data.updateInventory(); } } private Set getFactions() { diff --git a/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_Shaped.java b/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_Shaped.java index 6fe6f622..37fa666d 100644 --- a/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_Shaped.java +++ b/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_Shaped.java @@ -9,6 +9,7 @@ import io.lumine.mythic.lib.api.crafting.recipes.ShapedRecipe; import io.lumine.mythic.lib.api.crafting.uimanager.ProvidedUIFilter; import io.lumine.mythic.lib.api.util.Ref; import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider; +import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.api.crafting.MMOItemUIFilter; import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate; import net.Indyuce.mmoitems.api.util.message.FFPMMOItems; @@ -18,6 +19,8 @@ import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_AmountOutput; import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_HideFromBook; import net.Indyuce.mmoitems.gui.edition.recipe.recipes.RMG_Shaped; import net.Indyuce.mmoitems.gui.edition.recipe.recipes.RecipeMakerGUI; +import net.Indyuce.mmoitems.stat.data.StringData; +import net.Indyuce.mmoitems.stat.data.random.RandomStatData; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; @@ -65,6 +68,16 @@ public class RMGRR_Shaped implements RecipeRegistry { // That's our blueprint :) MythicRecipeBlueprint ret = new MythicRecipeBlueprint(input, outputRecipe, nk); + // Required permission? + RandomStatData perm = template.getBaseItemData().get(ItemStats.CRAFT_PERMISSION); + if (perm instanceof StringData) { + + // Ah yes + String permission = ((StringData) perm).getString(); + + // Finally + if (permission != null) { ret.addRequiredPermission(permission); } } + // Enable it ret.deploy(MythicRecipeStation.WORKBENCH, namespace); diff --git a/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_Shapeless.java b/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_Shapeless.java index 3cc7c52f..0452317d 100644 --- a/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_Shapeless.java +++ b/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_Shapeless.java @@ -10,6 +10,7 @@ import io.lumine.mythic.lib.api.crafting.recipes.ShapelessRecipe; import io.lumine.mythic.lib.api.crafting.uimanager.ProvidedUIFilter; import io.lumine.mythic.lib.api.util.Ref; import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider; +import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.api.crafting.MMOItemUIFilter; import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate; import net.Indyuce.mmoitems.api.util.message.FFPMMOItems; @@ -18,6 +19,8 @@ import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_AmountOutput; import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_HideFromBook; import net.Indyuce.mmoitems.gui.edition.recipe.recipes.RMG_Shapeless; import net.Indyuce.mmoitems.gui.edition.recipe.recipes.RecipeMakerGUI; +import net.Indyuce.mmoitems.stat.data.StringData; +import net.Indyuce.mmoitems.stat.data.random.RandomStatData; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; @@ -87,6 +90,16 @@ public class RMGRR_Shapeless implements RecipeRegistry { // That's our blueprint :) MythicRecipeBlueprint ret = new MythicRecipeBlueprint(input, outputRecipe, nk); + // Required permission? + RandomStatData perm = template.getBaseItemData().get(ItemStats.CRAFT_PERMISSION); + if (perm instanceof StringData) { + + // Ah yes + String permission = ((StringData) perm).getString(); + + // Finally + if (permission != null) { ret.addRequiredPermission(permission); } } + // Enable it ret.deploy(MythicRecipeStation.WORKBENCH, namespace); diff --git a/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_SuperShaped.java b/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_SuperShaped.java index 2458bd3f..10a370d7 100644 --- a/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_SuperShaped.java +++ b/src/main/java/net/Indyuce/mmoitems/gui/edition/recipe/registry/RMGRR_SuperShaped.java @@ -9,6 +9,8 @@ import io.lumine.mythic.lib.api.crafting.recipes.ShapedRecipe; import io.lumine.mythic.lib.api.crafting.uimanager.ProvidedUIFilter; import io.lumine.mythic.lib.api.util.Ref; import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider; +import net.Indyuce.mmoitems.ItemStats; +import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.crafting.MMOItemUIFilter; import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate; import net.Indyuce.mmoitems.api.util.message.FFPMMOItems; @@ -18,6 +20,9 @@ import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_AmountOutput; import net.Indyuce.mmoitems.gui.edition.recipe.rba.RBA_HideFromBook; import net.Indyuce.mmoitems.gui.edition.recipe.recipes.RMG_SuperShaped; import net.Indyuce.mmoitems.gui.edition.recipe.recipes.RecipeMakerGUI; +import net.Indyuce.mmoitems.stat.data.StringData; +import net.Indyuce.mmoitems.stat.data.random.RandomStatData; +import net.Indyuce.mmoitems.stat.data.type.StatData; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; @@ -65,6 +70,16 @@ public class RMGRR_SuperShaped implements RecipeRegistry { // That's our blueprint :) MythicRecipeBlueprint ret = new MythicRecipeBlueprint(input, outputRecipe, nk); + // Required permission? + RandomStatData perm = template.getBaseItemData().get(ItemStats.CRAFT_PERMISSION); + if (perm instanceof StringData) { + + // Ah yes + String permission = ((StringData) perm).getString(); + + // Finally + if (permission != null) { ret.addRequiredPermission(permission); } } + // Enable it ret.deploy(MythicRecipeStation.WORKBENCH, null); diff --git a/src/main/java/net/Indyuce/mmoitems/manager/SkillManager.java b/src/main/java/net/Indyuce/mmoitems/manager/SkillManager.java index c403d5b5..a1a7e5ac 100644 --- a/src/main/java/net/Indyuce/mmoitems/manager/SkillManager.java +++ b/src/main/java/net/Indyuce/mmoitems/manager/SkillManager.java @@ -7,6 +7,9 @@ import net.Indyuce.mmoitems.MMOUtils; import net.Indyuce.mmoitems.api.ConfigFile; import net.Indyuce.mmoitems.skill.RegisteredSkill; import org.apache.commons.lang.Validate; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -18,59 +21,94 @@ import java.util.Map; import java.util.Objects; import java.util.logging.Level; -@SuppressWarnings("unused") +/** + * A HUB for skills for them to be readily available within the plugin + */ public class SkillManager { - private final Map skills = new HashMap<>(); - public RegisteredSkill getSkill(String id) { - return skills.get(id); - } + /** + * The list of skills currently loaded. + */ + @NotNull private final HashMap skills = new HashMap<>(); - public RegisteredSkill getSkillOrThrow(String id) { + /** + * @param id Internal name of the skill you want to fetch. + * + * @return If a skill is loaded with this name, that skill. + */ + @Nullable public RegisteredSkill getSkill(@Nullable String id) { return skills.get(id); } + + /** + * @param id The internal name of the skill you want to fetch. + * + * @return The skill that is loaded with this name; NullPointerException if not loaded. + */ + @Contract("null -> fail") + @NotNull public RegisteredSkill getSkillOrThrow(@Nullable String id) { return Objects.requireNonNull(skills.get(id), "Could not find skill with ID '" + id + "'"); } - public void registerSkill(RegisteredSkill skill) { - Validate.notNull(skill); + /** + * @param skill Skill to load + */ + public void registerSkill(@Nullable RegisteredSkill skill) { + if (skill == null) { return; } - this.skills.put(skill.getHandler().getId(), skill); + // Include skill + skills.put(skill.getHandler().getId(), skill); } - public boolean hasSkill(String id) { - return skills.containsKey(id); - } + /** + * @param id Internal name of the skill you want to fetch. + * + * @return If a skill of this name is loaded by the plugin. + */ + public boolean hasSkill(@Nullable String id) { return skills.get(id) != null; } /** * @return Collection of all registered skills. It has the same number * of elements as MythicLib's skill handler registry. */ - public Collection getAll() { - return skills.values(); - } + @NotNull public Collection getAll() { return skills.values(); } + /** + * Will load skills from MythicLib as well as generate their configuration + * files in plugins/MMOItems/skills ~ for default values and translation. + * + * @param clearBefore If the previously-loaded skills should get cleared. + */ + @SuppressWarnings("ResultOfMethodCallIgnored") public void initialize(boolean clearBefore) { - if (clearBefore) - skills.clear(); + // Clear loaded skills + if (clearBefore) { skills.clear(); } // Check for default files File skillFolder = new File(MMOItems.plugin.getDataFolder() + "/skill"); - if (!skillFolder.exists()) + + // Create folder and files + if (!skillFolder.exists()) { + try { + + // Create folder skillFolder.mkdir(); + // Copy example skills for (SkillHandler handler : MythicLib.plugin.getSkills().getHandlers()) { InputStream res = MMOItems.plugin.getResource("default/skill/" + handler.getLowerCaseId() + ".yml"); - if (res != null) - Files.copy(res, new File(MMOItems.plugin.getDataFolder() + "/skill/" + handler.getLowerCaseId() + ".yml").getAbsoluteFile().toPath()); - } - } catch (IOException exception) { - MMOItems.plugin.getLogger().log(Level.WARNING, "Could not save default ability configs: " + exception.getMessage()); - } + if (res != null) { Files.copy(res, new File(MMOItems.plugin.getDataFolder() + "/skill/" + handler.getLowerCaseId() + ".yml").getAbsoluteFile().toPath()); } } + // Should not happen + } catch (IOException exception) { MMOItems.plugin.getLogger().log(Level.WARNING, "Could not save default ability configs: " + exception.getMessage()); } + } + + // Copy mythiclib skills for (SkillHandler handler : MythicLib.plugin.getSkills().getHandlers()) { - // Check if config file exists + /* + * Generate skill configuration files + */ ConfigFile config = new ConfigFile("/skill", handler.getLowerCaseId()); if (!config.exists()) { config.getConfig().set("name", MMOUtils.caseOnWords(handler.getId().replace("_", " ").replace("-", " ").toLowerCase())); @@ -81,11 +119,16 @@ public class SkillManager { config.save(); } + /* + * Load skill to the plugin + */ try { - this.skills.put(handler.getId(), new RegisteredSkill(handler, config.getConfig())); - } catch (RuntimeException exception) { - MMOItems.plugin.getLogger().log(Level.WARNING, "Could not load skill '" + handler.getId() + "': " + exception.getMessage()); - } + + // Attempt to register + skills.put(handler.getId(), new RegisteredSkill(handler, config.getConfig())); + + // Fail + } catch (RuntimeException exception) { MMOItems.plugin.getLogger().log(Level.WARNING, "Could not load skill '" + handler.getId() + "': " + exception.getMessage()); } } } } diff --git a/src/main/java/net/Indyuce/mmoitems/skill/RegisteredSkill.java b/src/main/java/net/Indyuce/mmoitems/skill/RegisteredSkill.java index 619e3d60..c02ad459 100644 --- a/src/main/java/net/Indyuce/mmoitems/skill/RegisteredSkill.java +++ b/src/main/java/net/Indyuce/mmoitems/skill/RegisteredSkill.java @@ -5,6 +5,7 @@ import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.MMOUtils; import net.Indyuce.mmoitems.ability.Ability; import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; @@ -12,12 +13,12 @@ import java.util.Map; import java.util.Objects; public class RegisteredSkill { - private final SkillHandler handler; - private final String name; - private final Map modifierNames = new HashMap<>(); - private final Map modifierDefaultValues = new HashMap<>(); + @NotNull private final SkillHandler handler; + @NotNull private final String name; + @NotNull private final Map modifierNames = new HashMap<>(); + @NotNull private final Map modifierDefaultValues = new HashMap<>(); - public RegisteredSkill(SkillHandler handler, ConfigurationSection config) { + public RegisteredSkill(@NotNull SkillHandler handler, @NotNull ConfigurationSection config) { this.handler = handler; this.name = Objects.requireNonNull(config.getString("name"), "Could not fill skill name"); @@ -29,7 +30,7 @@ public class RegisteredSkill { } @Deprecated - public RegisteredSkill(Ability ability) { + public RegisteredSkill(@NotNull Ability ability) { this.handler = ability; this.name = MMOItems.plugin.getLanguage().getAbilityName(ability); @@ -40,16 +41,16 @@ public class RegisteredSkill { } @Deprecated - public RegisteredSkill(SkillHandler handler, String name) { + public RegisteredSkill(@NotNull SkillHandler handler, @NotNull String name) { this.handler = handler; this.name = name; } - public SkillHandler getHandler() { + @NotNull public SkillHandler getHandler() { return handler; } - public String getName() { + @NotNull public String getName() { return name; } diff --git a/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java b/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java index d8a73001..0230bf46 100644 --- a/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java +++ b/src/main/java/net/Indyuce/mmoitems/stat/data/AbilityData.java @@ -18,6 +18,7 @@ import org.bukkit.ChatColor; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.text.DecimalFormat; import java.util.HashMap; @@ -142,8 +143,10 @@ public class AbilityData extends Skill { meta.getCaster().getData().getCooldownMap().applyCooldown(this, cooldown); } + @Nullable @Override public SkillHandler getHandler() { + if (ability == null) { return null; } return ability.getHandler(); }