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();
}