iterator = lootChests.getActive().iterator();
+ while (iterator.hasNext()) {
+ LootChest next = iterator.next();
+ if (next.shouldExpire()) {
+ iterator.remove();
+ next.expire(false);
+ }
+ }
+ }
+ }.runTaskTimer(this, 5 * 60 * 20, 5 * 60 * 20);
- /*
- * For the sake of the lord, make sure they aren't using MMOItems Mana and
- * Stamina Addon...This should prevent a couple error reports produced by people
- * not reading the installation guide...
- */
- if (Bukkit.getPluginManager().getPlugin("MMOMana") != null) {
- getLogger().log(Level.SEVERE, ChatColor.DARK_RED + "MMOCore is not meant to be used with MMOItems ManaAndStamina");
- getLogger().log(Level.SEVERE, ChatColor.DARK_RED + "Please read the installation guide!");
- Bukkit.broadcastMessage(ChatColor.DARK_RED + "[MMOCore] MMOCore is not meant to be used with MMOItems ManaAndStamina");
- Bukkit.broadcastMessage(ChatColor.DARK_RED + "[MMOCore] Please read the installation guide!");
- return;
- }
+ /*
+ * For the sake of the lord, make sure they aren't using MMOItems Mana and
+ * Stamina Addon...This should prevent a couple error reports produced by people
+ * not reading the installation guide...
+ */
+ if (Bukkit.getPluginManager().getPlugin("MMOMana") != null) {
+ getLogger().log(Level.SEVERE, ChatColor.DARK_RED + "MMOCore is not meant to be used with MMOItems ManaAndStamina");
+ getLogger().log(Level.SEVERE, ChatColor.DARK_RED + "Please read the installation guide!");
+ Bukkit.broadcastMessage(ChatColor.DARK_RED + "[MMOCore] MMOCore is not meant to be used with MMOItems ManaAndStamina");
+ Bukkit.broadcastMessage(ChatColor.DARK_RED + "[MMOCore] Please read the installation guide!");
+ return;
+ }
- initializePlugin(false);
+ initializePlugin(false);
- if (getConfig().getBoolean("vanilla-exp-redirection.enabled"))
- Bukkit.getPluginManager().registerEvents(new RedirectVanillaExp(getConfig().getDouble("vanilla-exp-redirection.ratio")), this);
+ if (getConfig().getBoolean("vanilla-exp-redirection.enabled"))
+ Bukkit.getPluginManager().registerEvents(new RedirectVanillaExp(getConfig().getDouble("vanilla-exp-redirection.ratio")), this);
- // Enable debug mode for extra debug tools
- if (getConfig().contains("debug")) {
- DebugMode.setLevel(getConfig().getInt("debug", 0));
- DebugMode.enableActionBar();
- }
+ // Enable debug mode for extra debug tools
+ if (getConfig().contains("debug")) {
+ DebugMode.setLevel(getConfig().getInt("debug", 0));
+ DebugMode.enableActionBar();
+ }
- // Load quest module
- try {
- String questPluginName = UtilityMethods.enumName(getConfig().getString("quest-plugin"));
- PartyModuleType moduleType = PartyModuleType.valueOf(questPluginName);
- Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed");
- partyModule = moduleType.provideModule();
- } catch (RuntimeException exception) {
- getLogger().log(Level.WARNING, "Could not initialize quest module: " + exception.getMessage());
- partyModule = new MMOCorePartyModule();
- }
+ // Load quest module
+ try {
+ String questPluginName = UtilityMethods.enumName(getConfig().getString("quest-plugin"));
+ PartyModuleType moduleType = PartyModuleType.valueOf(questPluginName);
+ Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed");
+ partyModule = moduleType.provideModule();
+ } catch (RuntimeException exception) {
+ getLogger().log(Level.WARNING, "Could not initialize quest module: " + exception.getMessage());
+ partyModule = new MMOCorePartyModule();
+ }
- // Load party module
- try {
- String partyPluginName = UtilityMethods.enumName(getConfig().getString("party-plugin"));
- PartyModuleType moduleType = PartyModuleType.valueOf(partyPluginName);
- Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed");
- partyModule = moduleType.provideModule();
- } catch (RuntimeException exception) {
- getLogger().log(Level.WARNING, "Could not initialize party module: " + exception.getMessage());
- partyModule = new MMOCorePartyModule();
- }
+ // Load party module
+ try {
+ String partyPluginName = UtilityMethods.enumName(getConfig().getString("party-plugin"));
+ PartyModuleType moduleType = PartyModuleType.valueOf(partyPluginName);
+ Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed");
+ partyModule = moduleType.provideModule();
+ } catch (RuntimeException exception) {
+ getLogger().log(Level.WARNING, "Could not initialize party module: " + exception.getMessage());
+ partyModule = new MMOCorePartyModule();
+ }
- // Skill casting
- try {
- SkillCastingMode mode = SkillCastingMode.valueOf(UtilityMethods.enumName(getConfig().getString("skill-casting.mode")));
- Bukkit.getPluginManager().registerEvents(mode.loadFromConfig(getConfig().getConfigurationSection("skill-casting")), this);
- } catch (RuntimeException exception) {
- getLogger().log(Level.WARNING, "Could not load skill casting: " + exception.getMessage());
- }
+ // Load guild module
+ try {
+ String pluginName = UtilityMethods.enumName(getConfig().getString("guild-plugin"));
+ GuildModuleType moduleType = GuildModuleType.valueOf(pluginName);
+ Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed");
+ guildModule = moduleType.provideModule();
+ } catch (RuntimeException exception) {
+ getLogger().log(Level.WARNING, "Could not initialize guild module: " + exception.getMessage());
+ guildModule = new MMOCoreGuildModule();
+ }
- if (configManager.overrideVanillaExp = getConfig().getBoolean("override-vanilla-exp"))
- Bukkit.getPluginManager().registerEvents(new VanillaExperienceOverride(), this);
+ // Skill casting
+ try {
+ SkillCastingMode mode = SkillCastingMode.valueOf(UtilityMethods.enumName(getConfig().getString("skill-casting.mode")));
+ Bukkit.getPluginManager().registerEvents(mode.loadFromConfig(getConfig().getConfigurationSection("skill-casting")), this);
+ } catch (RuntimeException exception) {
+ getLogger().log(Level.WARNING, "Could not load skill casting: " + exception.getMessage());
+ }
- if (getConfig().getBoolean("hotbar-swapping.enabled"))
- try {
- Bukkit.getPluginManager().registerEvents(new HotbarSwap(getConfig().getConfigurationSection("hotbar-swapping")), this);
- } catch (RuntimeException exception) {
- getLogger().log(Level.WARNING, "Could not load hotbar swapping: " + exception.getMessage());
- }
+ if (configManager.overrideVanillaExp = getConfig().getBoolean("override-vanilla-exp"))
+ Bukkit.getPluginManager().registerEvents(new VanillaExperienceOverride(), this);
- if (getConfig().getBoolean("prevent-spawner-xp"))
- Bukkit.getPluginManager().registerEvents(new NoSpawnerEXP(), this);
+ if (getConfig().getBoolean("hotbar-swapping.enabled"))
+ try {
+ Bukkit.getPluginManager().registerEvents(new HotbarSwap(getConfig().getConfigurationSection("hotbar-swapping")), this);
+ } catch (RuntimeException exception) {
+ getLogger().log(Level.WARNING, "Could not load hotbar swapping: " + exception.getMessage());
+ }
- if (getConfig().getBoolean("death-exp-loss.enabled"))
- Bukkit.getPluginManager().registerEvents(new DeathExperienceLoss(), this);
+ if (getConfig().getBoolean("prevent-spawner-xp"))
+ Bukkit.getPluginManager().registerEvents(new NoSpawnerEXP(), this);
- if (getConfig().getBoolean("shift-click-player-profile-check"))
- Bukkit.getPluginManager().registerEvents(new PlayerProfileCheck(), this);
+ if (getConfig().getBoolean("death-exp-loss.enabled"))
+ Bukkit.getPluginManager().registerEvents(new DeathExperienceLoss(), this);
- Bukkit.getPluginManager().registerEvents(new WaypointsListener(), this);
- Bukkit.getPluginManager().registerEvents(new PlayerListener(), this);
- Bukkit.getPluginManager().registerEvents(new GoldPouchesListener(), this);
- Bukkit.getPluginManager().registerEvents(new BlockListener(), this);
- Bukkit.getPluginManager().registerEvents(new LootableChestsListener(), this);
- Bukkit.getPluginManager().registerEvents(new GuildListener(), this);
- Bukkit.getPluginManager().registerEvents(new FishingListener(), this);
- Bukkit.getPluginManager().registerEvents(new PlayerCollectStats(), this);
- Bukkit.getPluginManager().registerEvents(new PlayerPressKeyListener(), this);
- // Bukkit.getPluginManager().registerEvents(new ClassTriggers(), this);
+ if (getConfig().getBoolean("shift-click-player-profile-check"))
+ Bukkit.getPluginManager().registerEvents(new PlayerProfileCheck(), this);
- /*
- * Initialize player data from all online players. This is very important to do
- * that after registering all the professses otherwise the player datas can't
- * recognize what profess the player has and professes will be lost
- */
- Bukkit.getOnlinePlayers().forEach(player -> dataProvider.getDataManager().setup(player.getUniqueId()));
+ Bukkit.getPluginManager().registerEvents(new WaypointsListener(), this);
+ Bukkit.getPluginManager().registerEvents(new PlayerListener(), this);
+ Bukkit.getPluginManager().registerEvents(new GoldPouchesListener(), this);
+ Bukkit.getPluginManager().registerEvents(new BlockListener(), this);
+ Bukkit.getPluginManager().registerEvents(new LootableChestsListener(), this);
+ Bukkit.getPluginManager().registerEvents(new GuildListener(), this);
+ Bukkit.getPluginManager().registerEvents(new FishingListener(), this);
+ Bukkit.getPluginManager().registerEvents(new PlayerCollectStats(), this);
+ Bukkit.getPluginManager().registerEvents(new PlayerPressKeyListener(), this);
+ // Bukkit.getPluginManager().registerEvents(new ClassTriggers(), this);
- // load guild data after loading player data
- dataProvider.getGuildManager().load();
+ /*
+ * Initialize player data from all online players. This is very important to do
+ * that after registering all the professses otherwise the player datas can't
+ * recognize what profess the player has and professes will be lost
+ */
+ Bukkit.getOnlinePlayers().forEach(player -> dataProvider.getDataManager().setup(player.getUniqueId()));
- // Command
- try {
- final Field bukkitCommandMap = Bukkit.getServer().getClass().getDeclaredField("commandMap");
+ // load guild data after loading player data
+ dataProvider.getGuildManager().load();
- bukkitCommandMap.setAccessible(true);
- CommandMap commandMap = (CommandMap) bukkitCommandMap.get(Bukkit.getServer());
+ // Command
+ try {
+ final Field bukkitCommandMap = Bukkit.getServer().getClass().getDeclaredField("commandMap");
- FileConfiguration config = new ConfigFile("commands").getConfig();
+ bukkitCommandMap.setAccessible(true);
+ CommandMap commandMap = (CommandMap) bukkitCommandMap.get(Bukkit.getServer());
+
+ FileConfiguration config = new ConfigFile("commands").getConfig();
if (config.contains("player"))
commandMap.register("mmocore", new PlayerStatsCommand(config.getConfigurationSection("player")));
@@ -340,129 +350,128 @@ public class MMOCore extends LuminePlugin {
ex.printStackTrace();
}
- MMOCoreCommandTreeRoot mmoCoreCommand = new MMOCoreCommandTreeRoot();
- getCommand("mmocore").setExecutor(mmoCoreCommand);
- getCommand("mmocore").setTabCompleter(mmoCoreCommand);
+ MMOCoreCommandTreeRoot mmoCoreCommand = new MMOCoreCommandTreeRoot();
+ getCommand("mmocore").setExecutor(mmoCoreCommand);
+ getCommand("mmocore").setTabCompleter(mmoCoreCommand);
- if (getConfig().getBoolean("auto-save.enabled")) {
- int autosave = getConfig().getInt("auto-save.interval") * 20;
- new BukkitRunnable() {
- public void run() {
+ if (getConfig().getBoolean("auto-save.enabled")) {
+ int autosave = getConfig().getInt("auto-save.interval") * 20;
+ new BukkitRunnable() {
+ public void run() {
- // Save player data
- for (PlayerData data : PlayerData.getAll())
- if (data.isFullyLoaded())
- dataProvider.getDataManager().saveData(data);
+ // Save player data
+ for (PlayerData data : PlayerData.getAll())
+ if (data.isFullyLoaded())
+ dataProvider.getDataManager().saveData(data);
- // Save guild info
- for (Guild guild : dataProvider.getGuildManager().getAll())
- dataProvider.getGuildManager().save(guild);
- }
- }.runTaskTimerAsynchronously(MMOCore.plugin, autosave, autosave);
- }
- }
+ // Save guild info
+ for (Guild guild : dataProvider.getGuildManager().getAll())
+ dataProvider.getGuildManager().save(guild);
+ }
+ }.runTaskTimerAsynchronously(MMOCore.plugin, autosave, autosave);
+ }
+ }
- public void disable() {
+ public void disable() {
- // Save player data
- for (PlayerData data : PlayerData.getAll())
- if (data.isFullyLoaded()) {
- data.close();
- dataProvider.getDataManager().saveData(data);
- }
+ // Save player data
+ for (PlayerData data : PlayerData.getAll())
+ if (data.isFullyLoaded()) {
+ data.close();
+ dataProvider.getDataManager().saveData(data);
+ }
- // Save guild info
- for (Guild guild : dataProvider.getGuildManager().getAll())
- dataProvider.getGuildManager().save(guild);
+ // Save guild info
+ for (Guild guild : dataProvider.getGuildManager().getAll())
+ dataProvider.getGuildManager().save(guild);
- // Close MySQL data provider (memory leaks)
- if (dataProvider instanceof MySQLDataProvider)
- ((MySQLDataProvider) dataProvider).close();
+ // Close MySQL data provider (memory leaks)
+ if (dataProvider instanceof MySQLDataProvider)
+ ((MySQLDataProvider) dataProvider).close();
- // Reset active blocks
- mineManager.resetRemainingBlocks();
+ // Reset active blocks
+ mineManager.resetRemainingBlocks();
- // Clear spawned loot chests
- lootChests.getActive().forEach(chest -> chest.expire(false));
- }
+ // Clear spawned loot chests
+ lootChests.getActive().forEach(chest -> chest.expire(false));
+ }
- /**
- * Called either when the server starts when initializing the manager for
- * the first time, or when issuing a plugin reload; in that case, stuff
- * like listeners must all be cleared before.
- *
- * Also see {@link MMOCoreManager}
- *
- * @param clearBefore True when issuing a plugin reload
- */
- public void initializePlugin(boolean clearBefore) {
- if (clearBefore)
- reloadConfig();
+ /**
+ * Called either when the server starts when initializing the manager for
+ * the first time, or when issuing a plugin reload; in that case, stuff
+ * like listeners must all be cleared before.
+ *
+ * Also see {@link MMOCoreManager}
+ *
+ * @param clearBefore True when issuing a plugin reload
+ */
+ public void initializePlugin(boolean clearBefore) {
+ if (clearBefore)
+ reloadConfig();
- configManager = new ConfigManager();
+ configManager = new ConfigManager();
- if (clearBefore)
- MythicLib.plugin.getSkills().initialize(true);
- skillManager.initialize(clearBefore);
- mineManager.initialize(clearBefore);
- partyManager.initialize(clearBefore);
- attributeManager.initialize(clearBefore);
+ if (clearBefore)
+ MythicLib.plugin.getSkills().initialize(true);
+ skillManager.initialize(clearBefore);
+ mineManager.initialize(clearBefore);
+ partyManager.initialize(clearBefore);
+ attributeManager.initialize(clearBefore);
- // Experience must be loaded before professions and classes
- experience.initialize(clearBefore);
+ // Experience must be loaded before professions and classes
+ experience.initialize(clearBefore);
- // Drop tables must be loaded before professions
- dropTableManager.initialize(clearBefore);
+ // Drop tables must be loaded before professions
+ dropTableManager.initialize(clearBefore);
- professionManager.initialize(clearBefore);
- classManager.initialize(clearBefore);
+ professionManager.initialize(clearBefore);
+ classManager.initialize(clearBefore);
- InventoryManager.load();
+ InventoryManager.load();
- questManager.initialize(clearBefore);
- lootChests.initialize(clearBefore);
- restrictionManager.initialize(clearBefore);
- waypointManager.initialize(clearBefore);
- requestManager.initialize(clearBefore);
- soundManager.initialize(clearBefore);
- configItems.initialize(clearBefore);
- skillTreeManager.initialize(clearBefore);
+ questManager.initialize(clearBefore);
+ lootChests.initialize(clearBefore);
+ restrictionManager.initialize(clearBefore);
+ waypointManager.initialize(clearBefore);
+ requestManager.initialize(clearBefore);
+ soundManager.initialize(clearBefore);
+ configItems.initialize(clearBefore);
- if (getConfig().isConfigurationSection("action-bar"))
- actionBarManager.reload(getConfig().getConfigurationSection("action-bar"));
+ if (getConfig().isConfigurationSection("action-bar"))
+ actionBarManager.reload(getConfig().getConfigurationSection("action-bar"));
- StatType.load();
+ StatType.load();
- if (clearBefore)
- PlayerData.getAll().forEach(PlayerData::update);
- }
+ if (clearBefore)
+ PlayerData.getAll().forEach(PlayerData::update);
+ }
- public static void log(String message) {
- log(Level.INFO, message);
- }
+ public static void log(String message) {
+ log(Level.INFO, message);
+ }
- public static void debug(int value, String message) {
- debug(value, Level.INFO, message);
- }
+ public static void debug(int value, String message) {
+ debug(value, Level.INFO, message);
+ }
- public static void log(Level level, String message) {
- plugin.getLogger().log(level, message);
- }
+ public static void log(Level level, String message) {
+ plugin.getLogger().log(level, message);
+ }
- public static void debug(int value, Level level, String message) {
- if (DebugMode.level > (value - 1)) plugin.getLogger().log(level, message);
- }
+ public static void debug(int value, Level level, String message) {
+ if (DebugMode.level > (value - 1)) plugin.getLogger().log(level, message);
+ }
- public File getJarFile() {
- return getFile();
- }
+ public File getJarFile() {
+ return getFile();
+ }
- public boolean hasEconomy() {
- return economy != null && economy.isValid();
- }
+ public boolean hasEconomy() {
+ return economy != null && economy.isValid();
+ }
- public static void sqlDebug(String s) {
- if (!MMOCore.plugin.shouldDebugSQL) return;
- MMOCore.plugin.getLogger().warning("- [SQL Debug] " + s);
- }
+ public static void sqlDebug(String s) {
+ if(!MMOCore.plugin.shouldDebugSQL) return;
+ MMOCore.plugin.getLogger().warning("- [SQL Debug] " + s);
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/api/ConfigFile.java b/src/main/java/net/Indyuce/mmocore/api/ConfigFile.java
index 5c611746..9aaa4e92 100644
--- a/src/main/java/net/Indyuce/mmocore/api/ConfigFile.java
+++ b/src/main/java/net/Indyuce/mmocore/api/ConfigFile.java
@@ -5,14 +5,13 @@ import java.io.IOException;
import java.util.UUID;
import java.util.logging.Level;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.guild.provided.Guild;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.guild.provided.Guild;
-
public class ConfigFile {
private final File file;
private final String name;
diff --git a/src/main/java/net/Indyuce/mmocore/api/MMOCoreAPI.java b/src/main/java/net/Indyuce/mmocore/api/MMOCoreAPI.java
index 1a843613..8cc99d58 100644
--- a/src/main/java/net/Indyuce/mmocore/api/MMOCoreAPI.java
+++ b/src/main/java/net/Indyuce/mmocore/api/MMOCoreAPI.java
@@ -6,11 +6,11 @@ import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.result.SkillResult;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.party.AbstractParty;
import net.Indyuce.mmocore.skill.CastableSkill;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
diff --git a/src/main/java/net/Indyuce/mmocore/api/PlayerActionBar.java b/src/main/java/net/Indyuce/mmocore/api/PlayerActionBar.java
index 594696b3..354d8888 100644
--- a/src/main/java/net/Indyuce/mmocore/api/PlayerActionBar.java
+++ b/src/main/java/net/Indyuce/mmocore/api/PlayerActionBar.java
@@ -1,73 +1,72 @@
-package net.Indyuce.mmocore.api;
-
-import java.text.DecimalFormat;
-
-import net.Indyuce.mmocore.api.player.PlayerActivity;
-import org.bukkit.attribute.Attribute;
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.scheduler.BukkitRunnable;
-
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.stats.StatType;
-import net.md_5.bungee.api.ChatMessageType;
-import net.md_5.bungee.api.chat.TextComponent;
-import io.lumine.mythic.lib.MythicLib;
-
-public class PlayerActionBar extends BukkitRunnable {
- boolean initialized = false;
-
- private ActionBarConfig config;
- private DecimalFormat digit;
-
- public void reload(ConfigurationSection cfg) {
- config = new ActionBarConfig(cfg);
- digit = MythicLib.plugin.getMMOConfig().newDecimalFormat(config.digit);
-
- if(!initialized && config.enabled) {
- runTaskTimer(MMOCore.plugin, 0, config.ticks);
- initialized = true;
- }
- }
-
- public long getTimeOut() {
- return config.timeout;
- }
-
- @Override
- public void run() {
- for (PlayerData data : PlayerData.getAll())
- if (data.isOnline() && !data.getPlayer().isDead() && !data.isCasting() && data.getActivityTimeOut(PlayerActivity.ACTION_BAR_MESSAGE) == 0) {
- data.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(MMOCore.plugin.placeholderParser.parse(data.getPlayer(),
- MythicLib.plugin.parseColors((data.getProfess().hasActionBar() ? data.getProfess().getActionBar() : config.format)
- .replace("{health}", digit.format(data.getPlayer().getHealth()))
- .replace("{max_health}", "" + StatType.MAX_HEALTH.format(data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()))
- .replace("{mana_icon}", data.getProfess().getManaDisplay().getIcon())
- .replace("{mana}", digit.format(data.getMana()))
- .replace("{max_mana}", "" + StatType.MAX_MANA.format(data.getStats().getStat(StatType.MAX_MANA)))
- .replace("{stamina}", digit.format(data.getStamina()))
- .replace("{max_stamina}", "" + StatType.MAX_STAMINA.format(data.getStats().getStat(StatType.MAX_STAMINA)))
- .replace("{stellium}", digit.format(data.getStellium()))
- .replace("{max_stellium}", "" + StatType.MAX_STELLIUM.format(data.getStats().getStat(StatType.MAX_STELLIUM)))
- .replace("{class}", data.getProfess().getName())
- .replace("{xp}", "" + data.getExperience())
- .replace("{armor}", "" + StatType.ARMOR.format(data.getPlayer().getAttribute(Attribute.GENERIC_ARMOR).getValue()))
- .replace("{level}", "" + data.getLevel())
- .replace("{name}", data.getPlayer().getDisplayName())))));
- }
- }
-
- private static class ActionBarConfig {
- private final boolean enabled;
- private final int ticks, timeout;
- private final String digit, format;
-
- private ActionBarConfig(ConfigurationSection config) {
- enabled = config.getBoolean("enabled", false);
- timeout = config.getInt("", 60);
- digit = config.getString("decimal", "0.#");
- ticks = config.getInt("ticks-to-update", 5);
- format = config.getString("format", "please format me :c");
- }
- }
-}
+package net.Indyuce.mmocore.api;
+
+import io.lumine.mythic.lib.MythicLib;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerActivity;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.player.stats.StatInfo;
+import net.md_5.bungee.api.ChatMessageType;
+import net.md_5.bungee.api.chat.TextComponent;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import java.text.DecimalFormat;
+
+public class PlayerActionBar extends BukkitRunnable {
+ boolean initialized = false;
+
+ private ActionBarConfig config;
+ private DecimalFormat digit;
+
+ public void reload(ConfigurationSection cfg) {
+ config = new ActionBarConfig(cfg);
+ digit = MythicLib.plugin.getMMOConfig().newDecimalFormat(config.digit);
+
+ if (!initialized && config.enabled) {
+ runTaskTimer(MMOCore.plugin, 0, config.ticks);
+ initialized = true;
+ }
+ }
+
+ public long getTimeOut() {
+ return config.timeout;
+ }
+
+ @Override
+ public void run() {
+ for (PlayerData data : PlayerData.getAll())
+ if (data.isOnline() && !data.getPlayer().isDead() && !data.isCasting() && data.getActivityTimeOut(PlayerActivity.ACTION_BAR_MESSAGE) == 0) {
+ data.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(MMOCore.plugin.placeholderParser.parse(data.getPlayer(),
+ MythicLib.plugin.parseColors((data.getProfess().hasActionBar() ? data.getProfess().getActionBar() : config.format)
+ .replace("{health}", digit.format(data.getPlayer().getHealth()))
+ .replace("{max_health}", StatInfo.valueOf("MAX_HEALTH").format(data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()))
+ .replace("{mana_icon}", data.getProfess().getManaDisplay().getIcon())
+ .replace("{mana}", digit.format(data.getMana()))
+ .replace("{max_mana}", StatInfo.valueOf("MAX_MANA").format(data.getStats().getStat("MAX_MANA")))
+ .replace("{stamina}", digit.format(data.getStamina()))
+ .replace("{max_stamina}", StatInfo.valueOf("MAX_STAMINA").format(data.getStats().getStat("MAX_STAMINA")))
+ .replace("{stellium}", digit.format(data.getStellium()))
+ .replace("{max_stellium}", StatInfo.valueOf("MAX_STELLIUM").format(data.getStats().getStat("MAX_STELLIUM")))
+ .replace("{class}", data.getProfess().getName())
+ .replace("{xp}", MythicLib.plugin.getMMOConfig().decimal.format(data.getExperience()))
+ .replace("{armor}", StatInfo.valueOf("ARMOR").format(data.getPlayer().getAttribute(Attribute.GENERIC_ARMOR).getValue()))
+ .replace("{level}", "" + data.getLevel())
+ .replace("{name}", data.getPlayer().getDisplayName())))));
+ }
+ }
+
+ private static class ActionBarConfig {
+ private final boolean enabled;
+ private final int ticks, timeout;
+ private final String digit, format;
+
+ private ActionBarConfig(ConfigurationSection config) {
+ enabled = config.getBoolean("enabled", false);
+ timeout = config.getInt("", 60);
+ digit = config.getString("decimal", "0.#");
+ ticks = config.getInt("ticks-to-update", 5);
+ format = config.getString("format", "please format me :c");
+ }
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/api/block/BlockInfo.java b/src/main/java/net/Indyuce/mmocore/api/block/BlockInfo.java
index 874e3507..394eaacd 100644
--- a/src/main/java/net/Indyuce/mmocore/api/block/BlockInfo.java
+++ b/src/main/java/net/Indyuce/mmocore/api/block/BlockInfo.java
@@ -1,175 +1,175 @@
-package net.Indyuce.mmocore.api.block;
-
-import io.lumine.mythic.lib.UtilityMethods;
-import io.lumine.mythic.lib.api.MMOLineConfig;
-import io.lumine.mythic.lib.api.condition.type.BlockCondition;
-import io.lumine.mythic.lib.api.condition.type.MMOCondition;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.loot.droptable.DropTable;
-import net.Indyuce.mmocore.loot.LootBuilder;
-import net.Indyuce.mmocore.api.quest.trigger.Trigger;
-import org.apache.commons.lang.Validate;
-import org.bukkit.Location;
-import org.bukkit.block.Block;
-import org.bukkit.block.data.BlockData;
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.inventory.ItemStack;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.*;
-import java.util.logging.Level;
-
-public class BlockInfo {
- private final BlockType block;
- private final DropTable table;
- private final RegenInfo regen;
- private final List triggers = new ArrayList<>();
- private final List conditions = new ArrayList<>();
- private final Map options = new HashMap<>();
-
- public BlockInfo(ConfigurationSection config) {
- Validate.notNull(config, "Could not load config");
- Validate.isTrue(config.contains("material"), "Could not find block type");
-
- block = MMOCore.plugin.loadManager.loadBlockType(new MMOLineConfig(config.getString("material")));
- table = config.contains("drop-table") ? MMOCore.plugin.dropTableManager.loadDropTable(config.get("drop-table")) : null;
-
- regen = config.contains("regen") ? new RegenInfo(config.getConfigurationSection("regen")) : null;
-
- if (config.contains("options"))
- for (String key : config.getConfigurationSection("options").getKeys(false))
- try {
- BlockInfoOption option = BlockInfoOption.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_"));
- options.put(option, config.getBoolean("options." + key));
- } catch (IllegalArgumentException exception) {
- MMOCore.plugin.getLogger().log(Level.WARNING,
- "Could not load option '" + key + "' from block info '" + block.generateKey() + "': " + exception.getMessage());
- }
-
- if (config.contains("triggers")) {
- List list = config.getStringList("triggers");
- Validate.notNull(list, "Could not load triggers");
-
- for (String key : list)
- try {
- triggers.add(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(key)));
- } catch (IllegalArgumentException exception) {
- MMOCore.plugin.getLogger().log(Level.WARNING,
- "Could not load trigger '" + key + "' from block info '" + block.generateKey() + "': " + exception.getMessage());
- }
- }
-
- if (config.isList("conditions"))
- for (String key : config.getStringList("conditions")) {
- MMOCondition condition = UtilityMethods.getCondition(key);
- if (condition instanceof BlockCondition)
- conditions.add((BlockCondition) condition);
- }
-
- }
-
- public boolean getOption(BlockInfoOption option) {
- return options.getOrDefault(option, option.getDefault());
- }
-
- public BlockType getBlock() {
- return block;
- }
-
- @NotNull
- public DropTable getDropTable() {
- return Objects.requireNonNull(table, "Block has no drop table");
- }
-
- public boolean hasDropTable() {
- return table != null;
- }
-
- public List collectDrops(LootBuilder builder) {
- return table != null ? table.collect(builder) : new ArrayList<>();
- }
-
- public boolean hasRegen() {
- return regen != null;
- }
-
- public boolean regenerates() {
- return regen != null;
- }
-
- public RegenInfo getRegenerationInfo() {
- return regen;
- }
-
- public RegeneratingBlock startRegeneration(BlockData data, Location loc) {
- return new RegeneratingBlock(data, loc, this);
- }
-
- public boolean hasTriggers() {
- return !triggers.isEmpty();
- }
-
- public List getTriggers() {
- return triggers;
- }
-
- public boolean checkConditions(Block block) {
- for (BlockCondition condition : conditions)
- if (!condition.check(block))
- return false;
- return true;
- }
-
- public static enum BlockInfoOption {
-
- /**
- * When disabled, removes the vanilla drops when a block is mined
- */
- VANILLA_DROPS(true),
-
- /**
- * When disabled, removes exp holograms when mined
- */
- EXP_HOLOGRAMS(true);
-
- private final boolean def;
-
- private BlockInfoOption(boolean def) {
- this.def = def;
- }
-
- public boolean getDefault() {
- return def;
- }
- }
-
- public static class RegeneratingBlock {
- private final BlockData data;
- private final Location loc;
- private final BlockInfo regenerating;
-
- private final long date = System.currentTimeMillis();
-
- public RegeneratingBlock(BlockData data, Location loc, BlockInfo regenerating) {
- this.data = data;
- this.loc = loc;
- this.regenerating = regenerating;
- }
-
- public boolean isTimedOut() {
- return date + regenerating.getRegenerationInfo().getTime() * 50 < System.currentTimeMillis();
- }
-
- public BlockData getBlockData() {
- return data;
- }
-
- public Location getLocation() {
- return loc;
- }
-
- public BlockInfo getRegeneratingBlock() {
- return regenerating;
- }
- }
-}
+package net.Indyuce.mmocore.api.block;
+
+import io.lumine.mythic.lib.UtilityMethods;
+import io.lumine.mythic.lib.api.MMOLineConfig;
+import io.lumine.mythic.lib.api.condition.type.BlockCondition;
+import io.lumine.mythic.lib.api.condition.type.MMOCondition;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.quest.trigger.Trigger;
+import net.Indyuce.mmocore.loot.droptable.DropTable;
+import net.Indyuce.mmocore.loot.LootBuilder;
+import org.apache.commons.lang.Validate;
+import org.bukkit.Location;
+import org.bukkit.block.Block;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+import java.util.logging.Level;
+
+public class BlockInfo {
+ private final BlockType block;
+ private final DropTable table;
+ private final RegenInfo regen;
+ private final List triggers = new ArrayList<>();
+ private final List conditions = new ArrayList<>();
+ private final Map options = new HashMap<>();
+
+ public BlockInfo(ConfigurationSection config) {
+ Validate.notNull(config, "Could not load config");
+ Validate.isTrue(config.contains("material"), "Could not find block type");
+
+ block = MMOCore.plugin.loadManager.loadBlockType(new MMOLineConfig(config.getString("material")));
+ table = config.contains("drop-table") ? MMOCore.plugin.dropTableManager.loadDropTable(config.get("drop-table")) : null;
+
+ regen = config.contains("regen") ? new RegenInfo(config.getConfigurationSection("regen")) : null;
+
+ if (config.contains("options"))
+ for (String key : config.getConfigurationSection("options").getKeys(false))
+ try {
+ BlockInfoOption option = BlockInfoOption.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_"));
+ options.put(option, config.getBoolean("options." + key));
+ } catch (IllegalArgumentException exception) {
+ MMOCore.plugin.getLogger().log(Level.WARNING,
+ "Could not load option '" + key + "' from block info '" + block.generateKey() + "': " + exception.getMessage());
+ }
+
+ if (config.contains("triggers")) {
+ List list = config.getStringList("triggers");
+ Validate.notNull(list, "Could not load triggers");
+
+ for (String key : list)
+ try {
+ triggers.addAll(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(key)));
+ } catch (IllegalArgumentException exception) {
+ MMOCore.plugin.getLogger().log(Level.WARNING,
+ "Could not load trigger '" + key + "' from block info '" + block.generateKey() + "': " + exception.getMessage());
+ }
+ }
+
+ if (config.isList("conditions"))
+ for (String key : config.getStringList("conditions")) {
+ MMOCondition condition = UtilityMethods.getCondition(key);
+ if (condition instanceof BlockCondition)
+ conditions.add((BlockCondition) condition);
+ }
+
+ }
+
+ public boolean getOption(BlockInfoOption option) {
+ return options.getOrDefault(option, option.getDefault());
+ }
+
+ public BlockType getBlock() {
+ return block;
+ }
+
+ @NotNull
+ public DropTable getDropTable() {
+ return Objects.requireNonNull(table, "Block has no drop table");
+ }
+
+ public boolean hasDropTable() {
+ return table != null;
+ }
+
+ public List collectDrops(LootBuilder builder) {
+ return table != null ? table.collect(builder) : new ArrayList<>();
+ }
+
+ public boolean hasRegen() {
+ return regen != null;
+ }
+
+ public boolean regenerates() {
+ return regen != null;
+ }
+
+ public RegenInfo getRegenerationInfo() {
+ return regen;
+ }
+
+ public RegeneratingBlock startRegeneration(BlockData data, Location loc) {
+ return new RegeneratingBlock(data, loc, this);
+ }
+
+ public boolean hasTriggers() {
+ return !triggers.isEmpty();
+ }
+
+ public List getTriggers() {
+ return triggers;
+ }
+
+ public boolean checkConditions(Block block) {
+ for (BlockCondition condition : conditions)
+ if (!condition.check(block))
+ return false;
+ return true;
+ }
+
+ public static enum BlockInfoOption {
+
+ /**
+ * When disabled, removes the vanilla drops when a block is mined
+ */
+ VANILLA_DROPS(true),
+
+ /**
+ * When disabled, removes exp holograms when mined
+ */
+ EXP_HOLOGRAMS(true);
+
+ private final boolean def;
+
+ private BlockInfoOption(boolean def) {
+ this.def = def;
+ }
+
+ public boolean getDefault() {
+ return def;
+ }
+ }
+
+ public static class RegeneratingBlock {
+ private final BlockData data;
+ private final Location loc;
+ private final BlockInfo regenerating;
+
+ private final long date = System.currentTimeMillis();
+
+ public RegeneratingBlock(BlockData data, Location loc, BlockInfo regenerating) {
+ this.data = data;
+ this.loc = loc;
+ this.regenerating = regenerating;
+ }
+
+ public boolean isTimedOut() {
+ return date + regenerating.getRegenerationInfo().getTime() * 50 < System.currentTimeMillis();
+ }
+
+ public BlockData getBlockData() {
+ return data;
+ }
+
+ public Location getLocation() {
+ return loc;
+ }
+
+ public BlockInfo getRegeneratingBlock() {
+ return regenerating;
+ }
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/api/block/BlockType.java b/src/main/java/net/Indyuce/mmocore/api/block/BlockType.java
index aa86aa21..f375f96f 100644
--- a/src/main/java/net/Indyuce/mmocore/api/block/BlockType.java
+++ b/src/main/java/net/Indyuce/mmocore/api/block/BlockType.java
@@ -1,31 +1,29 @@
-package net.Indyuce.mmocore.api.block;
-
-import org.bukkit.block.Block;
-
-import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
-
-public interface BlockType {
-
- /**
- * Called when placing temporary blocks
- */
- void place(RegeneratingBlock placed);
-
- /**
- * Called when regenerating an older block with block regen
- */
- void regenerate(RegeneratingBlock regenerating);
-
- /**
- * Generates a key used to store the BlockInfo instance in the manager map,
- * the key depends on the block type to make sure there is no interference
- */
- String generateKey();
-
- /**
- * Applies some extra break restrictions; returns TRUE if the block can be
- * broken. This method is used to prevent non mature crops from being broken
- * for example
- */
- boolean breakRestrictions(Block block);
-}
+package net.Indyuce.mmocore.api.block;
+
+import org.bukkit.block.Block;
+
+public interface BlockType {
+
+ /**
+ * Called when placing temporary blocks
+ */
+ void place(BlockInfo.RegeneratingBlock placed);
+
+ /**
+ * Called when regenerating an older block with block regen
+ */
+ void regenerate(BlockInfo.RegeneratingBlock regenerating);
+
+ /**
+ * Generates a key used to store the BlockInfo instance in the manager map,
+ * the key depends on the block type to make sure there is no interference
+ */
+ String generateKey();
+
+ /**
+ * Applies some extra break restrictions; returns TRUE if the block can be
+ * broken. This method is used to prevent non mature crops from being broken
+ * for example
+ */
+ boolean breakRestrictions(Block block);
+}
diff --git a/src/main/java/net/Indyuce/mmocore/api/block/RegenInfo.java b/src/main/java/net/Indyuce/mmocore/api/block/RegenInfo.java
index c33183ab..851c7eb0 100644
--- a/src/main/java/net/Indyuce/mmocore/api/block/RegenInfo.java
+++ b/src/main/java/net/Indyuce/mmocore/api/block/RegenInfo.java
@@ -1,31 +1,31 @@
-package net.Indyuce.mmocore.api.block;
-
-import org.apache.commons.lang.Validate;
-import org.bukkit.configuration.ConfigurationSection;
-
-import net.Indyuce.mmocore.MMOCore;
-import io.lumine.mythic.lib.api.MMOLineConfig;
-
-public class RegenInfo {
- private final BlockType temporary;
- private final int regenTime;
-
- public RegenInfo(ConfigurationSection config) {
- Validate.notNull(config, "Could not read regen info config");
-
- temporary = config.contains("temp-block") ? MMOCore.plugin.loadManager.loadBlockType(new MMOLineConfig(config.getString("temp-block"))) : null;
- regenTime = config.getInt("time", 2 * 60 * 20);
- }
-
- public int getTime() {
- return regenTime;
- }
-
- public boolean hasTemporaryBlock() {
- return temporary != null;
- }
-
- public BlockType getTemporaryBlock() {
- return temporary;
- }
-}
+package net.Indyuce.mmocore.api.block;
+
+import net.Indyuce.mmocore.MMOCore;
+import org.apache.commons.lang.Validate;
+import org.bukkit.configuration.ConfigurationSection;
+
+import io.lumine.mythic.lib.api.MMOLineConfig;
+
+public class RegenInfo {
+ private final BlockType temporary;
+ private final int regenTime;
+
+ public RegenInfo(ConfigurationSection config) {
+ Validate.notNull(config, "Could not read regen info config");
+
+ temporary = config.contains("temp-block") ? MMOCore.plugin.loadManager.loadBlockType(new MMOLineConfig(config.getString("temp-block"))) : null;
+ regenTime = config.getInt("time", 2 * 60 * 20);
+ }
+
+ public int getTime() {
+ return regenTime;
+ }
+
+ public boolean hasTemporaryBlock() {
+ return temporary != null;
+ }
+
+ public BlockType getTemporaryBlock() {
+ return temporary;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/api/block/SkullBlockType.java b/src/main/java/net/Indyuce/mmocore/api/block/SkullBlockType.java
index b3d01e3b..2c6d1cc8 100644
--- a/src/main/java/net/Indyuce/mmocore/api/block/SkullBlockType.java
+++ b/src/main/java/net/Indyuce/mmocore/api/block/SkullBlockType.java
@@ -1,59 +1,59 @@
-package net.Indyuce.mmocore.api.block;
-
-import org.bukkit.Location;
-import org.bukkit.block.Block;
-
-import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
-import net.Indyuce.mmocore.api.util.MMOCoreUtils;
-import io.lumine.mythic.lib.MythicLib;
-import io.lumine.mythic.lib.api.MMOLineConfig;
-import io.lumine.mythic.lib.version.VersionMaterial;
-
-public class SkullBlockType implements BlockType {
- private final String value;
-
- public SkullBlockType(MMOLineConfig config) {
- config.validate("value");
-
- value = config.getString("value");
- }
-
- public SkullBlockType(Block block) {
- value = MythicLib.plugin.getVersion().getWrapper().getSkullValue(block);
- }
-
- public String getValue() {
- return value;
- }
-
- @Override
- public void place(RegeneratingBlock block) {
- Location loc = block.getLocation();
- loc.getBlock().setType(VersionMaterial.PLAYER_HEAD.toMaterial());
-
- // save skull orientation if replaced block is a player head
- if (MMOCoreUtils.isPlayerHead(block.getBlockData().getMaterial()))
- loc.getBlock().setBlockData(block.getBlockData());
-
- MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
- }
-
- @Override
- public void regenerate(RegeneratingBlock block) {
- Location loc = block.getLocation();
- // This makes sure that if a skull loses its original rotation
- // it can revert back to it when the base block is regenerated
- loc.getBlock().setBlockData(block.getBlockData());
- MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
- }
-
- @Override
- public String generateKey() {
- return "vanilla-skull-" + value;
- }
-
- @Override
- public boolean breakRestrictions(Block block) {
- return true;
- }
-}
+package net.Indyuce.mmocore.api.block;
+
+import org.bukkit.Location;
+import org.bukkit.block.Block;
+
+import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
+import net.Indyuce.mmocore.api.util.MMOCoreUtils;
+import io.lumine.mythic.lib.MythicLib;
+import io.lumine.mythic.lib.api.MMOLineConfig;
+import io.lumine.mythic.lib.version.VersionMaterial;
+
+public class SkullBlockType implements BlockType {
+ private final String value;
+
+ public SkullBlockType(MMOLineConfig config) {
+ config.validate("value");
+
+ value = config.getString("value");
+ }
+
+ public SkullBlockType(Block block) {
+ value = MythicLib.plugin.getVersion().getWrapper().getSkullValue(block);
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public void place(RegeneratingBlock block) {
+ Location loc = block.getLocation();
+ loc.getBlock().setType(VersionMaterial.PLAYER_HEAD.toMaterial());
+
+ // save skull orientation if replaced block is a player head
+ if (MMOCoreUtils.isPlayerHead(block.getBlockData().getMaterial()))
+ loc.getBlock().setBlockData(block.getBlockData());
+
+ MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
+ }
+
+ @Override
+ public void regenerate(RegeneratingBlock block) {
+ Location loc = block.getLocation();
+ // This makes sure that if a skull loses its original rotation
+ // it can revert back to it when the base block is regenerated
+ loc.getBlock().setBlockData(block.getBlockData());
+ MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
+ }
+
+ @Override
+ public String generateKey() {
+ return "vanilla-skull-" + value;
+ }
+
+ @Override
+ public boolean breakRestrictions(Block block) {
+ return true;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/api/block/VanillaBlockType.java b/src/main/java/net/Indyuce/mmocore/api/block/VanillaBlockType.java
index 121538b0..e0076cf0 100644
--- a/src/main/java/net/Indyuce/mmocore/api/block/VanillaBlockType.java
+++ b/src/main/java/net/Indyuce/mmocore/api/block/VanillaBlockType.java
@@ -1,69 +1,69 @@
-package net.Indyuce.mmocore.api.block;
-
-import org.apache.commons.lang.Validate;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.block.Block;
-import org.bukkit.block.data.Ageable;
-import org.bukkit.block.data.BlockData;
-
-import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
-import io.lumine.mythic.lib.api.MMOLineConfig;
-
-public class VanillaBlockType implements BlockType {
- private final Material type;
-
- /*
- * allows to plant back crops with a custom age so that it does not always
- * have to full grow again-
- */
- private final int age;
-
- public VanillaBlockType(MMOLineConfig config) {
- config.validate("type");
-
- type = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
- age = config.getInt("age", 0);
-
- Validate.isTrue(age >= 0 && age < 8, "Age must be between 0 and 7");
- }
-
- public VanillaBlockType(Block block) {
- type = block.getType();
- age = 0;
- }
-
- public Material getType() {
- return type;
- }
-
- @Override
- public void place(RegeneratingBlock block) {
- Location loc = block.getLocation();
- block.getLocation().getBlock().setType(type);
-
- BlockData state = block.getLocation().getBlock().getBlockData();
- if (age > 0 && state instanceof Ageable) {
- ((Ageable) state).setAge(age);
- loc.getBlock().setBlockData(state);
- }
- }
-
- @Override
- public void regenerate(RegeneratingBlock block) {
- Location loc = block.getLocation();
- loc.getBlock().setType(type);
- // Sets the original blocks old data (only when regenerating)
- loc.getBlock().setBlockData(block.getBlockData());
- }
-
- @Override
- public String generateKey() {
- return "vanilla-block-" + type.name();
- }
-
- @Override
- public boolean breakRestrictions(Block block) {
- return age == 0 || (block.getBlockData() instanceof Ageable && ((Ageable) block.getBlockData()).getAge() >= age);
- }
-}
+package net.Indyuce.mmocore.api.block;
+
+import org.apache.commons.lang.Validate;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.block.data.Ageable;
+import org.bukkit.block.data.BlockData;
+
+import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
+import io.lumine.mythic.lib.api.MMOLineConfig;
+
+public class VanillaBlockType implements BlockType {
+ private final Material type;
+
+ /*
+ * allows to plant back crops with a custom age so that it does not always
+ * have to full grow again-
+ */
+ private final int age;
+
+ public VanillaBlockType(MMOLineConfig config) {
+ config.validate("type");
+
+ type = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
+ age = config.getInt("age", 0);
+
+ Validate.isTrue(age >= 0 && age < 8, "Age must be between 0 and 7");
+ }
+
+ public VanillaBlockType(Block block) {
+ type = block.getType();
+ age = 0;
+ }
+
+ public Material getType() {
+ return type;
+ }
+
+ @Override
+ public void place(RegeneratingBlock block) {
+ Location loc = block.getLocation();
+ block.getLocation().getBlock().setType(type);
+
+ BlockData state = block.getLocation().getBlock().getBlockData();
+ if (age > 0 && state instanceof Ageable) {
+ ((Ageable) state).setAge(age);
+ loc.getBlock().setBlockData(state);
+ }
+ }
+
+ @Override
+ public void regenerate(RegeneratingBlock block) {
+ Location loc = block.getLocation();
+ loc.getBlock().setType(type);
+ // Sets the original blocks old data (only when regenerating)
+ loc.getBlock().setBlockData(block.getBlockData());
+ }
+
+ @Override
+ public String generateKey() {
+ return "vanilla-block-" + type.name();
+ }
+
+ @Override
+ public boolean breakRestrictions(Block block) {
+ return age == 0 || (block.getBlockData() instanceof Ageable && ((Ageable) block.getBlockData()).getAge() >= age);
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/api/eco/Withdraw.java b/src/main/java/net/Indyuce/mmocore/api/eco/Withdraw.java
index e143c2b7..9b46af96 100644
--- a/src/main/java/net/Indyuce/mmocore/api/eco/Withdraw.java
+++ b/src/main/java/net/Indyuce/mmocore/api/eco/Withdraw.java
@@ -4,6 +4,7 @@ import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
@@ -16,7 +17,6 @@ import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.util.item.CurrencyItemBuilder;
import io.lumine.mythic.lib.api.util.SmartGive;
diff --git a/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java
index bd48b40d..eebb698b 100644
--- a/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java
+++ b/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java
@@ -2,10 +2,10 @@ package net.Indyuce.mmocore.api.event;
import javax.annotation.Nullable;
+import net.Indyuce.mmocore.experience.EXPSource;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
-import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.api.player.PlayerData;
diff --git a/src/main/java/net/Indyuce/mmocore/api/event/PlayerLevelUpEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/PlayerLevelUpEvent.java
index b02a90bc..0938dc8a 100644
--- a/src/main/java/net/Indyuce/mmocore/api/event/PlayerLevelUpEvent.java
+++ b/src/main/java/net/Indyuce/mmocore/api/event/PlayerLevelUpEvent.java
@@ -4,11 +4,12 @@ import org.bukkit.event.HandlerList;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.api.player.PlayerData;
+import org.jetbrains.annotations.Nullable;
public class PlayerLevelUpEvent extends PlayerDataEvent {
private static final HandlerList handlers = new HandlerList();
- // if null, this is main level
+ // If null, this is main level
private final Profession profession;
private final int oldLevel, newLevel;
@@ -36,6 +37,7 @@ public class PlayerLevelUpEvent extends PlayerDataEvent {
return profession != null;
}
+ @Nullable
public Profession getProfession() {
return profession;
}
diff --git a/src/main/java/net/Indyuce/mmocore/api/event/PlayerResourceUpdateEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/PlayerResourceUpdateEvent.java
index 291f4876..6a10469e 100644
--- a/src/main/java/net/Indyuce/mmocore/api/event/PlayerResourceUpdateEvent.java
+++ b/src/main/java/net/Indyuce/mmocore/api/event/PlayerResourceUpdateEvent.java
@@ -1,5 +1,9 @@
package net.Indyuce.mmocore.api.event;
+import net.Indyuce.mmocore.api.quest.trigger.ManaTrigger;
+import net.Indyuce.mmocore.api.quest.trigger.StaminaTrigger;
+import net.Indyuce.mmocore.api.quest.trigger.StelliumTrigger;
+import net.Indyuce.mmocore.command.rpg.admin.ResourceCommandTreeNode;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.skill.list.Neptune_Gift;
@@ -104,14 +108,14 @@ public class PlayerResourceUpdateEvent extends PlayerDataEvent implements Cancel
/**
* Used by quests triggers
- * - {@link net.Indyuce.mmocore.api.quest.trigger.ManaTrigger}
- * - {@link net.Indyuce.mmocore.api.quest.trigger.StaminaTrigger}
- * - {@link net.Indyuce.mmocore.api.quest.trigger.StelliumTrigger}
+ * - {@link ManaTrigger}
+ * - {@link StaminaTrigger}
+ * - {@link StelliumTrigger}
*/
TRIGGER,
/**
- * When using the resource command {@link net.Indyuce.mmocore.command.rpg.admin.ResourceCommandTreeNode}
+ * When using the resource command {@link ResourceCommandTreeNode}
*/
COMMAND,
diff --git a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java
index 9ec22aca..cd2c891d 100644
--- a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java
+++ b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java
@@ -1,13 +1,16 @@
package net.Indyuce.mmocore.api.load;
-import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
-import net.Indyuce.mmocore.experience.source.*;
-import net.Indyuce.mmocore.loot.chest.condition.*;
-import org.bukkit.configuration.ConfigurationSection;
-
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.api.block.BlockType;
import net.Indyuce.mmocore.api.block.SkullBlockType;
import net.Indyuce.mmocore.api.block.VanillaBlockType;
+import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
+import net.Indyuce.mmocore.experience.source.*;
+import net.Indyuce.mmocore.loot.chest.condition.*;
+import org.apache.commons.math3.analysis.function.Exp;
+import org.bukkit.configuration.ConfigurationSection;
+
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
import net.Indyuce.mmocore.loot.droptable.dropitem.DropTableDropItem;
@@ -30,34 +33,53 @@ import net.Indyuce.mmocore.api.quest.trigger.StaminaTrigger;
import net.Indyuce.mmocore.api.quest.trigger.StelliumTrigger;
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
import io.lumine.mythic.lib.api.MMOLineConfig;
+import org.checkerframework.checker.units.qual.C;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Level;
public class DefaultMMOLoader extends MMOLoader {
@Override
- public Trigger loadTrigger(MMOLineConfig config) {
+ public List loadTrigger(MMOLineConfig config) {
+ if (config.getKey().equals("from")) {
+ String source = config.getString("source");
+ ConfigFile configFile = new ConfigFile("triggers");
+ if (!configFile.getConfig().contains(source)) {
+ MMOCore.plugin.getLogger().log(Level.WARNING, "Couldn't find " + source + " in experience-sources.yml");
+ return null;
+ }
+ List list = new ArrayList<>();
+ for (String trigger : configFile.getConfig().getStringList(source)) {
+ list.addAll(loadTrigger(new MMOLineConfig(trigger)));
+ }
+ return list;
+ }
if (config.getKey().equals("message"))
- return new MessageTrigger(config);
+ return Arrays.asList(new MessageTrigger(config));
if (config.getKey().equals("sound") || config.getKey().equals("playsound"))
- return new SoundTrigger(config);
+ return Arrays.asList(new SoundTrigger(config));
if (config.getKey().equals("mana"))
- return new ManaTrigger(config);
+ return Arrays.asList(new ManaTrigger(config));
if (config.getKey().equals("stamina"))
- return new StaminaTrigger(config);
+ return Arrays.asList(new StaminaTrigger(config));
if (config.getKey().equals("stellium"))
- return new StelliumTrigger(config);
+ return Arrays.asList(new StelliumTrigger(config));
if (config.getKey().equals("command"))
- return new CommandTrigger(config);
+ return Arrays.asList(new CommandTrigger(config));
if (config.getKey().equals("item") || config.getKey().equals("vanilla"))
- return new ItemTrigger(config);
+ return Arrays.asList(new ItemTrigger(config));
if (config.getKey().equals("exp") || config.getKey().equals("experience"))
- return new ExperienceTrigger(config);
+ return Arrays.asList(new ExperienceTrigger(config));
return null;
}
@@ -97,77 +119,111 @@ public class DefaultMMOLoader extends MMOLoader {
}
@Override
- public Condition loadCondition(MMOLineConfig config) {
+ public List loadCondition(MMOLineConfig config) {
+ if (config.getKey().equals("from")) {
+ String source = config.getString("source");
+ ConfigFile configFile = new ConfigFile("conditions");
+ if (!configFile.getConfig().contains(source)) {
+ MMOCore.plugin.getLogger().log(Level.WARNING, "Couldn't find " + source + " in experience-sources.yml");
+ return null;
+ }
+ List list = new ArrayList<>();
+ for (String condition : configFile.getConfig().getStringList(source)) {
+ list.addAll(loadCondition(new MMOLineConfig(condition)));
+ }
+ return list;
+
+ }
+
if (config.getKey().equals("distance"))
- return new DistanceCondition(config);
+ return Arrays.asList(new DistanceCondition(config));
if (config.getKey().equals("world"))
- return new WorldCondition(config);
+ return Arrays.asList(new WorldCondition(config));
if (config.getKey().equals("biome"))
- return new BiomeCondition(config);
+ return Arrays.asList(new BiomeCondition(config));
if (config.getKey().equals("level"))
- return new LevelCondition(config);
+ return Arrays.asList(new LevelCondition(config));
if (config.getKey().equals("permission"))
- return new PermissionCondition(config);
+ return Arrays.asList(new PermissionCondition(config));
return null;
}
+
@Override
- public ExperienceSource> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
+ public List> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
+ if (config.getKey().equals("from")) {
+ String source = config.getString("source");
+ ConfigFile configFile = new ConfigFile("exp-sources");
+ if (!configFile.getConfig().contains(source)) {
+ MMOCore.plugin.getLogger().log(Level.WARNING, "Couldn't find " + source + " in experience-sources.yml");
+ return null;
+ }
+ List> list = new ArrayList<>();
+ for (String expSource : configFile.getConfig().getStringList(source)) {
+ list.addAll(loadExperienceSource(new MMOLineConfig(expSource), dispenser));
+ }
+ return list;
+
+ }
if (config.getKey().equals("resource"))
- return new ResourceExperienceSource(dispenser, config);
+ return Arrays.asList(new ResourceExperienceSource(dispenser, config));
if (config.getKey().equals("climb"))
- return new ClimbExperienceSource(dispenser, config);
+ return Arrays.asList(new ClimbExperienceSource(dispenser, config));
+
+ if (config.getKey().equals("eat")) {
+ return Arrays.asList(new EatExperienceSource(dispenser, config));
+ }
if (config.getKey().equals("damagedealt"))
- return new DamageDealtExperienceSource(dispenser, config);
+ return Arrays.asList(new DamageDealtExperienceSource(dispenser, config));
if (config.getKey().equals("damagetaken"))
- return new DamageTakenExperienceSource(dispenser, config);
+ return Arrays.asList(new DamageTakenExperienceSource(dispenser, config));
if (config.getKey().equals("move"))
- return new MoveExperienceSource(dispenser, config);
+ return Arrays.asList(new MoveExperienceSource(dispenser, config));
if (config.getKey().equals("play"))
- return new PlayExperienceSource(dispenser, config);
+ return Arrays.asList(new PlayExperienceSource(dispenser, config));
if (config.getKey().equals("projectile"))
- return new ProjectileExperienceSource(dispenser, config);
+ return Arrays.asList(new ProjectileExperienceSource(dispenser, config));
if (config.getKey().equals("ride"))
- return new RideExperienceSource(dispenser, config);
+ return Arrays.asList(new RideExperienceSource(dispenser, config));
if (config.getKey().equals("tame"))
- return new TameExperienceSource(dispenser, config);
+ return Arrays.asList(new TameExperienceSource(dispenser, config));
if (config.getKey().equals("killmob"))
- return new KillMobExperienceSource(dispenser, config);
+ return Arrays.asList(new KillMobExperienceSource(dispenser, config));
if (config.getKey().equals("mineblock"))
- return new MineBlockExperienceSource(dispenser, config);
+ return Arrays.asList(new MineBlockExperienceSource(dispenser, config));
if (config.getKey().equals("placeblock"))
- return new PlaceBlockExperienceSource(dispenser, config);
+ return Arrays.asList(new PlaceBlockExperienceSource(dispenser, config));
if (config.getKey().equals("brewpotion"))
- return new BrewPotionExperienceSource(dispenser, config);
+ return Arrays.asList(new BrewPotionExperienceSource(dispenser, config));
if (config.getKey().equals("smeltitem"))
- return new SmeltItemExperienceSource(dispenser, config);
+ return Arrays.asList(new SmeltItemExperienceSource(dispenser, config));
if (config.getKey().equals("enchantitem"))
- return new EnchantItemExperienceSource(dispenser, config);
+ return Arrays.asList(new EnchantItemExperienceSource(dispenser, config));
if (config.getKey().equals("repairitem"))
- return new RepairItemExperienceSource(dispenser, config);
+ return Arrays.asList(new RepairItemExperienceSource(dispenser, config));
if (config.getKey().equals("craftitem"))
- return new CraftItemExperienceSource(dispenser, config);
+ return Arrays.asList(new CraftItemExperienceSource(dispenser, config));
return null;
}
diff --git a/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java
index c1bed441..4e83734e 100644
--- a/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java
+++ b/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java
@@ -2,14 +2,16 @@ package net.Indyuce.mmocore.api.load;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.api.block.BlockType;
+import net.Indyuce.mmocore.api.quest.trigger.Trigger;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
import net.Indyuce.mmocore.api.quest.objective.Objective;
-import net.Indyuce.mmocore.api.quest.trigger.Trigger;
import org.bukkit.configuration.ConfigurationSection;
+import java.util.List;
+
/**
* MMOLoader was initially an interface but it is now a
* class so devs do not have to add a new method
@@ -17,11 +19,11 @@ import org.bukkit.configuration.ConfigurationSection;
*/
public class MMOLoader {
- public Condition loadCondition(MMOLineConfig config) {
+ public List loadCondition(MMOLineConfig config) {
return null;
}
- public Trigger loadTrigger(MMOLineConfig config) {
+ public List loadTrigger(MMOLineConfig config) {
return null;
}
@@ -33,7 +35,7 @@ public class MMOLoader {
return null;
}
- public ExperienceSource> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
+ public List> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
return null;
}
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java
index c10a803a..d180dd97 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java
@@ -1,22 +1,14 @@
package net.Indyuce.mmocore.api.player;
+import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.player.MMOPlayerData;
import io.lumine.mythic.lib.player.TemporaryPlayerData;
import io.lumine.mythic.lib.player.cooldown.CooldownMap;
-import io.lumine.mythic.lib.player.modifier.PlayerModifier;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.SoundEvent;
-import net.Indyuce.mmocore.api.quest.trigger.Trigger;
import net.Indyuce.mmocore.player.Unlockable;
-import net.Indyuce.mmocore.tree.IntegerCoordinates;
-import net.Indyuce.mmocore.tree.NodeState;
-import net.Indyuce.mmocore.tree.SkillTreeNode;
-import net.Indyuce.mmocore.tree.skilltree.AutomaticSkillTree;
-import net.Indyuce.mmocore.tree.skilltree.LinkedSkillTree;
-import net.Indyuce.mmocore.tree.skilltree.SkillTree;
-import net.Indyuce.mmocore.tree.skilltree.display.DisplayInfo;
-import net.Indyuce.mmocore.tree.skilltree.display.Icon;
+import net.Indyuce.mmocore.waypoint.CostType;
import net.Indyuce.mmocore.waypoint.Waypoint;
import net.Indyuce.mmocore.api.event.PlayerExperienceGainEvent;
import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
@@ -47,7 +39,6 @@ import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
import net.Indyuce.mmocore.waypoint.WaypointOption;
-import net.java.truecommons.shed.Link;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.apache.commons.lang.Validate;
@@ -62,8 +53,6 @@ import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.stream.Collectors;
public class PlayerData extends OfflinePlayerData implements Closable, ExperienceTableClaimer {
@@ -113,6 +102,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
*/
private final Map tableItemClaims = new HashMap<>();
+ // NON-FINAL player data stuff made public to facilitate field change
+ public int skillGuiDisplayOffset;
public boolean noCooldown;
public CombatRunnable combat;
@@ -179,6 +170,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
} catch (NullPointerException exception) {
MMOCore.log(Level.SEVERE, "[Userdata] Could not find class " + getProfess().getId() + " while refreshing player data.");
}
+
int j = 0;
while (j < boundSkills.size())
try {
@@ -501,8 +493,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return guild != null;
}
+ /**
+ * @return If the item is unlocked by the player
+ */
public boolean hasUnlocked(Unlockable unlockable) {
- throw new RuntimeException("Not implemented yet");
+ return unlockedItems.contains(unlockable.getUnlockNamespacedKey());
}
/**
@@ -511,7 +506,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
* @return If the item was already unlocked when calling this method
*/
public boolean unlock(Unlockable unlockable) {
- throw new RuntimeException("Not implemented yet");
+ return unlockedItems.add(unlockable.getUnlockNamespacedKey());
}
public void setLevel(int level) {
@@ -544,7 +539,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void refreshVanillaExp() {
if (!isOnline() || !MMOCore.plugin.configManager.overrideVanillaExp)
return;
-
+ getPlayer().sendExperienceChange(0.01f);
getPlayer().setLevel(getLevel());
getPlayer().setExp(Math.max(0, Math.min(1, (float) experience / (float) getLevelUpExperience())));
}
@@ -718,6 +713,63 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
}.runTaskTimer(MMOCore.plugin, 0, 1);
}
+ public String toJson() {
+
+ //We create the JSON corresponding to player Data
+ JsonObject jsonObject = new JsonObject();
+ MMOCore.sqlDebug("Saving data for: '" + getUniqueId() + "'...");
+
+ jsonObject.addProperty("class_points", getClassPoints());
+ jsonObject.addProperty("skill_points", getSkillPoints());
+ jsonObject.addProperty("attribute_points", getAttributePoints());
+ jsonObject.addProperty("attribute_realloc_points", getAttributeReallocationPoints());
+ jsonObject.addProperty("level", getLevel());
+ jsonObject.addProperty("experience", getExperience());
+ jsonObject.addProperty("class", getProfess().getId());
+ jsonObject.addProperty("last_login", getLastLogin());
+ jsonObject.addProperty("guild", hasGuild() ? getGuild().getId() : null);
+
+ jsonObject.addProperty("waypoints", MMOCoreUtils.arrayToJsonString(getWaypoints()));
+ jsonObject.addProperty("friends", MMOCoreUtils.arrayToJsonString(getFriends().stream().map(UUID::toString).collect(Collectors.toList())));
+ jsonObject.addProperty("bound_skills", MMOCoreUtils.arrayToJsonString(getBoundSkills().stream().map(skill -> skill.getSkill().getHandler().getId()).collect(Collectors.toList())));
+
+ jsonObject.addProperty("skills", MMOCoreUtils.entrySetToJsonString(mapSkillLevels().entrySet()));
+ jsonObject.addProperty("times_claimed", MMOCoreUtils.entrySetToJsonString(getItemClaims().entrySet()));
+
+ jsonObject.addProperty("attributes", getAttributes().toJsonString());
+ jsonObject.addProperty("professions", getCollectionSkills().toJsonString());
+ jsonObject.addProperty("quests", getQuestData().toJsonString());
+ jsonObject.addProperty("class_info", createClassInfoData(this).toString());
+
+ return jsonObject.toString();
+ }
+
+
+ public static JsonObject createClassInfoData(PlayerData data) {
+ JsonObject json = new JsonObject();
+ for (String c : data.getSavedClasses()) {
+ SavedClassInformation info = data.getClassInfo(c);
+ JsonObject classinfo = new JsonObject();
+ classinfo.addProperty("level", info.getLevel());
+ classinfo.addProperty("experience", info.getExperience());
+ classinfo.addProperty("skill-points", info.getSkillPoints());
+ classinfo.addProperty("attribute-points", info.getAttributePoints());
+ classinfo.addProperty("attribute-realloc-points", info.getAttributeReallocationPoints());
+ JsonObject skillinfo = new JsonObject();
+ for (String skill : info.getSkillKeys())
+ skillinfo.addProperty(skill, info.getSkillLevel(skill));
+ classinfo.add("skill", skillinfo);
+ JsonObject attributeinfo = new JsonObject();
+ for (String attribute : info.getAttributeKeys())
+ attributeinfo.addProperty(attribute, info.getAttributeLevel(attribute));
+ classinfo.add("attribute", attributeinfo);
+
+ json.add(c, classinfo);
+ }
+
+ return json;
+ }
+
public boolean hasReachedMaxLevel() {
return getProfess().getMaxLevel() > 0 && getLevel() >= getProfess().getMaxLevel();
}
@@ -742,6 +794,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
* @param splitExp Should the exp be split among party members
*/
public void giveExperience(double value, EXPSource source, @Nullable Location hologramLocation, boolean splitExp) {
+ if (value <= 0)
+ return;
+
if (hasReachedMaxLevel()) {
setExperience(0);
return;
@@ -751,14 +806,18 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
value *= 1 + getStats().getStat(StatType.ADDITIONAL_EXPERIENCE) / 100;
// Splitting exp through party members
- AbstractParty party = getParty();
- if (splitExp && party != null) {
- List onlineMembers = getParty().getOnlineMembers();
+ AbstractParty party;
+ if (splitExp && (party = getParty()) != null) {
+ List onlineMembers = party.getOnlineMembers();
value /= onlineMembers.size();
for (PlayerData member : onlineMembers)
- member.giveExperience(value, EXPSource.PARTY_SHARING, null, false);
+ if (!equals(member))
+ member.giveExperience(value, source, null, false);
}
+ // Apply buffs AFTER splitting exp
+ value *= (1 + getStats().getStat("ADDITIONAL_EXPERIENCE") / 100) * MMOCore.plugin.boosterManager.getMultiplier(null);
+
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, value, source);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled())
@@ -766,7 +825,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
// Experience hologram
if (hologramLocation != null && isOnline())
- MMOCoreUtils.displayIndicator(hologramLocation, MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", String.valueOf(event.getExperience())).message());
+ MMOCoreUtils.displayIndicator(hologramLocation, MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", MythicLib.plugin.getMMOConfig().decimal.format(event.getExperience())).message());
experience = Math.max(0, experience + event.getExperience());
@@ -781,6 +840,10 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
experience -= needed;
level = getLevel() + 1;
+
+ // Apply class experience table
+ if (getProfess().hasExperienceTable())
+ getProfess().getExperienceTable().claim(this, level, getProfess());
}
if (level > oldLevel) {
@@ -800,6 +863,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
refreshVanillaExp();
}
+
+
public double getExperience() {
return experience;
}
@@ -821,7 +886,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void giveMana(double amount, PlayerResourceUpdateEvent.UpdateReason reason) {
// Avoid calling useless event
- double max = getStats().getStat(StatType.MAX_MANA);
+ double max = getStats().getStat("MAX_MANA");
double newest = Math.max(0, Math.min(mana + amount, max));
if (mana == newest)
return;
@@ -846,7 +911,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void giveStamina(double amount, PlayerResourceUpdateEvent.UpdateReason reason) {
// Avoid calling useless event
- double max = getStats().getStat(StatType.MAX_STAMINA);
+ double max = getStats().getStat("MAX_STAMINA");
double newest = Math.max(0, Math.min(stamina + amount, max));
if (stamina == newest)
return;
@@ -871,7 +936,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void giveStellium(double amount, PlayerResourceUpdateEvent.UpdateReason reason) {
// Avoid calling useless event
- double max = getStats().getStat(StatType.MAX_STELLIUM);
+ double max = getStats().getStat("MAX_STELLIUM");
double newest = Math.max(0, Math.min(stellium + amount, max));
if (stellium == newest)
return;
@@ -906,15 +971,15 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
}
public void setMana(double amount) {
- mana = Math.max(0, Math.min(amount, getStats().getStat(StatType.MAX_MANA)));
+ mana = Math.max(0, Math.min(amount, getStats().getStat("MAX_MANA")));
}
public void setStamina(double amount) {
- stamina = Math.max(0, Math.min(amount, getStats().getStat(StatType.MAX_STAMINA)));
+ stamina = Math.max(0, Math.min(amount, getStats().getStat("MAX_STAMINA")));
}
public void setStellium(double amount) {
- stellium = Math.max(0, Math.min(amount, getStats().getStat(StatType.MAX_STELLIUM)));
+ stellium = Math.max(0, Math.min(amount, getStats().getStat("MAX_STELLIUM")));
}
public boolean isFullyLoaded() {
@@ -947,6 +1012,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
Validate.isTrue(isCasting(), "Player not in casting mode");
skillCasting.close();
this.skillCasting = null;
+ setLastActivity(PlayerActivity.ACTION_BAR_MESSAGE, 0); // Reset action bar
}
public void displayActionBar(String message) {
@@ -1099,6 +1165,34 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
combat = new CombatRunnable(this);
}
+ /**
+ * @return The savingPlayerData object corresponding to the playerData
+ */
+ public SavingPlayerData getSavingPlayerData() {
+ return new SavingPlayerData(
+ getUniqueId(),
+ getClassPoints(),
+ getSkillPoints(),
+ getAttributePoints(),
+ getAttributeReallocationPoints(),
+ getLevel(),
+ getExperience(),
+ getProfess().getId(),
+ getLastLogin(),
+ hasGuild() ? getGuild().getId() : null,
+ getWaypoints(),
+ getFriends(),
+ getBoundSkills().stream().map(skill -> skill.getSkill().getHandler().getId()).toList(),
+ mapSkillLevels(),
+ getItemClaims(),
+ getAttributes().toJsonString(),
+ getCollectionSkills().toJsonString(),
+ getQuestData().toJsonString(),
+ createClassInfoData(this).toString());
+ }
+
+
+
@Override
public int hashCode() {
return mmoData.hashCode();
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/SavingPlayerData.java b/src/main/java/net/Indyuce/mmocore/api/player/SavingPlayerData.java
new file mode 100644
index 00000000..a0e6a443
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/api/player/SavingPlayerData.java
@@ -0,0 +1,42 @@
+package net.Indyuce.mmocore.api.player;
+
+import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
+import net.Indyuce.mmocore.api.quest.PlayerQuests;
+import net.Indyuce.mmocore.experience.PlayerProfessions;
+import net.Indyuce.mmocore.skill.ClassSkill;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * Just a container holding the basic playerData information that are needed to save it in a database.
+ */
+public record SavingPlayerData(
+ UUID uuid,
+ int classPoints,
+ int skillPoints,
+ int attributePoints,
+ int attributeReallocationPoints,
+ int level,
+ double experience,
+ String classId,
+ long lastLogin,
+ String guildId,
+ Set waypoints,
+ List friends,
+ List boundSkills,
+ Map skills,
+ Map itemClaims,
+ String attributes,
+ String collectionsSkills,
+ String questData,
+ String classInfoData)
+{
+
+
+
+
+
+}
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/attribute/AttributeModifier.java b/src/main/java/net/Indyuce/mmocore/api/player/attribute/AttributeModifier.java
index 108d3ebb..7dd53051 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/attribute/AttributeModifier.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/attribute/AttributeModifier.java
@@ -12,6 +12,7 @@ import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;
import java.text.DecimalFormat;
+import java.util.Objects;
public class AttributeModifier extends PlayerModifier {
private final String attribute;
@@ -74,9 +75,10 @@ public class AttributeModifier extends PlayerModifier {
public AttributeModifier(ConfigObject object) {
super(object.getString("key"), EquipmentSlot.OTHER, ModifierSource.OTHER);
+ String str = Objects.requireNonNull(object.getString("value"));
+ type = str.toCharArray()[str.length() - 1] == '%' ? ModifierType.RELATIVE : ModifierType.FLAT;
+ value = Double.parseDouble(type == ModifierType.RELATIVE ? str.substring(0, str.length() - 1) : str);
this.attribute = object.getString("attribute");
- this.value = object.getDouble("value");
- type = object.getBoolean("multiplicative", false) ? ModifierType.RELATIVE : ModifierType.FLAT;
}
public String getAttribute() {
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java b/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java
index 8f714bf7..b2858e48 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttribute.java
@@ -3,57 +3,109 @@ package net.Indyuce.mmocore.api.player.attribute;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.experience.EXPSource;
+import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.experience.ExpCurve;
+import net.Indyuce.mmocore.experience.ExperienceObject;
import org.apache.commons.lang.Validate;
+import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
+import java.util.Objects;
import java.util.Set;
import java.util.logging.Level;
-public class PlayerAttribute {
- private final String id, name;
- private final int max;
+public class PlayerAttribute implements ExperienceObject {
+ private final String id, name;
+ private final int max;
+ private final ExperienceTable expTable;
- /**
- * Used to store stats using StatType, but attributes also need to access
- * non basic MMOCore stats hence the string maps keys
- */
- private final Set buffs = new HashSet<>();
+ /**
+ * All buffs granted by an attribute. These are normalized and
+ * must be multiplied by the player level first
+ */
+ private final Set buffs = new HashSet<>();
- public PlayerAttribute(ConfigurationSection config) {
- Validate.notNull(config, "Could not load config");
- id = config.getName().toLowerCase().replace("_", "-").replace(" ", "-");
+ public PlayerAttribute(ConfigurationSection config) {
+ Validate.notNull(config, "Could not load config");
+ id = config.getName().toLowerCase().replace("_", "-").replace(" ", "-");
- name = MythicLib.plugin.parseColors(config.getString("name", "Attribute"));
- max = config.contains("max-points") ? Math.max(1, config.getInt("max-points")) : 0;
+ name = MythicLib.plugin.parseColors(config.getString("name", "Attribute"));
+ max = config.contains("max-points") ? Math.max(1, config.getInt("max-points")) : 0;
- if (config.contains("buff"))
- for (String key : config.getConfigurationSection("buff").getKeys(false))
- try {
- String stat = key.toUpperCase().replace("-", "_").replace(" ", "_");
- buffs.add(new StatModifier("attribute." + id, stat, config.getString("buff." + key)));
- } catch (IllegalArgumentException exception) {
- MMOCore.log(Level.WARNING, "Could not load buff '" + key + "' from attribute '" + id + "': " + exception.getMessage());
- }
- }
+ if (config.contains("buff"))
+ for (String key : config.getConfigurationSection("buff").getKeys(false))
+ try {
+ String stat = key.toUpperCase().replace("-", "_").replace(" ", "_");
+ buffs.add(new StatModifier("attribute." + id, stat, config.getString("buff." + key)));
+ } catch (IllegalArgumentException exception) {
+ MMOCore.log(Level.WARNING, "Could not load buff '" + key + "' from attribute '" + id + "': " + exception.getMessage());
+ }
- public String getId() {
- return id;
- }
+ // Load exp table
+ ExperienceTable expTable = null;
+ if (config.contains("exp-table"))
+ try {
+ expTable = MMOCore.plugin.experience.loadExperienceTable(config.get("exp-table"));
+ } catch (RuntimeException exception) {
+ MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp table from class '" + id + "': " + exception.getMessage());
+ }
+ this.expTable = expTable;
+ }
- public String getName() {
- return name;
- }
+ public String getId() {
+ return id;
+ }
- public boolean hasMax() {
- return max > 0;
- }
+ public String getName() {
+ return name;
+ }
- public int getMax() {
- return max;
- }
+ public boolean hasMax() {
+ return max > 0;
+ }
- public Set getBuffs() {
- return buffs;
- }
+ public int getMax() {
+ return max;
+ }
+
+ public Set getBuffs() {
+ return buffs;
+ }
+
+ @Override
+ public String getKey() {
+ return "attribute:" + getId().replace("-", "_");
+ }
+
+ @NotNull
+ @Override
+ public ExperienceTable getExperienceTable() {
+ return Objects.requireNonNull(expTable);
+ }
+
+ @Override
+ public boolean hasExperienceTable() {
+ return expTable != null;
+ }
+
+ @Nullable
+ @Override
+ public ExpCurve getExpCurve() {
+ throw new RuntimeException("Attributes don't have experience");
+ }
+
+ @Override
+ public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, @NotNull EXPSource source) {
+ throw new RuntimeException("Attributes don't have experience");
+ }
+
+ @Override
+ public boolean shouldHandle(PlayerData playerData) {
+ throw new RuntimeException("Attributes don't have experience");
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttributes.java b/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttributes.java
index 2569d811..82eae2ce 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttributes.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/attribute/PlayerAttributes.java
@@ -159,14 +159,14 @@ public class PlayerAttributes {
return map.get(key);
}
- public void addModifier(String key, double value) {
- addModifier(new AttributeModifier(key, id, value, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER));
+ public AttributeModifier addModifier(String key, double value) {
+ return addModifier(new AttributeModifier(key, id, value, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER));
}
- public void addModifier(AttributeModifier modifier) {
- map.put(modifier.getKey(), modifier);
-
+ public AttributeModifier addModifier(AttributeModifier modifier) {
+ AttributeModifier mod = map.put(modifier.getKey(), modifier);
update();
+ return mod;
}
public Set getKeys() {
@@ -177,7 +177,7 @@ public class PlayerAttributes {
return map.containsKey(key);
}
- public void removeModifier(String key) {
+ public AttributeModifier removeModifier(String key) {
AttributeModifier mod = map.remove(key);
/*
@@ -190,12 +190,13 @@ public class PlayerAttributes {
((Closeable) mod).close();
update();
}
+ return mod;
}
public void update() {
- PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
+ PlayerAttribute attr = MMOCore.plugin.attributeManager.get(id);
int total = getTotal();
- attribute.getBuffs().forEach(buff -> buff.multiply(total).register(data.getMMOPlayerData()));
+ attr.getBuffs().forEach(buff -> buff.multiply(total).register(data.getMMOPlayerData()));
}
public String getId() {
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/ClassOption.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/ClassOption.java
index 5a6e5e29..22978d97 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/profess/ClassOption.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/ClassOption.java
@@ -1,52 +1,58 @@
-package net.Indyuce.mmocore.api.player.profess;
-
-public enum ClassOption {
-
- /**
- * If the class should be applied to newcomers
- */
- DEFAULT,
-
- /**
- * If the class should in the /class GUI
- */
- DISPLAY(true),
-
- /**
- * Health only regens when out of combat
- */
- OFF_COMBAT_HEALTH_REGEN,
-
- /**
- * Mana only regens when out of combat
- */
- OFF_COMBAT_MANA_REGEN,
-
- /**
- * Stamina only regens when out of combat
- */
- OFF_COMBAT_STAMINA_REGEN,
-
- /**
- * Stellium only regens when out of combat
- */
- OFF_COMBAT_STELLIUM_REGEN;
-
- private final boolean def;
-
- ClassOption() {
- this(false);
- }
-
- ClassOption(boolean def) {
- this.def = def;
- }
-
- public boolean getDefault() {
- return def;
- }
-
- public String getPath() {
- return name().toLowerCase().replace("_", "-");
- }
+package net.Indyuce.mmocore.api.player.profess;
+
+public enum ClassOption {
+
+ /**
+ * If the class should be applied to newcomers
+ */
+ DEFAULT,
+
+ /**
+ * When set to true any player has to have the
+ * mmocore.class.lower_case_name permission to use the class
+ */
+ NEEDS_PERMISSION,
+
+ /**
+ * If the class should in the /class GUI
+ */
+ DISPLAY(true),
+
+ /**
+ * Health only regens when out of combat
+ */
+ OFF_COMBAT_HEALTH_REGEN,
+
+ /**
+ * Mana only regens when out of combat
+ */
+ OFF_COMBAT_MANA_REGEN,
+
+ /**
+ * Stamina only regens when out of combat
+ */
+ OFF_COMBAT_STAMINA_REGEN,
+
+ /**
+ * Stellium only regens when out of combat
+ */
+ OFF_COMBAT_STELLIUM_REGEN;
+
+ private final boolean def;
+
+ ClassOption() {
+ this(false);
+ }
+
+ ClassOption(boolean def) {
+ this.def = def;
+ }
+
+ public boolean getDefault() {
+ return def;
+ }
+
+ public String getPath() {
+ return name().toLowerCase().replace("_", "-");
+ }
}
\ No newline at end of file
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java
index 346a2b9a..3021d87e 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java
@@ -8,26 +8,27 @@ import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.util.PostLoadObject;
import io.lumine.mythic.lib.version.VersionMaterial;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.event.EventTrigger;
import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions;
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.api.player.profess.resource.ResourceRegeneration;
-import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
-import net.Indyuce.mmocore.loot.chest.particle.CastingParticle;
+import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.ExpCurve;
import net.Indyuce.mmocore.experience.ExperienceObject;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
-import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
-import net.Indyuce.mmocore.experience.dispenser.ClassExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
+import net.Indyuce.mmocore.loot.chest.particle.CastingParticle;
import net.Indyuce.mmocore.player.playerclass.ClassTrigger;
import net.Indyuce.mmocore.player.playerclass.ClassTriggerType;
+import net.Indyuce.mmocore.player.stats.StatInfo;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.md_5.bungee.api.ChatColor;
-import org.apache.commons.lang.Validate;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.configuration.ConfigurationSection;
@@ -51,7 +52,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
private final ExpCurve expCurve;
private final ExperienceTable expTable;
- private final Map stats = new HashMap<>();
+ private final Map stats = new HashMap<>();
private final Map skills = new LinkedHashMap<>();
private final List subclasses = new ArrayList<>();
@@ -83,7 +84,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
profileField.set(meta, gp);
icon.setItemMeta(meta);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException
- | SecurityException exception) {
+ | SecurityException exception) {
throw new IllegalArgumentException("Could not apply playerhead texture: " + exception.getMessage());
}
@@ -124,7 +125,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
if (config.contains("attributes"))
for (String key : config.getConfigurationSection("attributes").getKeys(false))
try {
- stats.put(StatType.valueOf(key.toUpperCase().replace("-", "_")),
+ stats.put(UtilityMethods.enumName(key),
new LinearValue(config.getConfigurationSection("attributes." + key)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load stat info '" + key + "' from class '"
@@ -155,12 +156,12 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
"Could not load option '" + key + "' from class '" + key + "': " + exception.getMessage());
}
- if (config.contains("main-exp-sources")) {
- ExperienceDispenser dispenser = new ClassExperienceDispenser(this);
- for (String key : config.getStringList("main-exp-sources"))
+ if (config.contains("main-exp-sources.yml")) {
+ for (String key : config.getStringList("main-exp-sources.yml"))
try {
- ExperienceSource> source = MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), dispenser);
- MMOCore.plugin.experience.registerSource(source);
+ List> list = MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), this);
+ for (ExperienceSource source : list)
+ MMOCore.plugin.experience.registerSource(source);
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp source '" + key + "' from class '"
+ id + "': " + exception.getMessage());
@@ -187,11 +188,12 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
}
/**
- * Used to generate the default Human class if no one is
- * specified after loading all the player classes. This is
- * a very basic class that will make sure MMOCore can still
- * continue to run without having to stop the server because
- * some option was not provided
+ * Used to generate the default Human class if no one is specified
+ * after loading all the player classes.
+ *
+ * This is a very basic class that will make sure MMOCore can still
+ * continue to run without having to stop the server because some
+ * option was not provided.
*/
public PlayerClass(String id, String name, Material material) {
super(null);
@@ -205,7 +207,6 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
expTable = null;
castParticle = new CastingParticle(Particle.SPELL_INSTANT);
actionBarFormat = "";
-
this.icon = new ItemStack(material);
setOption(ClassOption.DISPLAY, false);
setOption(ClassOption.DEFAULT, false);
@@ -296,7 +297,19 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
}
public boolean hasOption(ClassOption option) {
- return options.containsKey(option) ? options.get(option) : option.getDefault();
+ return options.getOrDefault(option, option.getDefault());
+ }
+
+ @Override
+ public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) {
+ hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null
+ : hologramLocation;
+ playerData.giveExperience(experience, source, hologramLocation, true);
+ }
+
+ @Override
+ public boolean shouldHandle(PlayerData playerData) {
+ return equals(playerData.getProfess());
}
@Nullable
@@ -320,16 +333,11 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
return eventTriggers.get(name);
}
- @Deprecated
- public void setStat(StatType type, double base, double perLevel) {
- setStat(type, new LinearValue(base, perLevel));
+ public void setDefaultStatFormula(String type, LinearValue value) {
+ stats.put(UtilityMethods.enumName(type), value);
}
- public void setStat(StatType type, LinearValue value) {
- stats.put(type, value);
- }
-
- public double calculateStat(StatType stat, int level) {
+ public double calculateStat(String stat, int level) {
return getStatInfo(stat).calculate(level);
}
@@ -363,19 +371,6 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
return getSkill(skill.getHandler().getId());
}
- /**
- * Reduces map checkups when skills are being checked on events that are
- * commonly called like EntityDamageEvent or regen events.
- *
- * Examples:
- * - {@link net.Indyuce.mmocore.skill.list.Neptune_Gift}
- * - {@link net.Indyuce.mmocore.skill.list.Ambers}
- */
- public Optional findSkill(RegisteredSkill skill) {
- ClassSkill found = skills.get(skill.getHandler().getId());
- return found == null ? Optional.empty() : Optional.of(found);
- }
-
@Nullable
public ClassSkill getSkill(String id) {
return skills.get(id);
@@ -385,8 +380,10 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
return skills.values();
}
- private LinearValue getStatInfo(StatType type) {
- return stats.containsKey(type) ? stats.get(type) : type.getDefault();
+ @NotNull
+ private LinearValue getStatInfo(String stat) {
+ LinearValue found = stats.get(stat);
+ return found == null ? StatInfo.valueOf(stat).getDefaultFormula() : found;
}
@Override
@@ -394,6 +391,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
return obj instanceof PlayerClass && ((PlayerClass) obj).id.equals(id);
}
+ @Nullable
public String getActionBar() {
return actionBarFormat;
}
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java
index f5d2698e..52e06d1f 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java
@@ -6,15 +6,15 @@ import java.util.Map.Entry;
import java.util.Set;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
+import net.Indyuce.mmocore.manager.data.PlayerDataManager;
+import net.Indyuce.mmocore.skill.RegisteredSkill;
import org.bukkit.configuration.ConfigurationSection;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
-import net.Indyuce.mmocore.skill.RegisteredSkill;
-import net.Indyuce.mmocore.manager.data.PlayerDataManager.DefaultPlayerData;
public class SavedClassInformation {
private final int level, skillPoints, attributePoints, attributeReallocationPoints;
@@ -60,7 +60,7 @@ public class SavedClassInformation {
player.getAttributes().mapPoints(), player.mapSkillLevels());
}
- public SavedClassInformation(DefaultPlayerData data) {
+ public SavedClassInformation(PlayerDataManager.DefaultPlayerData data) {
this(data.getLevel(), 0, data.getSkillPoints(), data.getAttributePoints(), data.getAttrReallocPoints());
}
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/Subclass.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/Subclass.java
index 5a088a88..9bfd4fde 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/profess/Subclass.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/Subclass.java
@@ -1,23 +1,23 @@
-package net.Indyuce.mmocore.api.player.profess;
-
-import org.apache.commons.lang.Validate;
-
-public class Subclass {
- private final PlayerClass profess;
- private final int level;
-
- public Subclass(PlayerClass profess, int level) {
- Validate.notNull(profess, "Subclass cannot be null");
-
- this.profess = profess;
- this.level = level;
- }
-
- public PlayerClass getProfess() {
- return profess;
- }
-
- public int getLevel() {
- return level;
- }
+package net.Indyuce.mmocore.api.player.profess;
+
+import org.apache.commons.lang.Validate;
+
+public class Subclass {
+ private final PlayerClass profess;
+ private final int level;
+
+ public Subclass(PlayerClass profess, int level) {
+ Validate.notNull(profess, "Subclass cannot be null");
+
+ this.profess = profess;
+ this.level = level;
+ }
+
+ public PlayerClass getProfess() {
+ return profess;
+ }
+
+ public int getLevel() {
+ return level;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/event/EventTrigger.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/event/EventTrigger.java
index 17923fbd..ac223e92 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/profess/event/EventTrigger.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/event/EventTrigger.java
@@ -3,7 +3,6 @@ package net.Indyuce.mmocore.api.player.profess.event;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
-import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import org.apache.commons.lang.Validate;
import java.util.LinkedHashSet;
@@ -26,7 +25,7 @@ public class EventTrigger {
for (String format : list)
try {
- triggers.add(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(format)));
+ triggers.addAll(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(format)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load trigger '" + format + "' from event trigger '" + event + "': " + exception.getMessage());
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/AttackEventTrigger.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/AttackEventTrigger.java
index e2b3d8e7..87f2e978 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/AttackEventTrigger.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/AttackEventTrigger.java
@@ -2,8 +2,8 @@ package net.Indyuce.mmocore.api.player.profess.event.trigger;
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
import io.lumine.mythic.lib.damage.DamageType;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
+import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/LevelUpEventTrigger.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/LevelUpEventTrigger.java
index 325aaf5d..40d25462 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/LevelUpEventTrigger.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/LevelUpEventTrigger.java
@@ -1,11 +1,11 @@
package net.Indyuce.mmocore.api.player.profess.event.trigger;
+import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
+import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
-import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
@Deprecated
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/MultipleLevelUpEventTrigger.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/MultipleLevelUpEventTrigger.java
index 20f4800b..0844a62b 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/MultipleLevelUpEventTrigger.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/event/trigger/MultipleLevelUpEventTrigger.java
@@ -1,8 +1,8 @@
package net.Indyuce.mmocore.api.player.profess.event.trigger;
import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
+import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/PlayerResource.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/PlayerResource.java
index fcbec451..d5c4de3b 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/PlayerResource.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/PlayerResource.java
@@ -1,10 +1,10 @@
package net.Indyuce.mmocore.api.player.profess.resource;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
+import net.Indyuce.mmocore.api.quest.trigger.ManaTrigger;
+import net.Indyuce.mmocore.command.rpg.admin.ResourceCommandTreeNode;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.ClassOption;
-import net.Indyuce.mmocore.api.player.stats.StatType;
-import net.Indyuce.mmocore.api.quest.trigger.ManaTrigger;
import org.bukkit.attribute.Attribute;
import java.util.function.BiConsumer;
@@ -20,27 +20,27 @@ public enum PlayerResource {
(data, amount) -> data.getPlayer().setHealth(amount)),
MANA(PlayerData::getMana,
- data -> data.getStats().getStat(StatType.MAX_MANA),
+ data -> data.getStats().getStat("MAX_MANA"),
(data, amount) -> data.giveMana(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION),
(data, amount) -> data.giveMana(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.giveMana(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.setMana(amount)),
STAMINA(PlayerData::getStamina,
- data -> data.getStats().getStat(StatType.MAX_STAMINA),
+ data -> data.getStats().getStat("MAX_STAMINA"),
(data, amount) -> data.giveStamina(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION),
(data, amount) -> data.giveStamina(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.giveStamina(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.setStamina(amount)),
STELLIUM(PlayerData::getStellium,
- data -> data.getStats().getStat(StatType.MAX_STELLIUM),
+ data -> data.getStats().getStat("MAX_STELLIUM"),
(data, amount) -> data.giveStellium(amount, PlayerResourceUpdateEvent.UpdateReason.REGENERATION),
(data, amount) -> data.giveStellium(amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.giveStellium(-amount, PlayerResourceUpdateEvent.UpdateReason.COMMAND),
(data, amount) -> data.setStellium(amount));
- private final StatType regenStat, maxRegenStat;
+ private final String regenStat, maxRegenStat;
private final ClassOption offCombatRegen;
private final Function current, max;
private final BiConsumer regen;
@@ -54,8 +54,8 @@ public enum PlayerResource {
BiConsumer give,
BiConsumer take,
BiConsumer set) {
- this.regenStat = StatType.valueOf(name() + "_REGENERATION");
- this.maxRegenStat = StatType.valueOf("MAX_" + name() + "_REGENERATION");
+ this.regenStat = name() + "_REGENERATION";
+ this.maxRegenStat = "MAX_" + name() + "_REGENERATION";
this.offCombatRegen = ClassOption.valueOf("OFF_COMBAT_" + name() + "_REGEN");
this.current = current;
this.max = max;
@@ -68,14 +68,14 @@ public enum PlayerResource {
/**
* @return Stat which corresponds to flat resource regeneration
*/
- public StatType getRegenStat() {
+ public String getRegenStat() {
return regenStat;
}
/**
* @return Stat which corresponds to resource regeneration scaling with the player's max health
*/
- public StatType getMaxRegenStat() {
+ public String getMaxRegenStat() {
return maxRegenStat;
}
@@ -112,7 +112,7 @@ public enum PlayerResource {
}
/**
- * Used by MMOCore admin commands here: {@link net.Indyuce.mmocore.command.rpg.admin.ResourceCommandTreeNode}
+ * Used by MMOCore admin commands here: {@link ResourceCommandTreeNode}
*/
public BiConsumer getConsumer(ManaTrigger.Operation operation) {
switch (operation) {
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/ResourceRegeneration.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/ResourceRegeneration.java
index 071fe4b7..6062cf11 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/ResourceRegeneration.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/resource/ResourceRegeneration.java
@@ -1,7 +1,7 @@
package net.Indyuce.mmocore.api.player.profess.resource;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java b/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java
index be0912c7..56204d7f 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/stats/PlayerStats.java
@@ -6,19 +6,16 @@ import io.lumine.mythic.lib.api.stat.StatMap;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.modifier.ModifierType;
+import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.Profession;
-import net.Indyuce.mmocore.skill.ClassSkill;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Locale;
+import net.Indyuce.mmocore.player.stats.StatInfo;
public class PlayerStats {
private final PlayerData data;
/**
- * Utilclass to easily manipulate the MMOLib stat map
+ * Util class to easily manipulate the MMOLib stat map
*
* @param data Playerdata
*/
@@ -34,6 +31,7 @@ public class PlayerStats {
return data.getMMOPlayerData().getStatMap();
}
+ @Deprecated
public StatInstance getInstance(StatType stat) {
return getMap().getInstance(stat.name());
}
@@ -42,35 +40,26 @@ public class PlayerStats {
return getMap().getInstance(stat);
}
- /**
- * Allows for stat type enum to have dynamic professions.
- * ID FORMAT: STAT_TYPE_HERE_PROFESSION_HERE
- *
- * @param type the type of stat
- * @param profession the stat's specific permission
- * @return instance of found stat
- * @author Ehhthan
- */
- @NotNull
- public StatInstance getInstance(StatType type, @Nullable Profession profession) {
- if (profession == null)
- return getInstance(type);
- else {
- String id = (type.name() + '_' + profession.getId()).replace('-', '_').replace(' ', '_').toUpperCase(Locale.ROOT);
- return getInstance(id);
- }
- }
-
- /*
- * applies relative attributes on the base stat too
- */
- public double getStat(StatType stat) {
+ public double getStat(String stat) {
return getInstance(stat).getTotal();
}
- public double getBase(StatType stat) {
- return data.getProfess().calculateStat(stat,
- stat.hasProfession() ? data.getCollectionSkills().getLevel(stat.getProfession()) : data.getLevel());
+ /**
+ * MMOCore base stat value differs from the on in MythicLib.
+ *
+ * MythicLib: the base stat value is only defined for stats
+ * which are based on vanilla player attributes. It corresponds
+ * to the stat amount any player has with NO attribute modifier whatsoever.
+ *
+ * MMOCore: the base stat value corresponds to the stat amount
+ * the player CLASS grants. It can be similar or equal to the one
+ * in MMOCore but it really is completely different.
+ *
+ * @return MMOCore base stat value
+ */
+ public double getBase(String stat) {
+ Profession profession = StatInfo.valueOf(stat).profession;
+ return data.getProfess().calculateStat(stat, profession == null ? data.getLevel() : data.getCollectionSkills().getLevel(profession));
}
/**
@@ -81,7 +70,7 @@ public class PlayerStats {
* see {@link PlayerData#update()} for more info
*/
public synchronized void updateStats() {
- for (StatType stat : StatType.values()) {
+ for (StatType stat : StatType.values()) { // TODO fix
StatInstance instance = getMap().getInstance(stat.name());
StatInstance.ModifierPacket packet = instance.newPacket();
@@ -89,7 +78,7 @@ public class PlayerStats {
packet.removeIf(str -> str.equals("mmocoreClass"));
// Add newest one
- double total = getBase(stat) - instance.getBase();
+ double total = getBase(stat.name()) - instance.getBase();
if (total != 0)
packet.addModifier(new StatModifier("mmocoreClass", stat.name(), total, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER));
diff --git a/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java b/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java
index 9f66f9bf..6adbde42 100644
--- a/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java
+++ b/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java
@@ -1,14 +1,14 @@
package net.Indyuce.mmocore.api.player.stats;
-import io.lumine.mythic.lib.MythicLib;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.Indyuce.mmocore.experience.Profession;
-import org.bukkit.configuration.file.FileConfiguration;
+import net.Indyuce.mmocore.player.stats.StatInfo;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import java.text.DecimalFormat;
+import java.util.Objects;
+@Deprecated
public enum StatType {
// Vanilla stats
@@ -87,17 +87,17 @@ public enum StatType {
/**
* Reduces amount of tugs needed to fish
*/
- FISHING_STRENGTH("fishing"),
+ FISHING_STRENGTH,
/**
* Chance of instant success when fishing
*/
- CRITICAL_FISHING_CHANCE("fishing"),
+ CRITICAL_FISHING_CHANCE,
/**
* Chance of crit fishing failure
*/
- CRITICAL_FISHING_FAILURE_CHANCE("fishing"),
+ CRITICAL_FISHING_FAILURE_CHANCE,
/**
* Chance of dropping more minerals when mining.
@@ -114,49 +114,35 @@ public enum StatType {
*/
LUCK_OF_THE_FIELD;
- private String profession;
-
- private LinearValue defaultInfo;
- private DecimalFormat format;
-
- StatType() {
- // Completely custom stat
- }
-
- @SuppressWarnings("SameParameterValue")
- StatType(String profession) {
- this.profession = profession;
- }
-
+ @Deprecated
public String getProfession() {
- return profession;
+ return findProfession().getId();
}
+ @Deprecated
+ @Nullable
public Profession findProfession() {
- return MMOCore.plugin.professionManager.get(profession);
+ return StatInfo.valueOf(name()).profession;
}
+ @Deprecated
public boolean hasProfession() {
- return profession != null;
+ return findProfession() != null;
}
+ @Deprecated
+ @NotNull
public LinearValue getDefault() {
- return defaultInfo;
+ return StatInfo.valueOf(name()).getDefaultFormula();
}
+ @Deprecated
public boolean matches(Profession profession) {
- return this.profession != null && this.profession.equals(profession.getId());
+ return Objects.equals(findProfession(), profession);
}
+ @Deprecated
public String format(double value) {
- return format.format(value);
- }
-
- public static void load() {
- FileConfiguration config = new ConfigFile("stats").getConfig();
- for (StatType stat : values()) {
- stat.defaultInfo = config.contains("default." + stat.name()) ? new LinearValue(config.getConfigurationSection("default." + stat.name())) : new LinearValue(0, 0);
- stat.format = MythicLib.plugin.getMMOConfig().newDecimalFormat(config.contains("decimal-format." + stat.name()) ? config.getString("decimal-format." + stat.name()) : "0.#");
- }
+ return StatInfo.valueOf(name()).format(value);
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/api/quest/PlayerQuests.java b/src/main/java/net/Indyuce/mmocore/api/quest/PlayerQuests.java
index 5a3d54ab..7929032c 100644
--- a/src/main/java/net/Indyuce/mmocore/api/quest/PlayerQuests.java
+++ b/src/main/java/net/Indyuce/mmocore/api/quest/PlayerQuests.java
@@ -100,6 +100,7 @@ public class PlayerQuests implements Closable {
}
}
+
if (jo.has("finished"))
for (Entry entry : jo.getAsJsonObject("finished").entrySet())
finished.put(entry.getKey(), entry.getValue().getAsLong());
diff --git a/src/main/java/net/Indyuce/mmocore/api/quest/objective/ClickonObjective.java b/src/main/java/net/Indyuce/mmocore/api/quest/objective/ClickonObjective.java
index 506b13c2..c3e8b0ed 100644
--- a/src/main/java/net/Indyuce/mmocore/api/quest/objective/ClickonObjective.java
+++ b/src/main/java/net/Indyuce/mmocore/api/quest/objective/ClickonObjective.java
@@ -1,5 +1,7 @@
package net.Indyuce.mmocore.api.quest.objective;
+import net.Indyuce.mmocore.api.quest.ObjectiveProgress;
+import net.Indyuce.mmocore.api.quest.QuestProgress;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -11,8 +13,6 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
-import net.Indyuce.mmocore.api.quest.ObjectiveProgress;
-import net.Indyuce.mmocore.api.quest.QuestProgress;
import io.lumine.mythic.lib.api.MMOLineConfig;
public class ClickonObjective extends Objective {
diff --git a/src/main/java/net/Indyuce/mmocore/api/quest/objective/GoToObjective.java b/src/main/java/net/Indyuce/mmocore/api/quest/objective/GoToObjective.java
index ee85470a..59e65860 100644
--- a/src/main/java/net/Indyuce/mmocore/api/quest/objective/GoToObjective.java
+++ b/src/main/java/net/Indyuce/mmocore/api/quest/objective/GoToObjective.java
@@ -1,5 +1,7 @@
package net.Indyuce.mmocore.api.quest.objective;
+import net.Indyuce.mmocore.api.quest.ObjectiveProgress;
+import net.Indyuce.mmocore.api.quest.QuestProgress;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -10,8 +12,6 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
-import net.Indyuce.mmocore.api.quest.ObjectiveProgress;
-import net.Indyuce.mmocore.api.quest.QuestProgress;
import io.lumine.mythic.lib.api.MMOLineConfig;
public class GoToObjective extends Objective {
diff --git a/src/main/java/net/Indyuce/mmocore/api/quest/objective/KillMobObjective.java b/src/main/java/net/Indyuce/mmocore/api/quest/objective/KillMobObjective.java
index 7af8e7fd..9cfaee40 100644
--- a/src/main/java/net/Indyuce/mmocore/api/quest/objective/KillMobObjective.java
+++ b/src/main/java/net/Indyuce/mmocore/api/quest/objective/KillMobObjective.java
@@ -1,13 +1,13 @@
package net.Indyuce.mmocore.api.quest.objective;
import io.lumine.mythic.lib.api.event.PlayerKillEntityEvent;
+import net.Indyuce.mmocore.api.quest.ObjectiveProgress;
+import net.Indyuce.mmocore.api.quest.QuestProgress;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
-import net.Indyuce.mmocore.api.quest.ObjectiveProgress;
-import net.Indyuce.mmocore.api.quest.QuestProgress;
import io.lumine.mythic.lib.api.MMOLineConfig;
public class KillMobObjective extends Objective {
diff --git a/src/main/java/net/Indyuce/mmocore/api/quest/objective/MineBlockObjective.java b/src/main/java/net/Indyuce/mmocore/api/quest/objective/MineBlockObjective.java
index 59ddf77c..c01a2c38 100644
--- a/src/main/java/net/Indyuce/mmocore/api/quest/objective/MineBlockObjective.java
+++ b/src/main/java/net/Indyuce/mmocore/api/quest/objective/MineBlockObjective.java
@@ -1,5 +1,8 @@
package net.Indyuce.mmocore.api.quest.objective;
+import net.Indyuce.mmocore.api.event.CustomBlockMineEvent;
+import net.Indyuce.mmocore.api.quest.ObjectiveProgress;
+import net.Indyuce.mmocore.api.quest.QuestProgress;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.EventHandler;
@@ -7,9 +10,6 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
-import net.Indyuce.mmocore.api.event.CustomBlockMineEvent;
-import net.Indyuce.mmocore.api.quest.ObjectiveProgress;
-import net.Indyuce.mmocore.api.quest.QuestProgress;
import io.lumine.mythic.lib.api.MMOLineConfig;
public class MineBlockObjective extends Objective {
diff --git a/src/main/java/net/Indyuce/mmocore/api/quest/objective/Objective.java b/src/main/java/net/Indyuce/mmocore/api/quest/objective/Objective.java
index 3f23fa9e..35305647 100644
--- a/src/main/java/net/Indyuce/mmocore/api/quest/objective/Objective.java
+++ b/src/main/java/net/Indyuce/mmocore/api/quest/objective/Objective.java
@@ -30,7 +30,7 @@ public abstract class Objective {
for (String key : config.getStringList("triggers"))
try {
- triggers.add(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(key)));
+ triggers.addAll(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(key)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load trigger '" + key + "' from objective '" + id + "': " + exception.getMessage());
diff --git a/src/main/java/net/Indyuce/mmocore/api/quest/trigger/ExperienceTrigger.java b/src/main/java/net/Indyuce/mmocore/api/quest/trigger/ExperienceTrigger.java
index 4a84e0b0..6a9c0b9c 100644
--- a/src/main/java/net/Indyuce/mmocore/api/quest/trigger/ExperienceTrigger.java
+++ b/src/main/java/net/Indyuce/mmocore/api/quest/trigger/ExperienceTrigger.java
@@ -1,12 +1,11 @@
package net.Indyuce.mmocore.api.quest.trigger;
+import net.Indyuce.mmocore.experience.EXPSource;
+import net.Indyuce.mmocore.experience.SimpleExperienceObject;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
-import net.Indyuce.mmocore.experience.dispenser.ProfessionExperienceDispenser;
-import net.Indyuce.mmocore.experience.dispenser.SimpleExperienceDispenser;
import org.apache.commons.lang.Validate;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
import io.lumine.mythic.lib.api.MMOLineConfig;
@@ -28,9 +27,9 @@ public class ExperienceTrigger extends Trigger {
if (config.contains("profession")) {
String id = config.getString("profession").toLowerCase().replace("_", "-");
Validate.isTrue(MMOCore.plugin.professionManager.has(id), "Could not find profession");
- dispenser = new ProfessionExperienceDispenser(MMOCore.plugin.professionManager.get(id));
+ dispenser = MMOCore.plugin.professionManager.get(id);
} else
- dispenser = new SimpleExperienceDispenser();
+ dispenser = new SimpleExperienceObject();
amount = new RandomAmount(config.getString("amount"));
source = config.contains("source") ? EXPSource.valueOf(config.getString("source").toUpperCase()) : EXPSource.QUEST;
}
diff --git a/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java b/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java
index bc799e79..264dcb3b 100644
--- a/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java
+++ b/src/main/java/net/Indyuce/mmocore/api/util/MMOCoreUtils.java
@@ -1,9 +1,10 @@
package net.Indyuce.mmocore.api.util;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
import io.lumine.mythic.lib.MythicLib;
+import io.lumine.mythic.lib.hologram.Hologram;
import io.lumine.mythic.lib.version.VersionMaterial;
-import io.lumine.mythic.utils.holograms.Hologram;
-import io.lumine.mythic.utils.serialize.Position;
import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -104,8 +105,7 @@ public class MMOCoreUtils {
* @param message Message to display
*/
public static void displayIndicator(Location loc, String message) {
- Hologram holo = Hologram.create(Position.of(loc), Arrays.asList(message));
- holo.spawn();
+ Hologram holo = Hologram.create(loc, Arrays.asList(message));
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> holo.despawn(), 20);
}
@@ -180,6 +180,27 @@ public class MMOCoreUtils {
return result.toString();
}
+
+ public static Collection jsonArrayToList(String json) {
+ return new ArrayList<>(Arrays.asList(MythicLib.plugin.getJson().parse(json, String[].class)));
+ }
+
+ public static String arrayToJsonString(Collection array) {
+ JsonArray object = new JsonArray();
+ for (String str : array) {
+ object.add(str);
+ }
+ return object.toString();
+ }
+
+ public static String entrySetToJsonString(Set> entrySet) {
+ JsonObject object = new JsonObject();
+ for (Map.Entry entry : entrySet) {
+ object.addProperty(entry.getKey(), entry.getValue());
+ }
+ return object.toString();
+ }
+
/**
* Method to get all entities surrounding a location. This method does not
* take every entity in the world but rather takes all the entities from the
@@ -236,7 +257,7 @@ public class MMOCoreUtils {
*/
public static void decreaseDurability(Player player, EquipmentSlot slot, int damage) {
ItemStack item = player.getInventory().getItem(slot);
- if (!item.hasItemMeta() || !(item.getItemMeta() instanceof Damageable) || item.getItemMeta().isUnbreakable())
+ if (item == null || item.getType().getMaxDurability() == 0 || !item.hasItemMeta() || !(item.getItemMeta() instanceof Damageable) || item.getItemMeta().isUnbreakable())
return;
PlayerItemDamageEvent event = new PlayerItemDamageEvent(player, item, damage);
diff --git a/src/main/java/net/Indyuce/mmocore/api/util/debug/ActionBarRunnable.java b/src/main/java/net/Indyuce/mmocore/api/util/debug/ActionBarRunnable.java
index 452dd438..bc9fbe41 100644
--- a/src/main/java/net/Indyuce/mmocore/api/util/debug/ActionBarRunnable.java
+++ b/src/main/java/net/Indyuce/mmocore/api/util/debug/ActionBarRunnable.java
@@ -1,32 +1,32 @@
-package net.Indyuce.mmocore.api.util.debug;
-
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
-import org.bukkit.scheduler.BukkitRunnable;
-
-import net.Indyuce.mmocore.MMOCore;
-import net.md_5.bungee.api.ChatMessageType;
-import net.md_5.bungee.api.chat.TextComponent;
-
-public class ActionBarRunnable extends BukkitRunnable {
-
- /*
- * how to enable it: set 'debug' to true in the config and use the
- * 'debug-action-bar' string parameter. hot changes, only need /mmocore
- * reload.
- */
-
- @Override
- public void run() {
- Bukkit.getOnlinePlayers().forEach(this::sendActionBar);
- }
-
- private void sendActionBar(Player player) {
- player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(MMOCore.plugin.placeholderParser.parse(player, getMessage())));
- }
-
- private String getMessage() {
- String str = MMOCore.plugin.getConfig().getString("debug-action-bar.format");
- return str == null ? "" : str;
- }
-}
+package net.Indyuce.mmocore.api.util.debug;
+
+import net.Indyuce.mmocore.MMOCore;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import net.md_5.bungee.api.ChatMessageType;
+import net.md_5.bungee.api.chat.TextComponent;
+
+public class ActionBarRunnable extends BukkitRunnable {
+
+ /*
+ * how to enable it: set 'debug' to true in the config and use the
+ * 'debug-action-bar' string parameter. hot changes, only need /mmocore
+ * reload.
+ */
+
+ @Override
+ public void run() {
+ Bukkit.getOnlinePlayers().forEach(this::sendActionBar);
+ }
+
+ private void sendActionBar(Player player) {
+ player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(MMOCore.plugin.placeholderParser.parse(player, getMessage())));
+ }
+
+ private String getMessage() {
+ String str = MMOCore.plugin.getConfig().getString("debug-action-bar.format");
+ return str == null ? "" : str;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/api/util/debug/DebugMode.java b/src/main/java/net/Indyuce/mmocore/api/util/debug/DebugMode.java
index b5033900..a4b00706 100644
--- a/src/main/java/net/Indyuce/mmocore/api/util/debug/DebugMode.java
+++ b/src/main/java/net/Indyuce/mmocore/api/util/debug/DebugMode.java
@@ -1,25 +1,25 @@
-package net.Indyuce.mmocore.api.util.debug;
-
-import net.Indyuce.mmocore.MMOCore;
-
-public class DebugMode {
- /*
- * Debug Levels:
- * 1:
- * - Print WorldGuard Flag Registry
- * 2:
- * - Print Profession Trigger Things
- * 3:
- * - Debug Action Bar
- */
- public static int level = 0;
-
- public static void setLevel(int i) {
- level = i;
- }
-
- public static void enableActionBar() {
- if (level > 2 && MMOCore.plugin.getConfig().getBoolean("debug-action-bar.enabled"))
- new ActionBarRunnable().runTaskTimer(MMOCore.plugin, 0, 10);
- }
-}
+package net.Indyuce.mmocore.api.util.debug;
+
+import net.Indyuce.mmocore.MMOCore;
+
+public class DebugMode {
+ /*
+ * Debug Levels:
+ * 1:
+ * - Print WorldGuard Flag Registry
+ * 2:
+ * - Print Profession Trigger Things
+ * 3:
+ * - Debug Action Bar
+ */
+ public static int level = 0;
+
+ public static void setLevel(int i) {
+ level = i;
+ }
+
+ public static void enableActionBar() {
+ if (level > 2 && MMOCore.plugin.getConfig().getBoolean("debug-action-bar.enabled"))
+ new ActionBarRunnable().runTaskTimer(MMOCore.plugin, 0, 10);
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/api/util/input/AnvilGUI.java b/src/main/java/net/Indyuce/mmocore/api/util/input/AnvilGUI.java
index 45e3a4f4..2363716b 100644
--- a/src/main/java/net/Indyuce/mmocore/api/util/input/AnvilGUI.java
+++ b/src/main/java/net/Indyuce/mmocore/api/util/input/AnvilGUI.java
@@ -1,5 +1,6 @@
package net.Indyuce.mmocore.api.util.input;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -11,7 +12,6 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.Consumer;
-import net.Indyuce.mmocore.MMOCore;
import io.lumine.mythic.lib.MythicLib;
public class AnvilGUI extends PlayerInput {
diff --git a/src/main/java/net/Indyuce/mmocore/api/util/input/ChatInput.java b/src/main/java/net/Indyuce/mmocore/api/util/input/ChatInput.java
index 001e6214..a5b94106 100644
--- a/src/main/java/net/Indyuce/mmocore/api/util/input/ChatInput.java
+++ b/src/main/java/net/Indyuce/mmocore/api/util/input/ChatInput.java
@@ -1,5 +1,6 @@
package net.Indyuce.mmocore.api.util.input;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -8,8 +9,6 @@ import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.util.Consumer;
-import net.Indyuce.mmocore.MMOCore;
-
public class ChatInput extends PlayerInput {
public ChatInput(Player player, InputType type, Consumer output) {
super(player, output);
diff --git a/src/main/java/net/Indyuce/mmocore/api/util/input/PlayerInput.java b/src/main/java/net/Indyuce/mmocore/api/util/input/PlayerInput.java
index aa1f374f..e2934f3f 100644
--- a/src/main/java/net/Indyuce/mmocore/api/util/input/PlayerInput.java
+++ b/src/main/java/net/Indyuce/mmocore/api/util/input/PlayerInput.java
@@ -1,12 +1,11 @@
package net.Indyuce.mmocore.api.util.input;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.util.Consumer;
-import net.Indyuce.mmocore.MMOCore;
-
public abstract class PlayerInput implements Listener {
private final Player player;
private final Consumer output;
diff --git a/src/main/java/net/Indyuce/mmocore/api/util/math/formula/LinearValue.java b/src/main/java/net/Indyuce/mmocore/api/util/math/formula/LinearValue.java
index 5bd0d5ef..972bf5b2 100644
--- a/src/main/java/net/Indyuce/mmocore/api/util/math/formula/LinearValue.java
+++ b/src/main/java/net/Indyuce/mmocore/api/util/math/formula/LinearValue.java
@@ -110,4 +110,16 @@ public class LinearValue {
return value;
}
+
+ @Override
+ public String toString() {
+ return "LinearValue{" +
+ "base=" + base +
+ ", perLevel=" + perLevel +
+ ", min=" + min +
+ ", max=" + max +
+ ", hasmin=" + hasmin +
+ ", hasmax=" + hasmax +
+ '}';
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/command/AttributesCommand.java b/src/main/java/net/Indyuce/mmocore/command/AttributesCommand.java
index 4c5240b0..8f800686 100644
--- a/src/main/java/net/Indyuce/mmocore/command/AttributesCommand.java
+++ b/src/main/java/net/Indyuce/mmocore/command/AttributesCommand.java
@@ -1,5 +1,7 @@
package net.Indyuce.mmocore.command;
+import net.Indyuce.mmocore.api.event.MMOCommandEvent;
+import net.Indyuce.mmocore.manager.InventoryManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@@ -7,9 +9,7 @@ import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.manager.InventoryManager;
public class AttributesCommand extends BukkitCommand {
public AttributesCommand(ConfigurationSection config) {
diff --git a/src/main/java/net/Indyuce/mmocore/command/ClassCommand.java b/src/main/java/net/Indyuce/mmocore/command/ClassCommand.java
index 2691ad07..3927741d 100644
--- a/src/main/java/net/Indyuce/mmocore/command/ClassCommand.java
+++ b/src/main/java/net/Indyuce/mmocore/command/ClassCommand.java
@@ -1,5 +1,7 @@
package net.Indyuce.mmocore.command;
+import net.Indyuce.mmocore.api.event.MMOCommandEvent;
+import net.Indyuce.mmocore.manager.InventoryManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@@ -7,9 +9,7 @@ import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.manager.InventoryManager;
public class ClassCommand extends BukkitCommand {
public ClassCommand(ConfigurationSection config) {
diff --git a/src/main/java/net/Indyuce/mmocore/command/DepositCommand.java b/src/main/java/net/Indyuce/mmocore/command/DepositCommand.java
index 214334e4..75c8bd69 100644
--- a/src/main/java/net/Indyuce/mmocore/command/DepositCommand.java
+++ b/src/main/java/net/Indyuce/mmocore/command/DepositCommand.java
@@ -1,5 +1,6 @@
package net.Indyuce.mmocore.command;
+import net.Indyuce.mmocore.gui.eco.DepositMenu;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@@ -7,8 +8,6 @@ import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.gui.eco.DepositMenu;
-
public class DepositCommand extends BukkitCommand {
public DepositCommand(ConfigurationSection config) {
super(config.getString("main"));
diff --git a/src/main/java/net/Indyuce/mmocore/command/FriendsCommand.java b/src/main/java/net/Indyuce/mmocore/command/FriendsCommand.java
index e4ad152e..41af99ec 100644
--- a/src/main/java/net/Indyuce/mmocore/command/FriendsCommand.java
+++ b/src/main/java/net/Indyuce/mmocore/command/FriendsCommand.java
@@ -2,11 +2,11 @@ package net.Indyuce.mmocore.command;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.MMOCommandEvent;
+import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.social.FriendRequest;
import net.Indyuce.mmocore.api.player.social.Request;
-import net.Indyuce.mmocore.manager.InventoryManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/net/Indyuce/mmocore/command/GuildCommand.java b/src/main/java/net/Indyuce/mmocore/command/GuildCommand.java
index 30f6efc9..c67f8b85 100644
--- a/src/main/java/net/Indyuce/mmocore/command/GuildCommand.java
+++ b/src/main/java/net/Indyuce/mmocore/command/GuildCommand.java
@@ -2,6 +2,9 @@ package net.Indyuce.mmocore.command;
import java.util.UUID;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.event.MMOCommandEvent;
+import net.Indyuce.mmocore.manager.InventoryManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
@@ -10,12 +13,9 @@ import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.social.Request;
import net.Indyuce.mmocore.guild.provided.GuildInvite;
-import net.Indyuce.mmocore.manager.InventoryManager;
public class GuildCommand extends BukkitCommand {
diff --git a/src/main/java/net/Indyuce/mmocore/command/MMOCoreCommandTreeRoot.java b/src/main/java/net/Indyuce/mmocore/command/MMOCoreCommandTreeRoot.java
index f80d57c3..dcefd387 100644
--- a/src/main/java/net/Indyuce/mmocore/command/MMOCoreCommandTreeRoot.java
+++ b/src/main/java/net/Indyuce/mmocore/command/MMOCoreCommandTreeRoot.java
@@ -33,6 +33,5 @@ public class MMOCoreCommandTreeRoot extends CommandTreeRoot implements CommandEx
addChild(new BoosterCommandTreeNode(this));
addChild(new WaypointsCommandTreeNode(this));
addChild(new QuestCommandTreeNode(this));
- addChild(new WaypointsCommandTreeNode(this));
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/command/PartyCommand.java b/src/main/java/net/Indyuce/mmocore/command/PartyCommand.java
index 603ca617..ab7a6bef 100644
--- a/src/main/java/net/Indyuce/mmocore/command/PartyCommand.java
+++ b/src/main/java/net/Indyuce/mmocore/command/PartyCommand.java
@@ -2,6 +2,9 @@ package net.Indyuce.mmocore.command;
import java.util.UUID;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.event.MMOCommandEvent;
+import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -11,12 +14,9 @@ import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.party.provided.PartyInvite;
import net.Indyuce.mmocore.api.player.social.Request;
-import net.Indyuce.mmocore.manager.InventoryManager;
public class PartyCommand extends BukkitCommand {
diff --git a/src/main/java/net/Indyuce/mmocore/command/PlayerStatsCommand.java b/src/main/java/net/Indyuce/mmocore/command/PlayerStatsCommand.java
index a8bfe6fa..edcbe743 100644
--- a/src/main/java/net/Indyuce/mmocore/command/PlayerStatsCommand.java
+++ b/src/main/java/net/Indyuce/mmocore/command/PlayerStatsCommand.java
@@ -1,5 +1,7 @@
package net.Indyuce.mmocore.command;
+import net.Indyuce.mmocore.api.event.MMOCommandEvent;
+import net.Indyuce.mmocore.manager.InventoryManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@@ -7,9 +9,7 @@ import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.manager.InventoryManager;
public class PlayerStatsCommand extends BukkitCommand {
public PlayerStatsCommand(ConfigurationSection config) {
diff --git a/src/main/java/net/Indyuce/mmocore/command/QuestsCommand.java b/src/main/java/net/Indyuce/mmocore/command/QuestsCommand.java
index 2eebc76b..4bf898a5 100644
--- a/src/main/java/net/Indyuce/mmocore/command/QuestsCommand.java
+++ b/src/main/java/net/Indyuce/mmocore/command/QuestsCommand.java
@@ -1,14 +1,14 @@
package net.Indyuce.mmocore.command;
+import net.Indyuce.mmocore.api.event.MMOCommandEvent;
+import net.Indyuce.mmocore.manager.InventoryManager;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.manager.InventoryManager;
public class QuestsCommand extends BukkitCommand {
public QuestsCommand(ConfigurationSection config) {
diff --git a/src/main/java/net/Indyuce/mmocore/command/SkillsCommand.java b/src/main/java/net/Indyuce/mmocore/command/SkillsCommand.java
index a13b5c1f..cd49dcf6 100644
--- a/src/main/java/net/Indyuce/mmocore/command/SkillsCommand.java
+++ b/src/main/java/net/Indyuce/mmocore/command/SkillsCommand.java
@@ -1,15 +1,15 @@
package net.Indyuce.mmocore.command;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.event.MMOCommandEvent;
+import net.Indyuce.mmocore.manager.InventoryManager;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.manager.InventoryManager;
public class SkillsCommand extends BukkitCommand {
public SkillsCommand(ConfigurationSection config) {
diff --git a/src/main/java/net/Indyuce/mmocore/command/WaypointsCommand.java b/src/main/java/net/Indyuce/mmocore/command/WaypointsCommand.java
index 0e958636..9726333c 100644
--- a/src/main/java/net/Indyuce/mmocore/command/WaypointsCommand.java
+++ b/src/main/java/net/Indyuce/mmocore/command/WaypointsCommand.java
@@ -1,12 +1,12 @@
package net.Indyuce.mmocore.command;
+import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.api.event.MMOCommandEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.manager.InventoryManager;
diff --git a/src/main/java/net/Indyuce/mmocore/command/WithdrawCommand.java b/src/main/java/net/Indyuce/mmocore/command/WithdrawCommand.java
index 4b5c03e2..361b38b2 100644
--- a/src/main/java/net/Indyuce/mmocore/command/WithdrawCommand.java
+++ b/src/main/java/net/Indyuce/mmocore/command/WithdrawCommand.java
@@ -1,5 +1,6 @@
package net.Indyuce.mmocore.command;
+import net.Indyuce.mmocore.MMOCore;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -9,7 +10,6 @@ import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.eco.Withdraw;
public class WithdrawCommand extends BukkitCommand {
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/ReloadCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/ReloadCommandTreeNode.java
index c85df307..c7df1d41 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/ReloadCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/ReloadCommandTreeNode.java
@@ -1,10 +1,9 @@
package net.Indyuce.mmocore.command.rpg;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
public class ReloadCommandTreeNode extends CommandTreeNode {
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/AdminCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/AdminCommandTreeNode.java
index d7e2e630..88998b14 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/AdminCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/AdminCommandTreeNode.java
@@ -15,6 +15,7 @@ public class AdminCommandTreeNode extends CommandTreeNode {
addChild(new InfoCommandTreeNode(this));
addChild(new ClassCommandTreeNode(this));
addChild(new ForceClassCommandTreeNode(this));
+ addChild(new TransferDataTreeNode(this));
addChild(new ExperienceCommandTreeNode(this));
addChild(new LevelCommandTreeNode(this));
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/AttributeCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/AttributeCommandTreeNode.java
index c1682b00..f4adcb6d 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/AttributeCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/AttributeCommandTreeNode.java
@@ -1,15 +1,15 @@
package net.Indyuce.mmocore.command.rpg.admin;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
+import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.command.CommandVerbose;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
-import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes.AttributeInstance;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
@@ -61,7 +61,7 @@ public class AttributeCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
- AttributeInstance instance = PlayerData.get(player).getAttributes().getInstance(attribute);
+ PlayerAttributes.AttributeInstance instance = PlayerData.get(player).getAttributes().getInstance(attribute);
instance.setBase(Math.min(attribute.getMax(), instance.getBase() + c * amount));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.ATTRIBUTE, ChatColor.GOLD + player.getName() + ChatColor.YELLOW
+ " now has " + ChatColor.GOLD + instance.getBase() + ChatColor.YELLOW + " " + attribute.getName() + ".");
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ClassCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ClassCommandTreeNode.java
index 4328fa8a..a25c10f4 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ClassCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ClassCommandTreeNode.java
@@ -1,15 +1,15 @@
package net.Indyuce.mmocore.command.rpg.admin;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
+import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.command.CommandVerbose;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ExperienceCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ExperienceCommandTreeNode.java
index b556d3d7..e025fc2c 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ExperienceCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ExperienceCommandTreeNode.java
@@ -1,12 +1,13 @@
package net.Indyuce.mmocore.command.rpg.admin;
+import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.command.CommandVerbose;
import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
-import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.PlayerProfessions;
import net.Indyuce.mmocore.experience.Profession;
import org.apache.commons.lang.Validate;
@@ -23,9 +24,9 @@ public class ExperienceCommandTreeNode extends CommandTreeNode {
addChild(new ActionCommandTreeNode(this, "set", PlayerData::setExperience, PlayerProfessions::setExperience));
addChild(new ActionCommandTreeNode(this, "give", (data, value) -> data.giveExperience(value, EXPSource.COMMAND), (professions, profession,
- value) -> professions.giveExperience(profession, value, EXPSource.COMMAND, professions.getPlayerData().getPlayer().getLocation())));
+ value) -> professions.giveExperience(profession, value, EXPSource.COMMAND)));
addChild(new ActionCommandTreeNode(this, "take", (data, value) -> data.giveExperience(-value, EXPSource.COMMAND), (professions, profession,
- value) -> professions.giveExperience(profession, -value, EXPSource.COMMAND, professions.getPlayerData().getPlayer().getLocation())));
+ value) -> professions.giveExperience(profession, -value, EXPSource.COMMAND)));
}
public static class ActionCommandTreeNode extends CommandTreeNode {
@@ -58,8 +59,8 @@ public class ExperienceCommandTreeNode extends CommandTreeNode {
int amount;
try {
amount = Integer.parseInt(args[5]);
- Validate.isTrue(amount > 0);
- } catch (NumberFormatException exception) {
+ Validate.isTrue(amount >= 0);
+ } catch (RuntimeException exception) {
sender.sendMessage(ChatColor.RED + args[5] + " is not a valid number.");
return CommandResult.FAILURE;
}
@@ -68,7 +69,7 @@ public class ExperienceCommandTreeNode extends CommandTreeNode {
if (args[4].equalsIgnoreCase("main")) {
main.accept(data, amount);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.EXPERIENCE, ChatColor.GOLD + player.getName() + ChatColor.YELLOW
- + " now has " + ChatColor.GOLD + data.getExperience() + ChatColor.YELLOW + " EXP.");
+ + " now has " + ChatColor.GOLD + MythicLib.plugin.getMMOConfig().decimal.format(data.getExperience()) + ChatColor.YELLOW + " EXP.");
return CommandResult.SUCCESS;
}
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ForceClassCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ForceClassCommandTreeNode.java
index 17bdcbce..6fded3c4 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ForceClassCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ForceClassCommandTreeNode.java
@@ -1,14 +1,14 @@
package net.Indyuce.mmocore.command.rpg.admin;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.command.CommandVerbose;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/InfoCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/InfoCommandTreeNode.java
index 4b26626e..7590a394 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/InfoCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/InfoCommandTreeNode.java
@@ -1,11 +1,12 @@
package net.Indyuce.mmocore.command.rpg.admin;
+import io.lumine.mythic.lib.MythicLib;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.api.player.PlayerData;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
@@ -33,7 +34,7 @@ public class InfoCommandTreeNode extends CommandTreeNode {
sender.sendMessage(ChatColor.YELLOW + "----------------------------------------------------");
sender.sendMessage(ChatColor.YELLOW + "Class: " + ChatColor.GOLD + playerData.getProfess().getName());
sender.sendMessage(ChatColor.YELLOW + "Level: " + ChatColor.GOLD + playerData.getLevel());
- sender.sendMessage(ChatColor.YELLOW + "Experience: " + ChatColor.GOLD + playerData.getExperience() + ChatColor.YELLOW + " / " + ChatColor.GOLD
+ sender.sendMessage(ChatColor.YELLOW + "Experience: " + ChatColor.GOLD + MythicLib.plugin.getMMOConfig().decimal.format(playerData.getExperience()) + ChatColor.YELLOW + " / " + ChatColor.GOLD
+ playerData.getLevelUpExperience());
sender.sendMessage(ChatColor.YELLOW + "Class Points: " + ChatColor.GOLD + playerData.getClassPoints());
sender.sendMessage(ChatColor.YELLOW + "Quests: " + ChatColor.GOLD + playerData.getQuestData().getFinishedQuests().size() + ChatColor.YELLOW
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/LevelCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/LevelCommandTreeNode.java
index 512c187a..6e2d874d 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/LevelCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/LevelCommandTreeNode.java
@@ -2,14 +2,14 @@ package net.Indyuce.mmocore.command.rpg.admin;
import java.util.function.BiConsumer;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.command.CommandVerbose;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.PlayerProfessions;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.api.player.PlayerData;
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResetCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResetCommandTreeNode.java
index de2b6824..cb7df301 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResetCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResetCommandTreeNode.java
@@ -1,14 +1,14 @@
package net.Indyuce.mmocore.command.rpg.admin;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes.AttributeInstance;
import net.Indyuce.mmocore.command.CommandVerbose;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
@@ -171,7 +171,7 @@ public class ResetCommandTreeNode extends CommandTreeNode {
if (args.length > 4 && args[4].equalsIgnoreCase("-reallocate")) {
int points = 0;
- for (AttributeInstance ins : data.getAttributes().getInstances()) {
+ for (PlayerAttributes.AttributeInstance ins : data.getAttributes().getInstances()) {
points += ins.getBase();
ins.setBase(0);
}
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResourceCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResourceCommandTreeNode.java
index 9f453a35..4dc947bd 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResourceCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResourceCommandTreeNode.java
@@ -2,9 +2,9 @@ package net.Indyuce.mmocore.command.rpg.admin;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
+import net.Indyuce.mmocore.api.quest.trigger.ManaTrigger;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
-import net.Indyuce.mmocore.api.quest.trigger.ManaTrigger;
import net.Indyuce.mmocore.command.CommandVerbose;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/admin/TransferDataTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/TransferDataTreeNode.java
new file mode 100644
index 00000000..7e523fea
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/admin/TransferDataTreeNode.java
@@ -0,0 +1,108 @@
+package net.Indyuce.mmocore.command.rpg.admin;
+
+import io.lumine.mythic.lib.command.api.CommandTreeNode;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.player.SavingPlayerData;
+import net.Indyuce.mmocore.guild.provided.Guild;
+import net.Indyuce.mmocore.manager.data.DataProvider;
+import net.Indyuce.mmocore.manager.data.mysql.MySQLDataProvider;
+import net.Indyuce.mmocore.manager.data.yaml.YAMLDataProvider;
+import org.bukkit.command.CommandSender;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import java.io.File;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+
+/**
+ * This command allows to transfer data from your actual storage type
+ * to the other one which lets the user switch between storage types.
+ */
+public class TransferDataTreeNode extends CommandTreeNode {
+ public TransferDataTreeNode(CommandTreeNode parent) {
+ super(parent, "transferdata");
+ }
+
+ @Override
+ public CommandResult execute(CommandSender commandSender, String[] strings) {
+
+ final List playerUUIDs = new ArrayList<>();
+ if (MMOCore.plugin.dataProvider instanceof YAMLDataProvider) {
+ File folder = new File(MMOCore.plugin.getDataFolder() + "/userdata");
+ playerUUIDs.addAll(Arrays.stream(folder.listFiles())
+ .map(file -> UUID.fromString(file.getName().replace(".yml", "")))
+ .collect(Collectors.toList()));
+ } else {
+ ((MySQLDataProvider) MMOCore.plugin.dataProvider).getResult(
+ "SELECT uuid from mmocore_playerdata", (result) -> {
+ try {
+
+ while (result.next()) {
+ playerUUIDs.add(UUID.fromString(result.getString("uuid")));
+
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ });
+ }
+
+ List savingPlayerDataList = new ArrayList<>();
+ for (UUID uuid : playerUUIDs) {
+ MMOCore.plugin.dataProvider.getDataManager().loadSavingPlayerData(uuid, savingPlayerDataList);
+ }
+
+
+ final DataProvider provider;
+ if (MMOCore.plugin.dataProvider instanceof YAMLDataProvider) {
+ provider = new MySQLDataProvider(MMOCore.plugin.getConfig());
+ ((MySQLDataProvider) provider).load();
+ } else {
+ provider = new YAMLDataProvider();
+ }
+
+
+ //5 seconds later we put all this data into the other data storage.
+ new BukkitRunnable() {
+
+ @Override
+ public void run() {
+ try {
+ // Save player data
+ for (SavingPlayerData data : savingPlayerDataList)
+ provider.getDataManager().saveData(data);
+
+ // Save guild info
+ for (Guild guild : provider.getGuildManager().getAll())
+ provider.getGuildManager().save(guild);
+ } catch (Exception e) {
+ commandSender.sendMessage("Couldn't transfer properly the data.");
+ e.printStackTrace();
+ if (provider != null && provider instanceof MySQLDataProvider) {
+ ((MySQLDataProvider) provider).close();
+ }
+ }
+ }
+ }.runTaskLater(MMOCore.plugin, 100L);
+
+
+ //We close the connection 10 s later to avoid memory leaks.
+ new BukkitRunnable() {
+
+ @Override
+ public void run() {
+ if (provider != null && provider instanceof MySQLDataProvider) {
+ ((MySQLDataProvider) provider).close();
+ }
+ }
+ }.runTaskLater(MMOCore.plugin, 200);
+
+ return CommandResult.SUCCESS;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/booster/CreateCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/booster/CreateCommandTreeNode.java
index 99b0742d..2139d37f 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/booster/CreateCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/booster/CreateCommandTreeNode.java
@@ -2,12 +2,12 @@ package net.Indyuce.mmocore.command.rpg.booster;
import java.util.Arrays;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.experience.Booster;
import net.Indyuce.mmocore.experience.Profession;
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/booster/ListCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/booster/ListCommandTreeNode.java
index ecaba7d3..6c504fd0 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/booster/ListCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/booster/ListCommandTreeNode.java
@@ -1,10 +1,10 @@
package net.Indyuce.mmocore.command.rpg.booster;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.experience.Booster;
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
import io.lumine.mythic.lib.MythicLib;
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/booster/RemoveCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/booster/RemoveCommandTreeNode.java
index 03ce630f..4ee4186c 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/booster/RemoveCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/booster/RemoveCommandTreeNode.java
@@ -3,10 +3,10 @@ package net.Indyuce.mmocore.command.rpg.booster;
import java.util.Iterator;
import java.util.UUID;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.experience.Booster;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatModifiersCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatModifiersCommandTreeNode.java
index 38de283c..d440e4ee 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatModifiersCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatModifiersCommandTreeNode.java
@@ -1,11 +1,11 @@
package net.Indyuce.mmocore.command.rpg.debug;
+import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.stat.StatInstance;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.stats.StatType;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -15,10 +15,7 @@ public class StatModifiersCommandTreeNode extends CommandTreeNode {
public StatModifiersCommandTreeNode(CommandTreeNode parent) {
super(parent, "statmods");
- addParameter(new Parameter("", (explorer, list) -> {
- for (StatType stat : StatType.values())
- list.add(stat.name());
- }));
+ addParameter(new Parameter("", (explorer, list) -> list.add("STAT_ID")));
}
@Override
@@ -32,15 +29,7 @@ public class StatModifiersCommandTreeNode extends CommandTreeNode {
}
PlayerData data = PlayerData.get((Player) sender);
- StatType stat;
- try {
- stat = StatType.valueOf(args[2].toUpperCase().replace("-", "_").replace(" ", "_"));
- } catch (IllegalArgumentException exception) {
- sender.sendMessage(ChatColor.RED + "Could not find stat: " + args[2] + ".");
- return CommandResult.FAILURE;
- }
-
- StatInstance instance = data.getStats().getInstance(stat);
+ StatInstance instance = data.getStats().getInstance(UtilityMethods.enumName(args[2]));
sender.sendMessage("Stat Modifiers (" + instance.getKeys().size() + "):");
for (String key : instance.getKeys()) {
StatModifier mod = instance.getModifier(key);
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatValueCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatValueCommandTreeNode.java
index f13d42a4..f582ab31 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatValueCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/debug/StatValueCommandTreeNode.java
@@ -1,51 +1,36 @@
package net.Indyuce.mmocore.command.rpg.debug;
+import io.lumine.mythic.lib.UtilityMethods;
+import io.lumine.mythic.lib.command.api.CommandTreeNode;
+import io.lumine.mythic.lib.command.api.Parameter;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.player.stats.StatInfo;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.stats.StatType;
-import io.lumine.mythic.lib.command.api.CommandTreeNode;
-import io.lumine.mythic.lib.command.api.Parameter;
-
public class StatValueCommandTreeNode extends CommandTreeNode {
- public StatValueCommandTreeNode(CommandTreeNode parent) {
- super(parent, "statvalue");
+ public StatValueCommandTreeNode(CommandTreeNode parent) {
+ super(parent, "statvalue");
- addParameter(new Parameter("", (explorer, list) -> {
- for (StatType stat : StatType.values())
- list.add(stat.name());
- }));
- addParameter(new Parameter("(formatted)", (explorer, list) -> list.add("true")));
- }
+ addParameter(new Parameter("", (explorer, list) -> list.add("STAT_ID")));
+ }
- @Override
- public CommandResult execute(CommandSender sender, String[] args) {
- if (args.length < 3)
- return CommandResult.THROW_USAGE;
+ @Override
+ public CommandResult execute(CommandSender sender, String[] args) {
+ if (args.length < 3)
+ return CommandResult.THROW_USAGE;
- if (!(sender instanceof Player)) {
- sender.sendMessage(ChatColor.RED + "This command can only be used by a player.");
- return CommandResult.FAILURE;
- }
- PlayerData data = PlayerData.get((Player) sender);
+ if (!(sender instanceof Player)) {
+ sender.sendMessage(ChatColor.RED + "This command can only be used by a player.");
+ return CommandResult.FAILURE;
+ }
+ PlayerData data = PlayerData.get((Player) sender);
- StatType stat;
- try {
- stat = StatType.valueOf(args[2].toUpperCase().replace("-", "_").replace(" ", "_"));
- } catch (IllegalArgumentException exception) {
- sender.sendMessage(ChatColor.RED + "Could not find stat: " + args[2] + ".");
- return CommandResult.FAILURE;
- }
+ StatInfo stat = StatInfo.valueOf(UtilityMethods.enumName(args[2]));
+ sender.sendMessage(DebugCommandTreeNode.commandPrefix + "Stat Value (" + ChatColor.BLUE + stat.name + ChatColor.WHITE + "): "
+ + ChatColor.GREEN + data.getStats().getStat(stat.name));
- if (args.length > 3 && args[3].equals("true"))
- sender.sendMessage(DebugCommandTreeNode.commandPrefix + "Stat Value (" + ChatColor.BLUE + stat.name() + ChatColor.WHITE + "): "
- + ChatColor.GREEN + stat.format(data.getStats().getStat(stat)) + ChatColor.WHITE + " *");
- else
- sender.sendMessage(DebugCommandTreeNode.commandPrefix + "Stat Value (" + ChatColor.BLUE + stat.name() + ChatColor.WHITE + "): "
- + ChatColor.GREEN + data.getStats().getStat(stat));
-
- return CommandResult.SUCCESS;
- }
+ return CommandResult.SUCCESS;
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/quest/CancelCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/quest/CancelCommandTreeNode.java
index 1556da28..c3731a6d 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/quest/CancelCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/quest/CancelCommandTreeNode.java
@@ -1,43 +1,43 @@
-package net.Indyuce.mmocore.command.rpg.quest;
-
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.quest.PlayerQuests;
-import io.lumine.mythic.lib.command.api.CommandTreeNode;
-import io.lumine.mythic.lib.command.api.Parameter;
-
-public class CancelCommandTreeNode extends CommandTreeNode {
- public CancelCommandTreeNode(CommandTreeNode parent) {
- super(parent, "cancel");
-
- addParameter(Parameter.PLAYER);
- }
-
- @Override
- public CommandResult execute(CommandSender sender, String[] args) {
- if (args.length < 3)
- return CommandResult.THROW_USAGE;
-
- Player player = Bukkit.getPlayer(args[2]);
- if (player == null) {
- sender.sendMessage(ChatColor.RED + "Could not find player called " + args[2] + ".");
- return CommandResult.FAILURE;
- }
-
- PlayerQuests quests = PlayerData.get(player).getQuestData();
- if (!quests.hasCurrent()) {
- if (sender instanceof Player)
- sender.sendMessage(ChatColor.RED + player.getName() + " has no ongoing quest.");
- return CommandResult.SUCCESS;
- }
-
- quests.start(null);
- if (sender instanceof Player)
- sender.sendMessage(ChatColor.YELLOW + player.getName() + " no longer has any ongoing quest.");
- return CommandResult.SUCCESS;
- }
-}
+package net.Indyuce.mmocore.command.rpg.quest;
+
+import net.Indyuce.mmocore.api.quest.PlayerQuests;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import net.Indyuce.mmocore.api.player.PlayerData;
+import io.lumine.mythic.lib.command.api.CommandTreeNode;
+import io.lumine.mythic.lib.command.api.Parameter;
+
+public class CancelCommandTreeNode extends CommandTreeNode {
+ public CancelCommandTreeNode(CommandTreeNode parent) {
+ super(parent, "cancel");
+
+ addParameter(Parameter.PLAYER);
+ }
+
+ @Override
+ public CommandResult execute(CommandSender sender, String[] args) {
+ if (args.length < 3)
+ return CommandResult.THROW_USAGE;
+
+ Player player = Bukkit.getPlayer(args[2]);
+ if (player == null) {
+ sender.sendMessage(ChatColor.RED + "Could not find player called " + args[2] + ".");
+ return CommandResult.FAILURE;
+ }
+
+ PlayerQuests quests = PlayerData.get(player).getQuestData();
+ if (!quests.hasCurrent()) {
+ if (sender instanceof Player)
+ sender.sendMessage(ChatColor.RED + player.getName() + " has no ongoing quest.");
+ return CommandResult.SUCCESS;
+ }
+
+ quests.start(null);
+ if (sender instanceof Player)
+ sender.sendMessage(ChatColor.YELLOW + player.getName() + " no longer has any ongoing quest.");
+ return CommandResult.SUCCESS;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/quest/FinishCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/quest/FinishCommandTreeNode.java
index 5514bfbb..779a918b 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/quest/FinishCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/quest/FinishCommandTreeNode.java
@@ -2,8 +2,8 @@ package net.Indyuce.mmocore.command.rpg.quest;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.PlayerQuests;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/quest/QuestCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/quest/QuestCommandTreeNode.java
index 866b6981..2cb909ad 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/quest/QuestCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/quest/QuestCommandTreeNode.java
@@ -1,21 +1,21 @@
-package net.Indyuce.mmocore.command.rpg.quest;
-
-import org.bukkit.command.CommandSender;
-
-import io.lumine.mythic.lib.command.api.CommandTreeNode;
-
-public class QuestCommandTreeNode extends CommandTreeNode {
-
- public QuestCommandTreeNode(CommandTreeNode parent) {
- super(parent, "quest");
-
- addChild(new StartCommandTreeNode(this));
- addChild(new CancelCommandTreeNode(this));
- addChild(new FinishCommandTreeNode(this));
- }
-
- @Override
- public CommandResult execute(CommandSender sender, String[] args) {
- return CommandResult.THROW_USAGE;
- }
-}
+package net.Indyuce.mmocore.command.rpg.quest;
+
+import org.bukkit.command.CommandSender;
+
+import io.lumine.mythic.lib.command.api.CommandTreeNode;
+
+public class QuestCommandTreeNode extends CommandTreeNode {
+
+ public QuestCommandTreeNode(CommandTreeNode parent) {
+ super(parent, "quest");
+
+ addChild(new StartCommandTreeNode(this));
+ addChild(new CancelCommandTreeNode(this));
+ addChild(new FinishCommandTreeNode(this));
+ }
+
+ @Override
+ public CommandResult execute(CommandSender sender, String[] args) {
+ return CommandResult.THROW_USAGE;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/quest/StartCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/quest/StartCommandTreeNode.java
index 079c262c..e2941ebc 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/quest/StartCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/quest/StartCommandTreeNode.java
@@ -1,55 +1,55 @@
-package net.Indyuce.mmocore.command.rpg.quest;
-
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.quest.PlayerQuests;
-import net.Indyuce.mmocore.api.quest.Quest;
-import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
-import io.lumine.mythic.lib.command.api.CommandTreeNode;
-import io.lumine.mythic.lib.command.api.Parameter;
-
-public class StartCommandTreeNode extends CommandTreeNode {
- public StartCommandTreeNode(CommandTreeNode parent) {
- super(parent, "start");
-
- addParameter(Parameter.PLAYER);
- addParameter(MMOCoreCommandTreeRoot.QUEST);
- }
-
- @Override
- public CommandResult execute(CommandSender sender, String[] args) {
- if (args.length < 4)
- return CommandResult.THROW_USAGE;
-
- Player player = Bukkit.getPlayer(args[2]);
- if (player == null) {
- sender.sendMessage(ChatColor.RED + "Could not find player called " + args[2] + ".");
- return CommandResult.FAILURE;
- }
-
- Quest quest;
- try {
- quest = MMOCore.plugin.questManager.get(args[3].replace("_", "-").toLowerCase());
- } catch (Exception exception) {
- sender.sendMessage(ChatColor.RED + "Could not find quest with ID " + args[3].replace("_", "-").toLowerCase() + ".");
- return CommandResult.FAILURE;
- }
-
- PlayerQuests quests = PlayerData.get(player).getQuestData();
- if (quests.hasCurrent()) {
- if (sender instanceof Player)
- sender.sendMessage(ChatColor.RED + player.getName() + " already has an ongoing quest.");
- return CommandResult.SUCCESS;
- }
-
- quests.start(quest);
- if (sender instanceof Player)
- sender.sendMessage(ChatColor.YELLOW + player.getName() + " successfully started " + quest.getName() + ".");
- return CommandResult.SUCCESS;
- }
-}
+package net.Indyuce.mmocore.command.rpg.quest;
+
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.quest.PlayerQuests;
+import net.Indyuce.mmocore.api.quest.Quest;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.command.MMOCoreCommandTreeRoot;
+import io.lumine.mythic.lib.command.api.CommandTreeNode;
+import io.lumine.mythic.lib.command.api.Parameter;
+
+public class StartCommandTreeNode extends CommandTreeNode {
+ public StartCommandTreeNode(CommandTreeNode parent) {
+ super(parent, "start");
+
+ addParameter(Parameter.PLAYER);
+ addParameter(MMOCoreCommandTreeRoot.QUEST);
+ }
+
+ @Override
+ public CommandResult execute(CommandSender sender, String[] args) {
+ if (args.length < 4)
+ return CommandResult.THROW_USAGE;
+
+ Player player = Bukkit.getPlayer(args[2]);
+ if (player == null) {
+ sender.sendMessage(ChatColor.RED + "Could not find player called " + args[2] + ".");
+ return CommandResult.FAILURE;
+ }
+
+ Quest quest;
+ try {
+ quest = MMOCore.plugin.questManager.get(args[3].replace("_", "-").toLowerCase());
+ } catch (Exception exception) {
+ sender.sendMessage(ChatColor.RED + "Could not find quest with ID " + args[3].replace("_", "-").toLowerCase() + ".");
+ return CommandResult.FAILURE;
+ }
+
+ PlayerQuests quests = PlayerData.get(player).getQuestData();
+ if (quests.hasCurrent()) {
+ if (sender instanceof Player)
+ sender.sendMessage(ChatColor.RED + player.getName() + " already has an ongoing quest.");
+ return CommandResult.SUCCESS;
+ }
+
+ quests.start(quest);
+ if (sender instanceof Player)
+ sender.sendMessage(ChatColor.YELLOW + player.getName() + " successfully started " + quest.getName() + ".");
+ return CommandResult.SUCCESS;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/ItemCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/ItemCommandTreeNode.java
new file mode 100644
index 00000000..a8279746
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/ItemCommandTreeNode.java
@@ -0,0 +1,44 @@
+package net.Indyuce.mmocore.command.rpg.waypoint;
+
+import io.lumine.mythic.lib.api.util.SmartGive;
+import io.lumine.mythic.lib.command.api.CommandTreeNode;
+import io.lumine.mythic.lib.command.api.Parameter;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.waypoint.Waypoint;
+import net.Indyuce.mmocore.util.item.WaypointBookBuilder;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class ItemCommandTreeNode extends CommandTreeNode {
+ public ItemCommandTreeNode(CommandTreeNode parent) {
+ super(parent, "item");
+
+ addParameter(new Parameter("", (explorer, list) -> MMOCore.plugin.waypointManager.getAll().forEach(way -> list.add(way.getId()))));
+ addParameter(Parameter.PLAYER);
+ }
+
+ @Override
+ public CommandResult execute(CommandSender sender, String[] args) {
+ if (args.length < 4)
+ return CommandResult.THROW_USAGE;
+
+ if (!MMOCore.plugin.waypointManager.has(args[2])) {
+ sender.sendMessage(ChatColor.RED + "Could not find waypoint " + args[2]);
+ return CommandResult.FAILURE;
+ }
+
+ Player player = Bukkit.getPlayer(args[3]);
+ if (player == null) {
+ sender.sendMessage(ChatColor.RED + "Could not find player " + args[3]);
+ return CommandResult.FAILURE;
+ }
+
+ Waypoint waypoint = MMOCore.plugin.waypointManager.get(args[2]);
+ new SmartGive(player).give(new WaypointBookBuilder(waypoint).build());
+ sender.sendMessage(ChatColor.GOLD + "Gave " + player.getName() + ChatColor.YELLOW + " a waypoint book of " + ChatColor.GOLD + waypoint.getId()
+ + ChatColor.YELLOW + ".");
+ return CommandResult.SUCCESS;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/OpenCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/OpenCommandTreeNode.java
index 84f1ac91..ec41723d 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/OpenCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/OpenCommandTreeNode.java
@@ -1,5 +1,6 @@
package net.Indyuce.mmocore.command.rpg.waypoint;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@@ -27,7 +28,7 @@ public class OpenCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
- InventoryManager.WAYPOINTS.newInventory(net.Indyuce.mmocore.api.player.PlayerData.get(player)).open();
+ InventoryManager.WAYPOINTS.newInventory(PlayerData.get(player)).open();
return CommandResult.SUCCESS;
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/UnlockCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/UnlockCommandTreeNode.java
index a33e7a30..94386fdb 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/UnlockCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/UnlockCommandTreeNode.java
@@ -1,12 +1,12 @@
package net.Indyuce.mmocore.command.rpg.waypoint;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.waypoint.Waypoint;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.waypoint.Waypoint;
import net.Indyuce.mmocore.api.player.PlayerData;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
diff --git a/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/WaypointsCommandTreeNode.java b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/WaypointsCommandTreeNode.java
index 839f2995..48aeba29 100644
--- a/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/WaypointsCommandTreeNode.java
+++ b/src/main/java/net/Indyuce/mmocore/command/rpg/waypoint/WaypointsCommandTreeNode.java
@@ -11,6 +11,7 @@ public class WaypointsCommandTreeNode extends CommandTreeNode {
addChild(new UnlockCommandTreeNode(this));
addChild(new OpenCommandTreeNode(this));
addChild(new TeleportCommandTreeNode(this));
+ addChild(new ItemCommandTreeNode(this));
}
@Override
diff --git a/src/main/java/net/Indyuce/mmocore/comp/MMOCoreTargetRestriction.java b/src/main/java/net/Indyuce/mmocore/comp/MMOCoreTargetRestriction.java
deleted file mode 100644
index 5935b582..00000000
--- a/src/main/java/net/Indyuce/mmocore/comp/MMOCoreTargetRestriction.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.Indyuce.mmocore.comp;
-
-import io.lumine.mythic.lib.comp.target.InteractionType;
-import io.lumine.mythic.lib.comp.target.TargetRestriction;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.party.AbstractParty;
-import org.bukkit.entity.LivingEntity;
-import org.bukkit.entity.Player;
-
-import java.util.Optional;
-
-public class MMOCoreTargetRestriction implements TargetRestriction {
-
- @Override
- public boolean canTarget(Player player, LivingEntity target, InteractionType interaction) {
-
- if (interaction.isOffense() && target instanceof Player && PlayerData.has(target.getUniqueId())) {
- PlayerData targetData = PlayerData.get(target.getUniqueId());
-
- // Check for the same party
- AbstractParty party = targetData.getParty();
- if (party != null && party.hasMember(player))
- return false;
- }
-
- return true;
- }
-}
diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicHook.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicHook.java
index bbcc4a53..e6d72660 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicHook.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicHook.java
@@ -4,11 +4,11 @@ import io.lumine.mythic.bukkit.MythicBukkit;
import io.lumine.mythic.bukkit.events.MythicDropLoadEvent;
import io.lumine.mythic.bukkit.events.MythicReloadedEvent;
import io.lumine.mythic.core.skills.placeholders.Placeholder;
+import net.Indyuce.mmocore.comp.mythicmobs.load.CurrencyItemDrop;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
-import net.Indyuce.mmocore.comp.mythicmobs.load.CurrencyItemDrop;
import net.Indyuce.mmocore.comp.mythicmobs.load.GoldPouchDrop;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicMobsMMOLoader.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicMobsMMOLoader.java
index 8a197ee8..f471dcd5 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicMobsMMOLoader.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/MythicMobsMMOLoader.java
@@ -1,22 +1,25 @@
package net.Indyuce.mmocore.comp.mythicmobs;
import io.lumine.mythic.lib.api.MMOLineConfig;
+import net.Indyuce.mmocore.comp.mythicmobs.load.*;
import net.Indyuce.mmocore.api.load.MMOLoader;
import net.Indyuce.mmocore.api.quest.objective.Objective;
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
-import net.Indyuce.mmocore.comp.mythicmobs.load.*;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
import org.bukkit.configuration.ConfigurationSection;
+import java.util.Arrays;
+import java.util.List;
+
public class MythicMobsMMOLoader extends MMOLoader {
@Override
- public Trigger loadTrigger(MMOLineConfig config) {
+ public List loadTrigger(MMOLineConfig config) {
if (config.getKey().equalsIgnoreCase("mmskill") || config.getKey().equalsIgnoreCase("mythicmobskill"))
- return new MythicSkillTrigger(config);
+ return Arrays.asList(new MythicSkillTrigger(config));
return null;
}
@@ -42,12 +45,12 @@ public class MythicMobsMMOLoader extends MMOLoader {
}
@Override
- public ExperienceSource> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
+ public List> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
if (config.getKey().equalsIgnoreCase("killmythicmob"))
- return new KillMythicMobExperienceSource(dispenser, config);
+ return Arrays.asList(new KillMythicMobExperienceSource(dispenser, config));
if (config.getKey().equalsIgnoreCase("killmythicfaction"))
- return new KillMythicFactionExperienceSource(dispenser, config);
+ return Arrays.asList(new KillMythicFactionExperienceSource(dispenser, config));
return null;
}
diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/CurrencyItemDrop.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/CurrencyItemDrop.java
index ccba02f2..4285eca5 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/CurrencyItemDrop.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/CurrencyItemDrop.java
@@ -1,17 +1,16 @@
package net.Indyuce.mmocore.comp.mythicmobs.load;
+import io.lumine.mythic.api.adapters.AbstractItemStack;
import io.lumine.mythic.api.config.MythicLineConfig;
import io.lumine.mythic.api.drops.DropMetadata;
-import io.lumine.mythic.api.drops.IMultiDrop;
+import io.lumine.mythic.api.drops.IItemDrop;
import io.lumine.mythic.bukkit.adapters.BukkitItemStack;
import io.lumine.mythic.core.drops.Drop;
-import io.lumine.mythic.core.drops.LootBag;
-import io.lumine.mythic.core.drops.droppables.ItemDrop;
import net.Indyuce.mmocore.util.item.CurrencyItemBuilder;
import java.util.Random;
-public class CurrencyItemDrop extends Drop implements IMultiDrop {
+public class CurrencyItemDrop extends Drop implements IItemDrop {
private final String key;
private final int minw;
private final int maxw;
@@ -26,12 +25,9 @@ public class CurrencyItemDrop extends Drop implements IMultiDrop {
maxw = config.getInteger("maxw", 1);
}
- @SuppressWarnings("deprecation")
@Override
- public LootBag get(DropMetadata metadata) {
- LootBag loot = new LootBag(metadata);
- loot.add(new ItemDrop(this.getLine(), this.getConfig(), new BukkitItemStack(new CurrencyItemBuilder(key, random(minw, maxw)).build())));
- return loot;
+ public AbstractItemStack getDrop(DropMetadata dropMetadata, double v) {
+ return new BukkitItemStack(new CurrencyItemBuilder(key, random(minw, maxw)).build());
}
private int random(int a, int b) {
diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/GoldPouchDrop.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/GoldPouchDrop.java
index 65c4123a..7d952e26 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/GoldPouchDrop.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/GoldPouchDrop.java
@@ -1,12 +1,11 @@
package net.Indyuce.mmocore.comp.mythicmobs.load;
+import io.lumine.mythic.api.adapters.AbstractItemStack;
import io.lumine.mythic.api.config.MythicLineConfig;
import io.lumine.mythic.api.drops.DropMetadata;
-import io.lumine.mythic.api.drops.IMultiDrop;
+import io.lumine.mythic.api.drops.IItemDrop;
import io.lumine.mythic.bukkit.adapters.BukkitItemStack;
import io.lumine.mythic.core.drops.Drop;
-import io.lumine.mythic.core.drops.LootBag;
-import io.lumine.mythic.core.drops.droppables.ItemDrop;
import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
@@ -17,7 +16,7 @@ import org.bukkit.inventory.ItemStack;
import java.util.Random;
-public class GoldPouchDrop extends Drop implements IMultiDrop {
+public class GoldPouchDrop extends Drop implements IItemDrop {
private final int min;
private final int max;
@@ -30,10 +29,8 @@ public class GoldPouchDrop extends Drop implements IMultiDrop {
max = config.getInteger("max", 10);
}
- @SuppressWarnings("deprecation")
@Override
- public LootBag get(DropMetadata metadata) {
- LootBag loot = new LootBag(metadata);
+ public AbstractItemStack getDrop(DropMetadata dropMetadata, double v) {
NBTItem nbt = NBTItem.get(new SimpleItemBuilder("MOB_GOLD_POUCH").build());
ItemStack[] content = new ItemStack[18];
@@ -52,8 +49,7 @@ public class GoldPouchDrop extends Drop implements IMultiDrop {
}
nbt.addTag(new ItemTag("RpgPouchSize", 18), new ItemTag("RpgPouchMob", true), new ItemTag("RpgPouchInventory", MMOCoreUtils.toBase64(content)));
- loot.add(new ItemDrop(this.getLine(), this.getConfig(), new BukkitItemStack(nbt.toItem())));
- return loot;
+ return new BukkitItemStack(nbt.toItem());
}
private ItemStack setAmount(ItemStack item, int amount) {
diff --git a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/KillMythicMobExperienceSource.java b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/KillMythicMobExperienceSource.java
index bf161320..f81621fc 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/KillMythicMobExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/mythicmobs/load/KillMythicMobExperienceSource.java
@@ -4,6 +4,7 @@ import io.lumine.mythic.bukkit.events.MythicMobDeathEvent;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
@@ -33,7 +34,7 @@ public class KillMythicMobExperienceSource extends SpecificExperienceSource= j ? MMOCore.plugin.configManager.staminaFull
: ratio >= j - .5 ? MMOCore.plugin.configManager.staminaHalf : MMOCore.plugin.configManager.staminaEmpty)
@@ -182,8 +182,8 @@ public class RPGPlaceholders extends PlaceholderExpansion {
}
else if (identifier.startsWith("stat_")) {
- StatType type = StatType.valueOf(identifier.substring(5).toUpperCase());
- return type == null ? "Invalid Stat" : type.format(playerData.getStats().getStat(type));
+ StatInfo info = StatInfo.valueOf(identifier.substring(5).toUpperCase());
+ return info.format(playerData.getStats().getStat(info.name));
}
else if (identifier.equals("stellium"))
@@ -191,7 +191,7 @@ public class RPGPlaceholders extends PlaceholderExpansion {
else if (identifier.equals("stellium_bar")) {
StringBuilder format = new StringBuilder();
- double ratio = 20 * playerData.getStellium() / playerData.getStats().getStat(StatType.MAX_STELLIUM);
+ double ratio = 20 * playerData.getStellium() / playerData.getStats().getStat("MAX_STELLIUM");
for (double j = 1; j < 20; j++)
format.append(ratio >= j ? ChatColor.BLUE : ratio >= j - .5 ? ChatColor.AQUA : ChatColor.WHITE).append(AltChar.listSquare);
return format.toString();
@@ -226,9 +226,9 @@ public class RPGPlaceholders extends PlaceholderExpansion {
else if (placeholder.equalsIgnoreCase("leader"))
return Bukkit.getOfflinePlayer(playerData.getGuild().getOwner()).getName();
else if (placeholder.equalsIgnoreCase("members"))
- return "" + playerData.getGuild().getMembers().count();
+ return String.valueOf(playerData.getGuild().countMembers());
else if (placeholder.equalsIgnoreCase("online_members"))
- return "" + playerData.getGuild().getMembers().countOnline();
+ return String.valueOf(playerData.getGuild().countOnlineMembers());
}
return null;
diff --git a/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java b/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java
index 735ebda6..50da8a61 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java
@@ -4,13 +4,16 @@ import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.api.load.MMOLoader;
import io.lumine.mythic.lib.api.MMOLineConfig;
+import java.util.Arrays;
+import java.util.List;
+
public class WorldGuardMMOLoader extends MMOLoader {
@Override
- public Condition loadCondition(MMOLineConfig config) {
+ public List loadCondition(MMOLineConfig config) {
if (config.getKey().equals("region"))
- return new RegionCondition(config);
+ return Arrays.asList(new RegionCondition(config));
return null;
}
diff --git a/src/main/java/net/Indyuce/mmocore/comp/vault/MoneyTrigger.java b/src/main/java/net/Indyuce/mmocore/comp/vault/MoneyTrigger.java
index 94b16b01..16fee03e 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/vault/MoneyTrigger.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/vault/MoneyTrigger.java
@@ -1,8 +1,8 @@
package net.Indyuce.mmocore.comp.vault;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
+import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
import io.lumine.mythic.lib.api.MMOLineConfig;
diff --git a/src/main/java/net/Indyuce/mmocore/comp/vault/VaultEconomy.java b/src/main/java/net/Indyuce/mmocore/comp/vault/VaultEconomy.java
index a9fe6a51..139e0e41 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/vault/VaultEconomy.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/vault/VaultEconomy.java
@@ -2,9 +2,9 @@ package net.Indyuce.mmocore.comp.vault;
import java.util.logging.Level;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Bukkit;
-import net.Indyuce.mmocore.MMOCore;
import net.milkbowl.vault.economy.Economy;
public class VaultEconomy {
diff --git a/src/main/java/net/Indyuce/mmocore/comp/vault/VaultMMOLoader.java b/src/main/java/net/Indyuce/mmocore/comp/vault/VaultMMOLoader.java
index a77f69f7..db004558 100644
--- a/src/main/java/net/Indyuce/mmocore/comp/vault/VaultMMOLoader.java
+++ b/src/main/java/net/Indyuce/mmocore/comp/vault/VaultMMOLoader.java
@@ -1,16 +1,19 @@
package net.Indyuce.mmocore.comp.vault;
-import net.Indyuce.mmocore.api.load.MMOLoader;
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
+import net.Indyuce.mmocore.api.load.MMOLoader;
import io.lumine.mythic.lib.api.MMOLineConfig;
+import java.util.Arrays;
+import java.util.List;
+
public class VaultMMOLoader extends MMOLoader {
@Override
- public Trigger loadTrigger(MMOLineConfig config) {
+ public List loadTrigger(MMOLineConfig config) {
if (config.getKey().equalsIgnoreCase("money"))
- return new MoneyTrigger(config);
+ return Arrays.asList(new MoneyTrigger(config));
return null;
}
diff --git a/src/main/java/net/Indyuce/mmocore/experience/Booster.java b/src/main/java/net/Indyuce/mmocore/experience/Booster.java
index c15d6928..28f609a5 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/Booster.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/Booster.java
@@ -1,5 +1,7 @@
package net.Indyuce.mmocore.experience;
+import net.Indyuce.mmocore.manager.social.BoosterManager;
+
import java.util.Objects;
import java.util.UUID;
@@ -14,7 +16,7 @@ public class Booster {
* Length is not final because boosters can stacks. This allows to reduce
* the amount of boosters displayed in the main player menu
*
- * See {@link net.Indyuce.mmocore.manager.social.BoosterManager#register(Booster)}
+ * See {@link BoosterManager#register(Booster)}
*/
private long length;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/EXPSource.java b/src/main/java/net/Indyuce/mmocore/experience/EXPSource.java
index 89f522f3..08ccf6c9 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/EXPSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/EXPSource.java
@@ -19,7 +19,10 @@ public enum EXPSource {
/**
* When party members share exp
+ *
+ * @deprecated Not used anymore
*/
+ @Deprecated
PARTY_SHARING,
/**
diff --git a/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java b/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java
index 3f9e6cc8..b51b1033 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/ExperienceObject.java
@@ -1,16 +1,20 @@
package net.Indyuce.mmocore.experience;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
+import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
/**
- * Either a profession or a class
+ * General implementation for professions, classes and attributes.
+ *
+ * An experience object is a type of object that can level up.
+ * It has an experience curve and table and can receive EXP
*
* @author jules
*/
-public interface ExperienceObject {
+public interface ExperienceObject extends ExperienceDispenser {
String getKey();
diff --git a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java
index d8a1ab21..2295a281 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java
@@ -4,15 +4,16 @@ import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.lumine.mythic.lib.MythicLib;
+import io.lumine.mythic.lib.UtilityMethods;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.event.PlayerExperienceGainEvent;
import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
+import net.Indyuce.mmocore.party.AbstractParty;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -22,6 +23,7 @@ import org.bukkit.configuration.ConfigurationSection;
import javax.annotation.Nullable;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -147,39 +149,49 @@ public class PlayerProfessions {
giveExperience(profession, total, source);
}
- public void giveExperience(Profession profession, double value, EXPSource source) {
- giveExperience(profession, value, source, null);
- }
-
public boolean hasReachedMaxLevel(Profession profession) {
return profession.hasMaxLevel() && getLevel(profession) >= profession.getMaxLevel();
}
- public void giveExperience(Profession profession, double value, EXPSource source, @Nullable Location hologramLocation) {
+ public void giveExperience(Profession profession, double value, EXPSource source) {
+ giveExperience(profession, value, source, null, true);
+ }
+
+ public void giveExperience(Profession profession, double value, EXPSource source, @Nullable Location hologramLocation, boolean splitExp) {
Validate.isTrue(playerData.isOnline(), "Cannot give experience to offline player");
+ if (value <= 0)
+ return;
if (hasReachedMaxLevel(profession)) {
setExperience(profession, 0);
return;
}
- value = MMOCore.plugin.boosterManager.calculateExp(profession, value);
+ // Splitting exp through party members
+ AbstractParty party;
+ if (splitExp && (party = playerData.getParty()) != null && MMOCore.plugin.configManager.splitProfessionExp) {
+ List onlineMembers = party.getOnlineMembers();
+ value /= onlineMembers.size();
+ for (PlayerData member : onlineMembers)
+ if (!member.equals(playerData))
+ member.getCollectionSkills().giveExperience(profession, value, source, null, false);
+ }
- // Adds functionality for additional experience per profession.
- value *= 1 + playerData.getStats().getInstance(StatType.ADDITIONAL_EXPERIENCE, profession).getTotal() / 100;
-
- // Display hologram
- if (hologramLocation != null)
- MMOCoreUtils.displayIndicator(hologramLocation.add(.5, 1.5, .5), MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", "" + value).message());
+ // Apply buffs AFTER splitting exp
+ value *= (1 + playerData.getStats().getStat("ADDITIONAL_EXPERIENCE_" + UtilityMethods.enumName(profession.getId())) / 100) * MMOCore.plugin.boosterManager.getMultiplier(profession);
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(playerData, profession, value, source);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled())
return;
+ // Display hologram
+ if (hologramLocation != null)
+ MMOCoreUtils.displayIndicator(hologramLocation.add(.5, 1.5, .5), MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", MythicLib.plugin.getMMOConfig().decimal.format(event.getExperience())).message());
+
exp.put(profession.getId(), Math.max(0, exp.getOrDefault(profession.getId(), 0.) + event.getExperience()));
int level, oldLevel = getLevel(profession);
- double needed,exp;
+ double needed, exp;
/*
* Loop for exp overload when leveling up, will continue
@@ -197,6 +209,11 @@ public class PlayerProfessions {
this.level.put(profession.getId(), level + 1);
check = true;
playerData.giveExperience(profession.getExperience().calculate(level), null);
+
+ // Apply profession experience table
+ if (profession.hasExperienceTable())
+ profession.getExperienceTable().claim(playerData, level, profession);
+
}
if (check) {
@@ -206,10 +223,6 @@ public class PlayerProfessions {
.send(playerData.getPlayer());
MMOCore.plugin.soundManager.getSound(SoundEvent.LEVEL_UP).playTo(playerData.getPlayer());
playerData.getStats().updateStats();
-
- // Apply profession experience table
- if (profession.hasExperienceTable())
- profession.getExperienceTable().claim(playerData, level, profession);
}
StringBuilder bar = new StringBuilder("" + ChatColor.BOLD);
diff --git a/src/main/java/net/Indyuce/mmocore/experience/Profession.java b/src/main/java/net/Indyuce/mmocore/experience/Profession.java
index ade8f4fb..03ba0db5 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/Profession.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/Profession.java
@@ -3,16 +3,19 @@ package net.Indyuce.mmocore.experience;
import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.util.PostLoadObject;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
-import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
-import net.Indyuce.mmocore.experience.dispenser.ProfessionExperienceDispenser;
+import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
import org.apache.commons.lang.Validate;
+import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
@@ -63,16 +66,17 @@ public class Profession extends PostLoadObject implements ExperienceObject {
maxLevel = config.getInt("max-level");
- if (config.contains("exp-sources")) {
- ExperienceDispenser dispenser = new ProfessionExperienceDispenser(this);
+ if (config.contains("exp-sources"))
for (String key : config.getStringList("exp-sources"))
try {
- MMOCore.plugin.experience.registerSource(MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), dispenser));
+ List> experienceSourceList=MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), this);
+ for(ExperienceSource experienceSource: experienceSourceList) {
+ MMOCore.plugin.experience.registerSource(experienceSource);
+ }
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not register exp source '" + key + "' from profession '" + id + "': " + exception.getMessage());
}
- }
}
@Override
@@ -124,6 +128,18 @@ public class Profession extends PostLoadObject implements ExperienceObject {
return Objects.requireNonNull(expTable, "Profession has no exp table");
}
+ @Override
+ public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) {
+ hologramLocation = !getOption(Profession.ProfessionOption.EXP_HOLOGRAMS) ? null
+ : hologramLocation;
+ playerData.getCollectionSkills().giveExperience(this, experience, EXPSource.SOURCE, hologramLocation, true);
+ }
+
+ @Override
+ public boolean shouldHandle(PlayerData playerData) {
+ return true;
+ }
+
public static enum ProfessionOption {
/**
diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/SimpleExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/SimpleExperienceObject.java
similarity index 79%
rename from src/main/java/net/Indyuce/mmocore/experience/dispenser/SimpleExperienceDispenser.java
rename to src/main/java/net/Indyuce/mmocore/experience/SimpleExperienceObject.java
index fc99e73b..87e013c7 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/SimpleExperienceDispenser.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/SimpleExperienceObject.java
@@ -1,12 +1,12 @@
-package net.Indyuce.mmocore.experience.dispenser;
+package net.Indyuce.mmocore.experience;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.experience.EXPSource;
+import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import org.bukkit.Location;
import org.jetbrains.annotations.Nullable;
-public class SimpleExperienceDispenser implements ExperienceDispenser {
+public class SimpleExperienceObject implements ExperienceDispenser {
@Override
public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) {
diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java
deleted file mode 100644
index 917f7b14..00000000
--- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.Indyuce.mmocore.experience.dispenser;
-
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.profess.PlayerClass;
-import net.Indyuce.mmocore.experience.EXPSource;
-import org.bukkit.Location;
-import org.jetbrains.annotations.Nullable;
-
-public class ClassExperienceDispenser implements ExperienceDispenser {
- private final PlayerClass profess;
-
- public ClassExperienceDispenser(PlayerClass profess) {
- this.profess = profess;
- }
-
- @Override
- public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) {
- hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null
- : hologramLocation;
- playerData.giveExperience(experience, source, hologramLocation, true);
- }
-
- @Override
- public boolean shouldHandle(PlayerData playerData) {
- return playerData.getProfess().equals(profess);
- }
-}
diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ExperienceDispenser.java
index 5ac9eac0..f5c1d2f8 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ExperienceDispenser.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ExperienceDispenser.java
@@ -1,8 +1,9 @@
package net.Indyuce.mmocore.experience.dispenser;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.experience.EXPSource;
+import net.Indyuce.mmocore.experience.ExperienceObject;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -11,16 +12,17 @@ import org.jetbrains.annotations.Nullable;
* Used to differenciate between the main class experience and
* experience given in a specific profession. Also being used to
* monitor EXP holograms.
+ *
+ * @deprecated Merged with {@link ExperienceObject}
*/
+@Deprecated
public interface ExperienceDispenser {
/**
* Called when experience is gained in main class/profession
*
* @param playerData Player gaining the experience
- * @param experience Experience gained. Note that it is a double
- * because it gets converted to an integer at
- * the very last moment in MMOCore
+ * @param experience Experience gained
* @param hologramLocation Location of displayed hologram. When set to null
* and if exp holograms are enabled it will take the
* player's location instead.
diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java
deleted file mode 100644
index 273a05b2..00000000
--- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package net.Indyuce.mmocore.experience.dispenser;
-
-import net.Indyuce.mmocore.experience.EXPSource;
-import net.Indyuce.mmocore.experience.Profession;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import org.bukkit.Location;
-import org.jetbrains.annotations.Nullable;
-
-public class ProfessionExperienceDispenser implements ExperienceDispenser {
- private final Profession profession;
-
- public ProfessionExperienceDispenser(Profession profession) {
- this.profession = profession;
- }
-
- @Override
- public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) {
- hologramLocation = !profession.getOption(Profession.ProfessionOption.EXP_HOLOGRAMS) ? null
- : hologramLocation;
- playerData.getCollectionSkills().giveExperience(profession, experience, EXPSource.SOURCE, hologramLocation);
- }
-
- @Override
- public boolean shouldHandle(PlayerData playerData) {
- return true;
- }
-}
diff --git a/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java b/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java
index 4ba8028c..aac2dd3f 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java
@@ -14,19 +14,23 @@ import java.util.Random;
public class ExperienceItem {
private final String id;
- //A period of 0 means the item will only trigger one time.
- private final int period;
- private final int firstTrigger;
+ private final int period, firstTrigger, lastTrigger;
private final double claimChance, failReduction;
private final List triggers;
private static final Random random = new Random();
+ @Deprecated
+ public ExperienceItem(String id, int period, int firstTrigger, double claimChance, double failReduction, List triggers) {
+ this(id, period, firstTrigger, Integer.MAX_VALUE, claimChance, failReduction, triggers);
+ }
+
/**
* One item for an experience table
*
* @param period The experience item is claimed every X level ups
* @param firstTrigger The experience item if claimed for the first time at X level ups.
+ * @param lastTrigger The last level at which the item can be claimed.
* @param claimChance Chance for that item to be claimed every X level ups
* @param failReduction Between 0 and 1, by how much the fail chance is reduced
* every time the item is not claimed when leveling up.
@@ -36,13 +40,14 @@ public class ExperienceItem {
* where n is the amount of successive claiming fails
* @param triggers Actions cast when the exp item is claimed
*/
- public ExperienceItem(String id, int period, int firstTrigger,double claimChance, double failReduction, List triggers) {
+ public ExperienceItem(String id, int period, int firstTrigger, int lastTrigger, double claimChance, double failReduction, List triggers) {
this.id = id;
this.period = period;
this.claimChance = claimChance;
this.failReduction = failReduction;
this.triggers = triggers;
- this.firstTrigger=firstTrigger;
+ this.firstTrigger = firstTrigger;
+ this.lastTrigger = lastTrigger;
}
public ExperienceItem(ConfigurationSection config) {
@@ -50,14 +55,15 @@ public class ExperienceItem {
Validate.isTrue(config.contains("triggers"));
id = config.getName();
- period = config.getInt("period", 0);
- firstTrigger=config.getInt("first-trigger",period);
+ period = config.getInt("period", 1);
+ firstTrigger = config.getInt("first-trigger", period);
+ lastTrigger = config.getInt("last-trigger", Integer.MAX_VALUE);
claimChance = config.getDouble("chance", 100) / 100;
failReduction = config.getDouble("fail-reduction", 80) / 100;
triggers = new ArrayList<>();
for (String triggerFormat : config.getStringList("triggers"))
- triggers.add(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(triggerFormat)));
+ triggers.addAll(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(triggerFormat)));
}
public String getId() {
@@ -71,7 +77,17 @@ public class ExperienceItem {
* account the randomness factor from the 'chance' parameter
*/
public boolean roll(int professionLevel, int timesCollected) {
- int claimsRequired = professionLevel+1 - (firstTrigger-+timesCollected * period);
+
+ // Check for the last triggering level
+ if (professionLevel > lastTrigger)
+ return false;
+
+ // A period of 0 means the item only triggers once
+ if (period == 0 && timesCollected > 0)
+ return false;
+
+ // Basic formula
+ final int claimsRequired = (professionLevel + 1 - (firstTrigger + timesCollected * period));
if (claimsRequired < 1)
return false;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java b/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java
index e4dbd0d3..0866aa29 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java
@@ -4,6 +4,7 @@ import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.ExperienceObject;
import org.apache.commons.lang.Validate;
+import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import java.util.ArrayList;
@@ -44,6 +45,7 @@ public class ExperienceTable {
*/
public void claim(PlayerData levelingUp, int professionLevel, ExperienceObject object) {
for (ExperienceItem item : items) {
+
int timesClaimed = levelingUp.getClaims(object, this, item);
if (!item.roll(professionLevel, timesClaimed))
continue;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java
index a0f6b5bf..8934ce22 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java
@@ -1,8 +1,8 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.experience.EXPSource;
+import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
import net.Indyuce.mmocore.api.player.PlayerData;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java
index c26ebd0a..2563a746 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java
@@ -6,11 +6,9 @@ import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang.Validate;
-import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerMoveEvent;
-import org.bukkit.util.Vector;
public class ClimbExperienceSource extends SpecificExperienceSource {
//Can be Ladder,Vines,Twisting Vines,Weeping Vines.
@@ -30,8 +28,8 @@ public class ClimbExperienceSource extends SpecificExperienceSource {
else {
String str = config.getString("type").toUpperCase().replace("-", "_");
Validate.isTrue(str.equals("LADDER") ||
- str.equals("VINE") || str.equals("TWISTING_VINES_PLANT") || str.equals("WEEPING_VINES"),
- "ClimbExperienceSource problem: The type must be ladder, vine, twisted-vines or weeping-vines");
+ str.equals("VINE") || str.equals("TWISTING_VINES") || str.equals("WEEPING_VINES"),
+ "ClimbExperienceSource problem: The type must be ladder, vine, twisting-vines or weeping-vines");
type = Material.valueOf(str);
}
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/CraftItemExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/CraftItemExperienceSource.java
index 55de061c..b53d6dd6 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/CraftItemExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/CraftItemExperienceSource.java
@@ -2,10 +2,10 @@ package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Material;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java
index 7e1c91ac..b290b8a6 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java
@@ -4,16 +4,18 @@ import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
import io.lumine.mythic.lib.damage.DamagePacket;
import io.lumine.mythic.lib.damage.DamageType;
-import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;
+import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
-import scala.Enumeration;
import java.util.Arrays;
import java.util.Objects;
+import java.util.logging.Level;
import java.util.stream.Collectors;
public class DamageDealtExperienceSource extends SpecificExperienceSource {
@@ -44,6 +46,7 @@ public class DamageDealtExperienceSource extends SpecificExperienceSource() {
@EventHandler
public void onDamageDealt(PlayerAttackEvent e) {
+
PlayerData playerData = PlayerData.get(e.getPlayer());
for (DamageDealtExperienceSource source : getSources()) {
double value = 0;
@@ -63,10 +66,13 @@ public class DamageDealtExperienceSource extends SpecificExperienceSource {
@@ -36,13 +37,13 @@ public class EatExperienceSource extends SpecificExperienceSource {
return new ExperienceSourceManager() {
@EventHandler
- public void a(FoodLevelChangeEvent e) {
- if (!(e.getEntity() instanceof Player) || e.getEntity().hasMetadata("NPC"))
- return;
- PlayerData playerData = PlayerData.get((OfflinePlayer) e.getEntity());
- for (EatExperienceSource source : getSources()) {
- if (source.matchesParameter(playerData, e.getItem()))
- source.giveExperience(playerData, e.getFoodLevel(), null);
+ public void a(PlayerItemConsumeEvent e) {
+ if(!e.getPlayer().hasMetadata("NPC")) {
+ PlayerData playerData = PlayerData.get(e.getPlayer());
+ for (EatExperienceSource source : getSources()) {
+ if (source.matchesParameter(playerData, e.getItem()))
+ source.giveExperience(playerData, 1, null);
+ }
}
}
};
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java
index 3a9c334d..679ec2e2 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java
@@ -3,11 +3,11 @@ package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/FishItemExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/FishItemExperienceSource.java
index 6bf23620..9a5f2184 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/FishItemExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/FishItemExperienceSource.java
@@ -3,8 +3,8 @@ package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Material;
import org.bukkit.entity.Item;
import org.bukkit.event.EventHandler;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/KillMobExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/KillMobExperienceSource.java
index 3596a77d..07adb354 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/KillMobExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/KillMobExperienceSource.java
@@ -3,16 +3,18 @@ package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.event.PlayerKillEntityEvent;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Bukkit;
+import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
+import org.bukkit.persistence.PersistentDataType;
public class KillMobExperienceSource extends SpecificExperienceSource {
public final EntityType type;
@@ -30,7 +32,7 @@ public class KillMobExperienceSource extends SpecificExperienceSource {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void a(PlayerKillEntityEvent event) {
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> {
- if (event.getTarget().isDead() && !event.getTarget().hasMetadata("spawner_spawned")) {
+ if (event.getTarget().isDead() && !event.getTarget().getPersistentDataContainer().has(new NamespacedKey(MMOCore.plugin,"spawner_spawned"),PersistentDataType.STRING)) {
PlayerData data = PlayerData.get(event.getPlayer());
for (KillMobExperienceSource source : getSources())
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/MineBlockExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/MineBlockExperienceSource.java
index 4eef178f..eaa280f0 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/MineBlockExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/MineBlockExperienceSource.java
@@ -2,10 +2,11 @@ package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.MMOLineConfig;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
@@ -15,7 +16,7 @@ import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
public class MineBlockExperienceSource extends SpecificExperienceSource {
- public final Material material;
+ private final Material material;
private final boolean silkTouch;
private final boolean crop;
@@ -39,7 +40,8 @@ public class MineBlockExperienceSource extends SpecificExperienceSource newManager() {
- return new ExperienceSourceManager() {
+ return
+ new ExperienceSourceManager() {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void a(BlockBreakEvent event) {
if (event.getPlayer().getGameMode() != GameMode.SURVIVAL)
@@ -63,11 +65,13 @@ public class MineBlockExperienceSource extends SpecificExperienceSource() {
@EventHandler
public void onMove(PlayerMoveEvent e) {
- double deltax=e.getTo().getBlockX()-e.getFrom().getBlockX();
- double deltay=e.getTo().getBlockY()-e.getFrom().getBlockY();
- double deltaz=e.getTo().getBlockZ()-e.getFrom().getBlockZ();
- if(deltax!=0&&deltay!=0&&deltaz!=0) {
- double delta=Math.sqrt(deltax*deltax+deltay*deltay+deltaz*deltaz);
- if(e.getPlayer().hasMetadata("NPC"))
+ double deltax = e.getTo().getBlockX() - e.getFrom().getBlockX();
+ double deltay = e.getTo().getBlockY() - e.getFrom().getBlockY();
+ double deltaz = e.getTo().getBlockZ() - e.getFrom().getBlockZ();
+ if (deltax != 0 || deltay != 0 || deltaz != 0) {
+
+ double delta = Math.sqrt(deltax * deltax + deltay * deltay + deltaz * deltaz);
+ if (e.getPlayer().hasMetadata("NPC"))
return;
- Player player=e.getPlayer();
- PlayerData playerData =PlayerData.get(player);
- for(MoveExperienceSource source:getSources()) {
- if(source.matchesParameter(playerData,null)) {
- giveExperience(playerData,delta,null);
+ Player player = e.getPlayer();
+ PlayerData playerData = PlayerData.get(player);
+ for (MoveExperienceSource source : getSources()) {
+ if (source.matchesParameter(playerData, null)) {
+ giveExperience(playerData, delta, null);
}
}
}
@@ -63,13 +59,13 @@ public class MoveExperienceSource extends SpecificExperienceSource {
@Override
public boolean matchesParameter(PlayerData player, Object obj) {
- return type==null||type.matches(player.getPlayer());
+ return type == null || type.matches(player.getPlayer());
}
public enum MovingType {
SNEAK(Player::isSneaking),
- FLY((p)->p.isFlying()||p.isGliding()),
- SWIM((p)->p.getLocation().getBlock().isLiquid()),
+ FLY((p) -> p.isFlying() || p.isGliding()),
+ SWIM((p) -> p.getLocation().getBlock().isLiquid()),
SPRINT(Player::isSprinting),
WALK((p) -> !p.isSneaking() && !p.isSprinting() && !p.isFlying() && !p.getLocation().getBlock().isLiquid());
@@ -80,7 +76,7 @@ public class MoveExperienceSource extends SpecificExperienceSource {
}
public boolean matches(Player player) {
- return !player.isInsideVehicle()&&matching.apply(player);
+ return !player.isInsideVehicle() && matching.apply(player);
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/PlaceBlockExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/PlaceBlockExperienceSource.java
index fcd19b70..d586609c 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/PlaceBlockExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/PlaceBlockExperienceSource.java
@@ -3,8 +3,8 @@ package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java
index d95e6a7b..e0a5a43d 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java
@@ -2,16 +2,17 @@ package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
-import org.apache.commons.lang.Validate;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.scheduler.BukkitRunnable;
+import java.util.Objects;
+
public class PlayExperienceSource extends SpecificExperienceSource {
private final World world;
@@ -25,18 +26,9 @@ public class PlayExperienceSource extends SpecificExperienceSource {
*/
public PlayExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
- if (!config.contains("in-combat"))
- inCombat = false;
- else {
- inCombat = config.getBoolean("in-combat");
- }
- if (!config.contains("world"))
- world = null;
- else {
- String name = config.getString("world");
- Validate.notNull(world = Bukkit.getWorld(name), "Could not find world " + config.getString("world"));
- }
+ inCombat = config.getBoolean("in-combat", false);
+ world = config.contains("world") ? Objects.requireNonNull(Bukkit.getWorld(config.getString("world")), "Could not find world " + config.getString("world")) : null;
if (!config.contains("x1") || !config.contains("x2")) {
x1 = Double.NEGATIVE_INFINITY;
x2 = Double.POSITIVE_INFINITY;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java
index 49647b70..bc9d7995 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java
@@ -1,18 +1,17 @@
package net.Indyuce.mmocore.experience.source;
-import de.schlichtherle.key.passwd.swing.BasicUnknownKeyFeedback;
-import io.lumine.mythic.core.skills.mechanics.ShootMechanic;
import io.lumine.mythic.lib.api.MMOLineConfig;
-import me.glaremasters.guilds.utils.BackupUtils;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;
-import org.bukkit.Bukkit;
import org.bukkit.Location;
-import org.bukkit.entity.*;
+import org.bukkit.entity.Arrow;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.Projectile;
+import org.bukkit.entity.Trident;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
@@ -21,13 +20,10 @@ import org.bukkit.scheduler.BukkitRunnable;
import java.util.Arrays;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Locale;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ProjectileExperienceSource extends SpecificExperienceSource {
-
private final ProjectileType projectileType;
public ProjectileExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
@@ -59,7 +55,7 @@ public class ProjectileExperienceSource extends SpecificExperienceSource {
private final PlayerResource resource;
-
/**
- * Gives experience when the player uses a specific resoure. If no resource is precised it will trigger for
+ * Gives experience when the player uses a specific resource type. If no type is precised it will trigger for
* mana, stamina and stellium. The amount specified si the xp given per resource consummed.
*/
public ResourceExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
- if (!config.contains("resource"))
+ if (!config.contains("type"))
resource = null;
else {
- String str = config.getString("resource").toUpperCase().replace("-", "_");
+ String str = config.getString("type").toUpperCase().replace("-", "_");
Validate.isTrue(str.equals("MANA") || str.equals("STELLIUM") || str.equals("STAMINA"),
"ResourceExperienceSource problem: The resource can only be mana, stamina or STELLIUM");
resource = PlayerResource.valueOf(str);
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java
index 9c9578ce..6841884f 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java
@@ -1,12 +1,11 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;
-import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/SmeltItemExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/SmeltItemExperienceSource.java
index 8993515d..0d745b5d 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/SmeltItemExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/SmeltItemExperienceSource.java
@@ -1,10 +1,10 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/TameExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/TameExperienceSource.java
index af7a22a4..4e2f10a6 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/TameExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/TameExperienceSource.java
@@ -1,11 +1,11 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.entity.Wolf;
@@ -13,8 +13,6 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
public class TameExperienceSource extends SpecificExperienceSource {
-
-
public TameExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
}
@@ -22,6 +20,7 @@ public class TameExperienceSource extends SpecificExperienceSource {
@Override
public ExperienceSourceManager newManager() {
return new ExperienceSourceManager() {
+
@EventHandler
public void onWolfHit(EntityDamageByEntityEvent e) {
if(e.getDamager() instanceof Wolf) {
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/type/ExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/type/ExperienceSource.java
index 66d3e7dd..96ca8e05 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/type/ExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/type/ExperienceSource.java
@@ -1,8 +1,8 @@
package net.Indyuce.mmocore.experience.source.type;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import net.Indyuce.mmocore.api.player.PlayerData;
public abstract class ExperienceSource {
private final ExperienceDispenser dispenser;
diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java
index 05cf0b3d..e877be29 100644
--- a/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java
+++ b/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java
@@ -1,11 +1,10 @@
package net.Indyuce.mmocore.experience.source.type;
import io.lumine.mythic.lib.api.MMOLineConfig;
+import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
-import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.jetbrains.annotations.Nullable;
diff --git a/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java b/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java
index 49e74717..21dd9065 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/AttributeView.java
@@ -5,14 +5,13 @@ import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.event.PlayerAttributeUseEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
-import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes.AttributeInstance;
+import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
-import net.Indyuce.mmocore.gui.api.PluginInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
-import net.Indyuce.mmocore.manager.SoundManager;
+import net.Indyuce.mmocore.player.stats.StatInfo;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.inventory.InventoryClickEvent;
@@ -46,12 +45,14 @@ public class AttributeView extends EditableInventory {
public static class AttributeItem extends InventoryItem {
private final PlayerAttribute attribute;
+ private final int shiftCost;
public AttributeItem(String function, ConfigurationSection config) {
super(config);
attribute = MMOCore.plugin.attributeManager
.get(function.substring("attribute_".length()).toLowerCase().replace(" ", "-").replace("_", "-"));
+ shiftCost = Math.max(config.getInt("shift-cost"), 1);
}
@Override
@@ -65,17 +66,22 @@ public class AttributeView extends EditableInventory {
holders.register("max", attribute.getMax());
holders.register("current", total);
holders.register("attribute_points", inv.getPlayerData().getAttributePoints());
+ holders.register("shift_points", shiftCost);
attribute.getBuffs().forEach(buff -> {
- holders.register("buff_" + buff.getStat().toLowerCase(), buff.getValue());
- holders.register("total_" + buff.getStat().toLowerCase(), buff.multiply(total).getValue());
+ StatInfo info = StatInfo.valueOf(buff.getStat());
+ holders.register("buff_" + buff.getStat().toLowerCase(), info.format(buff.getValue()));
+ holders.register("total_" + buff.getStat().toLowerCase(), info.format(buff.multiply(total).getValue()));
});
+
return holders;
}
}
public class AttributeViewerInventory extends GeneratedInventory {
+
public AttributeViewerInventory(PlayerData playerData, EditableInventory editable) {
super(playerData, editable);
+
}
@Override
@@ -117,16 +123,34 @@ public class AttributeView extends EditableInventory {
return;
}
- AttributeInstance ins = playerData.getAttributes().getInstance(attribute);
+ PlayerAttributes.AttributeInstance ins = playerData.getAttributes().getInstance(attribute);
if (attribute.hasMax() && ins.getBase() >= attribute.getMax()) {
MMOCore.plugin.configManager.getSimpleMessage("attribute-max-points-hit").send(player);
MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer());
return;
}
- ins.addBase(1);
- playerData.giveAttributePoints(-1);
- MMOCore.plugin.configManager.getSimpleMessage("attribute-level-up", "attribute", attribute.getName(), "level", "" + ins.getBase()).send(player);
+ // Amount of points spent
+ final boolean shiftClick = event.isShiftClick();
+ int pointsSpent = shiftClick ? ((AttributeItem) item).shiftCost : 1;
+ if (attribute.hasMax())
+ pointsSpent = Math.min(pointsSpent, attribute.getMax() - ins.getBase());
+
+ if (shiftClick && playerData.getAttributePoints() < pointsSpent) {
+ MMOCore.plugin.configManager.getSimpleMessage("not-attribute-point-shift", "shift_points", String.valueOf(pointsSpent)).send(player);
+ MMOCore.plugin.soundManager.getSound(SoundEvent.NOT_ENOUGH_POINTS).playTo(getPlayer());
+ return;
+ }
+
+ ins.addBase(pointsSpent);
+ playerData.giveAttributePoints(-pointsSpent);
+
+ // Apply exp table as many times as required
+ if (attribute.hasExperienceTable())
+ while (pointsSpent-- > 0)
+ attribute.getExperienceTable().claim(playerData, ins.getBase(), attribute);
+
+ MMOCore.plugin.configManager.getSimpleMessage("attribute-level-up", "attribute", attribute.getName(), "level", String.valueOf(ins.getBase())).send(player);
MMOCore.plugin.soundManager.getSound(SoundEvent.LEVEL_ATTRIBUTE).playTo(getPlayer());
PlayerAttributeUseEvent playerAttributeUseEvent = new PlayerAttributeUseEvent(playerData, attribute);
diff --git a/src/main/java/net/Indyuce/mmocore/gui/ClassConfirmation.java b/src/main/java/net/Indyuce/mmocore/gui/ClassConfirmation.java
index 6e6c65ad..dad42be6 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/ClassConfirmation.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/ClassConfirmation.java
@@ -1,18 +1,17 @@
package net.Indyuce.mmocore.gui;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
-import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.PluginInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
-import net.Indyuce.mmocore.manager.SoundManager;
+import net.Indyuce.mmocore.api.SoundEvent;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
diff --git a/src/main/java/net/Indyuce/mmocore/gui/ClassSelect.java b/src/main/java/net/Indyuce/mmocore/gui/ClassSelect.java
index dc62d6db..dea606ac 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/ClassSelect.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/ClassSelect.java
@@ -14,7 +14,6 @@ import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.manager.InventoryManager;
-import net.Indyuce.mmocore.manager.SoundManager;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.inventory.InventoryClickEvent;
@@ -83,6 +82,7 @@ public class ClassSelect extends EditableInventory {
lore.add(index + j, profess.getAttributeDescription().get(j));
}
+
meta.setLore(lore);
item.setItemMeta(meta);
return NBTItem.get(item).addTag(new ItemTag("classId", profess.getId())).toItem();
@@ -116,6 +116,12 @@ public class ClassSelect extends EditableInventory {
}
PlayerClass profess = MMOCore.plugin.classManager.get(tag);
+ if (profess.hasOption(ClassOption.NEEDS_PERMISSION) && !player.hasPermission("mmocore.class." + profess.getId().toLowerCase())) {
+ MMOCore.plugin.soundManager.getSound(SoundEvent.CANT_SELECT_CLASS).playTo(player);
+ new ConfigMessage("no-permission-for-class").send(player);
+ return;
+ }
+
if (profess.equals(playerData.getProfess())) {
MMOCore.plugin.soundManager.getSound(SoundEvent.CANT_SELECT_CLASS).playTo(player);
MMOCore.plugin.configManager.getSimpleMessage("already-on-class", "class", profess.getName()).send(player);
diff --git a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java
index 0a870c26..7c3954dc 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java
@@ -1,318 +1,349 @@
package net.Indyuce.mmocore.gui;
+import io.lumine.mythic.lib.MythicLib;
+import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.version.VersionMaterial;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.experience.Booster;
-import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
-import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
+import net.Indyuce.mmocore.experience.Booster;
+import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.party.AbstractParty;
+import net.Indyuce.mmocore.player.stats.StatInfo;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
+import java.util.Objects;
+
public class PlayerStats extends EditableInventory {
- public PlayerStats() {
- super("player-stats");
- }
+ public PlayerStats() {
+ super("player-stats");
+ }
- @Override
- public InventoryItem load(String function, ConfigurationSection config) {
+ @Override
+ public InventoryItem load(String function, ConfigurationSection config) {
- if (function.equals("boost"))
- return new BoostItem(config);
+ if (function.equals("boost"))
+ return new BoostItem(config);
- if (function.equals("boost-next"))
- return new SimplePlaceholderItem(config) {
+ if (function.equals("boost-next"))
+ return new SimplePlaceholderItem(config) {
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
- @Override
- public boolean canDisplay(PlayerStatsInventory inv) {
- InventoryItem boost = inv.getByFunction("boost");
- return boost != null && inv.boostOffset + boost.getSlots().size() < MMOCore.plugin.boosterManager.getActive().size();
- }
- };
+ @Override
+ public boolean canDisplay(PlayerStatsInventory inv) {
+ InventoryItem boost = inv.getByFunction("boost");
+ return boost != null && inv.boostOffset + boost.getSlots().size() < MMOCore.plugin.boosterManager.getActive().size();
+ }
+ };
- if (function.equals("boost-previous"))
- return new SimplePlaceholderItem(config) {
+ if (function.equals("boost-previous"))
+ return new SimplePlaceholderItem(config) {
- @Override
- public boolean canDisplay(PlayerStatsInventory inv) {
- return inv.boostOffset > 0;
- }
- };
+ @Override
+ public boolean canDisplay(PlayerStatsInventory inv) {
+ return inv.boostOffset > 0;
+ }
+ };
- if (function.equals("party"))
- return new PartyMoraleItem(config);
+ if (function.equals("party"))
+ return new PartyMoraleItem(config);
- if (function.startsWith("profession_")) {
- String id = function.substring("profession_".length()).toLowerCase();
- Validate.isTrue(MMOCore.plugin.professionManager.has(id));
- Profession profession = MMOCore.plugin.professionManager.get(id);
+ if (function.startsWith("profession_")) {
+ String id = function.substring("profession_".length()).toLowerCase();
+ Validate.isTrue(MMOCore.plugin.professionManager.has(id));
+ Profession profession = MMOCore.plugin.professionManager.get(id);
- return new InventoryItem(config) {
+ return new InventoryItem(config) {
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
- @Override
- public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
- Placeholders holders = new Placeholders();
- net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.getPlayerData().getStats();
+ Placeholders holders = new Placeholders();
+ net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.target.getStats();
- double ratio = (double) inv.getPlayerData().getCollectionSkills().getExperience(profession)
- / (double) inv.getPlayerData().getCollectionSkills().getLevelUpExperience(profession);
+ double ratio = inv.target.getCollectionSkills().getExperience(profession)
+ / (double) inv.target.getCollectionSkills().getLevelUpExperience(profession);
- String bar = "" + ChatColor.BOLD;
- int chars = (int) (ratio * 20);
- for (int j = 0; j < 20; j++)
- bar += (j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "") + "|";
+ String bar = "" + ChatColor.BOLD;
+ int chars = (int) (ratio * 20);
+ for (int j = 0; j < 20; j++)
+ bar += (j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "") + "|";
- // holders.register("profession", type.getName());
- holders.register("progress", bar);
- holders.register("level", "" + inv.getPlayerData().getCollectionSkills().getLevel(profession));
- holders.register("xp", inv.getPlayerData().getCollectionSkills().getExperience(profession));
- holders.register("percent", decimal.format(ratio * 100));
- for (StatType stat : StatType.values())
- if (stat.matches(profession))
- holders.register(stat.name().toLowerCase(), stat.format(stats.getStat(stat)));
+ // holders.register("profession", type.getName());
+ holders.register("progress", bar);
+ holders.register("level", "" + inv.target.getCollectionSkills().getLevel(profession));
+ holders.register("xp", inv.target.getCollectionSkills().getExperience(profession));
+ holders.register("percent", decimal.format(ratio * 100));
+ for (StatInfo stat : MMOCore.plugin.statManager.getLoaded())
+ if (Objects.equals(stat.profession, profession))
+ holders.register(stat.name.toLowerCase(), stat.format(stats.getStat(stat.name)));
- return holders;
- }
- };
- }
+ return holders;
+ }
+ };
+ }
- if (function.equals("profile"))
- return new PlayerProfileItem(config);
+ if (function.equals("profile"))
+ return new PlayerProfileItem(config);
- if (function.equals("stats"))
- return new InventoryItem(config) {
+ if (function.equals("stats"))
+ return new InventoryItem(config) {
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
- @Override
- public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
+ return new Placeholders() {
+ final net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.target.getStats();
- net.Indyuce.mmocore.api.player.stats.PlayerStats stats = inv.getPlayerData().getStats();
- Placeholders holders = new Placeholders();
+ public String apply(Player player, String str) {
+ while (str.contains("{") && str.substring(str.indexOf("{")).contains("}")) {
+ final String holder = str.substring(str.indexOf("{") + 1, str.indexOf("}"));
+ String replaced;
+ if (holder.endsWith("_base")) {
+ StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder.substring(0, holder.length() - 5)));
+ replaced = info.format(stats.getBase(info.name));
+ } else if (holder.endsWith("_extra")) {
+ StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder.substring(0, holder.length() - 6)));
+ replaced = info.format(MythicLib.plugin.getStats().getTotalValue(info.name, stats.getMap()) - stats.getBase(info.name));
+ } else if (holder.startsWith("attribute_")) {
+ PlayerAttribute attr = MMOCore.plugin.attributeManager.get(holder.substring(10).replace("_", "-").toLowerCase());
+ replaced = String.valueOf(inv.target.getAttributes().getAttribute(attr));
+ } else {
+ StatInfo info = StatInfo.valueOf(UtilityMethods.enumName(holder));
+ replaced = info.format(MythicLib.plugin.getStats().getTotalValue(info.name, stats.getMap()));
+ }
- for (StatType stat : StatType.values()) {
- double base = stats.getBase(stat), total = stats.getStat(stat), extra = total - base;
- holders.register(stat.name().toLowerCase(), stat.format(total));
- holders.register(stat.name().toLowerCase() + "_base", stat.format(base));
- holders.register(stat.name().toLowerCase() + "_extra", stat.format(extra));
- }
+ str = str.replace("{" + holder + "}", replaced);
+ }
- for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll())
- holders.register("attribute_" + attribute.getId().replace("-", "_"), inv.getPlayerData().getAttributes().getAttribute(attribute));
+ // External placeholders
+ return MMOCore.plugin.placeholderParser.parse(player, str);
+ }
+ };
+ }
+ };
- return holders;
- }
- };
+ return new SimplePlaceholderItem(config);
+ }
- return new SimplePlaceholderItem(config);
- }
+ public PlayerStatsInventory newInventory(PlayerData invTarget, PlayerData opening) {
+ return new PlayerStatsInventory(invTarget, opening, this);
+ }
- public PlayerStatsInventory newInventory(PlayerData data) {
- return new PlayerStatsInventory(data, this);
- }
+ public PlayerStatsInventory newInventory(PlayerData player) {
+ return new PlayerStatsInventory(player, player, this);
+ }
- public class PlayerStatsInventory extends GeneratedInventory {
- private int boostOffset;
+ public class PlayerStatsInventory extends GeneratedInventory {
+ private final PlayerData target;
- public PlayerStatsInventory(PlayerData playerData, EditableInventory editable) {
- super(playerData, editable);
- }
+ private int boostOffset;
- @Override
- public String calculateName() {
- return getName();
- }
+ /**
+ * @param invTarget Target player
+ * @param opening Player opening the inventory
+ * @param inv Corresponding editable inventory
+ */
+ public PlayerStatsInventory(PlayerData invTarget, PlayerData opening, EditableInventory inv) {
+ super(opening, inv);
- @Override
- public void whenClicked(InventoryClickEvent event, InventoryItem item) {
- if (item.hasFunction())
- if (item.getFunction().equals("boost-next")) {
- boostOffset++;
- open();
+ this.target = invTarget;
+ }
- } else if (item.getFunction().equals("boost-previous")) {
- boostOffset--;
- open();
- }
- }
- }
+ @Override
+ public String calculateName() {
+ return getName();
+ }
- private ItemStack amount(ItemStack item, int amount) {
- item.setAmount(amount);
- return item;
- }
+ @Override
+ public void whenClicked(InventoryClickEvent event, InventoryItem item) {
+ if (item.hasFunction())
+ if (item.getFunction().equals("boost-next")) {
+ boostOffset++;
+ open();
- public static class PartyMoraleItem extends InventoryItem {
- public PartyMoraleItem(ConfigurationSection config) {
- super(config);
- }
+ } else if (item.getFunction().equals("boost-previous")) {
+ boostOffset--;
+ open();
+ }
+ }
+ }
- @Override
- public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
- Placeholders holders = new Placeholders();
+ private ItemStack amount(ItemStack item, int amount) {
+ item.setAmount(amount);
+ return item;
+ }
- int count = inv.getPlayerData().getParty().getOnlineMembers().size();
- holders.register("count", "" + count);
- for (StatModifier buff : MMOCore.plugin.partyManager.getBonuses())
- holders.register("buff_" + buff.getStat().toLowerCase(), buff.multiply(count - 1).toString());
+ public static class PartyMoraleItem extends InventoryItem {
+ public PartyMoraleItem(ConfigurationSection config) {
+ super(config);
+ }
- return holders;
- }
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
+ Placeholders holders = new Placeholders();
- @Override
- public boolean canDisplay(GeneratedInventory inv) {
- AbstractParty party = inv.getPlayerData().getParty();
- return party != null && party.getOnlineMembers().size() > 1;
- }
- }
+ int count = inv.target.getParty().getOnlineMembers().size();
+ holders.register("count", "" + count);
+ for (StatModifier buff : MMOCore.plugin.partyManager.getBonuses())
+ holders.register("buff_" + buff.getStat().toLowerCase(), buff.multiply(count - 1).toString());
- public static class PlayerProfileItem extends InventoryItem {
- public PlayerProfileItem(ConfigurationSection config) {
- super(config);
- }
+ return holders;
+ }
- @Override
- public ItemStack display(GeneratedInventory inv, int n) {
- ItemStack disp = super.display(inv, n);
- if (disp.getType() == VersionMaterial.PLAYER_HEAD.toMaterial()) {
- SkullMeta meta = (SkullMeta) disp.getItemMeta();
- inv.dynamicallyUpdateItem(this, n, disp, current -> {
- meta.setOwningPlayer(inv.getPlayer());
- current.setItemMeta(meta);
- });
- }
- return disp;
- }
+ @Override
+ public boolean canDisplay(PlayerStatsInventory inv) {
+ AbstractParty party = inv.target.getParty();
+ return party != null && party.getOnlineMembers().size() > 1;
+ }
+ }
- @Override
- public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
- PlayerData data = inv.getPlayerData();
- Placeholders holders = new Placeholders();
+ public static class PlayerProfileItem extends InventoryItem {
+ public PlayerProfileItem(ConfigurationSection config) {
+ super(config);
+ }
- int nextLevelExp = inv.getPlayerData().getLevelUpExperience();
- double ratio = (double) data.getExperience() / (double) nextLevelExp;
+ @Override
+ public ItemStack display(PlayerStatsInventory inv, int n) {
+ ItemStack disp = super.display(inv, n);
+ if (disp.getType() == VersionMaterial.PLAYER_HEAD.toMaterial()) {
+ SkullMeta meta = (SkullMeta) disp.getItemMeta();
+ inv.dynamicallyUpdateItem(this, n, disp, current -> {
+ meta.setOwningPlayer(inv.target.getPlayer());
+ current.setItemMeta(meta);
+ });
+ }
+ return disp;
+ }
- StringBuilder bar = new StringBuilder("" + ChatColor.BOLD);
- int chars = (int) (ratio * 20);
- for (int j = 0; j < 20; j++)
- bar.append(j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "").append("|");
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
+ PlayerData data = inv.target;
+ Placeholders holders = new Placeholders();
- holders.register("percent", decimal.format(ratio * 100));
- holders.register("exp", "" + data.getExperience());
- holders.register("level", "" + data.getLevel());
- holders.register("class_points", "" + data.getClassPoints());
- holders.register("skill_points", "" + data.getSkillPoints());
- holders.register("attribute_points", "" + data.getAttributePoints());
- holders.register("progress", bar.toString());
- holders.register("next_level", "" + nextLevelExp);
- if (data.isOnline())
- holders.register("player", "" + data.getPlayer().getName());
- holders.register("class", "" + data.getProfess().getName());
+ int nextLevelExp = inv.target.getLevelUpExperience();
+ double ratio = (double) data.getExperience() / (double) nextLevelExp;
- return holders;
- }
- }
+ StringBuilder bar = new StringBuilder("" + ChatColor.BOLD);
+ int chars = (int) (ratio * 20);
+ for (int j = 0; j < 20; j++)
+ bar.append(j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "").append("|");
- public class BoostItem extends SimplePlaceholderItem {
- private final InventoryItem noBoost, mainLevel, profession;
+ holders.register("percent", decimal.format(ratio * 100));
+ holders.register("exp", MythicLib.plugin.getMMOConfig().decimal.format(data.getExperience()));
+ holders.register("level", "" + data.getLevel());
+ holders.register("class_points", "" + data.getClassPoints());
+ holders.register("skill_points", "" + data.getSkillPoints());
+ holders.register("attribute_points", "" + data.getAttributePoints());
+ holders.register("progress", bar.toString());
+ holders.register("next_level", "" + nextLevelExp);
+ if (data.isOnline())
+ holders.register("player", "" + data.getPlayer().getName());
+ holders.register("class", "" + data.getProfess().getName());
- public BoostItem(ConfigurationSection config) {
- super(config);
+ return holders;
+ }
+ }
- ConfigurationSection noBoost = config.getConfigurationSection("no-boost");
- Validate.notNull(noBoost, "Could not load 'no-boost' config");
- this.noBoost = new SimplePlaceholderItem(noBoost);
+ public class BoostItem extends SimplePlaceholderItem {
+ private final InventoryItem noBoost, mainLevel, profession;
- ConfigurationSection mainLevel = config.getConfigurationSection("main-level");
- Validate.notNull(mainLevel, "Could not load 'main-level' config");
- this.mainLevel = new InventoryItem(mainLevel) {
+ public BoostItem(ConfigurationSection config) {
+ super(config);
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ ConfigurationSection noBoost = config.getConfigurationSection("no-boost");
+ Validate.notNull(noBoost, "Could not load 'no-boost' config");
+ this.noBoost = new SimplePlaceholderItem(noBoost);
- @Override
- public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
- Placeholders holders = new Placeholders();
- Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
+ ConfigurationSection mainLevel = config.getConfigurationSection("main-level");
+ Validate.notNull(mainLevel, "Could not load 'main-level' config");
+ this.mainLevel = new InventoryItem(mainLevel) {
- holders.register("author", boost.hasAuthor() ? boost.getAuthor() : "Server");
- holders.register("value", (int) (boost.getExtra() * 100));
- holders.register("left", boost.isTimedOut() ?
- MMOCore.plugin.configManager.getSimpleMessage("booster-expired").message()
- : new DelayFormat(2).format(boost.getLeft()));
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
- return holders;
- }
- };
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
+ Placeholders holders = new Placeholders();
+ Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
- ConfigurationSection profession = config.getConfigurationSection("profession");
- Validate.notNull(profession, "Could not load 'profession' config");
- this.profession = new InventoryItem(profession) {
+ holders.register("author", boost.hasAuthor() ? boost.getAuthor() : "Server");
+ holders.register("value", (int) (boost.getExtra() * 100));
+ holders.register("left", boost.isTimedOut() ?
+ MMOCore.plugin.configManager.getSimpleMessage("booster-expired").message()
+ : new DelayFormat(2).format(boost.getLeft()));
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ return holders;
+ }
+ };
- @Override
- public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
- Placeholders holders = new Placeholders();
- Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
+ ConfigurationSection profession = config.getConfigurationSection("profession");
+ Validate.notNull(profession, "Could not load 'profession' config");
+ this.profession = new InventoryItem(profession) {
- holders.register("author", boost.hasAuthor() ? boost.getAuthor() : "Server");
- holders.register("profession", boost.getProfession().getName());
- holders.register("value", (int) (boost.getExtra() * 100));
- holders.register("left", boost.isTimedOut() ?
- MMOCore.plugin.configManager.getSimpleMessage("booster-expired").message()
- : new DelayFormat(2).format(boost.getLeft()));
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
- return holders;
- }
- };
- }
+ @Override
+ public Placeholders getPlaceholders(PlayerStatsInventory inv, int n) {
+ Placeholders holders = new Placeholders();
+ Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
- @Override
- public boolean hasDifferentDisplay() {
- return true;
- }
+ holders.register("author", boost.hasAuthor() ? boost.getAuthor() : "Server");
+ holders.register("profession", boost.getProfession().getName());
+ holders.register("value", (int) (boost.getExtra() * 100));
+ holders.register("left", boost.isTimedOut() ?
+ MMOCore.plugin.configManager.getSimpleMessage("booster-expired").message()
+ : new DelayFormat(2).format(boost.getLeft()));
- @Override
- public ItemStack display(PlayerStatsInventory inv, int n) {
- int offset = inv.boostOffset;
- if (n + offset >= MMOCore.plugin.boosterManager.getActive().size())
- return noBoost.display(inv, n);
+ return holders;
+ }
+ };
+ }
- Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
- return amount(boost.hasProfession() ? profession.display(inv, n) : mainLevel.display(inv, n), n + offset + 1);
- }
- }
+ @Override
+ public boolean hasDifferentDisplay() {
+ return true;
+ }
+
+ @Override
+ public ItemStack display(PlayerStatsInventory inv, int n) {
+ int offset = inv.boostOffset;
+ if (n + offset >= MMOCore.plugin.boosterManager.getActive().size())
+ return noBoost.display(inv, n);
+
+ Booster boost = MMOCore.plugin.boosterManager.get(inv.boostOffset + n);
+ return amount(boost.hasProfession() ? profession.display(inv, n) : mainLevel.display(inv, n), n + offset + 1);
+ }
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/gui/QuestViewer.java b/src/main/java/net/Indyuce/mmocore/gui/QuestViewer.java
index 66e2193d..8623599b 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/QuestViewer.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/QuestViewer.java
@@ -3,17 +3,16 @@ package net.Indyuce.mmocore.gui;
import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.SoundEvent;
-import net.Indyuce.mmocore.experience.Profession;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.quest.Quest;
-import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
-import net.Indyuce.mmocore.manager.SoundManager;
+import net.Indyuce.mmocore.api.SoundEvent;
+import net.Indyuce.mmocore.experience.Profession;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
diff --git a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java
index af983f3c..ee4393ea 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java
@@ -4,17 +4,15 @@ import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.gui.api.item.InventoryItem;
+import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
-import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
-import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
-import net.Indyuce.mmocore.manager.SkillManager;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
-import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Sound;
@@ -27,6 +25,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
+import java.util.logging.Level;
public class SkillList extends EditableInventory {
public SkillList() {
@@ -39,26 +38,11 @@ public class SkillList extends EditableInventory {
if (function.equals("skill"))
return new SkillItem(config);
-
if (function.equals("level"))
return new LevelItem(config);
if (function.equals("upgrade"))
- return new InventoryItem(config) {
-
- @Override
- public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
- RegisteredSkill selected = inv.selected==null?null:inv.selected.getSkill();
- Placeholders holders = new Placeholders();
-
- holders.register("skill_caps", selected.getName().toUpperCase());
- holders.register("skill", selected.getName());
- holders.register("skill_points", "" + inv.getPlayerData().getSkillPoints());
-
- return holders;
- }
-
- };
+ return new UpgradeItem(config);
if (function.equals("slot"))
return new InventoryItem(config) {
@@ -69,7 +53,7 @@ public class SkillList extends EditableInventory {
@Override
public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
- RegisteredSkill selected = inv.selected==null?null:inv.selected.getSkill();
+ RegisteredSkill selected = inv.selected == null ? null : inv.selected.getSkill();
RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n) ? inv.getPlayerData().getBoundSkill(n).getSkill() : null;
Placeholders holders = new Placeholders();
@@ -77,7 +61,7 @@ public class SkillList extends EditableInventory {
holders.register("skill", skill == null ? none : skill.getName());
holders.register("index", "" + (n + 1));
holders.register("slot", MMOCoreUtils.intToRoman(n + 1));
- holders.register("selected", selected==null?none:selected.getName());
+ holders.register("selected", selected == null ? none : selected.getName());
return holders;
}
@@ -115,7 +99,8 @@ public class SkillList extends EditableInventory {
@Override
public boolean canDisplay(SkillViewerInventory inv) {
- return inv.page < inv.skills.size() / 12;
+ final int perPage = inv.skillSlots.size();
+ return inv.page < (inv.skills.size() - 1) / perPage;
}
};
}
@@ -172,21 +157,15 @@ public class SkillList extends EditableInventory {
return NBTItem.get(item).addTag(new ItemTag("skillId", skill.getSkill().getHandler().getId())).toItem();
}
-
@Override
public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
return new Placeholders();
}
-
-
}
public class SkillItem extends InventoryItem {
-
-
public SkillItem(ConfigurationSection config) {
super(Material.BARRIER, config);
-
}
@Override
@@ -197,11 +176,9 @@ public class SkillList extends EditableInventory {
@Override
public ItemStack display(SkillViewerInventory inv, int n) {
- /*
- * calculate placeholders
- */
- int index=n+inv.skillSlots.size()*inv.page;
- if(index>=inv.skills.size())
+ // Calculate placeholders
+ int index = n + inv.skillSlots.size() * inv.page;
+ if (index >= inv.skills.size())
return new ItemStack(Material.AIR);
ClassSkill skill = inv.skills.get(index);
@@ -222,9 +199,7 @@ public class SkillList extends EditableInventory {
for (int j = 0; j < lore.size(); j++)
lore.set(j, ChatColor.GRAY + holders.apply(inv.getPlayer(), lore.get(j)));
- /*
- * generate item
- */
+ // Generate item
ItemStack item = skill.getSkill().getIcon();
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(holders.apply(inv.getPlayer(), getName()));
@@ -248,7 +223,35 @@ public class SkillList extends EditableInventory {
return new Placeholders();
}
}
-
+
+ public class UpgradeItem extends InventoryItem {
+ private int shiftCost=1;
+
+ public UpgradeItem(ConfigurationSection config) {
+ super(config);
+ if(config.contains("shift-cost")) {
+ this.shiftCost = config.getInt("shift-cost");
+ if (shiftCost < 1) {
+ MMOCore.log(Level.WARNING, "Upgrade shift-cost cannot be less than 1. Using default value: 1");
+ shiftCost = 1;
+ }
+ }
+
+ }
+
+ @Override
+ public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
+ RegisteredSkill selected = inv.selected == null ? null : inv.selected.getSkill();
+ Placeholders holders = new Placeholders();
+
+ holders.register("skill_caps", selected.getName().toUpperCase());
+ holders.register("skill", selected.getName());
+ holders.register("skill_points", "" + inv.getPlayerData().getSkillPoints());
+ holders.register("shift_points", shiftCost);
+ return holders;
+ }
+ }
+
public class SkillViewerInventory extends GeneratedInventory {
// Cached information
@@ -266,7 +269,7 @@ public class SkillList extends EditableInventory {
skills = new ArrayList<>(playerData.getProfess().getSkills());
skillSlots = getEditable().getByFunction("skill").getSlots();
slotSlots = getEditable().getByFunction("slot").getSlots();
- selected=skills.get(page*skillSlots.size());
+ selected = skills.get(page * skillSlots.size());
}
@Override
@@ -361,6 +364,8 @@ public class SkillList extends EditableInventory {
* upgrading a player skill
*/
if (item.getFunction().equals("upgrade")) {
+ int shiftCost = ((UpgradeItem) item).shiftCost;
+
if (!playerData.hasSkillUnlocked(selected)) {
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
@@ -378,9 +383,21 @@ public class SkillList extends EditableInventory {
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return;
}
-
- playerData.giveSkillPoints(-1);
- playerData.setSkillLevel(selected.getSkill(), playerData.getSkillLevel(selected.getSkill()) + 1);
+
+ if (event.isShiftClick()) {
+ if (playerData.getSkillPoints() < shiftCost) {
+ MMOCore.plugin.configManager.getSimpleMessage("not-enough-skill-points-shift", "shift_points", "" + shiftCost).send(player);
+ player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
+ return;
+ }
+
+ playerData.giveSkillPoints(-shiftCost);
+ playerData.setSkillLevel(selected.getSkill(), playerData.getSkillLevel(selected.getSkill()) + shiftCost);
+ } else {
+ playerData.giveSkillPoints(-1);
+ playerData.setSkillLevel(selected.getSkill(), playerData.getSkillLevel(selected.getSkill()) + 1);
+ }
+
MMOCore.plugin.configManager.getSimpleMessage("upgrade-skill", "skill", selected.getSkill().getName(), "level",
"" + playerData.getSkillLevel(selected.getSkill())).send(player);
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
diff --git a/src/main/java/net/Indyuce/mmocore/gui/SubclassConfirmation.java b/src/main/java/net/Indyuce/mmocore/gui/SubclassConfirmation.java
index cd499e10..bc64667d 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/SubclassConfirmation.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/SubclassConfirmation.java
@@ -1,9 +1,7 @@
package net.Indyuce.mmocore.gui;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
@@ -11,7 +9,8 @@ import net.Indyuce.mmocore.gui.api.PluginInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
-import net.Indyuce.mmocore.manager.SoundManager;
+import net.Indyuce.mmocore.api.SoundEvent;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.inventory.InventoryClickEvent;
diff --git a/src/main/java/net/Indyuce/mmocore/gui/SubclassSelect.java b/src/main/java/net/Indyuce/mmocore/gui/SubclassSelect.java
index d7080135..1e85268b 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/SubclassSelect.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/SubclassSelect.java
@@ -4,17 +4,16 @@ import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigMessage;
-import net.Indyuce.mmocore.api.SoundEvent;
-import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
-import net.Indyuce.mmocore.api.player.profess.Subclass;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.manager.InventoryManager;
-import net.Indyuce.mmocore.manager.SoundManager;
+import net.Indyuce.mmocore.api.ConfigMessage;
+import net.Indyuce.mmocore.api.SoundEvent;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.player.profess.Subclass;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.inventory.InventoryClickEvent;
diff --git a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java
index 1f68d5ac..668c6b15 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java
@@ -1,18 +1,17 @@
package net.Indyuce.mmocore.gui;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.gui.api.item.InventoryItem;
+import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
-import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
-import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
-import net.Indyuce.mmocore.waypoint.CostType;
import net.Indyuce.mmocore.waypoint.Waypoint;
-import net.Indyuce.mmocore.waypoint.WaypointOption;
+import net.Indyuce.mmocore.waypoint.WaypointPath;
import org.apache.commons.lang.Validate;
-import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection;
@@ -21,8 +20,12 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
+import org.jetbrains.annotations.Nullable;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
public class WaypointViewer extends EditableInventory {
public WaypointViewer() {
@@ -68,7 +71,6 @@ public class WaypointViewer extends EditableInventory {
private final SimplePlaceholderItem noWaypoint, locked;
private final WaypointItemHandler availWaypoint, noStellium, notLinked, notDynamic, currentWayPoint;
-
public WaypointItem(ConfigurationSection config) {
super(Material.BARRIER, config);
@@ -80,7 +82,6 @@ public class WaypointViewer extends EditableInventory {
Validate.notNull(config.getConfigurationSection("not-enough-stellium"), "Could not load 'not-enough-stellium' config");
Validate.notNull(config.getConfigurationSection("display"), "Could not load 'display' config");
-
noWaypoint = new SimplePlaceholderItem(config.getConfigurationSection("no-waypoint"));
locked = new SimplePlaceholderItem(config.getConfigurationSection("locked"));
notLinked = new WaypointItemHandler(config.getConfigurationSection("not-a-destination"), true);
@@ -107,7 +108,6 @@ public class WaypointViewer extends EditableInventory {
if (inv.current != null && inv.current.equals(waypoint))
return currentWayPoint.display(inv, n);
-
if (!inv.getPlayerData().hasWaypoint(waypoint))
return locked.display(inv, n);
@@ -115,7 +115,6 @@ public class WaypointViewer extends EditableInventory {
if (inv.current != null && !inv.paths.containsKey(waypoint))
return notLinked.display(inv, n);
-
// Not dynamic waypoint
if (inv.current == null && !inv.paths.containsKey(waypoint))
return notDynamic.display(inv, n);
@@ -124,7 +123,6 @@ public class WaypointViewer extends EditableInventory {
if (inv.paths.get(waypoint).getCost() > inv.getPlayerData().getStellium())
return noStellium.display(inv, n);
-
return availWaypoint.display(inv, n);
}
}
@@ -144,6 +142,16 @@ public class WaypointViewer extends EditableInventory {
// If a player can teleport to another waypoint given his location
Waypoint waypoint = inv.waypoints.get(inv.page * inv.getEditable().getByFunction("waypoint").getSlots().size() + n);
ItemMeta meta = disp.getItemMeta();
+
+ // Add waypoint lore if not empty
+ if (!waypoint.getLore().isEmpty()) {
+ List lore = meta.getLore();
+ Placeholders placeholders = new Placeholders();
+ for (String str : waypoint.getLore())
+ lore.add(0, ChatColor.GRAY + placeholders.apply(inv.getPlayer(), str));
+ meta.setLore(lore);
+ }
+
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(new NamespacedKey(MMOCore.plugin, "waypointId"), PersistentDataType.STRING, waypoint.getId());
disp.setItemMeta(meta);
@@ -160,7 +168,7 @@ public class WaypointViewer extends EditableInventory {
holders.register("current_cost", inv.paths.get(waypoint).getCost());
holders.register("normal_cost", decimal.format(inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).getCost() : Double.POSITIVE_INFINITY));
holders.register("dynamic_cost", decimal.format(waypoint.getDynamicCost()));
- holders.register("intermediary_waypoints", inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).displayIntermediaryWayPoints(inv.waypointCostType.equals(CostType.DYNAMIC_USE)) : "none");
+ holders.register("intermediary_waypoints", inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).displayIntermediaryWayPoints(inv.isDynamicUse()) : "None");
}
return holders;
@@ -169,9 +177,9 @@ public class WaypointViewer extends EditableInventory {
public class WaypointViewerInventory extends GeneratedInventory {
private final List waypoints = new ArrayList<>(MMOCore.plugin.waypointManager.getAll());
+ @Nullable
private final Waypoint current;
- private final Map paths = new HashMap<>();
- private final CostType waypointCostType;
+ private final Map paths = new HashMap<>();
private int page;
@@ -179,32 +187,29 @@ public class WaypointViewer extends EditableInventory {
super(playerData, editable);
this.current = current;
- if (current != null) {
- for (Waypoint.PathInfo pathInfo : current.getAllPath())
+ if (current != null)
+ for (WaypointPath pathInfo : current.getAllPath())
paths.put(pathInfo.getFinalWaypoint(), pathInfo);
- }
+
if (current == null) {
//Iterate through all the dynamic points and find all the points it is linked to and the path
HashMap dynamicPoints = new HashMap<>();
//We first check all the dynamic waypoints
for (Waypoint waypoint : waypoints) {
- if (waypoint.canHaveDynamicUse(playerData.getPlayer())) {
- paths.put(waypoint, new Waypoint.PathInfo(waypoint, waypoint.getDynamicCost()));
+ if (waypoint.mayBeUsedDynamically(playerData.getPlayer())) {
+ paths.put(waypoint, new WaypointPath(waypoint, waypoint.getDynamicCost()));
dynamicPoints.put(waypoint, waypoint.getDynamicCost());
}
}
- for(Waypoint source: dynamicPoints.keySet()){
- for (Waypoint.PathInfo target : source.getAllPath()) {
- if (!paths.containsKey(target.getFinalWaypoint()) || paths.get(target.getFinalWaypoint()).getCost() > target.getCost()+dynamicPoints.get(source)) {
+ for (Waypoint source : dynamicPoints.keySet()) {
+ for (WaypointPath target : source.getAllPath()) {
+ if (!paths.containsKey(target.getFinalWaypoint()) || paths.get(target.getFinalWaypoint()).getCost() > target.getCost() + dynamicPoints.get(source)) {
paths.put(target.getFinalWaypoint(), target.addCost(dynamicPoints.get(source)));
}
}
}
-
}
-
- this.waypointCostType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE;
}
@Override
@@ -212,6 +217,10 @@ public class WaypointViewer extends EditableInventory {
return getName();
}
+ public boolean isDynamicUse() {
+ return current == null;
+ }
+
@Override
public void whenClicked(InventoryClickEvent event, InventoryItem item) {
if (item.getFunction().equals("next")) {
@@ -260,7 +269,6 @@ public class WaypointViewer extends EditableInventory {
}
// Stellium cost
- CostType costType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE;
double withdraw = paths.get(waypoint).getCost();
double left = withdraw - playerData.getStellium();
if (left > 0) {
diff --git a/src/main/java/net/Indyuce/mmocore/gui/api/EditableInventory.java b/src/main/java/net/Indyuce/mmocore/gui/api/EditableInventory.java
index f650ba9d..5660ded8 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/api/EditableInventory.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/api/EditableInventory.java
@@ -40,6 +40,7 @@ public abstract class EditableInventory {
this.slots = Math.min(Math.max(9, config.getInt("slots")), 54);
Validate.isTrue((slots % 9) == 0, "Slots must be a multiple of 9");
+
items.clear();
if (config.contains("items")) {
Validate.notNull(config.getConfigurationSection("items"), "Could not load item list");
diff --git a/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java b/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java
index f01e98e2..e7c8c71b 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java
@@ -59,7 +59,7 @@ public abstract class GeneratedInventory extends PluginInventory {
@Override
public Inventory getInventory() {
- Inventory inv = Bukkit.createInventory(this, editable.getSlots(), MythicLib.plugin.parseColors(calculateName()));
+ Inventory inv = Bukkit.createInventory(this, editable.getSlots(), MythicLib.plugin.getPlaceholderParser().parse(getPlayer(), calculateName()));
for (InventoryItem item : editable.getItems())
if (item.canDisplay(this))
@@ -100,7 +100,7 @@ public abstract class GeneratedInventory extends PluginInventory {
return;
if (item instanceof TriggerItem)
- ((TriggerItem) item).getTrigger().apply(getPlayerData());
+ ((TriggerItem) item).getTriggers().forEach(trigger->trigger.apply(getPlayerData()));
else
whenClicked(event, item);
}
diff --git a/src/main/java/net/Indyuce/mmocore/gui/api/item/Placeholders.java b/src/main/java/net/Indyuce/mmocore/gui/api/item/Placeholders.java
index e6572908..48bc03ba 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/api/item/Placeholders.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/api/item/Placeholders.java
@@ -2,6 +2,7 @@ package net.Indyuce.mmocore.gui.api.item;
import net.Indyuce.mmocore.MMOCore;
import org.bukkit.entity.Player;
+import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
@@ -21,7 +22,9 @@ public class Placeholders {
// Internal placeholders
while (str.contains("{") && str.substring(str.indexOf("{")).contains("}")) {
String holder = str.substring(str.indexOf("{") + 1, str.indexOf("}"));
- str = str.replace("{" + holder + "}", placeholders.getOrDefault(holder, "Error"));
+ @Nullable String found = placeholders.get(holder);
+ if (found != null)
+ str = str.replace("{" + holder + "}", found);
}
// External placeholders
diff --git a/src/main/java/net/Indyuce/mmocore/gui/api/item/TriggerItem.java b/src/main/java/net/Indyuce/mmocore/gui/api/item/TriggerItem.java
index 28c0df3b..502bff75 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/api/item/TriggerItem.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/api/item/TriggerItem.java
@@ -4,16 +4,17 @@ import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
-import net.Indyuce.mmocore.gui.api.PluginInventory;
import org.bukkit.configuration.ConfigurationSection;
+import java.util.List;
+
public class TriggerItem extends InventoryItem {
- private final Trigger trigger;
+ private final List triggers;
public TriggerItem(ConfigurationSection config, String format) {
super(config);
- trigger = MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(format));
+ triggers = MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(format));
}
@Override
@@ -21,7 +22,7 @@ public class TriggerItem extends InventoryItem {
return new Placeholders();
}
- public Trigger getTrigger() {
- return trigger;
+ public List getTriggers() {
+ return triggers;
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/gui/eco/DepositMenu.java b/src/main/java/net/Indyuce/mmocore/gui/eco/DepositMenu.java
index 3260490c..cc1f64e8 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/eco/DepositMenu.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/eco/DepositMenu.java
@@ -1,5 +1,10 @@
package net.Indyuce.mmocore.gui.eco;
+import io.lumine.mythic.lib.api.item.NBTItem;
+import io.lumine.mythic.lib.api.util.SmartGive;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.util.MMOCoreUtils;
+import net.Indyuce.mmocore.gui.api.PluginInventory;
import net.Indyuce.mmocore.util.item.SimpleItemBuilder;
import net.milkbowl.vault.economy.EconomyResponse;
import org.bukkit.Bukkit;
@@ -12,109 +17,107 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.util.MMOCoreUtils;
-import net.Indyuce.mmocore.gui.api.PluginInventory;
-import io.lumine.mythic.lib.api.item.NBTItem;
-import io.lumine.mythic.lib.api.util.SmartGive;
-
public class DepositMenu extends PluginInventory {
- private ItemStack depositItem;
- private int deposit;
+ private ItemStack depositItem;
+ private int deposit;
- public DepositMenu(Player player) {
- super(player);
- }
+ /**
+ * Every time an item is clicked in the inventory, an inventory
+ * update is scheduled. If nothing happens for the next 10 ticks
+ * then the update is processed. If another item is clicked within
+ * this delay the task is cancelled and scheduled for later
+ */
+ private BukkitRunnable updateRunnable;
- @Override
- public Inventory getInventory() {
- Inventory inv = Bukkit.createInventory(this, 27, "Deposit");
+ public DepositMenu(Player player) {
+ super(player);
+ }
- inv.setItem(26, depositItem = new SimpleItemBuilder("DEPOSIT_ITEM").addPlaceholders("worth", "0").build());
+ @Override
+ public Inventory getInventory() {
+ Inventory inv = Bukkit.createInventory(this, 27, "Deposit");
+ updateDeposit(inv);
+ return inv;
+ }
- new BukkitRunnable() {
+ @Override
+ public void whenClicked(InventoryClickEvent event) {
+ if (event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR)
+ return;
- @Override
- public void run() {
- if (inv.getViewers().size() < 1) {
- cancel();
- return;
- }
+ if (event.getCurrentItem().isSimilar(depositItem)) {
+ event.setCancelled(true);
- updateDeposit(inv);
- }
- }.runTaskTimer(MMOCore.plugin, 0, 20);
- return inv;
- }
+ updateDeposit(event.getInventory());
+ if (deposit <= 0)
+ return;
- @Override
- public void whenClicked(InventoryClickEvent event) {
- // event.setCancelled(true);
- if (event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR)
- return;
+ EconomyResponse response = MMOCore.plugin.economy.getEconomy().depositPlayer(player, deposit);
+ if (!response.transactionSuccess())
+ return;
- if (event.getCurrentItem().isSimilar(depositItem)) {
- event.setCancelled(true);
+ event.getInventory().clear();
+ player.closeInventory();
+ player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
+ MMOCore.plugin.configManager.getSimpleMessage("deposit", "worth", String.valueOf(deposit)).send(player);
+ return;
+ }
- updateDeposit(event.getInventory());
- if (deposit <= 0)
- return;
+ int worth = NBTItem.get(event.getCurrentItem()).getInteger("RpgWorth");
+ if (worth < 1)
+ event.setCancelled(true);
+ else
+ scheduleUpdate(event.getInventory());
+ }
- EconomyResponse response = MMOCore.plugin.economy.getEconomy().depositPlayer(player, deposit);
- if (!response.transactionSuccess())
- return;
+ @Override
+ public void whenClosed(InventoryCloseEvent event) {
- event.getInventory().clear();
- player.closeInventory();
- player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
- MMOCore.plugin.configManager.getSimpleMessage("deposit", "worth", "" + deposit).send(player);
- return;
- }
+ // Cancel runnable
+ if (updateRunnable != null)
+ updateRunnable.cancel();
- int worth = NBTItem.get(event.getCurrentItem()).getInteger("RpgWorth");
- if (worth < 1) {
- event.setCancelled(true);
- }
+ // Give all items back
+ SmartGive smart = new SmartGive(player);
+ for (int j = 0; j < 26; j++) {
+ ItemStack item = event.getInventory().getItem(j);
+ if (item != null)
+ smart.give(item);
+ }
+ }
- // in deposit menu
- // if (event.getRawSlot() < 27) {
- // int empty = player.getInventory().firstEmpty();
- // if (empty < 0)
- // return;
- //
- // player.playSound(player.getLocation(), Sound.ENTITY_SHULKER_TELEPORT,
- // 1, 2);
- // player.getInventory().addItem(event.getCurrentItem());
- // event.setCurrentItem(null);
- // updateDeposit(event.getInventory());
- // return;
- // }
+ private BukkitRunnable newUpdateRunnable(Inventory inv) {
+ return new BukkitRunnable() {
- // in player inventory
- // int empty = event.getInventory().firstEmpty();
- // if (empty < 0)
- // return;
- //
- // player.playSound(player.getLocation(),
- // Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
- // event.getInventory().addItem(event.getCurrentItem());
- // event.setCurrentItem(null);
- // updateDeposit(event.getInventory());
- // return;
- }
+ @Override
+ public void run() {
+ updateDeposit(inv);
+ }
+ };
+ }
- @Override
- public void whenClosed(InventoryCloseEvent event) {
- SmartGive smart = new SmartGive(player);
- for (int j = 0; j < 26; j++) {
- ItemStack item = event.getInventory().getItem(j);
- if (item != null)
- smart.give(item);
- }
- }
+ private void scheduleUpdate(Inventory inv) {
+ if (updateRunnable != null)
+ updateRunnable.cancel();
- private void updateDeposit(Inventory inv) {
- deposit = MMOCoreUtils.getWorth(inv.getContents());
- inv.setItem(26, depositItem = new SimpleItemBuilder("DEPOSIT_ITEM").addPlaceholders("worth", "" + deposit).build());
- }
+ updateRunnable = new BukkitRunnable() {
+
+ @Override
+ public void run() {
+ updateRunnable = null;
+ updateDeposit(inv);
+ }
+ };
+ updateRunnable.runTaskLater(MMOCore.plugin, 10);
+ }
+
+ private void updateDeposit(Inventory inv) {
+ if (updateRunnable != null) {
+ updateRunnable.cancel();
+ updateRunnable = null;
+ }
+
+ deposit = MMOCoreUtils.getWorth(inv.getContents());
+ inv.setItem(26, depositItem = new SimpleItemBuilder("DEPOSIT_ITEM").addPlaceholders("worth", String.valueOf(deposit)).build());
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java b/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java
index 040ff023..fbb4f953 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java
@@ -130,8 +130,8 @@ public class EditableFriendList extends EditableInventory {
if (inv.getPlayerData().getFriends().size() <= n)
return super.display(inv, n);
- ItemStack disp = Bukkit.getOfflinePlayer(inv.getPlayerData().getFriends().get(n)).isOnline() ? online.display(inv, n) : offline.display(inv, n);
- Player friend = Bukkit.getPlayer(inv.getPlayerData().getFriends().get(n));
+ final OfflinePlayer friend = Bukkit.getOfflinePlayer(inv.getPlayerData().getFriends().get(n));
+ ItemStack disp = (friend.isOnline() ? online : offline).display(inv, n);
ItemMeta meta = disp.getItemMeta();
meta.getPersistentDataContainer().set(UUID_NAMESPACEDKEY, PersistentDataType.STRING, friend.getUniqueId().toString());
diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendRemoval.java b/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendRemoval.java
index 2ed26b27..e0ae0bea 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendRemoval.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendRemoval.java
@@ -1,11 +1,11 @@
package net.Indyuce.mmocore.gui.social.friend;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.gui.api.GeneratedInventory;
+import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.gui.api.EditableInventory;
-import net.Indyuce.mmocore.gui.api.GeneratedInventory;
-import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
import org.bukkit.OfflinePlayer;
import org.bukkit.Sound;
diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildAdmin.java b/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildAdmin.java
index accda5e7..f3a7218e 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildAdmin.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildAdmin.java
@@ -1,16 +1,14 @@
package net.Indyuce.mmocore.gui.social.guild;
-import io.lumine.mythic.lib.api.item.ItemTag;
-import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.util.input.PlayerInput.InputType;
-import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
-import net.Indyuce.mmocore.gui.api.EditableInventory;
+import net.Indyuce.mmocore.api.util.input.PlayerInput;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
-import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
+import net.Indyuce.mmocore.gui.api.EditableInventory;
+import net.Indyuce.mmocore.gui.api.item.Placeholders;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
@@ -25,6 +23,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataType;
+import java.util.List;
import java.util.UUID;
public class EditableGuildAdmin extends EditableInventory {
@@ -43,7 +42,7 @@ public class EditableGuildAdmin extends EditableInventory {
return new GuildViewInventory(data, this);
}
- public static class MemberDisplayItem extends InventoryItem {
+ public static class MemberDisplayItem extends InventoryItem {
public MemberDisplayItem(MemberItem memberItem, ConfigurationSection config) {
super(memberItem, config);
}
@@ -54,8 +53,8 @@ public class EditableGuildAdmin extends EditableInventory {
}
@Override
- public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
- PlayerData member = PlayerData.get(inv.getPlayerData().getGuild().getMembers().get(n));
+ public Placeholders getPlaceholders(GuildViewInventory inv, int n) {
+ PlayerData member = PlayerData.get(inv.members.get(n));
Placeholders holders = new Placeholders();
@@ -68,8 +67,8 @@ public class EditableGuildAdmin extends EditableInventory {
}
@Override
- public ItemStack display(GeneratedInventory inv, int n) {
- UUID uuid = inv.getPlayerData().getGuild().getMembers().get(n);
+ public ItemStack display(GuildViewInventory inv, int n) {
+ UUID uuid = inv.members.get(n);
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
ItemStack disp = super.display(inv, n);
@@ -87,7 +86,7 @@ public class EditableGuildAdmin extends EditableInventory {
}
}
- public static class MemberItem extends SimplePlaceholderItem {
+ public static class MemberItem extends SimplePlaceholderItem {
private final InventoryItem empty;
private final MemberDisplayItem member;
@@ -102,8 +101,8 @@ public class EditableGuildAdmin extends EditableInventory {
}
@Override
- public ItemStack display(GeneratedInventory inv, int n) {
- return inv.getPlayerData().getGuild().getMembers().count() > n ? member.display(inv, n) : empty.display(inv, n);
+ public ItemStack display(GuildViewInventory inv, int n) {
+ return inv.getPlayerData().getGuild().countMembers() > n ? member.display(inv, n) : empty.display(inv, n);
}
@Override
@@ -115,15 +114,23 @@ public class EditableGuildAdmin extends EditableInventory {
public class GuildViewInventory extends GeneratedInventory {
private final int max;
+ private List members;
+
public GuildViewInventory(PlayerData playerData, EditableInventory editable) {
super(playerData, editable);
max = editable.getByFunction("member").getSlots().size();
}
+ @Override
+ public void open() {
+ members = playerData.getGuild().listMembers();
+ super.open();
+ }
+
@Override
public String calculateName() {
- return getName().replace("{max}", "" + max).replace("{players}", "" + getPlayerData().getGuild().getMembers().count());
+ return getName().replace("{max}", "" + max).replace("{players}", "" + getPlayerData().getGuild().countMembers());
}
@Override
@@ -138,13 +145,13 @@ public class EditableGuildAdmin extends EditableInventory {
if (item.getFunction().equals("invite")) {
- if (playerData.getGuild().getMembers().count() >= max) {
+ if (playerData.getGuild().countMembers() >= max) {
MMOCore.plugin.configManager.getSimpleMessage("guild-is-full").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1);
return;
}
- MMOCore.plugin.configManager.newPlayerInput(player, InputType.GUILD_INVITE, (input) -> {
+ MMOCore.plugin.configManager.newPlayerInput(player, PlayerInput.InputType.GUILD_INVITE, (input) -> {
Player target = Bukkit.getPlayer(input);
if (target == null) {
MMOCore.plugin.configManager.getSimpleMessage("not-online-player", "player", input).send(player);
@@ -162,7 +169,7 @@ public class EditableGuildAdmin extends EditableInventory {
}
PlayerData targetData = PlayerData.get(target);
- if (playerData.getGuild().getMembers().has(target.getUniqueId())) {
+ if (playerData.getGuild().hasMember(target.getUniqueId())) {
MMOCore.plugin.configManager.getSimpleMessage("already-in-guild", "player", target.getName()).send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1);
open();
diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildCreation.java b/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildCreation.java
index 83e936e7..ae6e78e8 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildCreation.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildCreation.java
@@ -1,12 +1,12 @@
package net.Indyuce.mmocore.gui.social.guild;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.util.input.PlayerInput.InputType;
-import net.Indyuce.mmocore.gui.api.EditableInventory;
+import net.Indyuce.mmocore.api.util.input.PlayerInput;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.manager.data.GuildDataManager.GuildConfiguration.NamingRules;
import org.bukkit.Sound;
@@ -39,14 +39,14 @@ public class EditableGuildCreation extends EditableInventory {
return;
if (item.getFunction().equals("create")) {
- MMOCore.plugin.configManager.newPlayerInput(player, InputType.GUILD_CREATION_TAG, (input) -> {
+ MMOCore.plugin.configManager.newPlayerInput(player, PlayerInput.InputType.GUILD_CREATION_TAG, (input) -> {
if(MMOCore.plugin.dataProvider.getGuildManager().getConfig().shouldUppercaseTags())
input = input.toUpperCase();
if(check(player, input, MMOCore.plugin.dataProvider.getGuildManager().getConfig().getTagRules())) {
String tag = input;
- MMOCore.plugin.configManager.newPlayerInput(player, InputType.GUILD_CREATION_NAME, (name) -> {
+ MMOCore.plugin.configManager.newPlayerInput(player, PlayerInput.InputType.GUILD_CREATION_NAME, (name) -> {
if(check(player, name, MMOCore.plugin.dataProvider.getGuildManager().getConfig().getNameRules())) {
MMOCore.plugin.dataProvider.getGuildManager().newRegisteredGuild(playerData.getUniqueId(), name, tag);
MMOCore.plugin.dataProvider.getGuildManager().getGuild(tag.toLowerCase()).addMember(playerData.getUniqueId());
diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildView.java b/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildView.java
index 165b87e3..3ae1ccd5 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildView.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildView.java
@@ -1,15 +1,15 @@
package net.Indyuce.mmocore.gui.social.guild;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.OfflinePlayerData;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.util.input.PlayerInput.InputType;
-import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
-import net.Indyuce.mmocore.gui.api.EditableInventory;
+import net.Indyuce.mmocore.api.util.input.PlayerInput;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
-import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
+import net.Indyuce.mmocore.api.player.OfflinePlayerData;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
+import net.Indyuce.mmocore.gui.api.EditableInventory;
+import net.Indyuce.mmocore.gui.api.item.Placeholders;
import org.apache.commons.lang.Validate;
import org.bukkit.*;
import org.bukkit.configuration.ConfigurationSection;
@@ -21,6 +21,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataType;
+import java.util.List;
import java.util.UUID;
public class EditableGuildView extends EditableInventory {
@@ -35,7 +36,7 @@ public class EditableGuildView extends EditableInventory {
return function.equals("member") ? new MemberItem(config) : (function.equals("next") || function.equals("previous") || function.equals("disband") || function.equals("invite")) ? new ConditionalItem(function, config) : new SimplePlaceholderItem(config);
}
- public static class MemberDisplayItem extends InventoryItem {
+ public static class MemberDisplayItem extends InventoryItem {
public MemberDisplayItem(MemberItem memberItem, ConfigurationSection config) {
super(memberItem, config);
}
@@ -46,8 +47,8 @@ public class EditableGuildView extends EditableInventory {
}
@Override
- public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
- UUID uuid = inv.getPlayerData().getGuild().getMembers().get(n);
+ public Placeholders getPlaceholders(GuildViewInventory inv, int n) {
+ UUID uuid = inv.members.get(n);
Placeholders holders = new Placeholders();
/*
* Will never be null since a players name will always be recorded
@@ -64,8 +65,8 @@ public class EditableGuildView extends EditableInventory {
}
@Override
- public ItemStack display(GeneratedInventory inv, int n) {
- UUID uuid = inv.getPlayerData().getGuild().getMembers().get(n);
+ public ItemStack display(GuildViewInventory inv, int n) {
+ UUID uuid = inv.members.get(n);
ItemStack disp = super.display(inv, n);
ItemMeta meta = disp.getItemMeta();
@@ -99,7 +100,7 @@ public class EditableGuildView extends EditableInventory {
@Override
public ItemStack display(GuildViewInventory inv, int n) {
int index = n * inv.getPage();
- return inv.getPlayerData().getGuild().getMembers().count() > index ? member.display(inv, index) : empty.display(inv, index);
+ return inv.getPlayerData().getGuild().countMembers() > index ? member.display(inv, index) : empty.display(inv, index);
}
@Override
@@ -120,7 +121,7 @@ public class EditableGuildView extends EditableInventory {
public ItemStack display(GuildViewInventory inv, int n) {
if (function.equals("next"))
- if (inv.getPage() == (inv.getPlayerData().getGuild().getMembers().count() + 20)
+ if (inv.getPage() == (inv.getPlayerData().getGuild().countMembers() + 20)
/ inv.getByFunction("member").getSlots().size())
return null;
if (function.equals("previous") && inv.getPage() == 1)
@@ -136,19 +137,26 @@ public class EditableGuildView extends EditableInventory {
}
public class GuildViewInventory extends GeneratedInventory {
- private int page = 1;
private final int maxpages;
+ private int page = 1;
+ private List members;
+
public GuildViewInventory(PlayerData playerData, EditableInventory editable) {
super(playerData, editable);
- maxpages = (playerData.getGuild().getMembers().count() + 20)
- / editable.getByFunction("member").getSlots().size();
+ maxpages = (playerData.getGuild().countMembers() + 20) / editable.getByFunction("member").getSlots().size();
+ }
+
+ @Override
+ public void open() {
+ members = playerData.getGuild().listMembers();
+ super.open();
}
@Override
public String calculateName() {
- return getName().replace("{online_players}", "" + getPlayerData().getGuild().getMembers().countOnline()).replace("{page}", "" + page).replace("{maxpages}", "" + maxpages).replace("{players}", "" + getPlayerData().getGuild().getMembers().count()).replace("{tag}", getPlayerData().getGuild().getTag()).replace("{name}", getPlayerData().getGuild().getName());
+ return getName().replace("{online_players}", "" + getPlayerData().getGuild().countOnlineMembers()).replace("{page}", "" + page).replace("{maxpages}", "" + maxpages).replace("{players}", String.valueOf(getPlayerData().getGuild().countMembers())).replace("{tag}", getPlayerData().getGuild().getTag()).replace("{name}", getPlayerData().getGuild().getName());
}
@Override
@@ -192,7 +200,7 @@ public class EditableGuildView extends EditableInventory {
* Sound.ENTITY_VILLAGER_NO, 1, 1); return; }
*/
- MMOCore.plugin.configManager.newPlayerInput(player, InputType.GUILD_INVITE, (input) -> {
+ MMOCore.plugin.configManager.newPlayerInput(player, PlayerInput.InputType.GUILD_INVITE, (input) -> {
Player target = Bukkit.getPlayer(input);
if (target == null) {
MMOCore.plugin.configManager.getSimpleMessage("not-online-player", "player", input).send(player);
@@ -209,7 +217,7 @@ public class EditableGuildView extends EditableInventory {
}
PlayerData targetData = PlayerData.get(target);
- if (playerData.getGuild().getMembers().has(targetData.getUniqueId())) {
+ if (playerData.getGuild().hasMember(targetData.getUniqueId())) {
MMOCore.plugin.configManager.getSimpleMessage("already-in-guild", "player", target.getName()).send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1);
open();
diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyCreation.java b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyCreation.java
index c1e9b2ed..5cfdb14f 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyCreation.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyCreation.java
@@ -1,11 +1,11 @@
package net.Indyuce.mmocore.gui.social.party;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
import org.bukkit.Sound;
diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java
index ce442cf2..ec740dcd 100644
--- a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java
+++ b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java
@@ -2,7 +2,7 @@ package net.Indyuce.mmocore.gui.social.party;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.util.input.PlayerInput.InputType;
+import net.Indyuce.mmocore.api.util.input.PlayerInput;
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
@@ -148,7 +148,7 @@ public class EditablePartyView extends EditableInventory {
return;
}
- MMOCore.plugin.configManager.newPlayerInput(player, InputType.PARTY_INVITE, (input) -> {
+ MMOCore.plugin.configManager.newPlayerInput(player, PlayerInput.InputType.PARTY_INVITE, input -> {
Player target = Bukkit.getPlayer(input);
if (target == null) {
MMOCore.plugin.configManager.getSimpleMessage("not-online-player", "player", input).send(player);
@@ -172,6 +172,14 @@ public class EditablePartyView extends EditableInventory {
return;
}
+ int levelDifference = Math.abs(targetData.getLevel() - party.getLevel());
+ if (levelDifference > MMOCore.plugin.configManager.maxPartyLevelDifference) {
+ MMOCore.plugin.configManager.getSimpleMessage("high-level-difference", "player", target.getName(), "diff", String.valueOf(levelDifference)).send(player);
+ player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1);
+ open();
+ return;
+ }
+
party.sendInvite(playerData, targetData);
MMOCore.plugin.configManager.getSimpleMessage("sent-party-invite", "player", target.getName()).send(player);
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1);
diff --git a/src/main/java/net/Indyuce/mmocore/guild/AbstractGuild.java b/src/main/java/net/Indyuce/mmocore/guild/AbstractGuild.java
index 670c5a06..29694a1a 100644
--- a/src/main/java/net/Indyuce/mmocore/guild/AbstractGuild.java
+++ b/src/main/java/net/Indyuce/mmocore/guild/AbstractGuild.java
@@ -1,4 +1,11 @@
package net.Indyuce.mmocore.guild;
+import org.bukkit.entity.Player;
+
public interface AbstractGuild {
+
+ /**
+ * @return If given player is in that party
+ */
+ boolean hasMember(Player player);
}
diff --git a/src/main/java/net/Indyuce/mmocore/guild/GuildModuleType.java b/src/main/java/net/Indyuce/mmocore/guild/GuildModuleType.java
index bca192f4..cfbbaf25 100644
--- a/src/main/java/net/Indyuce/mmocore/guild/GuildModuleType.java
+++ b/src/main/java/net/Indyuce/mmocore/guild/GuildModuleType.java
@@ -1,7 +1,7 @@
package net.Indyuce.mmocore.guild;
-import net.Indyuce.mmocore.guild.compat.FactionsGuildModule;
import net.Indyuce.mmocore.guild.compat.GuildsGuildModule;
+import net.Indyuce.mmocore.guild.compat.KingdomsXGuildModule;
import net.Indyuce.mmocore.guild.compat.UltimateClansGuildModule;
import net.Indyuce.mmocore.guild.provided.MMOCoreGuildModule;
import org.bukkit.Bukkit;
@@ -9,9 +9,10 @@ import org.bukkit.Bukkit;
import javax.inject.Provider;
public enum GuildModuleType {
- FACTIONS("Factions", FactionsGuildModule::new),
+ // Useless since MythicLib already supports FactionBridge
+ // FACTIONS("Factions", FactionsGuildModule::new),
GUILDS("Guilds", GuildsGuildModule::new),
- KINGDOMSX("Guilds", GuildsGuildModule::new),
+ KINGDOMSX("KingdomsX", KingdomsXGuildModule::new),
MMOCORE("MMOCore", MMOCoreGuildModule::new),
ULTIMATE_CLANS("UltimateClans", UltimateClansGuildModule::new),
;
diff --git a/src/main/java/net/Indyuce/mmocore/guild/RelationType.java b/src/main/java/net/Indyuce/mmocore/guild/RelationType.java
new file mode 100644
index 00000000..1277296c
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/guild/RelationType.java
@@ -0,0 +1,19 @@
+package net.Indyuce.mmocore.guild;
+
+public enum RelationType {
+
+ /**
+ * In the same guild
+ */
+ ALLY,
+
+ /**
+ * One of the two players has no guild
+ */
+ NEUTRAL,
+
+ /**
+ *
+ */
+ ENEMY;
+}
diff --git a/src/main/java/net/Indyuce/mmocore/guild/compat/FactionsGuildModule.java b/src/main/java/net/Indyuce/mmocore/guild/compat/FactionsGuildModule.java
index 066b6181..bf3b4447 100644
--- a/src/main/java/net/Indyuce/mmocore/guild/compat/FactionsGuildModule.java
+++ b/src/main/java/net/Indyuce/mmocore/guild/compat/FactionsGuildModule.java
@@ -6,13 +6,20 @@ import com.massivecraft.factions.Faction;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.guild.AbstractGuild;
import net.Indyuce.mmocore.guild.GuildModule;
+import org.apache.commons.lang.NotImplementedException;
+import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
+import java.util.Objects;
+
public class FactionsGuildModule implements GuildModule {
@Override
public AbstractGuild getGuild(PlayerData playerData) {
FPlayer fPlayer = FPlayers.getInstance().getByPlayer(playerData.getPlayer());
+ if (fPlayer == null)
+ return null;
+
return fPlayer.hasFaction() ? new CustomGuild(fPlayer.getFaction()) : null;
}
@@ -22,7 +29,12 @@ public class FactionsGuildModule implements GuildModule {
private final Faction faction;
CustomGuild(Faction faction) {
- this.faction = faction;
+ this.faction = Objects.requireNonNull(faction);
+ }
+
+ @Override
+ public boolean hasMember(Player player) {
+ throw new NotImplementedException();
}
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/guild/compat/GuildsGuildModule.java b/src/main/java/net/Indyuce/mmocore/guild/compat/GuildsGuildModule.java
index bfeca8ce..2350fd88 100644
--- a/src/main/java/net/Indyuce/mmocore/guild/compat/GuildsGuildModule.java
+++ b/src/main/java/net/Indyuce/mmocore/guild/compat/GuildsGuildModule.java
@@ -5,8 +5,11 @@ import me.glaremasters.guilds.guild.Guild;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.guild.AbstractGuild;
import net.Indyuce.mmocore.guild.GuildModule;
+import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
+import java.util.Objects;
+
public class GuildsGuildModule implements GuildModule {
@Override
@@ -21,7 +24,12 @@ public class GuildsGuildModule implements GuildModule {
private final Guild guild;
CustomGuild(Guild guild) {
- this.guild = guild;
+ this.guild = Objects.requireNonNull(guild);
+ }
+
+ @Override
+ public boolean hasMember(Player player) {
+ return guild.getMember(player.getUniqueId()) != null;
}
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/guild/compat/KingdomsXGuildModule.java b/src/main/java/net/Indyuce/mmocore/guild/compat/KingdomsXGuildModule.java
index 21487d76..41eed066 100644
--- a/src/main/java/net/Indyuce/mmocore/guild/compat/KingdomsXGuildModule.java
+++ b/src/main/java/net/Indyuce/mmocore/guild/compat/KingdomsXGuildModule.java
@@ -3,18 +3,23 @@ package net.Indyuce.mmocore.guild.compat;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.guild.AbstractGuild;
import net.Indyuce.mmocore.guild.GuildModule;
+import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.kingdoms.constants.kingdom.Kingdom;
import org.kingdoms.constants.player.KingdomPlayer;
import org.kingdoms.main.Kingdoms;
+import java.util.Objects;
+
public class KingdomsXGuildModule implements GuildModule {
@Override
public AbstractGuild getGuild(PlayerData playerData) {
KingdomPlayer kPlayer = Kingdoms.get().getDataHandlers().getKingdomPlayerManager().getData(playerData.getUniqueId());
- Kingdom kingdom = kPlayer == null ? null : kPlayer.getKingdom();
+ if (kPlayer == null)
+ return null;
+
+ Kingdom kingdom = kPlayer.getKingdom();
return kingdom == null ? null : new CustomGuild(kingdom);
}
@@ -24,7 +29,12 @@ public class KingdomsXGuildModule implements GuildModule {
private final Kingdom kingdom;
CustomGuild(Kingdom kingdom) {
- this.kingdom = kingdom;
+ this.kingdom = Objects.requireNonNull(kingdom);
+ }
+
+ @Override
+ public boolean hasMember(Player player) {
+ return kingdom.isMember(player);
}
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/guild/compat/UltimateClansGuildModule.java b/src/main/java/net/Indyuce/mmocore/guild/compat/UltimateClansGuildModule.java
index 1005db38..2996a53d 100644
--- a/src/main/java/net/Indyuce/mmocore/guild/compat/UltimateClansGuildModule.java
+++ b/src/main/java/net/Indyuce/mmocore/guild/compat/UltimateClansGuildModule.java
@@ -6,8 +6,11 @@ import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.guild.AbstractGuild;
import net.Indyuce.mmocore.guild.GuildModule;
import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
+import java.util.Objects;
+
public class UltimateClansGuildModule implements GuildModule {
private static final UClans API = (UClans) Bukkit.getPluginManager().getPlugin("UltimateCLans");
@@ -22,7 +25,13 @@ public class UltimateClansGuildModule implements GuildModule {
private final ClanData clan;
CustomGuild(ClanData clan) {
- this.clan = clan;
+ this.clan = Objects.requireNonNull(clan);
+ }
+
+ @Override
+ public boolean hasMember(Player player) {
+ // List implementation. Pretty bad
+ return clan.getMembers().contains(player);
}
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/guild/provided/Guild.java b/src/main/java/net/Indyuce/mmocore/guild/provided/Guild.java
index 32106ae8..a5d624dc 100644
--- a/src/main/java/net/Indyuce/mmocore/guild/provided/Guild.java
+++ b/src/main/java/net/Indyuce/mmocore/guild/provided/Guild.java
@@ -1,164 +1,148 @@
package net.Indyuce.mmocore.guild.provided;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.function.Consumer;
-
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.gui.api.PluginInventory;
+import net.Indyuce.mmocore.gui.social.guild.EditableGuildView;
+import net.Indyuce.mmocore.manager.InventoryManager;
+import net.Indyuce.mmocore.api.ConfigMessage;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.player.social.Request;
import net.Indyuce.mmocore.guild.AbstractGuild;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigMessage;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.social.Request;
-import net.Indyuce.mmocore.gui.api.PluginInventory;
-import net.Indyuce.mmocore.gui.social.guild.EditableGuildView.GuildViewInventory;
-import net.Indyuce.mmocore.manager.InventoryManager;
+import java.util.*;
+import java.util.function.Consumer;
public class Guild implements AbstractGuild {
- private final GuildMembers members = new GuildMembers();
- private final Map invites = new HashMap<>();
- private final String guildId, guildName, guildTag;
+ private final Map invites = new HashMap<>();
+ private final String guildId, guildName, guildTag;
- /**
- * Owner changes when the old owner leaves guild
- */
- private UUID owner;
+ private final Set members = new HashSet<>();
- public Guild(UUID owner, String name, String tag) {
- this.owner = owner;
- this.guildId = tag.toLowerCase();
- this.guildName = name;
- this.guildTag = tag;
- }
+ /**
+ * Owner changes when the old owner leaves guild
+ */
+ private UUID owner;
- public UUID getOwner() {
- return owner;
- }
-
- public String getName() {
- return guildName;
- }
+ public Guild(UUID owner, String name, String tag) {
+ this.owner = owner;
+ this.guildId = tag.toLowerCase();
+ this.guildName = name;
+ this.guildTag = tag;
+ }
- public String getId() {
- return guildId;
- }
-
- public String getTag() {
- return guildTag;
- }
+ public UUID getOwner() {
+ return owner;
+ }
- public GuildMembers getMembers() {
- return members;
- }
+ public String getName() {
+ return guildName;
+ }
- public long getLastInvite(Player player) {
- return invites.containsKey(player.getUniqueId()) ? invites.get(player.getUniqueId()) : 0;
- }
+ public String getId() {
+ return guildId;
+ }
- public void removeLastInvite(Player player) {
- invites.remove(player.getUniqueId());
- }
-
- public void removeMember(UUID uuid)
- { removeMember(uuid, false); }
-
- // Disband boolean is to prevent co-modification exception when disbanding a guild
- public void removeMember(UUID uuid, boolean disband) {
- PlayerData data = PlayerData.get(uuid);
- if (data != null && data.isOnline() && data.getPlayer().getOpenInventory() != null && data.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof GuildViewInventory)
- InventoryManager.GUILD_CREATION.newInventory(data).open();
+ public String getTag() {
+ return guildTag;
+ }
- if(!disband) members.remove(uuid);
- if(data != null) data.setGuild(null);
- reopenInventories();
+ public long getLastInvite(Player player) {
+ return invites.containsKey(player.getUniqueId()) ? invites.get(player.getUniqueId()) : 0;
+ }
- //if(!disband) {
+ public void removeLastInvite(Player player) {
+ invites.remove(player.getUniqueId());
+ }
- // disband the guild if no member left
- if (members.count() < 1) {
- MMOCore.plugin.dataProvider.getGuildManager().unregisterGuild(this);
- return;
- }
+ public void removeMember(UUID uuid) {
+ removeMember(uuid, false);
+ }
- // transfer ownership
- if (owner.equals(uuid)) {
- owner = members.get(0);
- MMOCore.plugin.configManager.getSimpleMessage("transfer-guild-ownership").send(Bukkit.getPlayer(owner));
- }
- //}
- }
+ // Disband boolean is to prevent co-modification exception when disbanding a guild
+ public void removeMember(UUID uuid, boolean disband) {
+ PlayerData data = PlayerData.get(uuid);
+ if (data != null && data.isOnline() && data.getPlayer().getOpenInventory() != null && data.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof EditableGuildView.GuildViewInventory)
+ InventoryManager.GUILD_CREATION.newInventory(data).open();
- public void addMember(UUID uuid) {
- PlayerData data = PlayerData.get(uuid);
- if (data.inGuild())
- data.getGuild().removeMember(uuid);
+ if (!disband)
+ members.remove(uuid);
+ if (data != null)
+ data.setGuild(null);
+ reopenInventories();
- data.setGuild(this);
- members.add(uuid);
+ // Disband the guild if no member left
+ if (members.size() < 1) {
+ MMOCore.plugin.dataProvider.getGuildManager().unregisterGuild(this);
+ return;
+ }
- reopenInventories();
- }
-
- public void registerMember(UUID uuid) {
- members.add(uuid);
- }
+ // Transfer ownership
+ if (owner.equals(uuid)) {
+ owner = members.stream().findAny().get();
+ MMOCore.plugin.configManager.getSimpleMessage("transfer-guild-ownership").send(Bukkit.getPlayer(owner));
+ }
+ }
- public void reopenInventories() {
- for (UUID uuid : members.members) {
- PlayerData member = PlayerData.get(uuid);
- if (member != null && member.isOnline() && member.getPlayer().getOpenInventory() != null && member.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof GuildViewInventory)
- ((PluginInventory) member.getPlayer().getOpenInventory().getTopInventory().getHolder()).open();
- }
- }
+ public void addMember(UUID uuid) {
+ PlayerData data = PlayerData.get(uuid);
+ if (data.inGuild())
+ data.getGuild().removeMember(uuid);
- public void sendGuildInvite(PlayerData inviter, PlayerData target) {
- invites.put(target.getUniqueId(), System.currentTimeMillis());
- Request request = new GuildInvite(this, inviter, target);
- new ConfigMessage("guild-invite").addPlaceholders("player", inviter.getPlayer().getName(), "uuid", request.getUniqueId().toString()).sendAsJSon(target.getPlayer());
- MMOCore.plugin.requestManager.registerRequest(request);
- }
-
- public static class GuildMembers {
- private final List members = new ArrayList<>();
+ data.setGuild(this);
+ members.add(uuid);
- public UUID get(int count) {
- return members.get(count);
- }
+ reopenInventories();
+ }
- public boolean has(UUID player) {
- return members.contains(player);
- }
+ public void registerMember(UUID uuid) {
+ members.add(uuid);
+ }
- public void add(UUID player) {
- members.add(player);
- }
+ public void reopenInventories() {
+ for (UUID uuid : members) {
+ PlayerData member = PlayerData.get(uuid);
+ if (member != null && member.isOnline() && member.getPlayer().getOpenInventory() != null && member.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof EditableGuildView.GuildViewInventory)
+ ((PluginInventory) member.getPlayer().getOpenInventory().getTopInventory().getHolder()).open();
+ }
+ }
- public void remove(UUID player) {
- members.remove(player);
- }
+ public void sendGuildInvite(PlayerData inviter, PlayerData target) {
+ invites.put(target.getUniqueId(), System.currentTimeMillis());
+ Request request = new GuildInvite(this, inviter, target);
+ new ConfigMessage("guild-invite").addPlaceholders("player", inviter.getPlayer().getName(), "uuid", request.getUniqueId().toString()).sendAsJSon(target.getPlayer());
+ MMOCore.plugin.requestManager.registerRequest(request);
+ }
- public void forEach(Consumer super UUID> action) {
- members.forEach(action);
- }
+ @Override
+ public boolean hasMember(Player player) {
+ return hasMember(player.getUniqueId());
+ }
- public int countOnline() {
- int online = 0;
-
- for(UUID member : members)
- if(Bukkit.getOfflinePlayer(member).isOnline())
- online += 1;
-
- return online;
- }
+ public boolean hasMember(UUID player) {
+ return members.contains(player);
+ }
- public int count()
- { return members.size(); }
- public void clear()
- { members.clear(); }
- }
+ public List listMembers() {
+ return new ArrayList<>(members);
+ }
+
+ public void forEachMember(Consumer super UUID> action) {
+ members.forEach(action);
+ }
+
+ public int countOnlineMembers() {
+ int online = 0;
+
+ for (UUID member : members)
+ if (Bukkit.getOfflinePlayer(member).isOnline())
+ online++;
+
+ return online;
+ }
+
+ public int countMembers() {
+ return members.size();
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/guild/provided/GuildInvite.java b/src/main/java/net/Indyuce/mmocore/guild/provided/GuildInvite.java
index 7e908639..f7a78108 100644
--- a/src/main/java/net/Indyuce/mmocore/guild/provided/GuildInvite.java
+++ b/src/main/java/net/Indyuce/mmocore/guild/provided/GuildInvite.java
@@ -1,9 +1,9 @@
package net.Indyuce.mmocore.guild.provided;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.social.Request;
-import net.Indyuce.mmocore.manager.InventoryManager;
import org.bukkit.Bukkit;
public class GuildInvite extends Request {
@@ -27,7 +27,7 @@ public class GuildInvite extends Request {
@Override
public void whenAccepted() {
guild.removeLastInvite(getCreator().getPlayer());
- guild.getMembers().forEach(member -> {
+ guild.forEachMember(member -> {
if (Bukkit.getPlayer(member) != null) {
MMOCore.plugin.configManager.getSimpleMessage("guild-joined-other", "player",
getTarget().getPlayer().getName()).send(Bukkit.getPlayer(member));
diff --git a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java
index 2ff6c505..70d6a3d5 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java
@@ -1,10 +1,9 @@
package net.Indyuce.mmocore.listener;
+import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods;
-import io.lumine.mythic.utils.Schedulers;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.block.BlockInfo;
-import net.Indyuce.mmocore.api.block.BlockInfo.BlockInfoOption;
import net.Indyuce.mmocore.api.block.VanillaBlockType;
import net.Indyuce.mmocore.api.event.CustomBlockMineEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
@@ -106,7 +105,7 @@ public class BlockListener implements Listener {
* decreases the durability of the item
* used to mine the block.
*/
- if (!info.getOption(BlockInfoOption.VANILLA_DROPS)) {
+ if (!info.getOption(BlockInfo.BlockInfoOption.VANILLA_DROPS)) {
event.setCancelled(true);
event.getBlock().setType(Material.AIR);
MMOCoreUtils.decreaseDurability(player, EquipmentSlot.HAND, 1);
@@ -137,7 +136,7 @@ public class BlockListener implements Listener {
* Finally enable block regen.
*/
if (info.hasRegen())
- Schedulers.sync().runLater(() -> MMOCore.plugin.mineManager.initialize(info.startRegeneration(Bukkit.createBlockData(savedData), block.getLocation()), !temporaryBlock), 1);
+ Bukkit.getScheduler().runTaskLater(MythicLib.plugin, () -> MMOCore.plugin.mineManager.initialize(info.startRegeneration(Bukkit.createBlockData(savedData), block.getLocation()), !temporaryBlock), 1);
}
/**
@@ -185,9 +184,9 @@ public class BlockListener implements Listener {
}
}
- /*
- * Allows to mark cobblestone generated by cobblestone generators so that
- * exp is not gained by these blocks
+ /**
+ * Allows to mark cobblestone generated by cobblestone generators
+ * so that experience is not gained by these blocks
*/
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void cobblestoneGeneratorHandling(BlockFormEvent event) {
@@ -196,7 +195,7 @@ public class BlockListener implements Listener {
if (MMOCore.plugin.configManager.cobbleGeneratorXP) return;
if (event.getBlock().getType() == Material.WATER || event.getBlock().getType() == Material.LAVA)
- if (event.getNewState().getType() == Material.COBBLESTONE || event.getNewState().getType() == Material.OBSIDIAN)
+ if (MythicLib.plugin.getVersion().getWrapper().isGeneratorOutput(event.getNewState().getType()))
event.getNewState().setMetadata("player_placed", new FixedMetadataValue(MMOCore.plugin, true));
}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java b/src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java
index 44612aea..465b66cb 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java
@@ -52,7 +52,7 @@ public class ClassTriggers implements Listener {
public void onAttack(PlayerAttackEvent event) {
for (Map.Entry entry : damageTriggers.entrySet())
if (event.getDamage().hasType(entry.getKey()))
- applyTriggers(event.getPlayer(), entry.getValue()); //, () -> new TriggerMetadata(event.getAttack(), event.getEntity())
+ applyTriggers(event.getPlayer(), entry.getValue(), () -> new TriggerMetadata(event.getAttack(), event.getEntity()));
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
@@ -88,6 +88,16 @@ public class ClassTriggers implements Listener {
return applyTriggers(PlayerData.get(player), type, triggerMetaProvider);
}
+ /**
+ * Apply class shortcut skills from a specific class trigger type.
+ *
+ * @param player Player triggering
+ * @param type Trigger type
+ * @param triggerMetaProvider Small optimization: if no shortcut skill is found
+ * with the corresponding trigger type, trigger meta
+ * is not calculated which saves computations
+ * @return Skill result or null if no shortcut skill was cast
+ */
@Nullable
private SkillResult applyTriggers(PlayerData player, ClassTriggerType type, Provider triggerMetaProvider) {
ClassTrigger trigger = player.getProfess().getClassTrigger(type);
diff --git a/src/main/java/net/Indyuce/mmocore/listener/GuildListener.java b/src/main/java/net/Indyuce/mmocore/listener/GuildListener.java
index c94ce3f0..4e25df06 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/GuildListener.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/GuildListener.java
@@ -1,5 +1,8 @@
package net.Indyuce.mmocore.listener;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.event.social.GuildChatEvent;
+import net.Indyuce.mmocore.manager.ConfigManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -7,10 +10,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.event.social.GuildChatEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.manager.ConfigManager.SimpleMessage;
public class GuildListener implements Listener {
@EventHandler(priority = EventPriority.LOW)
@@ -28,11 +28,11 @@ public class GuildListener implements Listener {
* running it in a delayed task is recommended
*/
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> {
- SimpleMessage format = MMOCore.plugin.configManager.getSimpleMessage("guild-chat", "player", data.getPlayer().getName(), "tag", data.getGuild().getTag(), "message", event.getMessage().substring(MMOCore.plugin.dataProvider.getGuildManager().getConfig().getPrefix().length()));
+ ConfigManager.SimpleMessage format = MMOCore.plugin.configManager.getSimpleMessage("guild-chat", "player", data.getPlayer().getName(), "tag", data.getGuild().getTag(), "message", event.getMessage().substring(MMOCore.plugin.dataProvider.getGuildManager().getConfig().getPrefix().length()));
GuildChatEvent called = new GuildChatEvent(data, format.message());
Bukkit.getPluginManager().callEvent(called);
if (!called.isCancelled())
- data.getGuild().getMembers().forEach(member -> {
+ data.getGuild().forEachMember(member -> {
Player p = Bukkit.getPlayer(member);
if (p != null)
format.send(p);
diff --git a/src/main/java/net/Indyuce/mmocore/listener/LootableChestsListener.java b/src/main/java/net/Indyuce/mmocore/listener/LootableChestsListener.java
index b7f837d3..06cdf5ad 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/LootableChestsListener.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/LootableChestsListener.java
@@ -1,22 +1,36 @@
package net.Indyuce.mmocore.listener;
-import org.bukkit.block.Chest;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.inventory.InventoryCloseEvent;
-
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.loot.chest.LootChest;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.block.Chest;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.BlockBreakEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
public class LootableChestsListener implements Listener {
- @EventHandler
- public void a(InventoryCloseEvent event) {
- if (!(event.getInventory().getHolder() instanceof Chest))
- return;
- Chest chest = (Chest) event.getInventory().getHolder();
- LootChest lootChest = MMOCore.plugin.lootChests.getChest(chest.getLocation());
- if (lootChest != null)
- lootChest.expire(true);
- }
+ @EventHandler
+ public void expireOnClose(InventoryCloseEvent event) {
+ if (!(event.getInventory().getHolder() instanceof Chest))
+ return;
+
+ Chest chest = (Chest) event.getInventory().getHolder();
+ LootChest lootChest = MMOCore.plugin.lootChests.getChest(chest.getLocation());
+ if (lootChest != null)
+ lootChest.expire(true);
+ }
+
+ @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH)
+ public void noBreaking(BlockBreakEvent event) {
+ Block block = event.getBlock();
+ if (block.getType() == Material.CHEST) {
+ LootChest lootChest = MMOCore.plugin.lootChests.getChest(block.getLocation());
+ if (lootChest != null)
+ event.setCancelled(true);
+ }
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/WaypointsListener.java b/src/main/java/net/Indyuce/mmocore/listener/WaypointsListener.java
index f49dc3ca..d48ed573 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/WaypointsListener.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/WaypointsListener.java
@@ -2,12 +2,12 @@ package net.Indyuce.mmocore.listener;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.waypoint.Waypoint;
+import net.Indyuce.mmocore.waypoint.WaypointOption;
import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
import net.Indyuce.mmocore.manager.InventoryManager;
-import net.Indyuce.mmocore.waypoint.Waypoint;
-import net.Indyuce.mmocore.waypoint.WaypointOption;
import org.bukkit.Particle;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -52,7 +52,19 @@ public class WaypointsListener implements Listener {
return;
NBTItem nbtItem = NBTItem.get(event.getItem());
- if (Objects.equals(nbtItem.getString("MMOCoreItemId"), "WAYPOINT_BOOK"))
- InventoryManager.WAYPOINTS.newInventory(PlayerData.get(event.getPlayer())).open();
+ if (Objects.equals(nbtItem.getString("MMOCoreItemId"), "WAYPOINT_BOOK")) {
+ String waypointId = nbtItem.getString("WaypointBookId");
+ Waypoint waypoint = MMOCore.plugin.waypointManager.get(waypointId);
+ if (waypoint == null)
+ return;
+
+ PlayerData playerData = PlayerData.get(event.getPlayer());
+ if (playerData.hasWaypoint(waypoint))
+ return;
+
+ playerData.unlockWaypoint(waypoint);
+ event.getItem().setAmount(event.getItem().getAmount() - 1); // Consume item
+ MMOCore.plugin.configManager.getSimpleMessage("new-waypoint-book", "waypoint", waypoint.getName()).send(event.getPlayer());
+ }
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/bungee/GetMMOCorePlayerListener.java b/src/main/java/net/Indyuce/mmocore/listener/bungee/GetMMOCorePlayerListener.java
new file mode 100644
index 00000000..81e40242
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/listener/bungee/GetMMOCorePlayerListener.java
@@ -0,0 +1,21 @@
+package net.Indyuce.mmocore.listener.bungee;
+
+import com.google.common.io.ByteArrayDataInput;
+import com.google.common.io.ByteStreams;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.messaging.PluginMessageListener;
+
+import java.util.UUID;
+
+public class GetMMOCorePlayerListener implements PluginMessageListener {
+ @Override
+ public void onPluginMessageReceived( String channel, Player player, byte[] bytes) {
+ if(!channel.equals("give_mmocore_player"))
+ return;
+ ByteArrayDataInput input= ByteStreams.newDataInput(bytes);
+ UUID uuid=UUID.fromString(input.readUTF());
+ String Json=input.readUTF();
+ }
+
+
+}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/option/DeathExperienceLoss.java b/src/main/java/net/Indyuce/mmocore/listener/option/DeathExperienceLoss.java
index b6afa74d..410f8ee1 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/option/DeathExperienceLoss.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/option/DeathExperienceLoss.java
@@ -1,25 +1,25 @@
-package net.Indyuce.mmocore.listener.option;
-
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigMessage;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.EventPriority;
-import org.bukkit.event.Listener;
-import org.bukkit.event.entity.PlayerDeathEvent;
-
-public class DeathExperienceLoss implements Listener {
- private final double loss = MMOCore.plugin.getConfig().getDouble("death-exp-loss.percent") / 100;
-
- @EventHandler(priority = EventPriority.HIGH)
- public void a(PlayerDeathEvent event) {
- if (!PlayerData.has(event.getEntity()))
- return;
-
- PlayerData data = PlayerData.get(event.getEntity());
- int loss = (int) (data.getExperience() * this.loss);
- data.setExperience(data.getExperience() - loss);
- if (data.isOnline())
- new ConfigMessage("death-exp-loss").addPlaceholders("loss", "" + loss).send(data.getPlayer());
- }
-}
+package net.Indyuce.mmocore.listener.option;
+
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.ConfigMessage;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.PlayerDeathEvent;
+
+public class DeathExperienceLoss implements Listener {
+ private final double loss = MMOCore.plugin.getConfig().getDouble("death-exp-loss.percent") / 100;
+
+ @EventHandler(priority = EventPriority.HIGH)
+ public void a(PlayerDeathEvent event) {
+ if (!PlayerData.has(event.getEntity()))
+ return;
+
+ PlayerData data = PlayerData.get(event.getEntity());
+ int loss = (int) (data.getExperience() * this.loss);
+ data.setExperience(data.getExperience() - loss);
+ if (data.isOnline())
+ new ConfigMessage("death-exp-loss").addPlaceholders("loss", "" + loss).send(data.getPlayer());
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/option/HotbarSwap.java b/src/main/java/net/Indyuce/mmocore/listener/option/HotbarSwap.java
index 157c9211..6945b610 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/option/HotbarSwap.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/option/HotbarSwap.java
@@ -2,8 +2,8 @@ package net.Indyuce.mmocore.listener.option;
import io.lumine.mythic.lib.UtilityMethods;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent;
+import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.skill.cast.PlayerKey;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
diff --git a/src/main/java/net/Indyuce/mmocore/listener/option/NoSpawnerEXP.java b/src/main/java/net/Indyuce/mmocore/listener/option/NoSpawnerEXP.java
index 192644f7..6a03f24d 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/option/NoSpawnerEXP.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/option/NoSpawnerEXP.java
@@ -1,17 +1,20 @@
-package net.Indyuce.mmocore.listener.option;
-
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.entity.CreatureSpawnEvent;
-import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
-import org.bukkit.metadata.FixedMetadataValue;
-
-import net.Indyuce.mmocore.MMOCore;
-
-public class NoSpawnerEXP implements Listener {
- @EventHandler
- public void a(CreatureSpawnEvent event) {
- if(event.getSpawnReason() == SpawnReason.SPAWNER)
- event.getEntity().setMetadata("spawner_spawned", new FixedMetadataValue(MMOCore.plugin, true));
- }
-}
+package net.Indyuce.mmocore.listener.option;
+
+import net.Indyuce.mmocore.MMOCore;
+import org.bukkit.Bukkit;
+import org.bukkit.NamespacedKey;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
+import org.bukkit.metadata.FixedMetadataValue;
+import org.bukkit.persistence.PersistentDataType;
+
+public class NoSpawnerEXP implements Listener {
+ @EventHandler
+ public void onSpawn(CreatureSpawnEvent event) {
+ if(event.getSpawnReason() == SpawnReason.SPAWNER) {
+ event.getEntity().getPersistentDataContainer().set(new NamespacedKey(MMOCore.plugin,"spawner_spawned"), PersistentDataType.STRING,"true");
+ }
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/option/PlayerProfileCheck.java b/src/main/java/net/Indyuce/mmocore/listener/option/PlayerProfileCheck.java
index eab9afe3..5ff87df0 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/option/PlayerProfileCheck.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/option/PlayerProfileCheck.java
@@ -8,7 +8,6 @@ import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEntityEvent;
-import org.bukkit.inventory.Inventory;
public class PlayerProfileCheck implements Listener {
@@ -17,14 +16,6 @@ public class PlayerProfileCheck implements Listener {
if (event.getRightClicked().getType() != EntityType.PLAYER || !event.getPlayer().isSneaking() || !MythicLib.plugin.getEntities().canTarget(event.getPlayer(), event.getRightClicked(), InteractionType.SUPPORT_ACTION))
return;
- /*
- * This works because the PlayerStats class DOES NOT utilize
- * at all the player instance saved in the InventoryClickEvent
- *
- * Opening inventories like that to other players does NOT
- * necessarily works for any other custom inventory.
- * */
- Inventory inv = InventoryManager.PLAYER_STATS.newInventory(PlayerData.get(event.getRightClicked().getUniqueId())).getInventory();
- event.getPlayer().openInventory(inv);
+ InventoryManager.PLAYER_STATS.newInventory(PlayerData.get(event.getRightClicked().getUniqueId()), PlayerData.get(event.getPlayer())).open();
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java b/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java
index 49a19c45..b7d37027 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java
@@ -1,23 +1,20 @@
-package net.Indyuce.mmocore.listener.option;
-
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.player.PlayerExpChangeEvent;
-
-import net.Indyuce.mmocore.experience.EXPSource;
-import net.Indyuce.mmocore.api.player.PlayerData;
-
-public class RedirectVanillaExp implements Listener {
- private final double ratio;
-
- public RedirectVanillaExp(double ratio) {
- this.ratio = ratio;
- }
-
- @EventHandler
- public void a(PlayerExpChangeEvent event) {
- double a = (event.getAmount() * ratio);
- if (a > 0)
- PlayerData.get(event.getPlayer()).giveExperience(a, EXPSource.VANILLA);
- }
-}
+package net.Indyuce.mmocore.listener.option;
+
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.experience.EXPSource;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerExpChangeEvent;
+
+public class RedirectVanillaExp implements Listener {
+ private final double ratio;
+
+ public RedirectVanillaExp(double ratio) {
+ this.ratio = ratio;
+ }
+
+ @EventHandler
+ public void a(PlayerExpChangeEvent event) {
+ PlayerData.get(event.getPlayer()).giveExperience(event.getAmount() * ratio, EXPSource.VANILLA);
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/option/VanillaExperienceOverride.java b/src/main/java/net/Indyuce/mmocore/listener/option/VanillaExperienceOverride.java
index 14b22c46..530390f7 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/option/VanillaExperienceOverride.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/option/VanillaExperienceOverride.java
@@ -1,35 +1,35 @@
-package net.Indyuce.mmocore.listener.option;
-
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.EventPriority;
-import org.bukkit.event.Listener;
-import org.bukkit.event.enchantment.EnchantItemEvent;
-import org.bukkit.event.player.PlayerExpChangeEvent;
-
-public class VanillaExperienceOverride implements Listener {
-
- /**
- * When picking up exp orbs or any action like that
- */
- @EventHandler(priority = EventPriority.HIGHEST)
- public void a(PlayerExpChangeEvent event) {
- event.setAmount(0);
- }
-
- /**
- * This event is not supported by the expChangeEvent. Since the event is
- * actually called before applying the enchant and consuming levels, we must
- * update the player level using a delayed task.
- *
- * {@link EnchantItemEvent#setExpLevelCost(int)} does NOT work
- */
- @EventHandler
- public void b(EnchantItemEvent event) {
- Player player = event.getEnchanter();
- Bukkit.getScheduler().runTask(MMOCore.plugin, () -> player.setLevel(PlayerData.get(player).getLevel()));
- }
-}
+package net.Indyuce.mmocore.listener.option;
+
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.enchantment.EnchantItemEvent;
+import org.bukkit.event.player.PlayerExpChangeEvent;
+
+public class VanillaExperienceOverride implements Listener {
+
+ /**
+ * When picking up exp orbs or any action like that
+ */
+ @EventHandler(priority = EventPriority.HIGHEST)
+ public void a(PlayerExpChangeEvent event) {
+ event.setAmount(0);
+ }
+
+ /**
+ * This event is not supported by the expChangeEvent. Since the event is
+ * actually called before applying the enchant and consuming levels, we must
+ * update the player level using a delayed task.
+ *
+ * {@link EnchantItemEvent#setExpLevelCost(int)} does NOT work
+ */
+ @EventHandler
+ public void b(EnchantItemEvent event) {
+ Player player = event.getEnchanter();
+ Bukkit.getScheduler().runTask(MMOCore.plugin, () -> player.setLevel(PlayerData.get(player).getLevel()));
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java b/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java
index fe678f07..87719b7a 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java
@@ -3,12 +3,11 @@ package net.Indyuce.mmocore.listener.profession;
import io.lumine.mythic.lib.version.VersionSound;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.CustomPlayerFishEvent;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.stats.StatType;
-import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.experience.EXPSource;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.loot.LootBuilder;
-import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem;
+import net.Indyuce.mmocore.loot.fishing.FishingDropItem;
import net.Indyuce.mmocore.manager.profession.FishingManager.FishingDropTable;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -84,7 +83,7 @@ public class FishingListener implements Listener {
this.playerData = PlayerData.get(this.player = player);
this.hook = hook;
- this.fishStrength = (int) Math.floor(caught.rollTugs() * (1 - PlayerData.get(player).getStats().getStat(StatType.FISHING_STRENGTH) / 100));
+ this.fishStrength = (int) Math.floor(caught.rollTugs() * (1 - PlayerData.get(player).getStats().getStat("FISHING_STRENGTH") / 100));
this.experienceDropped = caught.rollExperience();
fishing.add(player.getUniqueId());
@@ -148,7 +147,7 @@ public class FishingListener implements Listener {
return;
}
- if (currentPulls == 0 && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat(StatType.CRITICAL_FISHING_CHANCE) / 100)
+ if (currentPulls == 0 && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat("CRITICAL_FISHING_CHANCE") / 100)
setCriticalFish();
// Check if enough pulls; if not, wait till the next fish event
@@ -165,7 +164,7 @@ public class FishingListener implements Listener {
(mainhand != null && mainhand.getType() == Material.FISHING_ROD) ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND, 1);
// Critical fishing failure
- if (!isCriticalFish() && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat(StatType.CRITICAL_FISHING_FAILURE_CHANCE) / 100) {
+ if (!isCriticalFish() && RANDOM.nextDouble() < PlayerData.get(player).getStats().getStat("CRITICAL_FISHING_FAILURE_CHANCE") / 100) {
player.setVelocity(hook.getLocation().subtract(player.getLocation()).toVector().setY(0).multiply(3).setY(.5));
hook.getWorld().spawnParticle(Particle.SMOKE_NORMAL, location, 24, 0, 0, 0, .08);
return;
@@ -198,7 +197,7 @@ public class FishingListener implements Listener {
location.getWorld().spawnParticle(Particle.FIREWORKS_SPARK, location, 0, 4 * (RANDOM.nextDouble() - .5), RANDOM.nextDouble() + 1, 4 * (RANDOM.nextDouble() - .5), .08);
if (MMOCore.plugin.fishingManager.hasLinkedProfession())
- playerData.getCollectionSkills().giveExperience(MMOCore.plugin.fishingManager.getLinkedProfession(), experienceDropped, EXPSource.FISHING, location);
+ playerData.getCollectionSkills().giveExperience(MMOCore.plugin.fishingManager.getLinkedProfession(), experienceDropped, EXPSource.FISHING, location, true);
}
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/listener/profession/PlayerCollectStats.java b/src/main/java/net/Indyuce/mmocore/listener/profession/PlayerCollectStats.java
index ce81b963..795d6ed7 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/profession/PlayerCollectStats.java
+++ b/src/main/java/net/Indyuce/mmocore/listener/profession/PlayerCollectStats.java
@@ -1,7 +1,8 @@
package net.Indyuce.mmocore.listener.profession;
-import java.util.Random;
-
+import io.lumine.mythic.lib.MythicLib;
+import net.Indyuce.mmocore.api.event.CustomBlockMineEvent;
+import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.entity.Player;
@@ -11,10 +12,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
-import net.Indyuce.mmocore.api.event.CustomBlockMineEvent;
-import net.Indyuce.mmocore.api.player.stats.StatType;
-import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
-import io.lumine.mythic.lib.MythicLib;
+import java.util.Random;
public class PlayerCollectStats implements Listener {
private static final Random random = new Random();
@@ -23,26 +21,26 @@ public class PlayerCollectStats implements Listener {
public void a(CustomBlockMineEvent event) {
Player player = event.getPlayer();
- // give haste if right enchant
- double h = event.getData().getStats().getStat(StatType.GATHERING_HASTE);
+ // Give haste if right enchant
+ double h = event.getData().getStats().getStat("GATHERING_HASTE");
if (h > 0 && random.nextDouble() < h * .045) {
new SmallParticleEffect(player, Particle.SPELL_INSTANT);
player.removePotionEffect(PotionEffectType.FAST_DIGGING);
player.addPotionEffect(new PotionEffect(PotionEffectType.FAST_DIGGING, (int) (10 * h), (int) (1 + h / 7)));
}
- // drop more items if fortune enchant
- double f = event.getData().getStats().getStat(StatType.FORTUNE);
+ // Drop more items if fortune enchant
+ double f = event.getData().getStats().getStat("FORTUNE");
if (f > 0 && random.nextDouble() < f * .045) {
int a = (int) (1.5 * Math.sqrt(f / 1.1));
for (ItemStack item : event.getDrops())
item.setAmount(item.getAmount() + a);
}
- if(MythicLib.plugin.getVersion().getWrapper().isCropFullyGrown(event.getBlock()))
- {
- // drop more items if fortune enchant
- double l = event.getData().getStats().getStat(StatType.LUCK_OF_THE_FIELD);
+ if (MythicLib.plugin.getVersion().getWrapper().isCropFullyGrown(event.getBlock())) {
+
+ // Drop more CROP items
+ double l = event.getData().getStats().getStat("LUCK_OF_THE_FIELD");
if (l > 0 && random.nextDouble() < l * .045) {
int a = (int) (1.5 * Math.sqrt(l / 1.1));
Location loc = event.getBlock().getLocation().add(.5, .1, .5);
diff --git a/src/main/java/net/Indyuce/mmocore/loot/LootBuilder.java b/src/main/java/net/Indyuce/mmocore/loot/LootBuilder.java
index b5a5ae7e..c23136ce 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/LootBuilder.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/LootBuilder.java
@@ -3,9 +3,8 @@ package net.Indyuce.mmocore.loot;
import java.util.ArrayList;
import java.util.List;
-import org.bukkit.inventory.ItemStack;
-
import net.Indyuce.mmocore.api.player.PlayerData;
+import org.bukkit.inventory.ItemStack;
public class LootBuilder {
private final PlayerData player;
diff --git a/src/main/java/net/Indyuce/mmocore/loot/RandomWeightedRoll.java b/src/main/java/net/Indyuce/mmocore/loot/RandomWeightedRoll.java
new file mode 100644
index 00000000..53e3fae2
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/loot/RandomWeightedRoll.java
@@ -0,0 +1,79 @@
+package net.Indyuce.mmocore.loot;
+
+import net.Indyuce.mmocore.api.player.PlayerData;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Random;
+
+/**
+ * Used whenever the chance stat appears in MMOCore
+ *
+ * @param Any weighted object, currently either fishing drop
+ * items or loot chest tiers.
+ */
+public class RandomWeightedRoll {
+ private final Collection collection;
+ private final T rolled;
+
+ private static final Random RANDOM = new Random();
+
+ public RandomWeightedRoll(PlayerData player, Collection collection, double chanceWeight) {
+ this.collection = collection;
+
+ double partialSum = 0;
+ final double randomCoefficient = RANDOM.nextDouble(), chance = chanceWeight * player.getStats().getStat("CHANCE"), sum = weightedSum(chance);
+
+ for (T item : collection) {
+ partialSum += computeRealWeight(item, chance);
+ if (partialSum > randomCoefficient * sum) {
+ rolled = item;
+ return;
+ }
+ }
+
+ throw new RuntimeException("Could not roll item");
+ }
+
+ /**
+ * The chance stat will make low weight items more
+ * likely to be chosen by the algorithm.
+ *
+ * @return Randomly computed item
+ */
+ @NotNull
+ public T rollItem() {
+ return rolled;
+ }
+
+ private double weightedSum(double chance) {
+ double sum = 0;
+ for (T item : collection)
+ sum += computeRealWeight(item, chance);
+ return sum;
+ }
+
+ private static final double CHANCE_COEFFICIENT = 7. / 100;
+
+ /**
+ * chance = 0 | tier chances are unchanged
+ * chance = +inf | uniform law for any drop item
+ * chance = 100 | all tier chances are taken their square root
+ *
+ * @return The real weight of an item considering the player's chance stat.
+ */
+ private double computeRealWeight(T item, double chance) {
+ return Math.pow(item.getWeight(), 1 / Math.pow(1 + CHANCE_COEFFICIENT * chance, 1 / 3));
+ }
+
+ /*
+ Should this be used
+ private double getTierCoefficient(double initialTierChance, double chance) {
+ /**
+ * - Chance = 0 | tier coefficient is left unchanged.
+ * - Chance -> +oo | all tier coefficients are the same (1)
+ * - Chance = 50 | coefficients become their square roots
+ *
+ return Math.pow(initialTierChance, 1 / Math.pow(1 + CHANCE_COEF * chance, 1 / 3));
+ }*/
+}
diff --git a/src/main/java/net/Indyuce/mmocore/loot/Weighted.java b/src/main/java/net/Indyuce/mmocore/loot/Weighted.java
new file mode 100644
index 00000000..4845b7a4
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/loot/Weighted.java
@@ -0,0 +1,6 @@
+package net.Indyuce.mmocore.loot;
+
+public interface Weighted {
+
+ public double getWeight();
+}
diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/ChestTier.java b/src/main/java/net/Indyuce/mmocore/loot/chest/ChestTier.java
index 770c7986..0e82e44d 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/chest/ChestTier.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/chest/ChestTier.java
@@ -2,16 +2,16 @@ package net.Indyuce.mmocore.loot.chest;
import io.lumine.mythic.lib.api.math.ScalingFormula;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.loot.droptable.DropTable;
import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.loot.Weighted;
+import net.Indyuce.mmocore.loot.droptable.DropTable;
import org.bukkit.configuration.ConfigurationSection;
-public class ChestTier {
+public class ChestTier implements Weighted {
private final TierEffect effect;
private final ScalingFormula capacity;
private final DropTable table;
-
- public final double chance;
+ private final double chance;
public ChestTier(ConfigurationSection config) {
effect = config.isConfigurationSection("effect") ? new TierEffect(config.getConfigurationSection("effect")) : null;
@@ -24,6 +24,15 @@ public class ChestTier {
return capacity.calculate(player.getLevel());
}
+ public double getChance() {
+ return chance;
+ }
+
+ @Override
+ public double getWeight() {
+ return chance;
+ }
+
public DropTable getDropTable() {
return table;
}
diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java
index 8c6d2ed3..3277d05e 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChest.java
@@ -2,6 +2,7 @@ package net.Indyuce.mmocore.loot.chest;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.SoundEvent;
+import net.Indyuce.mmocore.util.HashableLocation;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -9,7 +10,6 @@ import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.block.data.BlockData;
-import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import javax.annotation.Nullable;
@@ -20,7 +20,7 @@ public class LootChest {
private final ReplacedBlock block;
@Nullable
private final BukkitRunnable effectRunnable;
- private final long date = System.currentTimeMillis();
+ private final BukkitRunnable closeRunnable;
private boolean active = true;
@@ -36,6 +36,13 @@ public class LootChest {
this.region = region;
this.block = new ReplacedBlock(block);
this.effectRunnable = tier.hasEffect() ? tier.getEffect().startNewRunnable(block.getLocation().add(.5, .5, .5)) : null;
+ closeRunnable = new BukkitRunnable() {
+ @Override
+ public void run() {
+ expire(false);
+ }
+ };
+ closeRunnable.runTaskLater(MMOCore.plugin, MMOCore.plugin.configManager.lootChestExpireTime);
}
public ChestTier getTier() {
@@ -50,15 +57,8 @@ public class LootChest {
return region;
}
- public boolean hasPlayerNearby() {
- for (Player player : block.loc.getWorld().getPlayers())
- if (player.getLocation().distanceSquared(block.loc) < 625)
- return true;
- return false;
- }
-
- public boolean shouldExpire() {
- return System.currentTimeMillis() - date > MMOCore.plugin.configManager.lootChestExpireTime;
+ public boolean isActive() {
+ return active;
}
/**
@@ -76,10 +76,14 @@ public class LootChest {
Validate.isTrue(active, "Chest has already expired");
active = false;
+ // Close runnable
+ if (!closeRunnable.isCancelled())
+ closeRunnable.cancel();
+
// If a player is responsible of closing the chest, close it with sound
if (player) {
- MMOCore.plugin.soundManager.getSound(SoundEvent.CLOSE_LOOT_CHEST).playAt(block.loc);
- block.loc.getWorld().spawnParticle(Particle.CRIT, block.loc.clone().add(.5, .5, .5), 16, 0, 0, 0, .5);
+ MMOCore.plugin.soundManager.getSound(SoundEvent.CLOSE_LOOT_CHEST).playAt(block.loc.bukkit());
+ block.loc.getWorld().spawnParticle(Particle.CRIT, block.loc.bukkit().add(.5, .5, .5), 16, 0, 0, 0, .5);
}
/*
@@ -87,7 +91,7 @@ public class LootChest {
* off and accumulate on the ground (+during dev phase)
*/
else
- ((Chest) block.loc.getBlock().getState()).getBlockInventory().clear();
+ ((Chest) block.loc.bukkit().getBlock().getState()).getBlockInventory().clear();
block.restore();
if (effectRunnable != null)
@@ -97,22 +101,28 @@ public class LootChest {
public static class ReplacedBlock {
private final Material material;
private final BlockData data;
- private final Location loc;
+ private final HashableLocation loc;
public ReplacedBlock(Block block) {
this.material = block.getType();
this.data = block.getBlockData();
- this.loc = block.getLocation();
+ this.loc = new HashableLocation(block.getLocation());
}
+ public HashableLocation getLocation() {
+ return loc;
+ }
+
+ @Deprecated
public boolean matches(Location loc) {
- return this.loc.getWorld().equals(loc.getWorld()) && this.loc.getBlockX() == loc.getBlockX() && this.loc.getBlockY() == loc.getBlockY()
- && this.loc.getBlockZ() == loc.getBlockZ();
+ return this.loc.getWorld().equals(loc.getWorld()) && this.loc.getX() == loc.getBlockX() && this.loc.getY() == loc.getBlockY()
+ && this.loc.getZ() == loc.getBlockZ();
}
public void restore() {
- loc.getBlock().setType(material);
- loc.getBlock().setBlockData(data);
+ Block block = loc.bukkit().getBlock();
+ block.setType(material);
+ block.setBlockData(data);
}
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java
index 99773f8a..07ccc933 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java
@@ -4,8 +4,8 @@ import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.LootChestSpawnEvent;
import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.loot.LootBuilder;
+import net.Indyuce.mmocore.loot.RandomWeightedRoll;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -14,6 +14,7 @@ import org.bukkit.block.Chest;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.logging.Level;
@@ -34,7 +35,7 @@ public class LootChestRegion {
}
};
- private static final Random random = new Random();
+ private static final Random RANDOM = new Random();
public LootChestRegion(ConfigurationSection config) {
Validate.notNull(config, "Could not load config");
@@ -109,7 +110,7 @@ public class LootChestRegion {
location.getBlock().setType(Material.CHEST);
Chest chest = (Chest) location.getBlock().getState();
tier.getDropTable().collect(builder).forEach(item -> {
- Integer slot = slots.get(random.nextInt(slots.size()));
+ Integer slot = slots.get(RANDOM.nextInt(slots.size()));
chest.getInventory().setItem(slot, item);
slots.remove(slot);
});
@@ -117,26 +118,14 @@ public class LootChestRegion {
MMOCore.plugin.lootChests.register(lootChest);
}
+ /**
+ * @param player Player rolling the tier
+ * @return A randomly picked tiers taking into account tier spawn rates
+ * and the player Chance attribute
+ */
+ @NotNull
public ChestTier rollTier(PlayerData player) {
- double chance = player.getStats().getStat(StatType.CHANCE);
-
- //chance=0 ->the tier.chance remains the same
- //chance ->+inf -> the tier.chance becomes the same for everyone, uniform law
- //chance=8-> tierChance=sqrt(tierChance)
- double sum = 0;
- for (ChestTier tier : tiers) {
- sum += Math.pow(tier.chance, 1 / Math.log(1 + chance));
- }
- double randomCoefficient=random.nextDouble();
- double s=0;
- for (ChestTier tier : tiers) {
- s+=Math.pow(tier.chance, 1 / Math.pow((1 + chance),1/3))/sum;
- if (randomCoefficient < s)
- return tier;
- }
-
-
- throw new NullPointerException("Could not find item in the tier list");
+ return new RandomWeightedRoll<>(player, tiers, MMOCore.plugin.configManager.lootChestsChanceWeight).rollItem();
}
public Location getRandomLocation(Location center) {
@@ -161,9 +150,9 @@ public class LootChestRegion {
* Chooses a random direction and get the block in
* that direction which has the same height as the player
*/
- double a = random.nextDouble() * 2 * Math.PI;
+ double a = RANDOM.nextDouble() * 2 * Math.PI;
Vector dir = new Vector(Math.cos(a), 0, Math.sin(a))
- .multiply(algOptions.minRange + random.nextDouble() * (algOptions.maxRange - algOptions.minRange));
+ .multiply(algOptions.minRange + RANDOM.nextDouble() * (algOptions.maxRange - algOptions.minRange));
Location random = center.add(dir);
/*
diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/RegionBounds.java b/src/main/java/net/Indyuce/mmocore/loot/chest/RegionBounds.java
index 1e25507b..5b5cf8de 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/chest/RegionBounds.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/chest/RegionBounds.java
@@ -2,6 +2,7 @@ package net.Indyuce.mmocore.loot.chest;
import java.util.stream.Stream;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -9,8 +10,6 @@ import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
-import net.Indyuce.mmocore.api.player.PlayerData;
-
public class RegionBounds {
private final World world;
private final int x1, z1, x2, z2;
diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/TierEffect.java b/src/main/java/net/Indyuce/mmocore/loot/chest/TierEffect.java
index cf80f6d5..d44be8b5 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/chest/TierEffect.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/chest/TierEffect.java
@@ -1,14 +1,13 @@
package net.Indyuce.mmocore.loot.chest;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.loot.chest.particle.ChestParticleEffect;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.scheduler.BukkitRunnable;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.loot.chest.particle.ChestParticleEffect;
-
public class TierEffect {
private final ChestParticleEffect type;
private final Particle particle;
diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/condition/ConditionInstance.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/ConditionInstance.java
index 1666ee8e..02629763 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/chest/condition/ConditionInstance.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/ConditionInstance.java
@@ -3,11 +3,10 @@ package net.Indyuce.mmocore.loot.chest.condition;
import java.util.List;
import java.util.stream.Stream;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
-import net.Indyuce.mmocore.MMOCore;
-
public class ConditionInstance {
private final Entity entity;
private final Location applied;
diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/condition/PermissionCondition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/PermissionCondition.java
index 47d9c0b8..312719ca 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/chest/condition/PermissionCondition.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/PermissionCondition.java
@@ -15,8 +15,6 @@ public class PermissionCondition extends Condition {
@Override
public boolean isMet(ConditionInstance entity) {
- if (entity.getEntity() instanceof Player)
- return entity.getEntity().hasPermission(perm);
- return false;
+ return entity.getEntity() instanceof Player && entity.getEntity().hasPermission(perm);
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/particle/ChestParticleEffect.java b/src/main/java/net/Indyuce/mmocore/loot/chest/particle/ChestParticleEffect.java
index 00bb6c66..c66b5cd2 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/chest/particle/ChestParticleEffect.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/chest/particle/ChestParticleEffect.java
@@ -2,12 +2,11 @@ package net.Indyuce.mmocore.loot.chest.particle;
import java.util.function.BiConsumer;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.scheduler.BukkitRunnable;
-import net.Indyuce.mmocore.MMOCore;
-
public enum ChestParticleEffect {
HELIX((loc, particle) -> {
diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/particle/ParabolicProjectile.java b/src/main/java/net/Indyuce/mmocore/loot/chest/particle/ParabolicProjectile.java
index a1615350..c53732bf 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/chest/particle/ParabolicProjectile.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/chest/particle/ParabolicProjectile.java
@@ -2,14 +2,13 @@ package net.Indyuce.mmocore.loot.chest.particle;
import java.util.function.Consumer;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
-import net.Indyuce.mmocore.MMOCore;
-
public class ParabolicProjectile extends BukkitRunnable {
private final Location target;
private final Consumer display;
diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/particle/PotionParticles.java b/src/main/java/net/Indyuce/mmocore/loot/chest/particle/PotionParticles.java
index 63a9343a..25d4e522 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/chest/particle/PotionParticles.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/chest/particle/PotionParticles.java
@@ -1,13 +1,12 @@
package net.Indyuce.mmocore.loot.chest.particle;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Color;
import org.bukkit.Particle;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.scheduler.BukkitRunnable;
-import net.Indyuce.mmocore.MMOCore;
-
public class PotionParticles extends BukkitRunnable {
private double r, g, b;
private final ThrownPotion potion;
diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/particle/SmallParticleEffect.java b/src/main/java/net/Indyuce/mmocore/loot/chest/particle/SmallParticleEffect.java
index 0b0cdef5..9502604c 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/chest/particle/SmallParticleEffect.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/chest/particle/SmallParticleEffect.java
@@ -1,12 +1,11 @@
package net.Indyuce.mmocore.loot.chest.particle;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.entity.Entity;
import org.bukkit.scheduler.BukkitRunnable;
-import net.Indyuce.mmocore.MMOCore;
-
public class SmallParticleEffect extends BukkitRunnable {
private final Location loc;
private final Particle particle;
diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java
index c8588074..9b69db63 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java
@@ -5,14 +5,14 @@ import java.util.List;
import java.util.Set;
import java.util.logging.Level;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
-import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.loot.LootBuilder;
import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.util.PostLoadObject;
@@ -53,7 +53,7 @@ public class DropTable extends PostLoadObject {
}
for (String key : conditionsList)
try {
- conditions.add(MMOCore.plugin.loadManager.loadCondition(new MMOLineConfig(key)));
+ conditions.addAll(MMOCore.plugin.loadManager.loadCondition(new MMOLineConfig(key)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load condition '" + key + "' from table '" + id + "': " + exception.getMessage());
diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java
index 143ebbca..17f10cb6 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java
@@ -2,15 +2,15 @@ package net.Indyuce.mmocore.loot.droptable.dropitem;
import java.util.Random;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.stats.StatType;
-import net.Indyuce.mmocore.loot.LootBuilder;
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.loot.LootBuilder;
import io.lumine.mythic.lib.api.MMOLineConfig;
public abstract class DropItem {
protected static final Random random = new Random();
+ private static final double CHANCE_COEFFICIENT = 7. / 100;
private final double chance, weight;
private final RandomAmount amount;
@@ -36,11 +36,19 @@ public abstract class DropItem {
return amount.calculateInt();
}
+ /**
+ * CHANCE stat = 0 | tier chances are unchanged
+ * CHANCE stat = +inf | uniform law for any drop item
+ * CHANCE stat = 100 | all tier chances are taken their square root
+ *
+ * @return The real weight of an item considering the player's CHANCE stat.
+ */
/**
* If the player chance is 0 the random value will remain the same. When he get lucks the chance gets closer to one.
*/
public boolean rollChance(PlayerData player) {
- return Math.pow(random.nextDouble(), 1 / Math.log(1 + player.getStats().getStat(StatType.CHANCE))) < chance;
+ double value=random.nextDouble();
+ return value< Math.pow(chance, 1 / Math.pow(1 + CHANCE_COEFFICIENT * player.getStats().getStat("CHANCE"), 1.0 / 3.0));
}
public abstract void collect(LootBuilder builder);
diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/fishing/FishingDropItem.java b/src/main/java/net/Indyuce/mmocore/loot/fishing/FishingDropItem.java
similarity index 86%
rename from src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/fishing/FishingDropItem.java
rename to src/main/java/net/Indyuce/mmocore/loot/fishing/FishingDropItem.java
index 7762aa7b..b7ef45f4 100644
--- a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/fishing/FishingDropItem.java
+++ b/src/main/java/net/Indyuce/mmocore/loot/fishing/FishingDropItem.java
@@ -1,15 +1,16 @@
-package net.Indyuce.mmocore.loot.droptable.dropitem.fishing;
+package net.Indyuce.mmocore.loot.fishing;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
import net.Indyuce.mmocore.loot.LootBuilder;
+import net.Indyuce.mmocore.loot.Weighted;
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
import org.apache.commons.lang.Validate;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
-public class FishingDropItem {
+public class FishingDropItem implements Weighted {
private final RandomAmount experience, tugs;
private final DropItem dropItem;
@@ -23,9 +24,9 @@ public class FishingDropItem {
Validate.isTrue(dropItem.getWeight() > 0, "A fishing drop table item must have a strictly positive weight");
}
- @Deprecated
- public int getWeight() {
- return (int) Math.floor(getItem().getWeight());
+ @Override
+ public double getWeight() {
+ return dropItem.getWeight();
}
public DropItem getItem() {
diff --git a/src/main/java/net/Indyuce/mmocore/manager/AttributeManager.java b/src/main/java/net/Indyuce/mmocore/manager/AttributeManager.java
index ab85face..fc1a50b9 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/AttributeManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/AttributeManager.java
@@ -6,8 +6,8 @@ import java.util.Map;
import java.util.logging.Level;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
+import net.Indyuce.mmocore.api.ConfigFile;
public class AttributeManager implements MMOCoreManager {
private final Map map = new HashMap<>();
diff --git a/src/main/java/net/Indyuce/mmocore/manager/ClassManager.java b/src/main/java/net/Indyuce/mmocore/manager/ClassManager.java
index e94bb005..8d0356c0 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/ClassManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/ClassManager.java
@@ -1,9 +1,8 @@
package net.Indyuce.mmocore.manager;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.profess.ClassOption;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
+import net.Indyuce.mmocore.api.player.profess.ClassOption;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
import net.Indyuce.mmocore.api.player.profess.event.trigger.*;
import org.apache.commons.lang.Validate;
diff --git a/src/main/java/net/Indyuce/mmocore/manager/ConfigItemManager.java b/src/main/java/net/Indyuce/mmocore/manager/ConfigItemManager.java
index 46439ec5..38d895ad 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/ConfigItemManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/ConfigItemManager.java
@@ -1,8 +1,8 @@
package net.Indyuce.mmocore.manager;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.util.item.ConfigItem;
+import net.Indyuce.mmocore.api.ConfigFile;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.Nullable;
diff --git a/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java b/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java
index 52fd2d55..b2a2af12 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java
@@ -23,10 +23,12 @@ import java.util.logging.Level;
public class ConfigManager {
public final CommandVerbose commandVerbose = new CommandVerbose();
- public boolean overrideVanillaExp, canCreativeCast, cobbleGeneratorXP, saveDefaultClassInfo;
+ public boolean overrideVanillaExp, canCreativeCast, cobbleGeneratorXP, saveDefaultClassInfo, attributesAsClassInfo, splitProfessionExp;
public String partyChatPrefix, noSkillBoundPlaceholder;
public ChatColor staminaFull, staminaHalf, staminaEmpty;
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
+ public double lootChestsChanceWeight, fishingDropsChanceWeight;
+ public int maxPartyLevelDifference;
private final FileConfiguration messages;
private final boolean chatInput;
@@ -88,18 +90,25 @@ public class ConfigManager {
loadDefaultFile("loot-chests.yml");
loadDefaultFile("commands.yml");
loadDefaultFile("exp-tables.yml");
+ loadDefaultFile("exp-sources.yml");
+ loadDefaultFile("triggers.yml");
+ loadDefaultFile("conditions.yml");
loadDefaultFile("guilds.yml");
commandVerbose.reload(MMOCore.plugin.getConfig().getConfigurationSection("command-verbose"));
messages = new ConfigFile("messages").getConfig();
- chatInput = MMOCore.plugin.getConfig().getBoolean("use-chat-input");
+ chatInput = true; // MMOCore.plugin.getConfig().getBoolean("use-chat-input")
partyChatPrefix = MMOCore.plugin.getConfig().getString("party.chat-prefix");
combatLogTimer = MMOCore.plugin.getConfig().getInt("combat-log.timer") * 1000L;
- lootChestExpireTime = Math.max(MMOCore.plugin.getConfig().getInt("loot-chests.chest-expire-time"), 1) * 1000L;
+ lootChestExpireTime = Math.max(MMOCore.plugin.getConfig().getInt("loot-chests.chest-expire-time"), 1) * 20;
lootChestPlayerCooldown = (long) MMOCore.plugin.getConfig().getDouble("player-cooldown") * 1000L;
globalSkillCooldown = MMOCore.plugin.getConfig().getLong("global-skill-cooldown") * 50;
noSkillBoundPlaceholder = getSimpleMessage("no-skill-placeholder").message();
+ lootChestsChanceWeight = MMOCore.plugin.getConfig().getDouble("chance-stat-weight.loot-chests");
+ fishingDropsChanceWeight = MMOCore.plugin.getConfig().getDouble("chance-stat-weight.fishing-drops");
+ maxPartyLevelDifference = MMOCore.plugin.getConfig().getInt("party.max-level-difference");
+ splitProfessionExp = MMOCore.plugin.getConfig().getBoolean("party.profession-exp-split");
staminaFull = getColorOrDefault("stamina-whole", ChatColor.GREEN);
staminaHalf = getColorOrDefault("stamina-half", ChatColor.DARK_GREEN);
@@ -145,7 +154,7 @@ public class ConfigManager {
}
public SimpleMessage getSimpleMessage(String key, String... placeholders) {
- String format = messages.getString(key, "");
+ String format = messages.getString(key, "{MessageNotFound:\"" + key + "\"}");
for (int j = 0; j < placeholders.length - 1; j += 2)
format = format.replace("{" + placeholders[j] + "}", placeholders[j + 1]);
return new SimpleMessage(MythicLib.plugin.parseColors(format));
diff --git a/src/main/java/net/Indyuce/mmocore/manager/DropTableManager.java b/src/main/java/net/Indyuce/mmocore/manager/DropTableManager.java
index 00e21b48..4819eb72 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/DropTableManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/DropTableManager.java
@@ -8,12 +8,12 @@ import java.util.Set;
import java.util.logging.Level;
import io.lumine.mythic.lib.api.util.PostLoadObject;
+import net.Indyuce.mmocore.MMOCore;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
-import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.loot.droptable.DropTable;
public class DropTableManager implements MMOCoreManager {
diff --git a/src/main/java/net/Indyuce/mmocore/manager/ExperienceManager.java b/src/main/java/net/Indyuce/mmocore/manager/ExperienceManager.java
index 3f941a7b..c84ecbd1 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/ExperienceManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/ExperienceManager.java
@@ -1,110 +1,110 @@
-package net.Indyuce.mmocore.manager;
-
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigFile;
-import net.Indyuce.mmocore.experience.ExpCurve;
-import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
-import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
-import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
-import org.apache.commons.lang.Validate;
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.event.HandlerList;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.logging.Level;
-
-public class ExperienceManager implements MMOCoreManager {
- private final Map expCurves = new HashMap<>();
- private final Map expTables = new HashMap<>();
-
- /**
- * Saves different experience sources based on experience source type.
- */
- private final Map, ExperienceSourceManager>> managers = new HashMap<>();
-
- @SuppressWarnings("unchecked")
- public ExperienceSourceManager getManager(Class t) {
- return (ExperienceSourceManager) managers.get(t);
- }
-
- @SuppressWarnings("unchecked")
- public void registerSource(T source) {
- Class path = (Class) source.getClass();
-
- if (!managers.containsKey(path))
- managers.put(path, source.newManager());
- getManager(path).registerSource(source);
- }
-
- public boolean hasCurve(String id) {
- return expCurves.containsKey(id);
- }
-
- public ExpCurve getCurveOrThrow(String id) {
- Validate.isTrue(hasCurve(id), "Could not find exp curve with ID '" + id + "'");
- return expCurves.get(id);
- }
-
- public boolean hasTable(String id) {
- return expTables.containsKey(id);
- }
-
- public ExperienceTable getTableOrThrow(String id) {
- return Objects.requireNonNull(expTables.get(id), "Could not find exp table with ID '" + id + "'");
- }
-
- public ExperienceTable loadExperienceTable(Object obj) {
-
- if (obj instanceof ConfigurationSection)
- return new ExperienceTable((ConfigurationSection) obj);
-
- if (obj instanceof String)
- return MMOCore.plugin.experience.getTableOrThrow(obj.toString());
-
- throw new IllegalArgumentException("Please provide either a string (exp table name) or a config section (locally define an exp table)");
- }
-
- public Collection getCurves() {
- return expCurves.values();
- }
-
- public Collection getTables() {
- return expTables.values();
- }
-
- @Override
- public void initialize(boolean clearBefore) {
- if (clearBefore) {
- expCurves.clear();
- expTables.clear();
-
- managers.values().forEach(HandlerList::unregisterAll);
- managers.clear();
- }
-
- expCurves.clear();
- for (File file : new File(MMOCore.plugin.getDataFolder() + "/expcurves").listFiles())
- try {
- ExpCurve curve = new ExpCurve(file);
- expCurves.put(curve.getId(), curve);
- } catch (IllegalArgumentException | IOException exception) {
- MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp curve '" + file.getName() + "': " + exception.getMessage());
- }
-
- expTables.clear();
- FileConfiguration expTablesConfig = new ConfigFile("exp-tables").getConfig();
- for (String key : expTablesConfig.getKeys(false))
- try {
- ExperienceTable table = new ExperienceTable(expTablesConfig.getConfigurationSection(key));
- expTables.put(table.getId(), table);
- } catch (RuntimeException exception) {
- MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp table '" + key + "': " + exception.getMessage());
- }
- }
-}
+package net.Indyuce.mmocore.manager;
+
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
+import net.Indyuce.mmocore.api.ConfigFile;
+import net.Indyuce.mmocore.experience.ExpCurve;
+import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
+import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
+import org.apache.commons.lang.Validate;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.event.HandlerList;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+
+public class ExperienceManager implements MMOCoreManager {
+ private final Map expCurves = new HashMap<>();
+ private final Map expTables = new HashMap<>();
+
+ /**
+ * Saves different experience sources based on experience source type.
+ */
+ private final Map, ExperienceSourceManager>> managers = new HashMap<>();
+
+ @SuppressWarnings("unchecked")
+ public ExperienceSourceManager getManager(Class t) {
+ return (ExperienceSourceManager) managers.get(t);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void registerSource(T source) {
+ Class path = (Class) source.getClass();
+
+ if (!managers.containsKey(path))
+ managers.put(path, source.newManager());
+ getManager(path).registerSource(source);
+ }
+
+ public boolean hasCurve(String id) {
+ return expCurves.containsKey(id);
+ }
+
+ public ExpCurve getCurveOrThrow(String id) {
+ Validate.isTrue(hasCurve(id), "Could not find exp curve with ID '" + id + "'");
+ return expCurves.get(id);
+ }
+
+ public boolean hasTable(String id) {
+ return expTables.containsKey(id);
+ }
+
+ public ExperienceTable getTableOrThrow(String id) {
+ return Objects.requireNonNull(expTables.get(id), "Could not find exp table with ID '" + id + "'");
+ }
+
+ public ExperienceTable loadExperienceTable(Object obj) {
+
+ if (obj instanceof ConfigurationSection)
+ return new ExperienceTable((ConfigurationSection) obj);
+
+ if (obj instanceof String)
+ return MMOCore.plugin.experience.getTableOrThrow(obj.toString());
+
+ throw new IllegalArgumentException("Please provide either a string (exp table name) or a config section (locally define an exp table)");
+ }
+
+ public Collection getCurves() {
+ return expCurves.values();
+ }
+
+ public Collection getTables() {
+ return expTables.values();
+ }
+
+ @Override
+ public void initialize(boolean clearBefore) {
+ if (clearBefore) {
+ expCurves.clear();
+ expTables.clear();
+
+ managers.values().forEach(HandlerList::unregisterAll);
+ managers.clear();
+ }
+
+ expCurves.clear();
+ for (File file : new File(MMOCore.plugin.getDataFolder() + "/expcurves").listFiles())
+ try {
+ ExpCurve curve = new ExpCurve(file);
+ expCurves.put(curve.getId(), curve);
+ } catch (IllegalArgumentException | IOException exception) {
+ MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp curve '" + file.getName() + "': " + exception.getMessage());
+ }
+
+ expTables.clear();
+ FileConfiguration expTablesConfig = new ConfigFile("exp-tables").getConfig();
+ for (String key : expTablesConfig.getKeys(false))
+ try {
+ ExperienceTable table = new ExperienceTable(expTablesConfig.getConfigurationSection(key));
+ expTables.put(table.getId(), table);
+ } catch (RuntimeException exception) {
+ MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp table '" + key + "': " + exception.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/InventoryManager.java b/src/main/java/net/Indyuce/mmocore/manager/InventoryManager.java
index 1f51956f..622f0898 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/InventoryManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/InventoryManager.java
@@ -5,15 +5,15 @@ import java.util.List;
import java.util.logging.Level;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.gui.*;
-import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.social.friend.EditableFriendList;
import net.Indyuce.mmocore.gui.social.friend.EditableFriendRemoval;
import net.Indyuce.mmocore.gui.social.guild.EditableGuildCreation;
import net.Indyuce.mmocore.gui.social.guild.EditableGuildView;
import net.Indyuce.mmocore.gui.social.party.EditablePartyCreation;
import net.Indyuce.mmocore.gui.social.party.EditablePartyView;
+import net.Indyuce.mmocore.api.ConfigFile;
+import net.Indyuce.mmocore.gui.api.EditableInventory;
public class InventoryManager {
public static final PlayerStats PLAYER_STATS = new PlayerStats();
diff --git a/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java b/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java
index 4dab3230..090f188f 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/LootChestManager.java
@@ -1,85 +1,82 @@
-package net.Indyuce.mmocore.manager;
-
-import java.util.*;
-import java.util.logging.Level;
-
-import org.bukkit.Location;
-import org.bukkit.configuration.file.FileConfiguration;
-
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigFile;
-import net.Indyuce.mmocore.loot.chest.LootChest;
-import net.Indyuce.mmocore.loot.chest.LootChestRegion;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class LootChestManager implements MMOCoreManager {
-
- /**
- * Active loot chests in the server
- */
- private final Set active = new HashSet<>();
-
- /**
- * Registered loot chest regions
- */
- private final Map regions = new HashMap<>();
-
- public boolean hasRegion(String id) {
- return regions.containsKey(id);
- }
-
- /**
- * @return Region with specific identifier
- * @throws NullPointerException if not found
- */
- @NotNull
- public LootChestRegion getRegion(String id) {
- return Objects.requireNonNull(regions.get(id), "Could not find region with ID '" + id + "'");
- }
-
- public Collection getRegions() {
- return regions.values();
- }
-
- public Set getActive() {
- return active;
- }
-
- public void register(LootChest chest) {
- active.add(chest);
- }
-
- public void unregister(LootChest chest) {
- active.remove(chest);
- }
-
- @Nullable
- public LootChest getChest(Location loc) {
-
- for (LootChest chest : active)
- if (chest.getBlock().matches(loc))
- return chest;
-
- return null;
- }
-
- @Override
- public void initialize(boolean clearBefore) {
- if (clearBefore) {
- regions.values().forEach(region -> region.getRunnable().cancel());
- regions.clear();
- }
-
- FileConfiguration config = new ConfigFile("loot-chests").getConfig();
- for (String key : config.getKeys(false))
- try {
- LootChestRegion region = new LootChestRegion(config.getConfigurationSection(key));
- regions.put(region.getId(), region);
- } catch (IllegalArgumentException exception) {
- MMOCore.plugin.getLogger().log(Level.WARNING,
- "An error occured while trying to load loot chest region '" + key + "': " + exception.getMessage());
- }
-
- }
-}
+package net.Indyuce.mmocore.manager;
+
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.ConfigFile;
+import net.Indyuce.mmocore.loot.chest.LootChest;
+import net.Indyuce.mmocore.loot.chest.LootChestRegion;
+import net.Indyuce.mmocore.util.HashableLocation;
+import org.bukkit.Location;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+
+public class LootChestManager implements MMOCoreManager {
+
+ /**
+ * Active loot chests in the server
+ */
+ private final Map active = new HashMap<>();
+
+ /**
+ * Registered loot chest regions
+ */
+ private final Map regions = new HashMap<>();
+
+ public boolean hasRegion(String id) {
+ return regions.containsKey(id);
+ }
+
+ /**
+ * @return Region with specific identifier
+ * @throws NullPointerException if not found
+ */
+ @NotNull
+ public LootChestRegion getRegion(String id) {
+ return Objects.requireNonNull(regions.get(id), "Could not find region with ID '" + id + "'");
+ }
+
+ public Collection getRegions() {
+ return regions.values();
+ }
+
+ public Collection getActive() {
+ return active.values();
+ }
+
+ public void register(LootChest chest) {
+ active.put(chest.getBlock().getLocation(), chest);
+ }
+
+ public void unregister(LootChest chest) {
+ active.remove(chest.getBlock().getLocation());
+ }
+
+ @Nullable
+ public LootChest getChest(Location loc) {
+ return active.get(new HashableLocation(loc));
+ }
+
+ @Override
+ public void initialize(boolean clearBefore) {
+ if (clearBefore) {
+ regions.values().forEach(region -> region.getRunnable().cancel());
+ regions.clear();
+ }
+
+ FileConfiguration config = new ConfigFile("loot-chests").getConfig();
+ for (String key : config.getKeys(false))
+ try {
+ LootChestRegion region = new LootChestRegion(config.getConfigurationSection(key));
+ regions.put(region.getId(), region);
+ } catch (IllegalArgumentException exception) {
+ MMOCore.plugin.getLogger().log(Level.WARNING,
+ "An error occured while trying to load loot chest region '" + key + "': " + exception.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java b/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java
index 666ba042..95301573 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java
@@ -4,20 +4,20 @@ import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
+import net.Indyuce.mmocore.api.block.BlockType;
+import net.Indyuce.mmocore.api.quest.trigger.Trigger;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import com.google.gson.JsonParseException;
-import net.Indyuce.mmocore.api.block.BlockType;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
import net.Indyuce.mmocore.api.load.DefaultMMOLoader;
import net.Indyuce.mmocore.api.load.MMOLoader;
import net.Indyuce.mmocore.api.quest.objective.Objective;
-import net.Indyuce.mmocore.api.quest.trigger.Trigger;
import io.lumine.mythic.lib.api.MMOLineConfig;
public class MMOLoadManager {
@@ -33,20 +33,25 @@ public class MMOLoadManager {
loaders.add(loader);
}
- public Condition loadCondition(MMOLineConfig config) {
- return load(Condition.class, config, loader -> loader.loadCondition(config));
+ public List loadCondition(MMOLineConfig config) {
+ return load(List.class, config, loader -> loader.loadCondition(config));
}
public Objective loadObjective(MMOLineConfig config, ConfigurationSection section) {
return load(Objective.class, config, loader -> loader.loadObjective(config, section));
}
- public ExperienceSource> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
- return load(ExperienceSource.class, config, loader -> loader.loadExperienceSource(config, dispenser));
+ /**
+ Returns a List of Experience Source as one experience source can be linked to others.
+ Loading one exp source can in fact oad multiples if they are linked
+ */
+ @Deprecated
+ public List> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
+ return load(List.class, config, loader -> loader.loadExperienceSource(config, dispenser));
}
- public Trigger loadTrigger(MMOLineConfig config) {
- return load(Trigger.class, config, loader -> loader.loadTrigger(config));
+ public List loadTrigger(MMOLineConfig config) {
+ return load(List.class, config, loader -> loader.loadTrigger(config));
}
public DropItem loadDropItem(MMOLineConfig config) {
diff --git a/src/main/java/net/Indyuce/mmocore/manager/QuestManager.java b/src/main/java/net/Indyuce/mmocore/manager/QuestManager.java
index 31768d61..44ca127f 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/QuestManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/QuestManager.java
@@ -7,11 +7,10 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
-import org.apache.commons.lang.Validate;
-import org.bukkit.configuration.file.YamlConfiguration;
-
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.quest.Quest;
+import org.apache.commons.lang.Validate;
+import org.bukkit.configuration.file.YamlConfiguration;
public class QuestManager implements MMOCoreManager {
private final Map quests = new LinkedHashMap<>();
diff --git a/src/main/java/net/Indyuce/mmocore/manager/RestrictionManager.java b/src/main/java/net/Indyuce/mmocore/manager/RestrictionManager.java
index 503a2b95..4d06cdc6 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/RestrictionManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/RestrictionManager.java
@@ -5,8 +5,8 @@ import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.itemtype.ItemType;
import io.lumine.mythic.lib.api.util.PostLoadObject;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.api.block.BlockType;
+import net.Indyuce.mmocore.api.ConfigFile;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
diff --git a/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java b/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java
index 25a6d67b..2f95fdb1 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/SkillManager.java
@@ -2,13 +2,13 @@ package net.Indyuce.mmocore.manager;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
+import net.Indyuce.mmocore.skill.list.Sneaky_Picky;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.list.Ambers;
import net.Indyuce.mmocore.skill.list.Neptune_Gift;
-import net.Indyuce.mmocore.skill.list.Sneaky_Picky;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/src/main/java/net/Indyuce/mmocore/manager/StatManager.java b/src/main/java/net/Indyuce/mmocore/manager/StatManager.java
new file mode 100644
index 00000000..ee23b9d6
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/manager/StatManager.java
@@ -0,0 +1,71 @@
+package net.Indyuce.mmocore.manager;
+
+import io.lumine.mythic.lib.MythicLib;
+import net.Indyuce.mmocore.api.ConfigFile;
+import net.Indyuce.mmocore.player.stats.StatInfo;
+import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
+import net.Indyuce.mmocore.experience.Profession;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.text.DecimalFormat;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class StatManager implements MMOCoreManager {
+ private final Map loaded = new HashMap<>();
+
+ @Override
+ public void initialize(boolean clearBefore) {
+ if (clearBefore)
+ loaded.clear();
+
+ FileConfiguration config = new ConfigFile("stats").getConfig();
+
+ // Read decimal formats
+ for (String key : config.getConfigurationSection("decimal-format").getKeys(false))
+ registerDecimalFormat(key, MythicLib.plugin.getMMOConfig().newDecimalFormat(config.getString("decimal-format." + key)));
+
+ // Read default formulas
+ for (String key : config.getConfigurationSection("default").getKeys(false))
+ registerDefaultFormula(key, new LinearValue(config.getConfigurationSection("default." + key)));
+ }
+
+ public Collection getLoaded() {
+ return loaded.values();
+ }
+
+ @Nullable
+ public StatInfo getInfo(String stat) {
+ return loaded.get(stat);
+ }
+
+ public void registerProfession(String stat, Profession profession) {
+ compute(stat).profession = profession;
+ }
+
+ public void registerDefaultFormula(String stat, LinearValue defaultFormula) {
+ compute(stat).defaultInfo = defaultFormula;
+ }
+
+ public void registerDecimalFormat(String stat, DecimalFormat format) {
+ compute(stat).format = format;
+ }
+
+ /**
+ * @return A stat info for the specified stat. If it doesn't
+ * exist when method is called, it is registered into the map
+ */
+ @NotNull
+ private StatInfo compute(String stat) {
+ StatInfo found = loaded.get(stat);
+ if (found != null)
+ return found;
+
+ StatInfo newInfo = new StatInfo(stat);
+ loaded.put(stat, newInfo);
+ return newInfo;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java b/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java
index 9ff105f0..5ae15590 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/WaypointManager.java
@@ -1,8 +1,8 @@
package net.Indyuce.mmocore.manager;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.waypoint.Waypoint;
+import net.Indyuce.mmocore.api.ConfigFile;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
@@ -25,6 +25,7 @@ public class WaypointManager implements MMOCoreManager {
return waypoints.containsKey(id);
}
+ @Nullable
public Waypoint get(String id) {
return waypoints.get(id);
}
@@ -55,5 +56,12 @@ public class WaypointManager implements MMOCoreManager {
} catch (RuntimeException exception) {
MMOCore.log(Level.WARNING, "Could not load waypoint '" + key + "': " + exception.getMessage());
}
+
+ for (Waypoint waypoint : waypoints.values())
+ try {
+ waypoint.postLoad();
+ } catch (RuntimeException exception) {
+ MMOCore.log(Level.WARNING, "Could not post-load waypoint '" + waypoint.getId() + "': " + exception.getMessage());
+ }
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/DataProvider.java b/src/main/java/net/Indyuce/mmocore/manager/data/DataProvider.java
index 1114a86a..e992a5cd 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/data/DataProvider.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/data/DataProvider.java
@@ -1,15 +1,15 @@
-package net.Indyuce.mmocore.manager.data;
-
-/**
- * Used to separate MySQL data storage from YAML data storage.
- *
- * There is one data provider per storage mecanism (one for YAML, one for MySQL).
- * A data provider provides corresponding MMOManagers to correctly save and load
- * data
- */
-public interface DataProvider {
-
- PlayerDataManager getDataManager();
-
- GuildDataManager getGuildManager();
-}
+package net.Indyuce.mmocore.manager.data;
+
+/**
+ * Used to separate MySQL data storage from YAML data storage.
+ *
+ * There is one data provider per storage mecanism (one for YAML, one for MySQL).
+ * A data provider provides corresponding MMOManagers to correctly save and load
+ * data
+ */
+public interface DataProvider {
+
+ PlayerDataManager getDataManager();
+
+ GuildDataManager getGuildManager();
+}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/GuildDataManager.java b/src/main/java/net/Indyuce/mmocore/manager/data/GuildDataManager.java
index cedf04aa..a8a6bfe6 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/data/GuildDataManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/data/GuildDataManager.java
@@ -1,127 +1,127 @@
-package net.Indyuce.mmocore.manager.data;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
-
-import net.Indyuce.mmocore.api.ConfigFile;
-import net.Indyuce.mmocore.guild.provided.Guild;
-
-public abstract class GuildDataManager {
- protected final Map guilds = new HashMap<>();
-
- public Guild newRegisteredGuild(UUID owner, String name, String tag) {
- Guild guild = new Guild(owner, name, tag);
- registerGuild(guild);
- return guild;
- }
-
- public void registerGuild(Guild guild) {
- guilds.put(guild.getId(), guild);
- }
-
- public boolean isRegistered(Guild guild) {
- return guilds.containsValue(guild);
- }
-
- public boolean isRegistered(String tag) {
- return guilds.containsKey(tag);
- }
-
- public void unregisterGuild(Guild guild) {
- guild.getMembers().forEach(member -> guild.removeMember(member, true));
- // guild.getMembers().clear();
- guilds.remove(guild.getId());
- delete(guild);
- }
-
- public Guild getGuild(String guild) {
- return guilds.get(guild);
- }
-
- public Collection getAll() {
- return guilds.values();
- }
-
- @Deprecated
- public void reload() {
- for (Guild guild : guilds.values())
- save(guild);
- guilds.clear();
- load();
- config = new GuildConfiguration();
- }
-
- public abstract void save(Guild guild);
-
- // TODO move to constructor, useless to handle vie abstract method
- public abstract void load();
-
- public abstract void delete(Guild guild);
-
- // TODO fix this
- // Shitty code for loading config values for guilds.
- private GuildConfiguration config;
-
- public GuildConfiguration getConfig() {
- return config == null ? config = new GuildConfiguration() : config;
- }
-
- public static class GuildConfiguration {
- private final String prefix;
- private final boolean uppercaseTags;
- private final NamingRules tagRules, nameRules;
-
- public GuildConfiguration() {
- FileConfiguration config = new ConfigFile("guilds").getConfig();
-
- this.prefix = config.getString("chat-prefix", "*");
- this.uppercaseTags = config.getBoolean("uppercase-tags", true);
- this.tagRules = new NamingRules(config.getConfigurationSection("rules.tag"));
- this.nameRules = new NamingRules(config.getConfigurationSection("rules.name"));
- }
-
- public String getPrefix() {
- return prefix;
- }
-
- public boolean shouldUppercaseTags() {
- return uppercaseTags;
- }
-
- public NamingRules getTagRules() {
- return tagRules;
- }
-
- public NamingRules getNameRules() {
- return nameRules;
- }
-
- public static class NamingRules {
- private final String regex;
- private final int min, max;
-
- public NamingRules(ConfigurationSection config) {
- regex = config.getString("matches", "[a-zA-Z-_!?]+");
- min = config.getInt("min-length", 3);
- max = config.getInt("max-length", 5);
- }
-
- public String getRegex() {
- return regex;
- }
-
- public int getMin() {
- return min;
- }
-
- public int getMax() {
- return max;
- }
- }
- }
-}
+package net.Indyuce.mmocore.manager.data;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.FileConfiguration;
+
+import net.Indyuce.mmocore.api.ConfigFile;
+import net.Indyuce.mmocore.guild.provided.Guild;
+
+public abstract class GuildDataManager {
+ protected final Map guilds = new HashMap<>();
+
+ public Guild newRegisteredGuild(UUID owner, String name, String tag) {
+ Guild guild = new Guild(owner, name, tag);
+ registerGuild(guild);
+ return guild;
+ }
+
+ public void registerGuild(Guild guild) {
+ guilds.put(guild.getId(), guild);
+ }
+
+ public boolean isRegistered(Guild guild) {
+ return guilds.containsValue(guild);
+ }
+
+ public boolean isRegistered(String tag) {
+ return guilds.containsKey(tag);
+ }
+
+ public void unregisterGuild(Guild guild) {
+ guild.forEachMember(member -> guild.removeMember(member, true));
+ // guild.getMembers().clear();
+ guilds.remove(guild.getId());
+ delete(guild);
+ }
+
+ public Guild getGuild(String guild) {
+ return guilds.get(guild);
+ }
+
+ public Collection getAll() {
+ return guilds.values();
+ }
+
+ @Deprecated
+ public void reload() {
+ for (Guild guild : guilds.values())
+ save(guild);
+ guilds.clear();
+ load();
+ config = new GuildConfiguration();
+ }
+
+ public abstract void save(Guild guild);
+
+ // TODO move to constructor, useless to handle vie abstract method
+ public abstract void load();
+
+ public abstract void delete(Guild guild);
+
+ // TODO fix this
+ // Shitty code for loading config values for guilds.
+ private GuildConfiguration config;
+
+ public GuildConfiguration getConfig() {
+ return config == null ? config = new GuildConfiguration() : config;
+ }
+
+ public static class GuildConfiguration {
+ private final String prefix;
+ private final boolean uppercaseTags;
+ private final NamingRules tagRules, nameRules;
+
+ public GuildConfiguration() {
+ FileConfiguration config = new ConfigFile("guilds").getConfig();
+
+ this.prefix = config.getString("chat-prefix", "*");
+ this.uppercaseTags = config.getBoolean("uppercase-tags", true);
+ this.tagRules = new NamingRules(config.getConfigurationSection("rules.tag"));
+ this.nameRules = new NamingRules(config.getConfigurationSection("rules.name"));
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public boolean shouldUppercaseTags() {
+ return uppercaseTags;
+ }
+
+ public NamingRules getTagRules() {
+ return tagRules;
+ }
+
+ public NamingRules getNameRules() {
+ return nameRules;
+ }
+
+ public static class NamingRules {
+ private final String regex;
+ private final int min, max;
+
+ public NamingRules(ConfigurationSection config) {
+ regex = config.getString("matches", "[a-zA-Z-_!?]+");
+ min = config.getInt("min-length", 3);
+ max = config.getInt("max-length", 5);
+ }
+
+ public String getRegex() {
+ return regex;
+ }
+
+ public int getMin() {
+ return min;
+ }
+
+ public int getMax() {
+ return max;
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/PlayerDataManager.java b/src/main/java/net/Indyuce/mmocore/manager/data/PlayerDataManager.java
index 20549d26..978f41e3 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/data/PlayerDataManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/data/PlayerDataManager.java
@@ -1,188 +1,263 @@
-package net.Indyuce.mmocore.manager.data;
-
-import io.lumine.mythic.lib.api.player.MMOPlayerData;
-import io.lumine.mythic.lib.player.TemporaryPlayerData;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.event.AsyncPlayerDataLoadEvent;
-import net.Indyuce.mmocore.api.event.PlayerDataLoadEvent;
-import net.Indyuce.mmocore.api.player.OfflinePlayerData;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import org.bukkit.Bukkit;
-import org.bukkit.OfflinePlayer;
-import org.bukkit.configuration.ConfigurationSection;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.*;
-
-public abstract class PlayerDataManager {
- private final static Map data = Collections.synchronizedMap(new HashMap<>());
-
- private DefaultPlayerData defaultData = new DefaultPlayerData(1, 0, 0, 0, 0);
-
- public PlayerData get(OfflinePlayer player) {
- return get(player.getUniqueId());
- }
-
- /**
- * Gets the player data, or throws an exception if not found.
- * The player data should be loaded when the player logs in
- * so it's really bad practice to setup the player data if it's not loaded.
- *
- * @param uuid Player UUID
- * @return Player data, if it's loaded
- */
- public PlayerData get(UUID uuid) {
- return Objects.requireNonNull(data.get(uuid), "Player data is not loaded");
- }
-
- /**
- * Safely unregisters the player data from the map.
- * This saves the player data either through SQL or YAML,
- * then closes the player data and clears it from the data map.
- *
- * @param playerData PLayer data to unregister
- */
- public void unregisterSafe(PlayerData playerData) {
-
- // Save data async if required
- if (playerData.isFullyLoaded())
- Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> {
- saveData(playerData);
-
- // Unregister once the data was saved
- playerData.close();
- data.remove(playerData.getUniqueId());
- });
-
- // Just unregister data without saving
- else {
- playerData.close();
- data.remove(playerData.getUniqueId());
- }
- }
-
- /**
- * Offline player data is used to handle processes like friend removal
- * which can still occur if one of the two players is offline.
- *
- * Unlike {@link #get(UUID)} this method never returns a null instance
- *
- * @param uuid Player unique id
- * @return Offline player data
- */
- @NotNull
- public abstract OfflinePlayerData getOffline(UUID uuid);
-
- /**
- * Called when a player logs in, loading the player data inside the map.
- *
- * For YAML configs or SQL databases, data is loaded as not to overload
- * the main thread with SQL requests. Therefore, the player data returned
- * by that method, when the player joined for the first time, is not
- * fully loaded YET.
- *
- * @param uniqueId Player UUID
- * @return The loaded player data.
- */
- public PlayerData setup(UUID uniqueId) {
- // Load player data if it does not exist
- if (!data.containsKey(uniqueId)) {
- PlayerData newData = TemporaryPlayerData.has(uniqueId) ? new PlayerData(MMOPlayerData.get(uniqueId), TemporaryPlayerData.get(uniqueId)) : new PlayerData(MMOPlayerData.get(uniqueId));
-
- // Schedule async data loading
- Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> {
- loadData(newData);
- newData.getStats().updateStats();
- Bukkit.getPluginManager().callEvent(new AsyncPlayerDataLoadEvent(newData));
- Bukkit.getScheduler().runTask(MMOCore.plugin, () -> Bukkit.getPluginManager().callEvent(new PlayerDataLoadEvent(newData)));
- });
-
- // Update data map
- data.put(uniqueId, newData);
-
- return newData;
- }
-
- return data.get(uniqueId);
- }
-
- public DefaultPlayerData getDefaultData() {
- return defaultData;
- }
-
- public void loadDefaultData(ConfigurationSection config) {
- defaultData = new DefaultPlayerData(config);
- }
-
- public boolean isLoaded(UUID uuid) {
- return data.containsKey(uuid);
- }
-
- public Collection getLoaded() {
- return data.values();
- }
-
- /**
- * Called when player data must be loaded from database or config.
- *
- * @param data Player data to load
- */
- public abstract void loadData(PlayerData data);
-
- /**
- * Called when player data must be saved in configs or database.
- * This method should always be called sync because it DOES register
- * an async task in case MySQL storage is used.
- *
- * @param data Player data to save
- */
- public abstract void saveData(PlayerData data);
-
- public class DefaultPlayerData {
- private final int level, classPoints, skillPoints, attributePoints, attrReallocPoints;
-
- public DefaultPlayerData(ConfigurationSection config) {
- level = config.getInt("level", 1);
- classPoints = config.getInt("class-points");
- skillPoints = config.getInt("skill-points");
- attributePoints = config.getInt("attribute-points");
- attrReallocPoints = config.getInt("attribute-realloc-points");
- }
-
- public DefaultPlayerData(int level, int classPoints, int skillPoints, int attributePoints, int attrReallocPoints) {
- this.level = level;
- this.classPoints = classPoints;
- this.skillPoints = skillPoints;
- this.attributePoints = attributePoints;
- this.attrReallocPoints = attrReallocPoints;
- }
-
- public int getLevel() {
- return level;
- }
-
- public int getSkillPoints() {
- return skillPoints;
- }
-
- public int getClassPoints() {
- return classPoints;
- }
-
- public int getAttrReallocPoints() {
- return attrReallocPoints;
- }
-
- public int getAttributePoints() {
- return attributePoints;
- }
-
- public void apply(PlayerData player) {
- player.setLevel(level);
- player.setClassPoints(classPoints);
- player.setSkillPoints(skillPoints);
- player.setAttributePoints(attributePoints);
- player.setAttributeReallocationPoints(attrReallocPoints);
- }
- }
-}
+package net.Indyuce.mmocore.manager.data;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.lumine.mythic.lib.MythicLib;
+import io.lumine.mythic.lib.api.player.MMOPlayerData;
+import io.lumine.mythic.lib.player.TemporaryPlayerData;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.event.AsyncPlayerDataLoadEvent;
+import net.Indyuce.mmocore.api.event.PlayerDataLoadEvent;
+import net.Indyuce.mmocore.api.player.SavingPlayerData;
+import net.Indyuce.mmocore.api.player.profess.PlayerClass;
+import net.Indyuce.mmocore.api.player.OfflinePlayerData;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
+import net.Indyuce.mmocore.api.util.MMOCoreUtils;
+import net.Indyuce.mmocore.guild.provided.Guild;
+import org.apache.commons.lang.Validate;
+import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.configuration.ConfigurationSection;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+import java.util.logging.Level;
+
+public abstract class PlayerDataManager {
+ private final static Map data = Collections.synchronizedMap(new HashMap<>());
+
+ private DefaultPlayerData defaultData = new DefaultPlayerData(1, 0, 0, 0, 0);
+
+ public PlayerData get(OfflinePlayer player) {
+ return get(player.getUniqueId());
+ }
+
+ /**
+ * Gets the player data, or throws an exception if not found.
+ * The player data should be loaded when the player logs in
+ * so it's really bad practice to setup the player data if it's not loaded.
+ *
+ * @param uuid Player UUID
+ * @return Player data, if it's loaded
+ */
+ public PlayerData get(UUID uuid) {
+ return Objects.requireNonNull(data.get(uuid), "Player data is not loaded");
+ }
+
+
+ public static void loadDataFromJson(@NotNull PlayerData data, String json) {
+ JsonObject object = MythicLib.plugin.getJson().parse(json, JsonObject.class);
+
+ data.setClassPoints(object.get("class_points").getAsInt());
+ data.setSkillPoints(object.get("skill_points").getAsInt());
+ data.setAttributePoints(object.get("attribute_points").getAsInt());
+ data.setAttributeReallocationPoints(object.get("attribute_realloc_points").getAsInt());
+ data.setLevel(object.get("level").getAsInt());
+ data.setExperience(object.get("experience").getAsInt());
+ if (object.has("class"))
+ data.setClass(MMOCore.plugin.classManager.get(object.get(("class")).getAsString()));
+
+ if (object.has("times_claimed")) {
+ JsonObject timesClaimed =object.get(("times_claimed")).getAsJsonObject();
+ timesClaimed.entrySet().forEach(entry -> data.getItemClaims().put(entry.getKey(), entry.getValue().getAsInt()));
+ }
+
+ if (object.has(("guild"))) {
+ Guild guild = MMOCore.plugin.dataProvider.getGuildManager().getGuild(object.get("guild").getAsString());
+ data.setGuild(guild.hasMember(data.getUniqueId()) ? guild : null);
+ }
+ if (object.has(("attributes"))) data.getAttributes().load(object.get("attributes").getAsString());
+ if (object.has(("professions")))
+ data.getCollectionSkills().load(object.get("professions").getAsString());
+ if (object.has(("quests"))) data.getQuestData().load(object.get("quests").getAsString());
+ data.getQuestData().updateBossBar();
+ if (object.has(("waypoints")))
+ data.getWaypoints().addAll(MMOCoreUtils.jsonArrayToList(object.get("waypoints").getAsString()));
+ if (object.has(("friends")))
+ MMOCoreUtils.jsonArrayToList(object.get("friends").getAsString()).forEach(str -> data.getFriends().add(UUID.fromString(str)))
+ ;
+ if (object.has(("skills"))) {
+ JsonObject skillsObject = object.get("skills").getAsJsonObject();
+ for (Map.Entry entry : skillsObject.entrySet())
+ data.setSkillLevel(entry.getKey(), entry.getValue().getAsInt());
+ }
+ if (object.has(("bound_skills")))
+ for (String skill : MMOCoreUtils.jsonArrayToList(object.get("bound_skills").getAsString()))
+ if (data.getProfess().hasSkill(skill))
+ data.getBoundSkills().add(data.getProfess().getSkill(skill));
+ if (object.has(("class_info"))) {
+ JsonObject classObject = object.get("class_info").getAsJsonObject();
+ for (Map.Entry entry : classObject.entrySet()) {
+ try {
+ PlayerClass profess = MMOCore.plugin.classManager.get(entry.getKey());
+ Validate.notNull(profess, "Could not find class '" + entry.getKey() + "'");
+ data.applyClassInfo(profess, new SavedClassInformation(entry.getValue().getAsJsonObject()));
+ } catch (IllegalArgumentException exception) {
+ MMOCore.log(Level.WARNING, "Could not load class info '" + entry.getKey() + "': " + exception.getMessage());
+ }
+ }
+ }
+
+ }
+
+
+ /**
+ * Safely unregisters the player data from the map.
+ * This saves the player data either through SQL or YAML,
+ * then closes the player data and clears it from the data map.
+ *
+ * @param playerData PLayer data to unregister
+ */
+ public void unregisterSafe(PlayerData playerData) {
+
+ // Save data async if required
+ if (playerData.isFullyLoaded())
+ Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> {
+ saveData(playerData);
+
+ // Unregister once the data was saved
+ playerData.close();
+ data.remove(playerData.getUniqueId());
+ });
+
+ // Just unregister data without saving
+ else {
+ playerData.close();
+ data.remove(playerData.getUniqueId());
+ }
+ }
+
+ /**
+ * Offline player data is used to handle processes like friend removal
+ * which can still occur if one of the two players is offline.
+ *
+ * Unlike {@link #get(UUID)} this method never returns a null instance
+ *
+ * @param uuid Player unique id
+ * @return Offline player data
+ */
+ @NotNull
+ public abstract OfflinePlayerData getOffline(UUID uuid);
+
+ /**
+ * Called when a player logs in, loading the player data inside the map.
+ *
+ * For YAML configs or SQL databases, data is loaded as not to overload
+ * the main thread with SQL requests. Therefore, the player data returned
+ * by that method, when the player joined for the first time, is not
+ * fully loaded YET.
+ *
+ * @param uniqueId Player UUID
+ * @return The loaded player data.
+ */
+ public PlayerData setup(UUID uniqueId) {
+ // Load player data if it does not exist
+ if (!data.containsKey(uniqueId)) {
+ PlayerData newData = TemporaryPlayerData.has(uniqueId) ? new PlayerData(MMOPlayerData.get(uniqueId), TemporaryPlayerData.get(uniqueId)) : new PlayerData(MMOPlayerData.get(uniqueId));
+
+ // Schedule async data loading
+ Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> {
+ loadData(newData);
+ newData.getStats().updateStats();
+ Bukkit.getPluginManager().callEvent(new AsyncPlayerDataLoadEvent(newData));
+ Bukkit.getScheduler().runTask(MMOCore.plugin, () -> Bukkit.getPluginManager().callEvent(new PlayerDataLoadEvent(newData)));
+ });
+
+ // Update data map
+ data.put(uniqueId, newData);
+
+ return newData;
+ }
+
+ return data.get(uniqueId);
+ }
+
+ public DefaultPlayerData getDefaultData() {
+ return defaultData;
+ }
+
+ public void loadDefaultData(ConfigurationSection config) {
+ defaultData = new DefaultPlayerData(config);
+ }
+
+ public boolean isLoaded(UUID uuid) {
+ return data.containsKey(uuid);
+ }
+
+ public Collection getLoaded() {
+ return data.values();
+ }
+
+ /**
+ * Called when player data must be loaded from database or config.
+ *
+ * @param uuid The uuid to load
+ * @param savingPlayerDataList the list where the data will be added.
+ */
+ public abstract void loadSavingPlayerData(UUID uuid,List savingPlayerDataList);
+
+
+ public abstract void loadData(PlayerData data);
+
+ /**
+ * Called when player data must be saved in configs or database.
+ * This method should always be called sync because it DOES register
+ * an async task in case MySQL storage is used.
+ *
+ * @param data Player data to save
+ */
+ public void saveData(PlayerData data) {
+ saveData(data.getSavingPlayerData());
+ }
+
+ public abstract void saveData(SavingPlayerData data);
+
+ public class DefaultPlayerData {
+ private final int level, classPoints, skillPoints, attributePoints, attrReallocPoints;
+
+ public DefaultPlayerData(ConfigurationSection config) {
+ level = config.getInt("level", 1);
+ classPoints = config.getInt("class-points");
+ skillPoints = config.getInt("skill-points");
+ attributePoints = config.getInt("attribute-points");
+ attrReallocPoints = config.getInt("attribute-realloc-points");
+ }
+
+ public DefaultPlayerData(int level, int classPoints, int skillPoints, int attributePoints, int attrReallocPoints) {
+ this.level = level;
+ this.classPoints = classPoints;
+ this.skillPoints = skillPoints;
+ this.attributePoints = attributePoints;
+ this.attrReallocPoints = attrReallocPoints;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public int getSkillPoints() {
+ return skillPoints;
+ }
+
+ public int getClassPoints() {
+ return classPoints;
+ }
+
+ public int getAttrReallocPoints() {
+ return attrReallocPoints;
+ }
+
+ public int getAttributePoints() {
+ return attributePoints;
+ }
+
+ public void apply(PlayerData player) {
+ player.setLevel(level);
+ player.setClassPoints(classPoints);
+ player.setSkillPoints(skillPoints);
+ player.setAttributePoints(attributePoints);
+ player.setAttributeReallocationPoints(attrReallocPoints);
+ }
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLDataProvider.java b/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLDataProvider.java
index 72e4364a..f4fcb651 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLDataProvider.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLDataProvider.java
@@ -1,58 +1,71 @@
-package net.Indyuce.mmocore.manager.data.mysql;
-
-import io.lumine.mythic.lib.sql.MMODataSource;
-import net.Indyuce.mmocore.manager.data.DataProvider;
-import net.Indyuce.mmocore.manager.data.GuildDataManager;
-import net.Indyuce.mmocore.manager.data.PlayerDataManager;
-import net.Indyuce.mmocore.manager.data.yaml.YAMLGuildDataManager;
-import org.bukkit.configuration.file.FileConfiguration;
-
-public class MySQLDataProvider extends MMODataSource implements DataProvider {
- private final MySQLPlayerDataManager playerManager = new MySQLPlayerDataManager(this);
- private final YAMLGuildDataManager guildManager = new YAMLGuildDataManager();
-
- public MySQLDataProvider(FileConfiguration config) {
- this.setup(config);
- }
-
- @Override
- public void load() {
-
-
- /*TODO
- also move Debug function to mysql data provider
-
- String tableName = getPoolName();
-getResultAsync("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '" +getPoolName()+ "' AND TABLE_NAME = 'mmocore_playerdata' AND COLUMN_NAME = 'times_claimed'",
- result -> {
- if (!result.next())
- executeUpdateAsync()
- }):
- executeUpdateAsync();
-
-
- if (!provider.prepareStatement("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '" + provider.getDatabase()
- + "' AND TABLE_NAME = '" + provider.getBountyDataTable() + "' AND COLUMN_NAME = 'last_updated'").executeQuery().next())
- provider.prepareStatement("ALTER TABLE " + provider.getBountyDataTable() + " ADD COLUMN last_updated BIGINT").execute();*/
-
- executeUpdateAsync(
- "CREATE TABLE IF NOT EXISTS mmocore_playerdata(uuid VARCHAR(36),class_points "
- + "INT(11) DEFAULT 0,skill_points INT(11) DEFAULT 0,attribute_points INT(11) "
- + "DEFAULT 0,attribute_realloc_points INT(11) DEFAULT 0,level INT(11) DEFAULT 1,"
- + "experience INT(11) DEFAULT 0,class VARCHAR(20),guild VARCHAR(20),last_login LONG,"
- + "attributes LONGTEXT,professions LONGTEXT,times_claimed LONGTEXT,quests LONGTEXT,"
- + "waypoints LONGTEXT,friends LONGTEXT,skills LONGTEXT,bound_skills LONGTEXT,"
- + "class_info LONGTEXT,skill_tree_reallocation_points INT(11) DEFAULT 0,skill_tree_points"
- + " LONGTEXT,skill_tree_nodes_level LONGTEXT,PRIMARY KEY (uuid));");
- }
-
- @Override
- public PlayerDataManager getDataManager() {
- return playerManager;
- }
-
- @Override
- public GuildDataManager getGuildManager() {
- return guildManager;
- }
-}
+package net.Indyuce.mmocore.manager.data.mysql;
+
+import io.lumine.mythic.lib.sql.MMODataSource;
+import net.Indyuce.mmocore.manager.data.DataProvider;
+import net.Indyuce.mmocore.manager.data.GuildDataManager;
+import net.Indyuce.mmocore.manager.data.PlayerDataManager;
+import net.Indyuce.mmocore.manager.data.yaml.YAMLGuildDataManager;
+import org.bukkit.configuration.file.FileConfiguration;
+
+import java.sql.SQLException;
+
+public class MySQLDataProvider extends MMODataSource implements DataProvider {
+ private final MySQLPlayerDataManager playerManager = new MySQLPlayerDataManager(this);
+ private final YAMLGuildDataManager guildManager = new YAMLGuildDataManager();
+
+ public MySQLDataProvider(FileConfiguration config) {
+ this.setup(config);
+ }
+
+ @Override
+ public void load() {
+
+
+ /*TODO
+ also move Debug function to mysql data provider
+
+ String tableName = getPoolName();
+getResultAsync("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '" +getPoolName()+ "' AND TABLE_NAME = 'mmocore_playerdata' AND COLUMN_NAME = 'times_claimed'",
+ result -> {
+ if (!result.next())
+ executeUpdateAsync()
+ }):
+ executeUpdateAsync();
+
+
+ if (!provider.prepareStatement("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '" + provider.getDatabase()
+ + "' AND TABLE_NAME = '" + provider.getBountyDataTable() + "' AND COLUMN_NAME = 'last_updated'").executeQuery().next())
+ provider.prepareStatement("ALTER TABLE " + provider.getBountyDataTable() + " ADD COLUMN last_updated BIGINT").execute();*/
+
+ executeUpdateAsync(
+ "CREATE TABLE IF NOT EXISTS mmocore_playerdata(uuid VARCHAR(36),class_points "
+ + "INT(11) DEFAULT 0,skill_points INT(11) DEFAULT 0,attribute_points INT(11) "
+ + "DEFAULT 0,attribute_realloc_points INT(11) DEFAULT 0,level INT(11) DEFAULT 1,"
+ + "experience INT(11) DEFAULT 0,class VARCHAR(20),guild VARCHAR(20),last_login LONG,"
+ + "attributes LONGTEXT,professions LONGTEXT,times_claimed LONGTEXT,quests LONGTEXT,"
+ + "waypoints LONGTEXT,friends LONGTEXT,skills LONGTEXT,bound_skills LONGTEXT,"
+ + "class_info LONGTEXT, is_saved TINYINT, PRIMARY KEY (uuid));");
+
+
+ getResult("SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME = 'mmocore_playerdata'" +
+ " AND COLUMN_NAME = 'is_saved'",(result)-> {
+ try {
+ if(!result.next())
+ executeUpdate("ALTER TABLE mmocore_playerdata ADD COLUMN is_saved TINYINT");
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+
+ });
+ }
+
+ @Override
+ public PlayerDataManager getDataManager() {
+ return playerManager;
+ }
+
+ @Override
+ public GuildDataManager getGuildManager() {
+ return guildManager;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java b/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java
index 33c41266..90254927 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLPlayerDataManager.java
@@ -1,269 +1,317 @@
-package net.Indyuce.mmocore.manager.data.mysql;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import io.lumine.mythic.lib.MythicLib;
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.OfflinePlayerData;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.profess.PlayerClass;
-import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
-import net.Indyuce.mmocore.api.player.stats.StatType;
-import net.Indyuce.mmocore.guild.provided.Guild;
-import net.Indyuce.mmocore.manager.data.PlayerDataManager;
-import net.Indyuce.mmocore.manager.data.mysql.MySQLTableEditor.Table;
-import org.apache.commons.lang.Validate;
-import org.jetbrains.annotations.NotNull;
-
-import java.sql.SQLException;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.logging.Level;
-import java.util.stream.Collectors;
-
-public class MySQLPlayerDataManager extends PlayerDataManager {
- private final MySQLDataProvider provider;
-
- public MySQLPlayerDataManager(MySQLDataProvider provider) {
- this.provider = provider;
- }
-
- @Override
- public void loadData(PlayerData data) {
- provider.getResult("SELECT * FROM mmocore_playerdata WHERE uuid = '" + data.getUniqueId() + "';", (result) -> {
- try {
- MMOCore.sqlDebug("Loading data for: '" + data.getUniqueId() + "'...");
-
- if (!result.next()) {
- data.setLevel(getDefaultData().getLevel());
- data.setClassPoints(getDefaultData().getClassPoints());
- data.setSkillPoints(getDefaultData().getSkillPoints());
- data.setAttributePoints(getDefaultData().getAttributePoints());
- data.setAttributeReallocationPoints(getDefaultData().getAttrReallocPoints());
- data.setExperience(0);
- data.getQuestData().updateBossBar();
-
- if (!data.hasUsedTemporaryData()) {
- data.setMana(data.getStats().getStat(StatType.MAX_MANA));
- data.setStamina(data.getStats().getStat(StatType.MAX_STAMINA));
- data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM));
- }
-
- data.setFullyLoaded();
- MMOCore.sqlDebug("Loaded DEFAULT data for: '" + data.getUniqueId() + "' as no saved data was found.");
- return;
- }
-
- data.setClassPoints(result.getInt("class_points"));
- data.setSkillPoints(result.getInt("skill_points"));
- data.setAttributePoints(result.getInt("attribute_points"));
- data.setAttributeReallocationPoints(result.getInt("attribute_realloc_points"));
- data.setLevel(result.getInt("level"));
- data.setExperience(result.getInt("experience"));
- if (!isEmpty(result.getString("class")))
- data.setClass(MMOCore.plugin.classManager.get(result.getString("class")));
-
- if (!isEmpty(result.getString("times_claimed"))) {
- JsonObject json = new JsonParser().parse(result.getString("times_claimed")).getAsJsonObject();
- json.entrySet().forEach(entry -> data.getItemClaims().put(entry.getKey(), entry.getValue().getAsInt()));
- }
-
- if (!data.hasUsedTemporaryData()) {
- data.setMana(data.getStats().getStat(StatType.MAX_MANA));
- data.setStamina(data.getStats().getStat(StatType.MAX_STAMINA));
- data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM));
- }
-
- if (!isEmpty(result.getString("guild"))) {
- Guild guild = provider.getGuildManager().getGuild(result.getString("guild"));
- data.setGuild(guild.getMembers().has(data.getUniqueId()) ? guild : null);
- }
- if (!isEmpty(result.getString("attributes"))) data.getAttributes().load(result.getString("attributes"));
- if (!isEmpty(result.getString("professions")))
- data.getCollectionSkills().load(result.getString("professions"));
- if (!isEmpty(result.getString("quests"))) data.getQuestData().load(result.getString("quests"));
- data.getQuestData().updateBossBar();
- if (!isEmpty(result.getString("waypoints")))
- data.getWaypoints().addAll(getJSONArray(result.getString("waypoints")));
- if (!isEmpty(result.getString("friends")))
- getJSONArray(result.getString("friends")).forEach(str -> data.getFriends().add(UUID.fromString(str)));
- if (!isEmpty(result.getString("skills"))) {
- JsonObject object = MythicLib.plugin.getJson().parse(result.getString("skills"), JsonObject.class);
- for (Entry entry : object.entrySet())
- data.setSkillLevel(entry.getKey(), entry.getValue().getAsInt());
- }
- if (!isEmpty(result.getString("bound_skills")))
- for (String skill : getJSONArray(result.getString("bound_skills")))
- if (data.getProfess().hasSkill(skill))
- data.getBoundSkills().add(data.getProfess().getSkill(skill));
- if (!isEmpty(result.getString("class_info"))) {
- JsonObject object = MythicLib.plugin.getJson().parse(result.getString("class_info"), JsonObject.class);
- for (Entry entry : object.entrySet()) {
- try {
- PlayerClass profess = MMOCore.plugin.classManager.get(entry.getKey());
- Validate.notNull(profess, "Could not find class '" + entry.getKey() + "'");
- data.applyClassInfo(profess, new SavedClassInformation(entry.getValue().getAsJsonObject()));
- } catch (IllegalArgumentException exception) {
- MMOCore.log(Level.WARNING, "Could not load class info '" + entry.getKey() + "': " + exception.getMessage());
- }
- }
- }
- //We load the skill trees
- data.setSkillTreeReallocationPoints(result.getInt("skill_tree_reallocation_points"));
-
- JsonObject object = MythicLib.plugin.getJson().parse(result.getString("skill_tree_points"), JsonObject.class);
- for (Entry entry : object.entrySet()) {
- data.setSkillTreePoints(entry.getKey(), entry.getValue().getAsInt());
- }
- object = MythicLib.plugin.getJson().parse(result.getString("skill_tree_nodes_level"), JsonObject.class);
- for (Entry entry : object.entrySet()) {
- data.setNodeLevel(MMOCore.plugin.skillTreeManager.getNode(entry.getKey()),entry.getValue().getAsInt());
- }
-
- data.setFullyLoaded();
- MMOCore.sqlDebug("Loaded saved data for: '" + data.getUniqueId() + "'!");
- MMOCore.sqlDebug(String.format("{ class: %s, level: %d }", data.getProfess().getId(), data.getLevel()));
- } catch (SQLException e) {
- e.printStackTrace();
- }
- });
- }
-
- private boolean isEmpty(String s) {
- return s == null || s.equalsIgnoreCase("null") || s.equalsIgnoreCase("{}") || s.equalsIgnoreCase("[]") || s.equalsIgnoreCase("");
- }
-
- @Override
- public void saveData(PlayerData data) {
- MySQLTableEditor sql = new MySQLTableEditor(Table.PLAYERDATA, data.getUniqueId());
- MMOCore.sqlDebug("Saving data for: '" + data.getUniqueId() + "'...");
-
- sql.updateData("class_points", data.getClassPoints());
- sql.updateData("skill_points", data.getSkillPoints());
- sql.updateData("attribute_points", data.getAttributePoints());
- sql.updateData("attribute_realloc_points", data.getAttributeReallocationPoints());
- sql.updateData("level", data.getLevel());
- sql.updateData("experience", data.getExperience());
- sql.updateData("class", data.getProfess().getId());
- sql.updateData("last_login", data.getLastLogin());
- sql.updateData("guild", data.hasGuild() ? data.getGuild().getId() : null);
-
- sql.updateJSONArray("waypoints", data.getWaypoints());
- sql.updateJSONArray("friends", data.getFriends().stream().map(UUID::toString).collect(Collectors.toList()));
- sql.updateJSONArray("bound_skills", data.getBoundSkills().stream().map(skill -> skill.getSkill().getHandler().getId()).collect(Collectors.toList()));
-
- sql.updateJSONObject("skills", data.mapSkillLevels().entrySet());
- sql.updateJSONObject("times_claimed", data.getItemClaims().entrySet());
-
- sql.updateData("attributes", data.getAttributes().toJsonString());
- sql.updateData("professions", data.getCollectionSkills().toJsonString());
- sql.updateData("quests", data.getQuestData().toJsonString());
-
- sql.updateData("class_info", createClassInfoData(data).toString());
-
- //Load skill tree on
- sql.updateData("skill_tree_reallocation_points", data.getSkillTreeReallocationPoints());
- sql.updateJSONObject("skill_tree_points", data.getSkillTreePoints().entrySet());
- sql.updateJSONObject("skill_tree_nodes_level", data.getNodeLevelsEntrySet());
-
-
- MMOCore.sqlDebug("Saved data for: " + data.getUniqueId());
- MMOCore.sqlDebug(String.format("{ class: %s, level: %d }", data.getProfess().getId(), data.getLevel()));
- }
-
- private JsonObject createClassInfoData(PlayerData data) {
- JsonObject json = new JsonObject();
- for (String c : data.getSavedClasses()) {
- SavedClassInformation info = data.getClassInfo(c);
- JsonObject classinfo = new JsonObject();
- classinfo.addProperty("level", info.getLevel());
- classinfo.addProperty("experience", info.getExperience());
- classinfo.addProperty("skill-points", info.getSkillPoints());
- classinfo.addProperty("attribute-points", info.getAttributePoints());
- classinfo.addProperty("attribute-realloc-points", info.getAttributeReallocationPoints());
- JsonObject skillinfo = new JsonObject();
- for (String skill : info.getSkillKeys())
- skillinfo.addProperty(skill, info.getSkillLevel(skill));
- classinfo.add("skill", skillinfo);
- JsonObject attributeinfo = new JsonObject();
- for (String attribute : info.getAttributeKeys())
- attributeinfo.addProperty(attribute, info.getAttributeLevel(attribute));
- classinfo.add("attribute", attributeinfo);
-
- json.add(c, classinfo);
- }
-
- return json;
- }
-
- @NotNull
- @Override
- public OfflinePlayerData getOffline(UUID uuid) {
- return isLoaded(uuid) ? get(uuid) : new MySQLOfflinePlayerData(uuid);
- }
-
- private Collection getJSONArray(String json) {
- return new ArrayList<>(Arrays.asList(MythicLib.plugin.getJson().parse(json, String[].class)));
- }
-
- public class MySQLOfflinePlayerData extends OfflinePlayerData {
- private int level;
- private long lastLogin;
- private PlayerClass profess;
- private List friends;
-
- public MySQLOfflinePlayerData(UUID uuid) {
- super(uuid);
-
- provider.getResult("SELECT * FROM mmocore_playerdata WHERE uuid = '" + uuid + "';", (result) -> {
- try {
- MMOCore.sqlDebug("Loading OFFLINE data for '" + uuid + "'.");
- if (!result.next()) {
- level = 0;
- lastLogin = 0;
- profess = MMOCore.plugin.classManager.getDefaultClass();
- friends = new ArrayList<>();
- MMOCore.sqlDebug("Default OFFLINE data loaded.");
- } else {
- level = result.getInt("level");
- lastLogin = result.getLong("last_login");
- profess = isEmpty(result.getString("class")) ? MMOCore.plugin.classManager.getDefaultClass() : MMOCore.plugin.classManager.get(result.getString("class"));
- if (!isEmpty(result.getString("friends")))
- getJSONArray(result.getString("friends")).forEach(str -> friends.add(UUID.fromString(str)));
- else friends = new ArrayList<>();
- MMOCore.sqlDebug("Saved OFFLINE data loaded.");
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- });
- }
-
- @Override
- public void removeFriend(UUID uuid) {
- friends.remove(uuid);
- new MySQLTableEditor(Table.PLAYERDATA, uuid).updateData("friends", friends.stream().map(UUID::toString).collect(Collectors.toList()));
- }
-
- @Override
- public boolean hasFriend(UUID uuid) {
- return friends.contains(uuid);
- }
-
- @Override
- public PlayerClass getProfess() {
- return profess;
- }
-
- @Override
- public int getLevel() {
- return level;
- }
-
- @Override
- public long getLastLogin() {
- return lastLogin;
- }
- }
-}
+package net.Indyuce.mmocore.manager.data.mysql;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import io.lumine.mythic.lib.MythicLib;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.OfflinePlayerData;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.player.SavingPlayerData;
+import net.Indyuce.mmocore.api.player.profess.PlayerClass;
+import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
+import net.Indyuce.mmocore.api.util.MMOCoreUtils;
+import net.Indyuce.mmocore.guild.provided.Guild;
+import net.Indyuce.mmocore.manager.data.PlayerDataManager;
+import org.apache.commons.lang.Validate;
+import org.bukkit.Bukkit;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.jetbrains.annotations.NotNull;
+
+import java.sql.SQLException;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
+import java.util.stream.Collectors;
+
+public class MySQLPlayerDataManager extends PlayerDataManager {
+ private final MySQLDataProvider provider;
+
+ public MySQLPlayerDataManager(MySQLDataProvider provider) {
+ this.provider = provider;
+ }
+
+ @Override
+ public void loadData(PlayerData data) {
+ long startTime = System.currentTimeMillis();
+ BukkitRunnable runnable = new BukkitRunnable() {
+ @Override
+ public void run() {
+
+ provider.getResult("SELECT * FROM mmocore_playerdata WHERE uuid = '" + data.getUniqueId() + "';", (result) -> {
+ try {
+ if (result.next()) {
+
+ //If the data couldn't be loaded for more than 2 seconds its probably due to a server crash and we load the old data
+ //If it the status is is_saved we load the data
+ if (System.currentTimeMillis() - startTime > 2000 || result.getInt("is_saved") == 1) {
+ MMOCore.sqlDebug("Time waited: " + (System.currentTimeMillis() - startTime));
+ MMOCore.sqlDebug("Loading data for: '" + data.getUniqueId() + "'...");
+
+ // Initialize custom resources
+ if (!data.hasUsedTemporaryData()) {
+ data.setMana(data.getStats().getStat("MAX_MANA"));
+ data.setStamina(data.getStats().getStat("MAX_STAMINA"));
+ data.setStellium(data.getStats().getStat("MAX_STELLIUM"));
+ }
+
+ data.setClassPoints(result.getInt("class_points"));
+ data.setSkillPoints(result.getInt("skill_points"));
+ data.setAttributePoints(result.getInt("attribute_points"));
+ data.setAttributeReallocationPoints(result.getInt("attribute_realloc_points"));
+ data.setLevel(result.getInt("level"));
+ data.setExperience(result.getInt("experience"));
+ if (!isEmpty(result.getString("class")))
+ data.setClass(MMOCore.plugin.classManager.get(result.getString("class")));
+
+ if (!isEmpty(result.getString("times_claimed"))) {
+ JsonObject json = new JsonParser().parse(result.getString("times_claimed")).getAsJsonObject();
+ json.entrySet().forEach(entry -> data.getItemClaims().put(entry.getKey(), entry.getValue().getAsInt()));
+ }
+
+ if (!isEmpty(result.getString("guild"))) {
+ Guild guild = MMOCore.plugin.dataProvider.getGuildManager().getGuild(result.getString("guild"));
+ data.setGuild(guild.hasMember(data.getUniqueId()) ? guild : null);
+ }
+ if (!isEmpty(result.getString("attributes")))
+ data.getAttributes().load(result.getString("attributes"));
+ if (!isEmpty(result.getString("professions")))
+ data.getCollectionSkills().load(result.getString("professions"));
+ if (!isEmpty(result.getString("quests")))
+ data.getQuestData().load(result.getString("quests"));
+ data.getQuestData().updateBossBar();
+ if (!isEmpty(result.getString("waypoints")))
+ data.getWaypoints().addAll(MMOCoreUtils.jsonArrayToList(result.getString("waypoints")));
+ if (!isEmpty(result.getString("friends")))
+ MMOCoreUtils.jsonArrayToList(result.getString("friends")).forEach(str -> data.getFriends().add(UUID.fromString(str)));
+ if (!isEmpty(result.getString("skills"))) {
+ JsonObject object = MythicLib.plugin.getJson().parse(result.getString("skills"), JsonObject.class);
+ for (Entry entry : object.entrySet())
+ data.setSkillLevel(entry.getKey(), entry.getValue().getAsInt());
+ }
+ if (!isEmpty(result.getString("bound_skills")))
+ for (String skill : MMOCoreUtils.jsonArrayToList(result.getString("bound_skills")))
+ if (data.getProfess().hasSkill(skill))
+ data.getBoundSkills().add(data.getProfess().getSkill(skill));
+ if (!isEmpty(result.getString("class_info"))) {
+ JsonObject object = MythicLib.plugin.getJson().parse(result.getString("class_info"), JsonObject.class);
+ for (Entry entry : object.entrySet()) {
+ try {
+ PlayerClass profess = MMOCore.plugin.classManager.get(entry.getKey());
+ Validate.notNull(profess, "Could not find class '" + entry.getKey() + "'");
+ data.applyClassInfo(profess, new SavedClassInformation(entry.getValue().getAsJsonObject()));
+ } catch (IllegalArgumentException exception) {
+ MMOCore.log(Level.WARNING, "Could not load class info '" + entry.getKey() + "': " + exception.getMessage());
+ }
+ }
+ }
+
+ //We now change the saved status to false because the data on SQL won't be the same as in the RAM
+ MySQLTableEditor sql = new MySQLTableEditor(MySQLTableEditor.Table.PLAYERDATA, data.getUniqueId(), provider);
+
+ //We set the saved status to false
+ sql.updateData("is_saved", 0);
+ this.cancel();
+ data.setFullyLoaded();
+ MMOCore.sqlDebug("Loaded saved data for: '" + data.getUniqueId() + "'!");
+ MMOCore.sqlDebug(String.format("{ class: %s, level: %d }", data.getProfess().getId(), data.getLevel()));
+ } else {
+ MMOCore.sqlDebug("Failed to load data because is_saved is false.");
+ }
+
+ } else {
+ data.setLevel(getDefaultData().getLevel());
+ data.setClassPoints(getDefaultData().getClassPoints());
+ data.setSkillPoints(getDefaultData().getSkillPoints());
+ data.setAttributePoints(getDefaultData().getAttributePoints());
+ data.setAttributeReallocationPoints(getDefaultData().getAttrReallocPoints());
+ data.setExperience(0);
+ data.getQuestData().updateBossBar();
+
+ data.setFullyLoaded();
+ this.cancel();
+ MMOCore.sqlDebug("Loaded DEFAULT data for: '" + data.getUniqueId() + "' as no saved data was found.");
+ return;
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ });
+ }
+ };
+
+ runnable.runTaskTimerAsynchronously(MMOCore.plugin, 0L, 10L);
+
+ }
+
+
+ private boolean isEmpty(String s) {
+ return s == null || s.equalsIgnoreCase("null") || s.equalsIgnoreCase("{}") || s.equalsIgnoreCase("[]") || s.equalsIgnoreCase("");
+ }
+
+
+ @Override
+ public void saveData(SavingPlayerData data) {
+
+ MySQLTableEditor sql = new MySQLTableEditor(MySQLTableEditor.Table.PLAYERDATA, data.uuid(), provider);
+ MMOCore.sqlDebug("Saving data for: '" + data.uuid() + "'...");
+
+ sql.updateData("class_points", data.classPoints());
+ sql.updateData("skill_points", data.skillPoints());
+ sql.updateData("attribute_points", data.attributePoints());
+ sql.updateData("attribute_realloc_points", data.attributeReallocationPoints());
+ sql.updateData("level", data.level());
+ sql.updateData("experience", data.experience());
+ sql.updateData("class", data.classId());
+ sql.updateData("last_login", data.lastLogin());
+ sql.updateData("guild", data.guildId());
+
+ sql.updateJSONArray("waypoints", data.waypoints());
+ sql.updateJSONArray("friends", data.friends().stream().map(UUID::toString).collect(Collectors.toList()));
+ sql.updateJSONArray("bound_skills", data.boundSkills());
+
+ sql.updateJSONObject("skills", data.skills().entrySet());
+ sql.updateJSONObject("times_claimed", data.itemClaims().entrySet());
+
+ sql.updateData("attributes", data.attributes());
+ sql.updateData("professions", data.collectionsSkills());
+ sql.updateData("quests", data.questData());
+
+ sql.updateData("class_info", data.classInfoData());
+ sql.updateData("is_saved", 1);
+
+ MMOCore.sqlDebug("Saved data for: " + data.uuid());
+ MMOCore.sqlDebug(String.format("{ class: %s, level: %d }", data.classId(), data.level()));
+
+
+ }
+
+
+ @NotNull
+ @Override
+ public OfflinePlayerData getOffline(UUID uuid) {
+ return isLoaded(uuid) ? get(uuid) : new MySQLOfflinePlayerData(uuid);
+ }
+
+ @Override
+ public void loadSavingPlayerData(UUID uuid, List savingPlayerDataList) {
+
+ provider.getResult("SELECT * FROM mmocore_playerdata WHERE uuid = '" + uuid + "';", (result) -> {
+ try {
+
+
+ if (result.next()) {
+ Map skills = new HashMap<>();
+ Map itemClaims = new HashMap<>();
+
+ if (!isEmpty(result.getString("skills"))) {
+ JsonObject object = MythicLib.plugin.getJson().parse(result.getString("skills"), JsonObject.class);
+ for (Entry entry : object.entrySet())
+ skills.put(entry.getKey(), entry.getValue().getAsInt());
+ }
+
+ if (!isEmpty(result.getString("times_claimed"))) {
+ JsonObject json = new JsonParser().parse(result.getString("times_claimed")).getAsJsonObject();
+ json.entrySet().forEach(entry -> itemClaims.put(entry.getKey(), entry.getValue().getAsInt()));
+ }
+
+
+ SavingPlayerData data = new SavingPlayerData(
+ uuid,
+ result.getInt("class_points"),
+ result.getInt("skill_points"),
+ result.getInt("attribute_points"),
+ result.getInt("attribute_realloc_points"),
+ result.getInt("level"),
+ result.getInt("experience"),
+ result.getString("class"),
+ result.getLong("last_login"),
+ result.getString("guild"),
+ MMOCoreUtils.jsonArrayToList(result.getString("waypoints")).stream().collect(Collectors.toSet()),
+ MMOCoreUtils.jsonArrayToList(result.getString("friends")).stream().map(str -> UUID.fromString(str)).toList(),
+ MMOCoreUtils.jsonArrayToList(result.getString("bound_skills")).stream().toList(),
+ skills,
+ itemClaims,
+ result.getString("attributes"),
+ result.getString("professions"),
+ result.getString("quests"),
+ result.getString("class_info"));
+
+ savingPlayerDataList.add(data);
+ Bukkit.broadcastMessage(new Gson().toJson(data));
+
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+
+ });
+ }
+
+
+ public class MySQLOfflinePlayerData extends OfflinePlayerData {
+ private int level;
+ private long lastLogin;
+ private PlayerClass profess;
+ private List friends;
+
+ public MySQLOfflinePlayerData(UUID uuid) {
+ super(uuid);
+
+ provider.getResult("SELECT * FROM mmocore_playerdata WHERE uuid = '" + uuid + "';", (result) -> {
+ try {
+ MMOCore.sqlDebug("Loading OFFLINE data for '" + uuid + "'.");
+ if (!result.next()) {
+ level = 0;
+ lastLogin = 0;
+ profess = MMOCore.plugin.classManager.getDefaultClass();
+ friends = new ArrayList<>();
+ MMOCore.sqlDebug("Default OFFLINE data loaded.");
+ } else {
+ level = result.getInt("level");
+ lastLogin = result.getLong("last_login");
+ profess = isEmpty(result.getString("class")) ? MMOCore.plugin.classManager.getDefaultClass() : MMOCore.plugin.classManager.get(result.getString("class"));
+ if (!isEmpty(result.getString("friends")))
+ MMOCoreUtils.jsonArrayToList(result.getString("friends")).forEach(str -> friends.add(UUID.fromString(str)));
+ else friends = new ArrayList<>();
+ MMOCore.sqlDebug("Saved OFFLINE data loaded.");
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ });
+ }
+
+ @Override
+ public void removeFriend(UUID uuid) {
+ friends.remove(uuid);
+ new MySQLTableEditor(MySQLTableEditor.Table.PLAYERDATA, uuid, provider).updateData("friends", friends.stream().map(UUID::toString).collect(Collectors.toList()));
+ }
+
+ @Override
+ public boolean hasFriend(UUID uuid) {
+ return friends.contains(uuid);
+ }
+
+ @Override
+ public PlayerClass getProfess() {
+ return profess;
+ }
+
+ @Override
+ public int getLevel() {
+ return level;
+ }
+
+ @Override
+ public long getLastLogin() {
+ return lastLogin;
+ }
+ }
+}
+
+
+
diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLTableEditor.java b/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLTableEditor.java
index f6d1a7ad..16f387ac 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLTableEditor.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/data/mysql/MySQLTableEditor.java
@@ -1,55 +1,58 @@
-package net.Indyuce.mmocore.manager.data.mysql;
-
-import java.util.Collection;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.UUID;
-
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
-
-import net.Indyuce.mmocore.MMOCore;
-
-public class MySQLTableEditor {
- private final Table table;
- private final UUID uuid;
-
- public MySQLTableEditor(Table table, UUID uuid) {
- this.table = table;
- this.uuid = uuid;
- }
-
- public void updateData(String key, Object value) {
- ((MySQLDataProvider) MMOCore.plugin.dataProvider).executeUpdate("INSERT INTO " + table + "(uuid, " + key
- + ") VALUES('" + uuid + "', '" + value + "') ON DUPLICATE KEY UPDATE " + key + "='" + value + "';");
- }
-
- public void updateJSONArray(String key, Collection collection) {
- JsonArray json = new JsonArray();
- for (String s : collection)
- json.add(s);
- updateData(key, json.toString());
- }
-
- public void updateJSONObject(String key, Set> collection) {
- JsonObject json = new JsonObject();
- for (Entry entry : collection)
- json.addProperty(entry.getKey(), entry.getValue());
- updateData(key, json.toString());
- }
-
- public enum Table {
- PLAYERDATA("mmocore_playerdata"), GUILDDATA("mmocore_guilddata");
-
- final String tableName;
-
- Table(String tN) {
- tableName = tN;
- }
-
- @Override
- public String toString() {
- return tableName;
- }
- }
-}
+package net.Indyuce.mmocore.manager.data.mysql;
+
+import java.util.Collection;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.UUID;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+
+import net.Indyuce.mmocore.MMOCore;
+
+public class MySQLTableEditor {
+ private final Table table;
+ private final UUID uuid;
+
+ private final MySQLDataProvider provider;
+
+ public MySQLTableEditor(Table table, UUID uuid,MySQLDataProvider provider) {
+ this.table = table;
+ this.uuid = uuid;
+ this.provider=provider;
+ }
+
+ public void updateData(String key, Object value) {
+ provider.executeUpdate("INSERT INTO " + table + "(uuid, " + key
+ + ") VALUES('" + uuid + "', '" + value + "') ON DUPLICATE KEY UPDATE " + key + "='" + value + "';");
+ }
+
+ public void updateJSONArray(String key, Collection collection) {
+ JsonArray json = new JsonArray();
+ for (String s : collection)
+ json.add(s);
+ updateData(key, json.toString());
+ }
+
+ public void updateJSONObject(String key, Set> collection) {
+ JsonObject json = new JsonObject();
+ for (Entry entry : collection)
+ json.addProperty(entry.getKey(), entry.getValue());
+ updateData(key, json.toString());
+ }
+
+ public enum Table {
+ PLAYERDATA("mmocore_playerdata"), GUILDDATA("mmocore_guilddata");
+
+ final String tableName;
+
+ Table(String tN) {
+ tableName = tN;
+ }
+
+ @Override
+ public String toString() {
+ return tableName;
+ }
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLDataProvider.java b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLDataProvider.java
index d6ea6a2b..39d20dd5 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLDataProvider.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLDataProvider.java
@@ -1,20 +1,20 @@
-package net.Indyuce.mmocore.manager.data.yaml;
-
-import net.Indyuce.mmocore.manager.data.DataProvider;
-import net.Indyuce.mmocore.manager.data.GuildDataManager;
-import net.Indyuce.mmocore.manager.data.PlayerDataManager;
-
-public class YAMLDataProvider implements DataProvider {
- private final YAMLPlayerDataManager playerManager = new YAMLPlayerDataManager(this);
- private final YAMLGuildDataManager guildManager = new YAMLGuildDataManager();
-
- @Override
- public PlayerDataManager getDataManager() {
- return playerManager;
- }
-
- @Override
- public GuildDataManager getGuildManager() {
- return guildManager;
- }
-}
+package net.Indyuce.mmocore.manager.data.yaml;
+
+import net.Indyuce.mmocore.manager.data.DataProvider;
+import net.Indyuce.mmocore.manager.data.GuildDataManager;
+import net.Indyuce.mmocore.manager.data.PlayerDataManager;
+
+public class YAMLDataProvider implements DataProvider {
+ private final YAMLPlayerDataManager playerManager = new YAMLPlayerDataManager(this);
+ private final YAMLGuildDataManager guildManager = new YAMLGuildDataManager();
+
+ @Override
+ public PlayerDataManager getDataManager() {
+ return playerManager;
+ }
+
+ @Override
+ public GuildDataManager getGuildManager() {
+ return guildManager;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLGuildDataManager.java b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLGuildDataManager.java
index 8c4e0808..ab2557ce 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLGuildDataManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLGuildDataManager.java
@@ -1,50 +1,50 @@
-package net.Indyuce.mmocore.manager.data.yaml;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.configuration.file.YamlConfiguration;
-
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigFile;
-import net.Indyuce.mmocore.guild.provided.Guild;
-import net.Indyuce.mmocore.manager.data.GuildDataManager;
-
-public class YAMLGuildDataManager extends GuildDataManager {
- @Override
- public void save(Guild guild) {
- ConfigFile config = new ConfigFile(guild);
- config.getConfig().set("name", guild.getName());
- config.getConfig().set("tag", guild.getTag());
- config.getConfig().set("owner", guild.getOwner().toString());
-
- List memberList = new ArrayList<>();
- guild.getMembers().forEach(uuid -> memberList.add(uuid.toString()));
- config.getConfig().set("members", memberList);
-
- config.save();
- }
-
- @Override
- public void load() {
- File guildsFolder = new File(MMOCore.plugin.getDataFolder(), "guilds");
- if (!guildsFolder.exists())
- guildsFolder.mkdirs();
- for (File file : guildsFolder.listFiles()) {
- if (!file.isDirectory() && file.getName().substring(file.getName().lastIndexOf('.')).equalsIgnoreCase(".yml")) {
- FileConfiguration c = YamlConfiguration.loadConfiguration(file);
- Guild guild = newRegisteredGuild(UUID.fromString(c.getString("owner")), c.getString("name"), c.getString("tag"));
- for (String m : c.getStringList("members"))
- guild.registerMember(UUID.fromString(m));
- }
- }
- }
-
- @Override
- public void delete(Guild guild) {
- new ConfigFile(guild).delete();
- }
-}
+package net.Indyuce.mmocore.manager.data.yaml;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import net.Indyuce.mmocore.MMOCore;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import net.Indyuce.mmocore.api.ConfigFile;
+import net.Indyuce.mmocore.guild.provided.Guild;
+import net.Indyuce.mmocore.manager.data.GuildDataManager;
+
+public class YAMLGuildDataManager extends GuildDataManager {
+ @Override
+ public void save(Guild guild) {
+ ConfigFile config = new ConfigFile(guild);
+ config.getConfig().set("name", guild.getName());
+ config.getConfig().set("tag", guild.getTag());
+ config.getConfig().set("owner", guild.getOwner().toString());
+
+ List memberList = new ArrayList<>();
+ guild.forEachMember(uuid -> memberList.add(uuid.toString()));
+ config.getConfig().set("members", memberList);
+
+ config.save();
+ }
+
+ @Override
+ public void load() {
+ File guildsFolder = new File(MMOCore.plugin.getDataFolder(), "guilds");
+ if (!guildsFolder.exists())
+ guildsFolder.mkdirs();
+ for (File file : guildsFolder.listFiles()) {
+ if (!file.isDirectory() && file.getName().substring(file.getName().lastIndexOf('.')).equalsIgnoreCase(".yml")) {
+ FileConfiguration c = YamlConfiguration.loadConfiguration(file);
+ Guild guild = newRegisteredGuild(UUID.fromString(c.getString("owner")), c.getString("name"), c.getString("tag"));
+ for (String m : c.getStringList("members"))
+ guild.registerMember(UUID.fromString(m));
+ }
+ }
+ }
+
+ @Override
+ public void delete(Guild guild) {
+ new ConfigFile(guild).delete();
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLOfflinePlayerData.java b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLOfflinePlayerData.java
index c2eb4047..67de7675 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLOfflinePlayerData.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLOfflinePlayerData.java
@@ -1,51 +1,51 @@
-package net.Indyuce.mmocore.manager.data.yaml;
-
-import java.util.List;
-import java.util.UUID;
-
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigFile;
-import net.Indyuce.mmocore.api.player.OfflinePlayerData;
-import net.Indyuce.mmocore.api.player.profess.PlayerClass;
-
-public class YAMLOfflinePlayerData extends OfflinePlayerData {
- private final ConfigFile config;
-
- /**
- * Supports offline player data operations like friend removals which can't
- * be handled when their player data is not loaded in the data map.
- */
- public YAMLOfflinePlayerData(UUID uuid) {
- super(uuid);
-
- config = new ConfigFile(uuid);
- }
-
- @Override
- public void removeFriend(UUID uuid) {
- List friends = config.getConfig().getStringList("friends");
- friends.remove(uuid.toString());
- config.getConfig().set("friends", friends);
- config.save();
- }
-
- @Override
- public boolean hasFriend(UUID uuid) {
- return config.getConfig().getStringList("friends").contains(uuid.toString());
- }
-
- @Override
- public PlayerClass getProfess() {
- return config.getConfig().contains("class") ? MMOCore.plugin.classManager.get(config.getConfig().getString("class")) : MMOCore.plugin.classManager.getDefaultClass();
- }
-
- @Override
- public int getLevel() {
- return config.getConfig().getInt("level");
- }
-
- @Override
- public long getLastLogin() {
- return config.getConfig().getLong("last-login");
- }
-}
+package net.Indyuce.mmocore.manager.data.yaml;
+
+import java.util.List;
+import java.util.UUID;
+
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.profess.PlayerClass;
+import net.Indyuce.mmocore.api.ConfigFile;
+import net.Indyuce.mmocore.api.player.OfflinePlayerData;
+
+public class YAMLOfflinePlayerData extends OfflinePlayerData {
+ private final ConfigFile config;
+
+ /**
+ * Supports offline player data operations like friend removals which can't
+ * be handled when their player data is not loaded in the data map.
+ */
+ public YAMLOfflinePlayerData(UUID uuid) {
+ super(uuid);
+
+ config = new ConfigFile(uuid);
+ }
+
+ @Override
+ public void removeFriend(UUID uuid) {
+ List friends = config.getConfig().getStringList("friends");
+ friends.remove(uuid.toString());
+ config.getConfig().set("friends", friends);
+ config.save();
+ }
+
+ @Override
+ public boolean hasFriend(UUID uuid) {
+ return config.getConfig().getStringList("friends").contains(uuid.toString());
+ }
+
+ @Override
+ public PlayerClass getProfess() {
+ return config.getConfig().contains("class") ? MMOCore.plugin.classManager.get(config.getConfig().getString("class")) : MMOCore.plugin.classManager.getDefaultClass();
+ }
+
+ @Override
+ public int getLevel() {
+ return config.getConfig().getInt("level");
+ }
+
+ @Override
+ public long getLastLogin() {
+ return config.getConfig().getLong("last-login");
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java
index 7872d50e..4c135010 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/data/yaml/YAMLPlayerDataManager.java
@@ -1,189 +1,375 @@
-package net.Indyuce.mmocore.manager.data.yaml;
-
-import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.ConfigFile;
-import net.Indyuce.mmocore.api.player.OfflinePlayerData;
-import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.profess.PlayerClass;
-import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
-import net.Indyuce.mmocore.api.player.stats.StatType;
-import net.Indyuce.mmocore.guild.provided.Guild;
-import net.Indyuce.mmocore.manager.data.DataProvider;
-import net.Indyuce.mmocore.manager.data.PlayerDataManager;
-import net.Indyuce.mmocore.tree.SkillTreeNode;
-import net.Indyuce.mmocore.tree.skilltree.SkillTree;
-import org.apache.commons.lang.Validate;
-import org.bukkit.Bukkit;
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import java.util.logging.Level;
-import java.util.stream.Collectors;
-
-public class YAMLPlayerDataManager extends PlayerDataManager {
- private final DataProvider provider;
-
- public YAMLPlayerDataManager(DataProvider provider) {
- this.provider = provider;
- }
-
- @Override
- public void loadData(PlayerData data) {
- FileConfiguration config = new ConfigFile(data.getUniqueId()).getConfig();
-
- data.setClassPoints(config.getInt("class-points", getDefaultData().getClassPoints()));
- data.setSkillPoints(config.getInt("skill-points", getDefaultData().getSkillPoints()));
- data.setAttributePoints(config.getInt("attribute-points", getDefaultData().getAttributePoints()));
- data.setAttributeReallocationPoints(config.getInt("attribute-realloc-points", getDefaultData().getAttrReallocPoints()));
- data.setLevel(config.getInt("level", getDefaultData().getLevel()));
- data.setExperience(config.getInt("experience"));
- if (config.contains("class"))
- data.setClass(MMOCore.plugin.classManager.get(config.getString("class")));
-
- if (!data.hasUsedTemporaryData()) {
- data.setMana(data.getStats().getStat(StatType.MAX_MANA));
- data.setStamina(data.getStats().getStat(StatType.MAX_STAMINA));
- data.setStellium(data.getStats().getStat(StatType.MAX_STELLIUM));
- }
-
- if (config.contains("guild")) {
- Guild guild = provider.getGuildManager().getGuild(config.getString("guild"));
- data.setGuild(guild.getMembers().has(data.getUniqueId()) ? guild : null);
- }
- if (config.contains("attribute"))
- data.getAttributes().load(config.getConfigurationSection("attribute"));
- if (config.contains("profession"))
- data.getCollectionSkills().load(config.getConfigurationSection("profession"));
- if (config.contains("quest"))
- data.getQuestData().load(config.getConfigurationSection("quest"));
- data.getQuestData().updateBossBar();
- if (config.contains("waypoints"))
- data.getWaypoints().addAll(config.getStringList("waypoints"));
- if (config.contains("friends"))
- config.getStringList("friends").forEach(str -> data.getFriends().add(UUID.fromString(str)));
- if (config.contains("skill"))
- config.getConfigurationSection("skill").getKeys(false).forEach(id -> data.setSkillLevel(id, config.getInt("skill." + id)));
- if (config.contains("bound-skills"))
- for (String id : config.getStringList("bound-skills"))
- if (data.getProfess().hasSkill(id))
- data.getBoundSkills().add(data.getProfess().getSkill(id));
- if (config.contains("times-claimed"))
- for (String key : config.getConfigurationSection("times-claimed").getKeys(true))
- data.getItemClaims().put(key, config.getInt("times-claimed." + key));
- //Load skill tree nodes
-
- for (SkillTreeNode node : MMOCore.plugin.skillTreeManager.getAllNodes()) {
- String path = "skill-tree-nodes." + node.getFullId();
- if (config.contains(path))
- data.setNodeLevel(node, config.getInt(path));
- else {
- data.setNodeLevel(node, 0);
- }
- }
- //Setup the nodeStates
- data.setupNodeState();
- //Load skill tree points
- ConfigurationSection section = config.getConfigurationSection("skill-tree-points");
- if (section != null) {
- for (String key : section.getKeys(false))
- data.setSkillTreePoints(key, section.getInt(key));
- }
- //Put 0 to the rest of the values if nothing has been given
- List skillTreeIds = MMOCore.plugin.skillTreeManager.getAll().stream().map(SkillTree::getId).collect(Collectors.toList());
- skillTreeIds.add("global");
- for (String treeId : skillTreeIds) {
- if (!data.containsSkillPointTreeId(treeId))
- data.setSkillTreePoints(treeId, 0);
- }
-
- data.setSkillTreeReallocationPoints(config.getInt("skill-tree-reallocation-points", 0));
-
- // Load class slots, use try so the player can log in.
- if (config.contains("class-info"))
- for (String key : config.getConfigurationSection("class-info").getKeys(false))
- try {
- PlayerClass profess = MMOCore.plugin.classManager.get(key);
- Validate.notNull(profess, "Could not find class '" + key + "'");
- data.applyClassInfo(profess, new SavedClassInformation(config.getConfigurationSection("class-info." + key)));
- } catch (IllegalArgumentException exception) {
- MMOCore.log(Level.WARNING, "Could not load class info '" + key + "': " + exception.getMessage());
- }
-
- data.setFullyLoaded();
- }
-
- @Override
- public void saveData(PlayerData data) {
- ConfigFile file = new ConfigFile(data.getUniqueId());
- FileConfiguration config = file.getConfig();
-
- config.set("class-points", data.getClassPoints());
- config.set("skill-points", data.getSkillPoints());
- config.set("attribute-points", data.getAttributePoints());
- // config.set("skill-realloc-points", skillReallocationPoints);
- config.set("attribute-realloc-points", data.getAttributeReallocationPoints());
- config.set("level", data.getLevel());
- config.set("experience", data.getExperience());
- config.set("class", data.getProfess().getId());
- config.set("waypoints", new ArrayList<>(data.getWaypoints()));
- config.set("friends", data.getFriends().stream().map(UUID::toString).collect(Collectors.toList()));
- config.set("last-login", data.getLastLogin());
- config.set("guild", data.hasGuild() ? data.getGuild().getId() : null);
-
- config.set("skill", null);
- data.mapSkillLevels().forEach((key1, value) -> config.set("skill." + key1, value));
- data.getItemClaims().forEach((key, times) -> config.set("times-claimed." + key, times));
-
- //Save the node levels for the player
- for (SkillTreeNode node : MMOCore.plugin.skillTreeManager.getAllNodes()) {
- config.set("skill-tree-nodes." + node.getTree().getId() + "." + node.getId(), data.getNodeLevel(node));
- }
-
- //Saves skill tree points
- for (String treeId : data.getSkillTreePoints().keySet()) {
- config.set("skill-tree-points." + treeId, data.getSkillTreePoint(treeId));
- }
- config.set("skill-tree-reallocation-points", data.getSkillTreeReallocationPoints());
-
- List boundSkills = new ArrayList<>();
- data.getBoundSkills().forEach(skill -> boundSkills.add(skill.getSkill().getHandler().getId()));
- config.set("bound-skills", boundSkills);
-
- config.set("attribute", null);
- config.createSection("attribute");
- data.getAttributes().save(config.getConfigurationSection("attribute"));
-
- config.set("profession", null);
- config.createSection("profession");
- data.getCollectionSkills().save(config.getConfigurationSection("profession"));
-
- config.set("quest", null);
- config.createSection("quest");
- data.getQuestData().save(config.getConfigurationSection("quest"));
-
- config.set("class-info", null);
- for (String key : data.getSavedClasses()) {
- SavedClassInformation info = data.getClassInfo(key);
- config.set("class-info." + key + ".level", info.getLevel());
- config.set("class-info." + key + ".experience", info.getExperience());
- config.set("class-info." + key + ".skill-points", info.getSkillPoints());
- config.set("class-info." + key + ".attribute-points", info.getAttributePoints());
- config.set("class-info." + key + ".attribute-realloc-points", info.getAttributeReallocationPoints());
- info.getSkillKeys().forEach(skill -> config.set("class-info." + key + ".skill." + skill, info.getSkillLevel(skill)));
- info.getAttributeKeys()
- .forEach(attribute -> config.set("class-info." + key + ".attribute." + attribute, info.getAttributeLevel(attribute)));
- }
-
- file.save();
- }
-
- @NotNull
- @Override
- public OfflinePlayerData getOffline(UUID uuid) {
- return isLoaded(uuid) ? get(uuid) : new YAMLOfflinePlayerData(uuid);
- }
-}
+package net.Indyuce.mmocore.manager.data.yaml;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.SavingPlayerData;
+import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
+import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
+import net.Indyuce.mmocore.api.player.profess.PlayerClass;
+import net.Indyuce.mmocore.api.ConfigFile;
+import net.Indyuce.mmocore.api.player.OfflinePlayerData;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
+import net.Indyuce.mmocore.api.quest.PlayerQuests;
+import net.Indyuce.mmocore.experience.PlayerProfessions;
+import net.Indyuce.mmocore.experience.Profession;
+import net.Indyuce.mmocore.guild.provided.Guild;
+import net.Indyuce.mmocore.manager.data.DataProvider;
+import net.Indyuce.mmocore.manager.data.PlayerDataManager;
+import org.apache.commons.lang.Validate;
+import org.bukkit.Bukkit;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+import java.util.logging.Level;
+import java.util.stream.Collectors;
+
+public class YAMLPlayerDataManager extends PlayerDataManager {
+ private final DataProvider provider;
+
+ public YAMLPlayerDataManager(DataProvider provider) {
+ this.provider = provider;
+ }
+
+ @Override
+ public void loadData(PlayerData data) {
+ FileConfiguration config = new ConfigFile(data.getUniqueId()).getConfig();
+
+ data.setClassPoints(config.getInt("class-points", getDefaultData().getClassPoints()));
+ data.setSkillPoints(config.getInt("skill-points", getDefaultData().getSkillPoints()));
+ data.setAttributePoints(config.getInt("attribute-points", getDefaultData().getAttributePoints()));
+ data.setAttributeReallocationPoints(config.getInt("attribute-realloc-points", getDefaultData().getAttrReallocPoints()));
+ data.setLevel(config.getInt("level", getDefaultData().getLevel()));
+ data.setExperience(config.getInt("experience"));
+ if (config.contains("class"))
+ data.setClass(MMOCore.plugin.classManager.get(config.getString("class")));
+
+ if (!data.hasUsedTemporaryData()) {
+ data.setMana(data.getStats().getStat("MAX_MANA"));
+ data.setStamina(data.getStats().getStat("MAX_STAMINA"));
+ data.setStellium(data.getStats().getStat("MAX_STELLIUM"));
+ }
+
+ if (config.contains("guild")) {
+ Guild guild = provider.getGuildManager().getGuild(config.getString("guild"));
+ data.setGuild(guild.hasMember(data.getUniqueId()) ? guild : null);
+ }
+ if (config.contains("attribute"))
+ data.getAttributes().load(config.getConfigurationSection("attribute"));
+ if (config.contains("profession"))
+ data.getCollectionSkills().load(config.getConfigurationSection("profession"));
+ if (config.contains("quest"))
+ data.getQuestData().load(config.getConfigurationSection("quest"));
+ data.getQuestData().updateBossBar();
+ if (config.contains("waypoints"))
+ data.getWaypoints().addAll(config.getStringList("waypoints"));
+ if (config.contains("friends"))
+ config.getStringList("friends").forEach(str -> data.getFriends().add(UUID.fromString(str)));
+ if (config.contains("skill"))
+ config.getConfigurationSection("skill").getKeys(false).forEach(id -> data.setSkillLevel(id, config.getInt("skill." + id)));
+ if (config.contains("bound-skills"))
+ for (String id : config.getStringList("bound-skills"))
+ if (data.getProfess().hasSkill(id))
+ data.getBoundSkills().add(data.getProfess().getSkill(id));
+
+ if (config.contains("times-claimed"))
+ for (String key : config.getConfigurationSection("times-claimed").getKeys(true))
+ data.getItemClaims().put(key, config.getInt("times-claimed." + key));
+
+ // Load class slots, use try so the player can log in.
+ if (config.contains("class-info"))
+ for (String key : config.getConfigurationSection("class-info").getKeys(false))
+ try {
+ PlayerClass profess = MMOCore.plugin.classManager.get(key);
+ Validate.notNull(profess, "Could not find class '" + key + "'");
+ data.applyClassInfo(profess, new SavedClassInformation(config.getConfigurationSection("class-info." + key)));
+ } catch (IllegalArgumentException exception) {
+ MMOCore.log(Level.WARNING, "Could not load class info '" + key + "': " + exception.getMessage());
+ }
+
+ data.setFullyLoaded();
+ }
+
+ @Override
+ public void saveData(PlayerData data) {
+ ConfigFile file = new ConfigFile(data.getUniqueId());
+ FileConfiguration config = file.getConfig();
+
+ config.set("class-points", data.getClassPoints());
+ config.set("skill-points", data.getSkillPoints());
+ config.set("attribute-points", data.getAttributePoints());
+ // config.set("skill-realloc-points", skillReallocationPoints);
+ config.set("attribute-realloc-points", data.getAttributeReallocationPoints());
+ config.set("level", data.getLevel());
+ config.set("experience", data.getExperience());
+ config.set("class", data.getProfess().getId());
+ config.set("waypoints", new ArrayList<>(data.getWaypoints()));
+ config.set("friends", data.getFriends().stream().map(UUID::toString).collect(Collectors.toList()));
+ config.set("last-login", data.getLastLogin());
+ config.set("guild", data.hasGuild() ? data.getGuild().getId() : null);
+
+ config.set("skill", null);
+ data.mapSkillLevels().forEach((key1, value) -> config.set("skill." + key1, value));
+ data.getItemClaims().forEach((key, times) -> config.set("times-claimed." + key, times));
+
+ List boundSkills = new ArrayList<>();
+ data.getBoundSkills().forEach(skill -> boundSkills.add(skill.getSkill().getHandler().getId()));
+ config.set("bound-skills", boundSkills);
+
+ config.set("attribute", null);
+ config.createSection("attribute");
+ data.getAttributes().save(config.getConfigurationSection("attribute"));
+
+ config.set("profession", null);
+ config.createSection("profession");
+ data.getCollectionSkills().save(config.getConfigurationSection("profession"));
+
+ config.set("quest", null);
+ config.createSection("quest");
+ data.getQuestData().save(config.getConfigurationSection("quest"));
+
+ config.set("class-info", null);
+ for (String key : data.getSavedClasses()) {
+ SavedClassInformation info = data.getClassInfo(key);
+ config.set("class-info." + key + ".level", info.getLevel());
+ config.set("class-info." + key + ".experience", info.getExperience());
+ config.set("class-info." + key + ".skill-points", info.getSkillPoints());
+ config.set("class-info." + key + ".attribute-points", info.getAttributePoints());
+ config.set("class-info." + key + ".attribute-realloc-points", info.getAttributeReallocationPoints());
+ info.getSkillKeys().forEach(skill -> config.set("class-info." + key + ".skill." + skill, info.getSkillLevel(skill)));
+ info.getAttributeKeys()
+ .forEach(attribute -> config.set("class-info." + key + ".attribute." + attribute, info.getAttributeLevel(attribute)));
+ }
+
+ file.save();
+ }
+
+
+ /**
+ * Used to save Data from a SavingPlayerDataInstance (Data of an offline player)
+ *
+ * @param data
+ */
+ @Override
+ public void saveData(SavingPlayerData data) {
+ ConfigFile file = new ConfigFile(data.uuid());
+ FileConfiguration config = file.getConfig();
+
+ config.set("class-points", data.classPoints());
+ config.set("skill-points", data.skillPoints());
+ config.set("attribute-points", data.attributePoints());
+ // config.set("skill-realloc-points", skillReallocationPoints);
+ config.set("attribute-realloc-points", data.attributeReallocationPoints());
+ config.set("level", data.level());
+ config.set("experience", data.experience());
+ config.set("class", data.classId());
+ config.set("waypoints", data.waypoints().stream().toList());
+ config.set("friends", data.friends());
+ config.set("last-login", data.lastLogin());
+ if (data.guildId() != null)
+ config.set("guild", data.guildId());
+
+ config.set("skill", null);
+ data.skills().forEach((key1, value) -> config.set("skill." + key1, value));
+ data.itemClaims().forEach((key, times) -> config.set("times-claimed." + key, times));
+
+ List boundSkills = new ArrayList<>();
+ data.boundSkills().forEach(skill -> boundSkills.add(skill));
+ config.set("bound-skills", boundSkills);
+
+ config.set("attribute", null);
+ Gson parser = new Gson();
+ JsonObject jo = parser.fromJson(data.attributes(), JsonObject.class);
+ for (Map.Entry entry : jo.entrySet()) {
+ try {
+ String id = entry.getKey().toLowerCase().replace("_", "-").replace(" ", "-");
+ config.set("attribute." + id, entry.getValue().getAsInt());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ jo = parser.fromJson(data.collectionsSkills(), JsonObject.class);
+ config.createSection("profession");
+ ConfigurationSection section = config.getConfigurationSection("profession");
+ // Load profession exp and levels
+ for (Map.Entry entry : jo.entrySet())
+ if (MMOCore.plugin.professionManager.has(entry.getKey())) {
+ JsonObject value = entry.getValue().getAsJsonObject();
+ section.set(entry.getKey() + ".exp", value.get("exp").getAsDouble());
+ section.set(entry.getKey() + ".level", value.get("level").getAsInt());
+ }
+
+
+ config.set("quest", null);
+ config.createSection("quest");
+ section = config.getConfigurationSection("quest");
+ jo = parser.fromJson(data.questData(), JsonObject.class);
+ if (jo.has("current")) {
+ JsonObject cur = jo.getAsJsonObject("current");
+ try {
+ section.set("current.id", cur.get("id").getAsString());
+ section.set("current.objective", cur.get("objective").getAsInt());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ if (jo.has("finished"))
+ for (Map.Entry entry : jo.getAsJsonObject("finished").entrySet())
+ section.set("finished." + entry.getKey(), entry.getValue().getAsLong());
+
+
+ config.set("class-info", null);
+ jo = parser.fromJson(data.classInfoData(), JsonObject.class);
+
+
+ for (Map.Entry entry : jo.entrySet()) {
+ try {
+ String key = entry.getKey();
+ JsonObject info = entry.getValue().getAsJsonObject();
+ config.set("class-info." + key + ".level", info.get("level").getAsInt());
+ config.set("class-info." + key + ".experience", info.get("experience").getAsDouble());
+ config.set("class-info." + key + ".skill-points", info.get("skill-points").getAsInt());
+ config.set("class-info." + key + ".attribute-points", info.get("attribute-points").getAsInt());
+ config.set("class-info." + key + ".attribute-realloc-points", info.get("attribute-realloc-points").getAsInt());
+
+ if (info.has("attribute"))
+ for (Map.Entry attributesEntry : info.getAsJsonObject("attribute").entrySet())
+ config.set("class-info." + key + ".attribute." + attributesEntry.getKey(), attributesEntry.getValue().getAsInt());
+
+ if (info.has("skill"))
+ for (Map.Entry skillsEntry : info.getAsJsonObject("skill").entrySet())
+ config.set("class-info." + key + ".skill." + skillsEntry.getKey(), skillsEntry.getValue().getAsInt());
+
+ } catch (IllegalArgumentException exception) {
+ MMOCore.log(Level.WARNING, "Could not load class info '" + entry.getKey() + "': " + exception.getMessage());
+ }
+ }
+
+ Bukkit.broadcastMessage("SAVED");
+ file.save();
+ }
+
+ @NotNull
+ @Override
+ public OfflinePlayerData getOffline(UUID uuid) {
+ return isLoaded(uuid) ? get(uuid) : new YAMLOfflinePlayerData(uuid);
+ }
+
+ @Override
+ public void loadSavingPlayerData(UUID uuid, List savingPlayerDataList) {
+ FileConfiguration config = new ConfigFile(uuid).getConfig();
+
+ Map skills = new HashMap<>();
+ if (config.contains("skill"))
+ config.getConfigurationSection("skill").getKeys(false).forEach(id -> skills.put(id, config.getInt("skill." + id)));
+
+ Map itemClaims = new HashMap<>();
+ if (config.contains("times-claimed"))
+ for (String key : config.getConfigurationSection("times-claimed").getKeys(true))
+ itemClaims.put(key, config.getInt("times-claimed." + key));
+
+
+ //Creates the attributes json
+
+
+ ConfigurationSection section = config.getConfigurationSection("attributes");
+ JsonObject attributesJson = new JsonObject();
+ if (section != null)
+ for (String key : section.getKeys(false)) {
+ String id = key.toLowerCase().replace("-", "_").replace(" ", "_");
+ attributesJson.addProperty(id, section.getInt(key));
+ }
+
+
+ //Creates the profession json
+
+
+ section = config.getConfigurationSection("profession");
+ JsonObject collectionSkillsJson = new JsonObject();
+ if (section != null)
+ for (String key : section.getKeys(false)) {
+ if (MMOCore.plugin.professionManager.has(key)) {
+ JsonObject object = new JsonObject();
+ object.addProperty("exp", section.getDouble(key + ".exp"));
+ object.addProperty("level", section.getInt(key + ".level"));
+
+ collectionSkillsJson.add(key, object);
+ }
+ }
+
+ //Creates the questJson
+
+ section = config.getConfigurationSection("quest");
+ JsonObject questsJson = new JsonObject();
+
+ if (section.contains("current")) {
+ JsonObject cur = new JsonObject();
+ cur.addProperty("id", section.getString("current.id"));
+ cur.addProperty("objective", section.getInt("current.objective"));
+ questsJson.add("current", cur);
+ }
+ JsonObject fin = new JsonObject();
+ if (section.contains("finished"))
+ for (String key : section.getConfigurationSection("finished").getKeys(false))
+ fin.addProperty(key, section.getLong("finished." + key));
+
+ if (fin.size() != 0)
+ questsJson.add("finished", fin);
+
+
+ JsonObject classInfoJson = new JsonObject();
+ // Load class slots, use try so the player can log in.
+ if (config.contains("class-info"))
+ for (String key : config.getConfigurationSection("class-info").getKeys(false)) {
+ SavedClassInformation info = new SavedClassInformation(config.getConfigurationSection("class-info." + key));
+ JsonObject classinfo = new JsonObject();
+ classinfo.addProperty("level", info.getLevel());
+ classinfo.addProperty("experience", info.getExperience());
+ classinfo.addProperty("skill-points", info.getSkillPoints());
+ classinfo.addProperty("attribute-points", info.getAttributePoints());
+ classinfo.addProperty("attribute-realloc-points", info.getAttributeReallocationPoints());
+ JsonObject skillinfo = new JsonObject();
+ for (String skill : info.getSkillKeys())
+ skillinfo.addProperty(skill, info.getSkillLevel(skill));
+ classinfo.add("skill", skillinfo);
+ JsonObject attributeinfo = new JsonObject();
+ for (String attribute : info.getAttributeKeys())
+ attributeinfo.addProperty(attribute, info.getAttributeLevel(attribute));
+ classinfo.add("attribute", attributeinfo);
+ classInfoJson.add(key, classinfo);
+ }
+
+
+ SavingPlayerData data = new SavingPlayerData(
+ uuid,
+ config.getInt("class-points"),
+ config.getInt("skill-points"),
+ config.getInt("attribute-points"),
+ config.getInt("attribute-realloc-points"),
+ config.getInt("level"),
+ config.getInt("experience"),
+ config.getString("class"),
+ config.getLong("last-login"),
+ config.getString("guild"),
+ config.getStringList("waypoints").stream().collect(Collectors.toSet()),
+ config.getStringList("friends").stream().map(UUID::fromString).toList(),
+ config.getStringList("bound-skills"),
+ skills,
+ itemClaims,
+ attributesJson.toString(),
+ collectionSkillsJson.toString(),
+ questsJson.toString(),
+ classInfoJson.toString());
+
+ savingPlayerDataList.add(data);
+ }
+
+}
+
+
diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java
index 5b69846d..f1f23f87 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java
@@ -3,7 +3,6 @@ package net.Indyuce.mmocore.manager.profession;
import io.papermc.lib.PaperLib;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.block.BlockInfo;
-import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
import net.Indyuce.mmocore.api.block.BlockType;
import net.Indyuce.mmocore.api.block.SkullBlockType;
import net.Indyuce.mmocore.api.block.VanillaBlockType;
@@ -33,7 +32,7 @@ public class CustomBlockManager extends SpecificProfessionManager {
* Blocks that are regenerating and that must be refreshed whenever the
* server reloads or shuts down not to hurt the world map
*/
- private final Set active = new HashSet<>();
+ private final Set active = new HashSet<>();
/**
* Stores conditions which must be met to apply custom mining
@@ -93,7 +92,7 @@ public class CustomBlockManager extends SpecificProfessionManager {
* a "block chain", no regen should be scheduled as
* there is already one
*/
- public void initialize(RegeneratingBlock info, boolean scheduleRegen) {
+ public void initialize(BlockInfo.RegeneratingBlock info, boolean scheduleRegen) {
if (scheduleRegen) {
active.add(info);
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> regen(info, false), info.getRegeneratingBlock().getRegenerationInfo().getTime());
@@ -112,7 +111,7 @@ public class CustomBlockManager extends SpecificProfessionManager {
* the server shuts down, it iterates through active blocks.
* This prevents any issue when editing lists being iterated
*/
- private void regen(RegeneratingBlock info, boolean shutdown) {
+ private void regen(BlockInfo.RegeneratingBlock info, boolean shutdown) {
// Get the chunk and load it async if needed.
PaperLib.getChunkAtAsync(info.getLocation()).whenComplete((chunk, ex) -> {
@@ -138,7 +137,7 @@ public class CustomBlockManager extends SpecificProfessionManager {
*/
public boolean isTemporaryBlock(Block block) {
Location loc = block.getLocation();
- for (RegeneratingBlock info : active)
+ for (BlockInfo.RegeneratingBlock info : active)
if (info.getLocation().getBlockX() == loc.getBlockX() && info.getLocation().getBlockY() == loc.getBlockY()
&& info.getLocation().getBlockZ() == loc.getBlockZ())
return true;
@@ -190,7 +189,7 @@ public class CustomBlockManager extends SpecificProfessionManager {
for (String key : MMOCore.plugin.getConfig().getStringList("custom-mine-conditions"))
try {
- customMineConditions.add(MMOCore.plugin.loadManager.loadCondition(new MMOLineConfig(key)));
+ customMineConditions.addAll(MMOCore.plugin.loadManager.loadCondition(new MMOLineConfig(key)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load custom mining condition '" + key + "': " + exception.getMessage());
}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/EnchantManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/EnchantManager.java
index 592d69f4..25b3605f 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/profession/EnchantManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/profession/EnchantManager.java
@@ -4,17 +4,19 @@ import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmocore.MMOCore;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.enchantments.Enchantment;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
public class EnchantManager extends SpecificProfessionManager {
- private final Map base = new HashMap<>();
+ private final Map base = new HashMap<>();
- public EnchantManager() {
- super("base-enchant-exp");
- }
+ public EnchantManager() {
+ super("base-enchant-exp");
+ }
@Override
public void loadProfessionConfiguration(ConfigurationSection config) {
@@ -27,17 +29,20 @@ public class EnchantManager extends SpecificProfessionManager {
}
}
- public void registerBaseExperience(Enchantment enchant, double value) {
- base.put(enchant, value);
- }
+ public void registerBaseExperience(Enchantment enchant, double value) {
+ base.put(enchant, value);
+ }
- public double getBaseExperience(Enchantment enchant) {
- return base.get(enchant);
- }
+ @NotNull
+ public double getBaseExperience(Enchantment enchant) {
+ // Can be null if argument passed is an enchant with no config attached to it
+ @Nullable Double found = base.get(enchant);
+ return found == null ? 0 : found;
+ }
- @Override
- public void initialize(boolean clearBefore) {
- if (clearBefore)
- base.clear();
- }
+ @Override
+ public void initialize(boolean clearBefore) {
+ if (clearBefore)
+ base.clear();
+ }
}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java
index 93a5a73f..bd50a234 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java
@@ -3,10 +3,10 @@ package net.Indyuce.mmocore.manager.profession;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.api.player.stats.StatType;
+import net.Indyuce.mmocore.loot.RandomWeightedRoll;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
-import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem;
+import net.Indyuce.mmocore.loot.fishing.FishingDropItem;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
@@ -17,8 +17,6 @@ import java.util.logging.Level;
public class FishingManager extends SpecificProfessionManager {
private final Set tables = new LinkedHashSet<>();
- private static final Random RANDOM = new Random();
-
public FishingManager() {
super("on-fish");
}
@@ -31,6 +29,11 @@ public class FishingManager extends SpecificProfessionManager {
} catch (IllegalArgumentException exception) {
MMOCore.log(Level.WARNING, "Could not load fishing drop table " + key + ": " + exception.getMessage());
}
+
+ // Link fishing stats to this profession
+ MMOCore.plugin.statManager.registerProfession("FISHING_STRENGTH", getLinkedProfession());
+ MMOCore.plugin.statManager.registerProfession("CRITICAL_FISHING_CHANCE", getLinkedProfession());
+ MMOCore.plugin.statManager.registerProfession("CRITICAL_FISHING_FAILURE_CHANCE", getLinkedProfession());
}
public FishingDropTable calculateDropTable(Entity entity) {
@@ -46,7 +49,6 @@ public class FishingManager extends SpecificProfessionManager {
public static class FishingDropTable {
private final Set conditions = new HashSet<>();
private final List items = new ArrayList<>();
- private double maxWeight = 0;
public FishingDropTable(ConfigurationSection section) {
Validate.notNull(section, "Could not load config");
@@ -58,7 +60,7 @@ public class FishingManager extends SpecificProfessionManager {
for (String str : list)
try {
- conditions.add(MMOCore.plugin.loadManager.loadCondition(new MMOLineConfig(str)));
+ conditions.addAll(MMOCore.plugin.loadManager.loadCondition(new MMOLineConfig(str)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load condition '" + str + "' from fishing drop table '" + id + "': " + exception.getMessage());
@@ -72,7 +74,6 @@ public class FishingManager extends SpecificProfessionManager {
try {
FishingDropItem dropItem = new FishingDropItem(new MMOLineConfig(str));
items.add(dropItem);
- maxWeight += dropItem.getItem().getWeight();
} catch (RuntimeException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load item '" + str + "' from fishing drop table '" + id + "': " + exception.getMessage());
@@ -93,24 +94,13 @@ public class FishingManager extends SpecificProfessionManager {
}
/**
- * The Fishing Drop Item is calculated randomly bu the chance stat will make
- * low weight items more likely to be caught.
+ * The chance stat will make low weight items more
+ * likely to be chosen by the algorithm.
+ *
+ * @return Randomly computed fishing drop item
*/
public FishingDropItem getRandomItem(PlayerData player) {
- double chance = player.getStats().getStat(StatType.CHANCE);
-
- //chance=0 ->the tier.chance remains the same
- //chance ->+inf -> the tier.chance becomes the same for everyone, uniform law
- //chance=8-> tierChance=sqrt(tierChance)
- double sum = 0;
- double randomCoefficient=RANDOM.nextDouble();
- for (FishingDropItem item : items) {
- sum += Math.pow(item.getItem().getWeight(), 1 / Math.log(1 + chance));
- if(sum(player, items, MMOCore.plugin.configManager.fishingDropsChanceWeight).rollItem();
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java b/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java
index 113b99ba..9d31ace6 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/social/BoosterManager.java
@@ -2,6 +2,7 @@ package net.Indyuce.mmocore.manager.social;
import net.Indyuce.mmocore.experience.Booster;
import net.Indyuce.mmocore.experience.Profession;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -48,7 +49,7 @@ public class BoosterManager {
/**
* @return Sums all current experience boosters values
*/
- public double getMultiplier(Profession profession) {
+ public double getMultiplier(@Nullable Profession profession) {
double d = 1;
for (Booster booster : map)
@@ -58,10 +59,6 @@ public class BoosterManager {
return d;
}
- public double calculateExp(Profession profession, double exp) {
- return (exp * getMultiplier(profession));
- }
-
/**
* @return Collection of currently registered boosters. Some of them can be
* expired but are not unregistered yet!
diff --git a/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java b/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java
index be3c8358..b6a1f7f0 100644
--- a/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java
+++ b/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java
@@ -1,8 +1,8 @@
package net.Indyuce.mmocore.manager.social;
+import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.manager.MMOCoreManager;
import org.bukkit.configuration.ConfigurationSection;
@@ -26,8 +26,7 @@ public class PartyManager implements MMOCoreManager {
if (config != null)
for (String key : config.getKeys(false))
try {
- StatType stat = StatType.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_"));
- buffs.add(new StatModifier("mmocoreParty", stat.name(), config.getString(key)));
+ buffs.add(new StatModifier("mmocoreParty", UtilityMethods.enumName(key), config.getString(key)));
} catch (IllegalArgumentException exception) {
MMOCore.log(Level.WARNING, "Could not load party buff '" + key + "': " + exception.getMessage());
}
diff --git a/src/main/java/net/Indyuce/mmocore/party/MMOCoreTargetRestriction.java b/src/main/java/net/Indyuce/mmocore/party/MMOCoreTargetRestriction.java
new file mode 100644
index 00000000..0e67bf43
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/party/MMOCoreTargetRestriction.java
@@ -0,0 +1,32 @@
+package net.Indyuce.mmocore.party;
+
+import io.lumine.mythic.lib.comp.target.InteractionType;
+import io.lumine.mythic.lib.comp.target.TargetRestriction;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.guild.AbstractGuild;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+
+public class MMOCoreTargetRestriction implements TargetRestriction {
+
+ @Override
+ public boolean canTarget(Player player, LivingEntity livingEntity, InteractionType interactionType) {
+ if (!interactionType.isOffense() || !(livingEntity instanceof Player))
+ return true;
+
+ PlayerData data = PlayerData.get(player);
+
+ // Check for party
+ AbstractParty party = MMOCore.plugin.partyModule.getParty(data);
+ if (party != null && party.hasMember((Player) livingEntity))
+ return false;
+
+ // Check for guild
+ AbstractGuild guild = MMOCore.plugin.guildModule.getGuild(data);
+ if (guild != null && guild.hasMember((Player) livingEntity))
+ return false;
+
+ return true;
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/party/PartyModuleType.java b/src/main/java/net/Indyuce/mmocore/party/PartyModuleType.java
index f6b0370a..8a031652 100644
--- a/src/main/java/net/Indyuce/mmocore/party/PartyModuleType.java
+++ b/src/main/java/net/Indyuce/mmocore/party/PartyModuleType.java
@@ -1,13 +1,16 @@
package net.Indyuce.mmocore.party;
-import net.Indyuce.mmocore.party.compat.*;
+import net.Indyuce.mmocore.party.compat.DungeonsXLPartyModule;
+import net.Indyuce.mmocore.party.compat.McMMOPartyModule;
+import net.Indyuce.mmocore.party.compat.PAFPartyModule;
+import net.Indyuce.mmocore.party.compat.PartiesPartyModule;
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
import org.bukkit.Bukkit;
import javax.inject.Provider;
public enum PartyModuleType {
- DUNGEONS("Dungeons", DungeonsPartyModule::new),
+ // DUNGEONS("Dungeons", DungeonsPartyModule::new),
DUNGEONSXL("DungeonsXL", DungeonsXLPartyModule::new),
MCMMO("mcMMO", McMMOPartyModule::new),
MMOCORE("MMOCore", MMOCorePartyModule::new),
diff --git a/src/main/java/net/Indyuce/mmocore/party/provided/MMOCorePartyModule.java b/src/main/java/net/Indyuce/mmocore/party/provided/MMOCorePartyModule.java
index 98ad8656..3c0155cb 100644
--- a/src/main/java/net/Indyuce/mmocore/party/provided/MMOCorePartyModule.java
+++ b/src/main/java/net/Indyuce/mmocore/party/provided/MMOCorePartyModule.java
@@ -2,7 +2,6 @@ package net.Indyuce.mmocore.party.provided;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.listener.PartyListener;
import net.Indyuce.mmocore.party.PartyModule;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
diff --git a/src/main/java/net/Indyuce/mmocore/party/provided/Party.java b/src/main/java/net/Indyuce/mmocore/party/provided/Party.java
index 659906f1..1bceebd8 100644
--- a/src/main/java/net/Indyuce/mmocore/party/provided/Party.java
+++ b/src/main/java/net/Indyuce/mmocore/party/provided/Party.java
@@ -1,14 +1,15 @@
package net.Indyuce.mmocore.party.provided;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.gui.api.PluginInventory;
+import net.Indyuce.mmocore.gui.social.party.EditablePartyView;
+import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.social.Request;
-import net.Indyuce.mmocore.gui.api.PluginInventory;
-import net.Indyuce.mmocore.gui.social.party.EditablePartyView.PartyViewInventory;
-import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.party.AbstractParty;
import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.function.Consumer;
@@ -25,13 +26,21 @@ public class Party implements AbstractParty {
/**
* Owner has to change when previous owner leaves party
*/
+ @NotNull
private PlayerData owner;
+ /**
+ * If the difference between a player level and the party
+ * level is too high then players cannot join the party.
+ */
+ private final int partyLevel;
+
private final MMOCorePartyModule module;
public Party(MMOCorePartyModule module, PlayerData owner) {
this.owner = owner;
this.module = module;
+ this.partyLevel = owner.getLevel();
addMember(owner);
}
@@ -59,6 +68,10 @@ public class Party implements AbstractParty {
return online;
}
+ public int getLevel() {
+ return partyLevel;
+ }
+
@Override
public int countMembers() {
return members.size();
@@ -94,7 +107,7 @@ public class Party implements AbstractParty {
public void removeMember(PlayerData data, boolean notify) {
if (data.isOnline() && data.getPlayer().getOpenInventory() != null
- && data.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof PartyViewInventory)
+ && data.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof EditablePartyView.PartyViewInventory)
InventoryManager.PARTY_CREATION.newInventory(data).open();
members.remove(data);
@@ -133,7 +146,7 @@ public class Party implements AbstractParty {
private void updateOpenInventories() {
for (PlayerData member : members)
if (member.isOnline() && member.getPlayer().getOpenInventory() != null
- && member.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof PartyViewInventory)
+ && member.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof EditablePartyView.PartyViewInventory)
((PluginInventory) member.getPlayer().getOpenInventory().getTopInventory().getHolder()).open();
}
@@ -147,6 +160,7 @@ public class Party implements AbstractParty {
Request request = new PartyInvite(this, inviter, target);
new ConfigMessage("party-invite").addPlaceholders("player", inviter.getPlayer().getName(), "uuid", request.getUniqueId().toString())
.sendAsJSon(target.getPlayer());
+
MMOCore.plugin.requestManager.registerRequest(request);
}
diff --git a/src/main/java/net/Indyuce/mmocore/party/provided/PartyInvite.java b/src/main/java/net/Indyuce/mmocore/party/provided/PartyInvite.java
index 40d13a4c..e5010170 100644
--- a/src/main/java/net/Indyuce/mmocore/party/provided/PartyInvite.java
+++ b/src/main/java/net/Indyuce/mmocore/party/provided/PartyInvite.java
@@ -1,9 +1,9 @@
package net.Indyuce.mmocore.party.provided;
import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.manager.InventoryManager;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.social.Request;
-import net.Indyuce.mmocore.manager.InventoryManager;
public class PartyInvite extends Request {
private final Party party;
diff --git a/src/main/java/net/Indyuce/mmocore/listener/PartyListener.java b/src/main/java/net/Indyuce/mmocore/party/provided/PartyListener.java
similarity index 53%
rename from src/main/java/net/Indyuce/mmocore/listener/PartyListener.java
rename to src/main/java/net/Indyuce/mmocore/party/provided/PartyListener.java
index f5ed1be4..943aa556 100644
--- a/src/main/java/net/Indyuce/mmocore/listener/PartyListener.java
+++ b/src/main/java/net/Indyuce/mmocore/party/provided/PartyListener.java
@@ -1,16 +1,10 @@
-package net.Indyuce.mmocore.listener;
+package net.Indyuce.mmocore.party.provided;
-import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.social.PartyChatEvent;
+import net.Indyuce.mmocore.manager.ConfigManager;
import net.Indyuce.mmocore.api.player.PlayerData;
-import net.Indyuce.mmocore.manager.ConfigManager.SimpleMessage;
-import net.Indyuce.mmocore.party.AbstractParty;
-import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
-import net.Indyuce.mmocore.party.provided.Party;
import org.bukkit.Bukkit;
-import org.bukkit.entity.LivingEntity;
-import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@@ -37,7 +31,7 @@ public class PartyListener implements Listener {
// Running it in a delayed task is recommended
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> {
- SimpleMessage format = MMOCore.plugin.configManager.getSimpleMessage("party-chat", "player", data.getPlayer().getName(), "message",
+ ConfigManager.SimpleMessage format = MMOCore.plugin.configManager.getSimpleMessage("party-chat", "player", data.getPlayer().getName(), "message",
event.getMessage().substring(MMOCore.plugin.configManager.partyChatPrefix.length()));
PartyChatEvent called = new PartyChatEvent(party, data, format.message());
Bukkit.getPluginManager().callEvent(called);
@@ -45,21 +39,4 @@ public class PartyListener implements Listener {
party.getOnlineMembers().forEach(member -> format.send(member.getPlayer()));
});
}
-
- /**
- * Cancel damage of players from the same party
- *
- * @deprecated This should be useful with the {@link io.lumine.mythic.lib.comp.target.TargetRestriction} update
- */
- @Deprecated
- @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
- public void b(PlayerAttackEvent event) {
- LivingEntity entity = event.getEntity();
- if (entity instanceof Player && !entity.hasMetadata("NPC")) {
- PlayerData targetData = PlayerData.get((Player) event.getEntity());
- AbstractParty party = targetData.getParty();
- if (party != null && party.hasMember(event.getData().getPlayer()))
- event.setCancelled(true);
- }
- }
}
diff --git a/src/main/java/net/Indyuce/mmocore/player/Unlockable.java b/src/main/java/net/Indyuce/mmocore/player/Unlockable.java
index 6940d1a1..9349f308 100644
--- a/src/main/java/net/Indyuce/mmocore/player/Unlockable.java
+++ b/src/main/java/net/Indyuce/mmocore/player/Unlockable.java
@@ -3,8 +3,8 @@ package net.Indyuce.mmocore.player;
import net.Indyuce.mmocore.api.player.PlayerData;
/**
- * Some item that can be unlocked. ALl unlockable are saved in the same list in
- * the player data. This useful list can be used for:
+ * Some item that can be unlocked. All unlockables are saved in the
+ * same list in the player data. This useful list can be used for:
* - waypoints
* - skill tree nodes
* - skills using skill books? TODO
@@ -15,8 +15,8 @@ import net.Indyuce.mmocore.api.player.PlayerData;
public interface Unlockable {
/**
- * Format being used is the minecraft's default
- * namespaced key format, e.g "skill_tree:strength_1_5"
+ * Format being used is the minecraft's default namespaced
+ * key format, e.g "skill_tree:strength_1_5" for readability
*/
String getUnlockNamespacedKey();
}
diff --git a/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java b/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java
index a18649f8..4d5183f2 100644
--- a/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java
+++ b/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java
@@ -12,7 +12,6 @@ import io.lumine.mythic.lib.skill.result.SkillResult;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import io.lumine.mythic.lib.util.configobject.ConfigObject;
-import io.lumine.mythic.lib.util.configobject.LineConfigObject;
import net.Indyuce.mmocore.listener.ClassTriggers;
import org.apache.commons.lang.Validate;
@@ -43,7 +42,7 @@ public class ClassTrigger {
type = ClassTriggerType.valueOf(UtilityMethods.enumName(triggerTypeString));
for (String key : mechanicStringList) {
- ConfigObject config = new LineConfigObject(new MMOLineConfig(key));
+ ConfigObject config = new MMOLineConfig(key);
Mechanic mechanic = MythicLib.plugin.getSkills().loadMechanic(config);
skill.getMechanics().add(mechanic);
}
diff --git a/src/main/java/net/Indyuce/mmocore/player/stats/StatInfo.java b/src/main/java/net/Indyuce/mmocore/player/stats/StatInfo.java
new file mode 100644
index 00000000..078b4af7
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/player/stats/StatInfo.java
@@ -0,0 +1,71 @@
+package net.Indyuce.mmocore.player.stats;
+
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
+import net.Indyuce.mmocore.experience.Profession;
+import org.jetbrains.annotations.NotNull;
+
+import java.text.DecimalFormat;
+import java.util.Objects;
+
+/**
+ * @author Jules
+ * @impl MMOCore used to have a giant enum of all the stat types
+ * which is now incompatible with MythicLib because the MMO plugins
+ * now have completely OPEN to edition numeric stat registries
+ */
+public class StatInfo {
+ public final String name;
+
+ /**
+ * Profession linked to that stat. Stats which have a profession linked to
+ * them do NOT scale on the main player level but rather on that specific
+ * profession level
+ */
+ public Profession profession;
+
+ /**
+ * Default formula for the stat
+ */
+ public LinearValue defaultInfo;
+
+ /**
+ * How that stat displays anywhere in GUIs
+ */
+ public DecimalFormat format;
+
+ private static final DecimalFormat DEFAULT_DECIMAL_FORMAT = new DecimalFormat("0.#");
+
+ public StatInfo(String name) {
+ this.name = name;
+ }
+
+ @NotNull
+ public String format(double d) {
+ return (format == null ? DEFAULT_DECIMAL_FORMAT : format).format(d);
+ }
+
+ @NotNull
+ public LinearValue getDefaultFormula() {
+ return defaultInfo == null ? LinearValue.ZERO : defaultInfo;
+ }
+
+ @NotNull
+ public static StatInfo valueOf(String str) {
+ StatInfo found = MMOCore.plugin.statManager.getInfo(str);
+ return found == null ? new StatInfo(str) : found;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ StatInfo statInfo = (StatInfo) o;
+ return name.equals(statInfo.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name);
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java b/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java
index 075ae470..93316ec2 100644
--- a/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java
+++ b/src/main/java/net/Indyuce/mmocore/quest/AbstractQuest.java
@@ -3,5 +3,6 @@ package net.Indyuce.mmocore.quest;
public interface AbstractQuest {
public String getName();
+
public String getId();
}
diff --git a/src/main/java/net/Indyuce/mmocore/quest/MMOCoreQuestModule.java b/src/main/java/net/Indyuce/mmocore/quest/MMOCoreQuestModule.java
index c50b3c09..7f97a26c 100644
--- a/src/main/java/net/Indyuce/mmocore/quest/MMOCoreQuestModule.java
+++ b/src/main/java/net/Indyuce/mmocore/quest/MMOCoreQuestModule.java
@@ -6,10 +6,9 @@ import net.Indyuce.mmocore.quest.compat.QuestModule;
import org.bukkit.entity.Player;
public class MMOCoreQuestModule implements QuestModule {
-
@Override
- public AbstractQuest getQuest(String id) {
- Quest quest=MMOCore.plugin.questManager.get(id);
+ public AbstractQuest getQuestOrThrow(String id) {
+ Quest quest= MMOCore.plugin.questManager.get(id);
if(quest==null)
return null;
return new MMOCoreQuest(quest);
diff --git a/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java b/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java
index 7bcd4bfa..4c7e0366 100644
--- a/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java
+++ b/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java
@@ -1,7 +1,6 @@
package net.Indyuce.mmocore.quest;
-import net.Indyuce.mmocore.party.PartyModule;
-import net.Indyuce.mmocore.quest.compat.BeautyQuestModule;
+import net.Indyuce.mmocore.quest.compat.BeautyQuestsModule;
import net.Indyuce.mmocore.quest.compat.BlackVeinQuestsModule;
import net.Indyuce.mmocore.quest.compat.QuestCreatorModule;
import net.Indyuce.mmocore.quest.compat.QuestModule;
@@ -10,12 +9,10 @@ import org.bukkit.Bukkit;
import javax.inject.Provider;
public enum QuestModuleType {
- MMOCORE("MMOCore",MMOCoreQuestModule::new),
+ MMOCORE("MMOCore", MMOCoreQuestModule::new),
QUESTS("Quests", BlackVeinQuestsModule::new),
- BEAUTY_QUEST("Beauty Quests", BeautyQuestModule::new),
- QUEST_CREATOR("Quest Creator", QuestCreatorModule::new);
-
-
+ BEAUTY_QUEST("BeautyQuests", BeautyQuestsModule::new),
+ QUEST_CREATOR("QuestCreator", QuestCreatorModule::new);
private final String pluginName;
private final Provider provider;
diff --git a/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java b/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestsModule.java
similarity index 76%
rename from src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java
rename to src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestsModule.java
index e984b203..a611b88e 100644
--- a/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java
+++ b/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestsModule.java
@@ -8,13 +8,11 @@ import fr.skytasul.quests.structure.Quest;
import net.Indyuce.mmocore.quest.AbstractQuest;
import org.bukkit.entity.Player;
-import javax.annotation.Nonnull;
-
public class BeautyQuestModule implements QuestModule {
@Override
- public BeautyQuestQuest getQuest(String questId) {
+ public BeautyQuestQuest getQuestOrThrow(String questId) {
Quest quest=QuestsAPI.getQuests().getQuest(Integer.parseInt(questId));
return quest==null?null:new BeautyQuestQuest(quest);
}
@@ -22,15 +20,15 @@ public class BeautyQuestModule implements QuestModule{
@Override
- public QuestCreatorQuest getQuest(String id) {
+ public QuestCreatorQuest getQuestOrThrow(String id) {
return new QuestCreatorQuest(id);
}
@@ -34,14 +34,15 @@ public class QuestCreatorModule implements QuestModule {
/**
- * @return Quest with given name
+ * @return Quest with given identifier
*/
@Nullable
public T getQuest(String id);
/**
- * @return If a specific player did a certain quest
+ * @return If a specific player has made a certain quest
*/
public boolean hasCompletedQuest(String quest, Player player);
-
}
diff --git a/src/main/java/net/Indyuce/mmocore/skill/CastableSkill.java b/src/main/java/net/Indyuce/mmocore/skill/CastableSkill.java
index 97748824..dacfabe9 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/CastableSkill.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/CastableSkill.java
@@ -6,12 +6,10 @@ import io.lumine.mythic.lib.player.cooldown.CooldownInfo;
import io.lumine.mythic.lib.skill.Skill;
import io.lumine.mythic.lib.skill.SkillMetadata;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
-import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData;
-import org.jetbrains.annotations.NotNull;
public class CastableSkill extends Skill {
private final ClassSkill skill;
@@ -84,7 +82,8 @@ public class CastableSkill extends Skill {
casterData.giveStamina(-getModifier("stamina"), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST);
}
- casterData.setLastActivity(PlayerActivity.CAST_SKILL);
+ if (!getTrigger().isPassive())
+ casterData.setLastActivity(PlayerActivity.CAST_SKILL);
}
@Override
diff --git a/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java b/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java
index 1d72842b..386cd07a 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/ClassSkill.java
@@ -4,9 +4,10 @@ import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.player.cooldown.CooldownObject;
import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.skill.PassiveSkill;
-import net.Indyuce.mmocore.api.player.PlayerData;
+import io.lumine.mythic.lib.skill.custom.condition.Condition;
import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
+import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
@@ -17,6 +18,9 @@ public class ClassSkill implements CooldownObject {
private final int unlockLevel, maxSkillLevel;
private final Map modifiers = new HashMap<>();
+ @Deprecated
+ private final Set unlockConditions = new HashSet<>();
+
/**
* Class used to save information about skills IN A CLASS CONTEXT i.e at
* which level the skill can be unlocked, etc.
diff --git a/src/main/java/net/Indyuce/mmocore/skill/RegisteredSkill.java b/src/main/java/net/Indyuce/mmocore/skill/RegisteredSkill.java
index 8fb2b970..0d5ada32 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/RegisteredSkill.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/RegisteredSkill.java
@@ -5,6 +5,7 @@ import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
+import net.Indyuce.mmocore.player.Unlockable;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
@@ -15,7 +16,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
-public class RegisteredSkill {
+public class RegisteredSkill implements Unlockable {
private final SkillHandler> handler;
private final String name;
private final Map defaultModifiers = new HashMap<>();
@@ -45,6 +46,11 @@ public class RegisteredSkill {
this.triggerType = triggerType;
}
+ @Override
+ public String getUnlockNamespacedKey() {
+ return "registered_skill:" + handler.getId().toLowerCase();
+ }
+
public SkillHandler> getHandler() {
return handler;
}
diff --git a/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java b/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java
index 49c85ade..ebc82f10 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/cast/SkillCastingMode.java
@@ -19,17 +19,27 @@ public enum SkillCastingMode {
SKILL_BAR(config -> new SkillBar(config)),
/**
- *
+ * When entering casting mode you can use the mouse scroller
+ * to navigate through the entire castable skill list. Then press
+ * one key to cast the one selected.
*/
SKILL_SCROLL(config -> new SkillScroller(config)),
/**
* Initialize your skill combo by pressing some key.
*
- * Then press a certain amount of keys to
+ * Then press a certain key combo. The config can be used
+ * to map key combos to skill bind slots, for instance LLR
+ * would cast the 2nd skill but LRL the 3rd one.
*/
KEY_COMBOS(config -> new KeyCombos(config)),
+ /**
+ * Entirely disables skill casting.
+ */
+ NONE(config -> new Listener() {
+ });
+
/**
* Not implemented yet.
*
diff --git a/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java b/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java
index c33637e8..f59d888d 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/cast/listener/KeyCombos.java
@@ -8,8 +8,8 @@ import io.lumine.mythic.lib.player.PlayerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.SoundObject;
import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent;
+import net.Indyuce.mmocore.api.SoundObject;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.skill.cast.KeyCombo;
import net.Indyuce.mmocore.skill.cast.PlayerKey;
diff --git a/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java b/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java
index 3db7938d..99329793 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillBar.java
@@ -5,8 +5,8 @@ import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.player.PlayerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import net.Indyuce.mmocore.MMOCore;
-import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent;
+import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.cast.PlayerKey;
@@ -105,8 +105,7 @@ public class SkillBar implements Listener {
"" + (j + 1 + (data.getPlayer().getInventory().getHeldItemSlot() <= j ? 1 : 0)))
.replace("{skill}", data.getBoundSkill(j).getSkill().getName()));
}
-
- return str.toString();
+ return MMOCore.plugin.placeholderParser.parse(data.getPlayer(),str.toString());
}
/**
diff --git a/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java b/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java
index f9fdd078..c7189bcf 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/cast/listener/SkillScroller.java
@@ -4,8 +4,8 @@ import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.player.PlayerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
-import net.Indyuce.mmocore.api.SoundObject;
import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent;
+import net.Indyuce.mmocore.api.SoundObject;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.skill.cast.PlayerKey;
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
@@ -107,6 +107,9 @@ public class SkillScroller implements Listener {
CustomSkillCastingHandler casting = (CustomSkillCastingHandler) playerData.getSkillCasting();
casting.index = mod(casting.index + change, playerData.getBoundSkills().size());
casting.onTick();
+
+ if (changeSound != null)
+ changeSound.playTo(event.getPlayer());
}
private int mod(int x, int n) {
diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ExperienceMechanic.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ExperienceMechanic.java
new file mode 100644
index 00000000..61ae176e
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ExperienceMechanic.java
@@ -0,0 +1,46 @@
+package net.Indyuce.mmocore.skill.custom.mechanic;
+
+import io.lumine.mythic.lib.skill.SkillMetadata;
+import io.lumine.mythic.lib.skill.custom.mechanic.type.TargetMechanic;
+import io.lumine.mythic.lib.util.DoubleFormula;
+import io.lumine.mythic.lib.util.configobject.ConfigObject;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.experience.EXPSource;
+import net.Indyuce.mmocore.experience.SimpleExperienceObject;
+import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
+import org.apache.commons.lang.Validate;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+public class ExperienceMechanic extends TargetMechanic {
+ @NotNull
+ private final DoubleFormula amount;
+ @NotNull
+ private final EXPSource source;
+ @NotNull
+ private final ExperienceDispenser dispenser;
+
+ public ExperienceMechanic(ConfigObject config) {
+ super(config);
+
+ config.validateKeys("amount");
+ amount = config.getDoubleFormula("amount");
+
+ if (config.contains("profession")) {
+ String id = config.getString("profession").toLowerCase().replace("_", "-");
+ Validate.isTrue(MMOCore.plugin.professionManager.has(id), "Could not find profession");
+ dispenser = MMOCore.plugin.professionManager.get(id);
+ } else
+ dispenser = new SimpleExperienceObject();
+ source = config.contains("source") ? EXPSource.valueOf(config.getString("source").toUpperCase()) : EXPSource.QUEST;
+ }
+
+ @Override
+ public void cast(SkillMetadata meta, Entity target) {
+ Validate.isTrue(target instanceof Player, "Target is not a player");
+ PlayerData targetData = PlayerData.get(target.getUniqueId());
+ dispenser.giveExperience(targetData, amount.evaluate(meta), null, source);
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java
index ebd6e8b6..49f93831 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java
@@ -13,6 +13,7 @@ import org.bukkit.entity.Player;
public class ManaMechanic extends TargetMechanic {
private final DoubleFormula amount;
+ private final Operation operation;
private final PlayerResourceUpdateEvent.UpdateReason reason;
public ManaMechanic(ConfigObject config) {
@@ -22,12 +23,18 @@ public class ManaMechanic extends TargetMechanic {
amount = new DoubleFormula(config.getString("amount"));
reason = PlayerResourceUpdateEvent.UpdateReason.valueOf(UtilityMethods.enumName(config.getString("reason", "CUSTOM")));
+ operation = config.contains("operation") ? Operation.valueOf(config.getString("operation").toUpperCase()) : Operation.GIVE;
}
@Override
public void cast(SkillMetadata meta, Entity target) {
Validate.isTrue(target instanceof Player, "Target is not a player");
PlayerData targetData = PlayerData.get(target.getUniqueId());
- targetData.giveMana(amount.evaluate(meta), reason);
+ if (operation == Operation.GIVE)
+ targetData.giveMana(amount.evaluate(meta), reason);
+ else if (operation == Operation.SET)
+ targetData.setMana(amount.evaluate(meta));
+ else if (operation == Operation.TAKE)
+ targetData.giveMana(-amount.evaluate(meta), reason);
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/Operation.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/Operation.java
new file mode 100644
index 00000000..ea05f52c
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/Operation.java
@@ -0,0 +1,7 @@
+package net.Indyuce.mmocore.skill.custom.mechanic;
+
+public enum Operation {
+ GIVE,
+ SET,
+ TAKE
+}
\ No newline at end of file
diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java
index 3d6e4bd8..88f28384 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java
@@ -13,6 +13,7 @@ import org.bukkit.entity.Player;
public class StaminaMechanic extends TargetMechanic {
private final DoubleFormula amount;
+ private final Operation operation;
private final PlayerResourceUpdateEvent.UpdateReason reason;
public StaminaMechanic(ConfigObject config) {
@@ -22,12 +23,18 @@ public class StaminaMechanic extends TargetMechanic {
amount = new DoubleFormula(config.getString("amount"));
reason = PlayerResourceUpdateEvent.UpdateReason.valueOf(UtilityMethods.enumName(config.getString("reason", "CUSTOM")));
+ operation = config.contains("operation") ? Operation.valueOf(config.getString("operation").toUpperCase()) : Operation.GIVE;
}
@Override
public void cast(SkillMetadata meta, Entity target) {
Validate.isTrue(target instanceof Player, "Target is not a player");
PlayerData targetData = PlayerData.get(target.getUniqueId());
- targetData.giveStamina(amount.evaluate(meta), reason);
+ if (operation == Operation.GIVE)
+ targetData.giveStamina(amount.evaluate(meta), reason);
+ else if (operation == Operation.SET)
+ targetData.setStamina(amount.evaluate(meta));
+ else if (operation == Operation.TAKE)
+ targetData.giveStamina(-amount.evaluate(meta), reason);
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java
index 92ecb179..e104bbcb 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java
@@ -13,6 +13,7 @@ import org.bukkit.entity.Player;
public class StelliumMechanic extends TargetMechanic {
private final DoubleFormula amount;
+ private final Operation operation;
private final PlayerResourceUpdateEvent.UpdateReason reason;
public StelliumMechanic(ConfigObject config) {
@@ -22,12 +23,18 @@ public class StelliumMechanic extends TargetMechanic {
amount = new DoubleFormula(config.getString("amount"));
reason = PlayerResourceUpdateEvent.UpdateReason.valueOf(UtilityMethods.enumName(config.getString("reason", "CUSTOM")));
+ operation = config.contains("operation") ? Operation.valueOf(config.getString("operation").toUpperCase()) : Operation.GIVE;
}
@Override
public void cast(SkillMetadata meta, Entity target) {
Validate.isTrue(target instanceof Player, "Target is not a player");
PlayerData targetData = PlayerData.get(target.getUniqueId());
- targetData.giveStellium(amount.evaluate(meta), reason);
+ if (operation == Operation.GIVE)
+ targetData.giveStellium(amount.evaluate(meta), reason);
+ else if (operation == Operation.SET)
+ targetData.setStellium(amount.evaluate(meta));
+ else if (operation == Operation.TAKE)
+ targetData.giveStellium(-amount.evaluate(meta), reason);
}
}
diff --git a/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java b/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java
index bf45e0f4..71c036f3 100644
--- a/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java
+++ b/src/main/java/net/Indyuce/mmocore/skill/list/Neptune_Gift.java
@@ -5,7 +5,6 @@ import io.lumine.mythic.lib.skill.SkillMetadata;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
-import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -29,7 +28,6 @@ public class Neptune_Gift extends SkillHandler implements Lis
@EventHandler
public void a(PlayerResourceUpdateEvent event) {
- PlayerData data = event.getData();
if (event.getPlayer().getLocation().getBlock().getType() == Material.WATER) {
PassiveSkill skill = event.getData().getMMOPlayerData().getPassiveSkillMap().getSkill(this);
if (skill == null)
diff --git a/src/main/java/net/Indyuce/mmocore/tree/modifier/UnlockSkillModifier.java b/src/main/java/net/Indyuce/mmocore/tree/modifier/UnlockSkillModifier.java
new file mode 100644
index 00000000..570b8ab2
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/tree/modifier/UnlockSkillModifier.java
@@ -0,0 +1,28 @@
+package net.Indyuce.mmocore.tree.modifier;
+
+import io.lumine.mythic.lib.api.player.EquipmentSlot;
+import io.lumine.mythic.lib.api.player.MMOPlayerData;
+import io.lumine.mythic.lib.player.modifier.ModifierSource;
+import io.lumine.mythic.lib.player.modifier.PlayerModifier;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.skill.RegisteredSkill;
+import org.apache.commons.lang.NotImplementedException;
+
+public class UnlockSkillModifier extends PlayerModifier {
+ private RegisteredSkill unlocked = null;
+
+ public UnlockSkillModifier(String key, EquipmentSlot slot, ModifierSource source) {
+ super(key, slot, source);
+ }
+
+ @Override
+ public void register(MMOPlayerData mmoPlayerData) {
+ PlayerData playerData = PlayerData.get(mmoPlayerData.getUniqueId());
+ // playerData.unlock(unlocked);
+ }
+
+ @Override
+ public void unregister(MMOPlayerData mmoPlayerData) {
+ throw new NotImplementedException("");
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/util/HashableLocation.java b/src/main/java/net/Indyuce/mmocore/util/HashableLocation.java
new file mode 100644
index 00000000..1bc63bd6
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/util/HashableLocation.java
@@ -0,0 +1,52 @@
+package net.Indyuce.mmocore.util;
+
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Objects;
+
+public class HashableLocation {
+ private final World world;
+ private final int x, y, z;
+
+ public HashableLocation(@NotNull Location loc) {
+ this.world = loc.getWorld();
+ this.x = loc.getBlockX();
+ this.y = loc.getBlockY();
+ this.z = loc.getBlockZ();
+ }
+
+ public World getWorld() {
+ return world;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public int getZ() {
+ return z;
+ }
+
+ public Location bukkit() {
+ return new Location(world, x, y, z);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ HashableLocation that = (HashableLocation) o;
+ return x == that.x && y == that.y && z == that.z && world.equals(that.world);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(world, x, y, z);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/Indyuce/mmocore/util/item/ConfigItem.java b/src/main/java/net/Indyuce/mmocore/util/item/ConfigItem.java
index f778f7b6..50693c73 100644
--- a/src/main/java/net/Indyuce/mmocore/util/item/ConfigItem.java
+++ b/src/main/java/net/Indyuce/mmocore/util/item/ConfigItem.java
@@ -1,11 +1,13 @@
package net.Indyuce.mmocore.util.item;
+import io.lumine.mythic.lib.UtilityMethods;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import javax.annotation.Nullable;
import java.util.List;
+import java.util.Objects;
public class ConfigItem {
private final String name, id, texture;
@@ -15,10 +17,12 @@ public class ConfigItem {
private final boolean unbreakable;
public ConfigItem(ConfigurationSection config) {
- id = config.getName();
+ id = UtilityMethods.enumName(config.getName());
name = config.getString("name");
lore = config.getStringList("lore");
- material = Material.valueOf(config.getString("item"));
+ String itemFormat = Objects.requireNonNull(config.getString("item"), "Could not find item material");
+ Validate.isTrue(!itemFormat.contains(":"), "Invalid custom model data format, please use 'custom-model-data: X' instead");
+ material = Material.valueOf(UtilityMethods.enumName(itemFormat));
Validate.notNull(name, "Name cannot be null");
Validate.notNull(lore, "Lore can be empty but not null");
diff --git a/src/main/java/net/Indyuce/mmocore/util/item/SkillBookBuilder.java b/src/main/java/net/Indyuce/mmocore/util/item/SkillBookBuilder.java
new file mode 100644
index 00000000..6c809a26
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/util/item/SkillBookBuilder.java
@@ -0,0 +1,29 @@
+package net.Indyuce.mmocore.util.item;
+
+import io.lumine.mythic.lib.api.item.ItemTag;
+import io.lumine.mythic.lib.api.item.NBTItem;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.skill.RegisteredSkill;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+@Deprecated
+public class SkillBookBuilder extends AbstractItemBuilder {
+ private final RegisteredSkill skill;
+
+ public SkillBookBuilder(RegisteredSkill skill) {
+ super(MMOCore.plugin.configItems.get("SKILL_BOOK"));
+
+ this.skill = skill;
+ }
+
+ @Override
+ public void whenBuildingMeta(ItemStack item, ItemMeta meta) {
+
+ }
+
+ @Override
+ public void whenBuildingNBT(NBTItem nbtItem) {
+ nbtItem.addTag(new ItemTag("SkillBookId", skill.getHandler().getId()));
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/util/item/WaypointBookBuilder.java b/src/main/java/net/Indyuce/mmocore/util/item/WaypointBookBuilder.java
new file mode 100644
index 00000000..d16aeeb0
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/util/item/WaypointBookBuilder.java
@@ -0,0 +1,30 @@
+package net.Indyuce.mmocore.util.item;
+
+import io.lumine.mythic.lib.api.item.ItemTag;
+import io.lumine.mythic.lib.api.item.NBTItem;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.waypoint.Waypoint;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+public class WaypointBookBuilder extends AbstractItemBuilder {
+ private final Waypoint waypoint;
+
+ public WaypointBookBuilder(Waypoint waypoint) {
+ super(MMOCore.plugin.configItems.get("WAYPOINT_BOOK"));
+
+ this.waypoint = waypoint;
+
+ addPlaceholders("waypoint", waypoint.getName());
+ }
+
+ @Override
+ public void whenBuildingMeta(ItemStack item, ItemMeta meta) {
+
+ }
+
+ @Override
+ public void whenBuildingNBT(NBTItem nbtItem) {
+ nbtItem.addTag(new ItemTag("WaypointBookId", waypoint.getId()));
+ }
+}
diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/CostType.java b/src/main/java/net/Indyuce/mmocore/waypoint/CostType.java
deleted file mode 100644
index 6a0fefaa..00000000
--- a/src/main/java/net/Indyuce/mmocore/waypoint/CostType.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package net.Indyuce.mmocore.waypoint;
-
-public enum CostType {
-
- /**
- * When teleporting to this waypoint
- */
- NORMAL_USE,
-
- /**
- * When dynamically teleporting to this waypoint
- */
- DYNAMIC_USE,
-
- /**
- * When setting your spawn point to this waypoint.
- */
- // SET_SPAWNPOINT
- ;
-
- private final String path;
-
- CostType() {
- this.path = name().toLowerCase().replace("_", "-");
- }
-
- public String getPath() {
- return path;
- }
-}
diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java
index 07dbf8f6..bd263ac0 100644
--- a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java
+++ b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java
@@ -1,6 +1,7 @@
package net.Indyuce.mmocore.waypoint;
import io.lumine.mythic.lib.api.MMOLineConfig;
+import io.lumine.mythic.lib.api.util.PostLoadObject;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
@@ -12,12 +13,15 @@ import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.craftbukkit.libs.jline.internal.Nullable;
import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
import java.util.*;
+import java.util.logging.Level;
-public class Waypoint implements Unlockable {
+public class Waypoint extends PostLoadObject implements Unlockable {
private final String id, name;
private final Location loc;
+ private final List lore;
private final double radiusSquared;
/**
@@ -26,73 +30,53 @@ public class Waypoint implements Unlockable {
*
* If it's empty it can access any waypoint.
*/
- private final Map destinations = new HashMap<>();
+ private final Map destinations = new HashMap<>();
/**
* Waypoint options saved here.
*/
private final Map options = new HashMap<>();
-
- /**
- * Stellium cost for each action (0 being the default cost)
- */
- private final double dynamicCost, setSpawnCost;
- private final ArrayList dynamicUseConditions = new ArrayList<>();
-
- private final Map costs = new HashMap<>();
-
- public double getDynamicCost() {
- return dynamicCost;
- }
-
- public double getSetSpawnCost() {
- return setSpawnCost;
- }
-
- public double getCost(Waypoint waypoint) {
- return getPath(waypoint).cost;
- }
+ private final double dynamicCost, setSpawnCost, normalCost;
+ private final List dynamicUseConditions = new ArrayList<>();
public Waypoint(ConfigurationSection config) {
+ super(config);
+
id = Objects.requireNonNull(config, "Could not load config section").getName();
name = Objects.requireNonNull(config.getString("name"), "Could not load waypoint name");
+ lore = Objects.requireNonNullElse(config.getStringList("lore"), new ArrayList<>());
loc = readLocation(Objects.requireNonNull(config.getString("location"), "Could not read location"));
radiusSquared = Math.pow(config.getDouble("radius"), 2);
dynamicCost = config.getDouble("cost.dynamic-use");
+ normalCost = config.getDouble("cost.normal-use");
setSpawnCost = config.getDouble("cost.set-spawnpoint");
-
for (WaypointOption option : WaypointOption.values())
options.put(option, config.getBoolean("option." + option.getPath(), option.getDefaultValue()));
- //We load all the linked WayPoints
- if (config.contains("linked")) {
- ConfigurationSection section = config.getConfigurationSection("linked");
- for (String key : section.getKeys(false)) {
- destinations.put(key, section.getInt(key));
- }
- }
- if (config.contains("conditions")) {
- List