diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java index 7eb46f5c..1af1dc81 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -24,6 +24,7 @@ import net.Indyuce.mmocore.api.player.stats.PlayerStats; import net.Indyuce.mmocore.api.quest.PlayerQuests; import net.Indyuce.mmocore.api.quest.trigger.StatTrigger; import net.Indyuce.mmocore.api.quest.trigger.Trigger; +import net.Indyuce.mmocore.api.quest.trigger.api.Removable; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.experience.*; import net.Indyuce.mmocore.experience.droptable.ExperienceItem; @@ -173,7 +174,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD if (!nodeLevels.containsKey(node)) nodeLevels.put(node, 0); setupSkillTree(); - updateTemporaryTriggers(); + applyTemporaryTriggers(); getStats().updateStats(); } @@ -184,7 +185,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD @Override public void markAsSynchronized() { setupSkillTree(); - updateTemporaryTriggers(); + applyTemporaryTriggers(); getStats().updateStats(true); /* @@ -203,25 +204,19 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD @Deprecated public void setupRemovableTrigger() { - updateTemporaryTriggers(); + applyTemporaryTriggers(); } /** - * Some triggers are marked with the Removable interface as - * they are non-permanent triggers and they need to be updated - * everytime their MMOPlayerData gets flushed from ML cache. + * Some triggers are marked with the {@link Removable} interface as + * they are non-permanent triggers, and they need to be re-applied + * everytime their MMOPlayerData gets flushed from the MythicLib cache + * (everytime the player logs out). *

- * This method should go through ALL {@link ExperienceTable} - * that the player has spent points into and register all - * non-permanent triggers. - *

- * For ease of implementation, these non-permanent triggers are - * refreshed everytime the player joins the server ie on every - * player data fetch. - * - * @see {@link net.Indyuce.mmocore.api.quest.trigger.api.Removable} + * This method goes through all the player's experience tables that + * they have spent points into and register all their non-permanent triggers. */ - public void updateTemporaryTriggers() { + public void applyTemporaryTriggers() { // Remove all stats and buffs associated to triggers getMMOPlayerData().getStatMap().getInstances().forEach(statInstance -> statInstance.removeIf(Trigger.STAT_MODIFIER_KEY::equals)); @@ -229,17 +224,17 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD // Experience tables from main class if (getProfess().hasExperienceTable()) - getProfess().getExperienceTable().claimRemovableTrigger(this, getProfess()); + getProfess().getExperienceTable().applyTemporaryTriggers(this, getProfess()); // Experience tables from professions for (Profession profession : MMOCore.plugin.professionManager.getAll()) if (profession.hasExperienceTable()) - profession.getExperienceTable().claimRemovableTrigger(this, profession); + profession.getExperienceTable().applyTemporaryTriggers(this, profession); // Experience tables from skill tree nodes for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll()) for (SkillTreeNode node : skillTree.getNodes()) - node.getExperienceTable().claimRemovableTrigger(this, node); + node.getExperienceTable().applyTemporaryTriggers(this, node); } public void setupSkillTree() { @@ -383,7 +378,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD public void resetSkillTree(SkillTree skillTree) { for (SkillTreeNode node : skillTree.getNodes()) { - node.getExperienceTable().reset(this, node); + node.getExperienceTable().unclaim(this, node, true); setNodeLevel(node, 0); nodeStates.remove(node); } @@ -1216,7 +1211,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD // Clear bound skills boundSkills.forEach((slot, info) -> info.close()); boundSkills.clear(); - updateTemporaryTriggers(); + applyTemporaryTriggers(); // Update stats if (isOnline()) getStats().updateStats(); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java index 96cffb6d..e03db78d 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java @@ -297,9 +297,9 @@ public class SavedClassInformation implements ClassDataContainer { // Remove perm stats for nodes and class for (SkillTree skillTree : player.getProfess().getSkillTrees()) for (SkillTreeNode node : skillTree.getNodes()) - node.getExperienceTable().removePermStats(player, node); + node.getExperienceTable().unclaim(player, node, false); if (player.getProfess().hasExperienceTable()) - player.getProfess().getExperienceTable().removePermStats(player, player.getProfess()); + player.getProfess().getExperienceTable().unclaim(player, player.getProfess(), false); /* * Resets information which much be reset after everything is saved. @@ -356,7 +356,7 @@ public class SavedClassInformation implements ClassDataContainer { player.setMana(mana); player.setStellium(stellium); player.setStamina(stamina); - player.updateTemporaryTriggers(); + player.applyTemporaryTriggers(); player.getStats().updateStats(); } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/SkillModifierTrigger.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/SkillModifierTrigger.java index 9e6c5097..6859b054 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/SkillModifierTrigger.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/SkillModifierTrigger.java @@ -8,12 +8,13 @@ import io.lumine.mythic.lib.skill.handler.SkillHandler; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.quest.trigger.api.Removable; +import net.Indyuce.mmocore.api.quest.trigger.api.Temporary; import net.Indyuce.mmocore.skill.RegisteredSkill; import java.util.ArrayList; import java.util.List; -public class SkillModifierTrigger extends Trigger implements Removable { +public class SkillModifierTrigger extends Trigger implements Removable, Temporary { private final SkillModifier mod; private final double amount; diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/StatTrigger.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/StatTrigger.java index 6a60d3a4..0b9ff987 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/StatTrigger.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/StatTrigger.java @@ -5,9 +5,10 @@ import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import io.lumine.mythic.lib.player.modifier.ModifierType; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.quest.trigger.api.Removable; +import net.Indyuce.mmocore.api.quest.trigger.api.Temporary; import org.apache.commons.lang.Validate; -public class StatTrigger extends Trigger implements Removable { +public class StatTrigger extends Trigger implements Removable, Temporary { private final StatModifier modifier; private final String stat; private final double amount; diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/api/Removable.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/api/Removable.java index eb0c90eb..57de91ff 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/api/Removable.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/api/Removable.java @@ -2,8 +2,12 @@ package net.Indyuce.mmocore.api.quest.trigger.api; import net.Indyuce.mmocore.api.player.PlayerData; -// TODO rename to non-permanent -// TODO merge with MythicLib +/** + * Cancelable triggers cause problems when letting the player reset + * their advancement on things they can spend points in/level up. + * If you give access to some resource to the player via a trigger, + * you must take it away when resetting their progression. + */ public interface Removable { public void remove(PlayerData playerData); } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/api/Temporary.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/api/Temporary.java new file mode 100644 index 00000000..a2d72e79 --- /dev/null +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/api/Temporary.java @@ -0,0 +1,12 @@ +package net.Indyuce.mmocore.api.quest.trigger.api; + +/** + * Non-permanent triggers are triggers which are not saved + * by the player and taken off when the player logs off, + * for instance temporary player modifiers. They need to + * be re-applied everytime the player logs back. + * + * @author jules + */ +public interface Temporary { +} diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResetCommandTreeNode.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResetCommandTreeNode.java index d4b46ffe..86b3467c 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResetCommandTreeNode.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/ResetCommandTreeNode.java @@ -250,7 +250,7 @@ public class ResetCommandTreeNode extends CommandTreeNode { for (Profession profession : MMOCore.plugin.professionManager.getAll()) { data.getCollectionSkills().setExperience(profession, 0); data.getCollectionSkills().setLevel(profession, 0); - profession.getExperienceTable().reset(data, profession); + profession.getExperienceTable().unclaim(data, profession, true); } CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SkillCommandTreeNode.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SkillCommandTreeNode.java index 8d666a1a..f72221be 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SkillCommandTreeNode.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SkillCommandTreeNode.java @@ -68,7 +68,6 @@ public class SkillCommandTreeNode extends CommandTreeNode { return CommandResult.FAILURE; } - int amount; try { amount = Integer.parseInt(args[5]); diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java index 1abf446f..1366ea64 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java @@ -3,9 +3,9 @@ package net.Indyuce.mmocore.experience.droptable; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.quest.trigger.StatTrigger; import net.Indyuce.mmocore.api.quest.trigger.Trigger; import net.Indyuce.mmocore.api.quest.trigger.api.Removable; +import net.Indyuce.mmocore.api.quest.trigger.api.Temporary; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; @@ -132,12 +132,11 @@ public class ExperienceItem { } /** - * Used when a player connects back to give back all the stats that he should have. - * - * @param playerData + * Used when a player logs back, in order to apply again + * all the temporary triggers. */ - public void applyRemovableTrigger(PlayerData playerData) { + public void applyTemporaryTriggers(PlayerData playerData) { for (Trigger trigger : triggers) - if (trigger instanceof Removable) trigger.apply(playerData); + if (trigger instanceof Temporary) trigger.apply(playerData); } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java index 690c2ba6..b11fd08e 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceTable.java @@ -55,42 +55,30 @@ public class ExperienceTable { } /** - * Called when a player changes its class. - * Removes the perm stat but keeps the item claims in memory. + * Called for example when a player changes its class. This takes + * off triggers which can be canceled. */ - public void removePermStats(PlayerData playerData, ExperienceObject object) { + public void unclaim(PlayerData playerData, ExperienceObject object, boolean reset) { for (ExperienceItem item : items) { - int timesClaimed = playerData.getClaims(object, this, item); + final int timesClaimed = playerData.getClaims(object, this, item); + if (reset) playerData.setClaims(object, this, item, 0); for (int i = 0; i < timesClaimed; i++) item.removeTriggers(playerData); } } /** - * Called when the progression is reset(e.g skill tree reallocation) - */ - public void reset(PlayerData playerData, ExperienceObject object) { - for (ExperienceItem item : items) { - int timesClaimed = playerData.getClaims(object, this, item); - playerData.setClaims(object, this, item, 0); - for (int i = 0; i < timesClaimed; i++) - item.removeTriggers(playerData); - } - } - - - /** - * Called when a player joins and all the removable triggers get claimed back. + * Called when a player joins. All non-permanent/temporary triggers + * must be granted back to the player, including player modifiers. * * @param data PlayerData * @param object Either profession, skillTreeNode or class leveling up */ - public void claimRemovableTrigger(PlayerData data, ExperienceObject object) { + public void applyTemporaryTriggers(PlayerData data, ExperienceObject object) { for (ExperienceItem item : items) { int timesClaimed = data.getClaims(object, this, item); for (int i = 0; i < timesClaimed; i++) - item.applyRemovableTrigger(data); - + item.applyTemporaryTriggers(data); } } } diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/player/Unlockable.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/player/Unlockable.java index f9665e48..b9bc29bf 100644 --- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/player/Unlockable.java +++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/player/Unlockable.java @@ -3,19 +3,23 @@ package net.Indyuce.mmocore.player; import net.Indyuce.mmocore.api.player.PlayerData; /** - * 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: + * Some object that can be unlocked. All unlockables are saved in the + * same list in the player data, in the form of name-spaced keys. This + * tool is currently by: + * - skills + * - skill slots * - waypoints - * - skill tree nodes - * - skills using skill books? - * - external plugins that implement other unlockable items + *

+ * These objects are specific to the player's class and will not be + * transferred over to the new class if the player switches classes. * - * @see {@link PlayerData#unlock(Unlockable)} and {@link PlayerData#hasUnlocked(Unlockable)} + * @see PlayerData#unlock(Unlockable) + * @see PlayerData#hasUnlocked(Unlockable) */ public interface Unlockable { /** - * Format being used is the minecraft's default namespaced + * Format being used is the minecraft's default name-spaced * key format, e.g "skill_tree:strength_1_5" for readability */ String getUnlockNamespacedKey();