mirror of
https://gitlab.com/phoenix-dvpmt/mmocore.git
synced 2024-11-27 00:45:40 +01:00
Fixed /rpg reload increasing player skill levels when using skill trees
This commit is contained in:
parent
3231a69bf3
commit
d4bea3dba7
@ -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.PlayerQuests;
|
||||||
import net.Indyuce.mmocore.api.quest.trigger.StatTrigger;
|
import net.Indyuce.mmocore.api.quest.trigger.StatTrigger;
|
||||||
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
|
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.api.util.MMOCoreUtils;
|
||||||
import net.Indyuce.mmocore.experience.*;
|
import net.Indyuce.mmocore.experience.*;
|
||||||
import net.Indyuce.mmocore.experience.droptable.ExperienceItem;
|
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);
|
if (!nodeLevels.containsKey(node)) nodeLevels.put(node, 0);
|
||||||
|
|
||||||
setupSkillTree();
|
setupSkillTree();
|
||||||
updateTemporaryTriggers();
|
applyTemporaryTriggers();
|
||||||
getStats().updateStats();
|
getStats().updateStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +185,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
@Override
|
@Override
|
||||||
public void markAsSynchronized() {
|
public void markAsSynchronized() {
|
||||||
setupSkillTree();
|
setupSkillTree();
|
||||||
updateTemporaryTriggers();
|
applyTemporaryTriggers();
|
||||||
getStats().updateStats(true);
|
getStats().updateStats(true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -203,25 +204,19 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void setupRemovableTrigger() {
|
public void setupRemovableTrigger() {
|
||||||
updateTemporaryTriggers();
|
applyTemporaryTriggers();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some triggers are marked with the Removable interface as
|
* Some triggers are marked with the {@link Removable} interface as
|
||||||
* they are non-permanent triggers and they need to be updated
|
* they are non-permanent triggers, and they need to be re-applied
|
||||||
* everytime their MMOPlayerData gets flushed from ML cache.
|
* everytime their MMOPlayerData gets flushed from the MythicLib cache
|
||||||
|
* (everytime the player logs out).
|
||||||
* <p>
|
* <p>
|
||||||
* This method should go through ALL {@link ExperienceTable}
|
* This method goes through all the player's experience tables that
|
||||||
* that the player has spent points into and register all
|
* they have spent points into and register all their non-permanent triggers.
|
||||||
* non-permanent triggers.
|
|
||||||
* <p>
|
|
||||||
* 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}
|
|
||||||
*/
|
*/
|
||||||
public void updateTemporaryTriggers() {
|
public void applyTemporaryTriggers() {
|
||||||
|
|
||||||
// Remove all stats and buffs associated to triggers
|
// Remove all stats and buffs associated to triggers
|
||||||
getMMOPlayerData().getStatMap().getInstances().forEach(statInstance -> statInstance.removeIf(Trigger.STAT_MODIFIER_KEY::equals));
|
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
|
// Experience tables from main class
|
||||||
if (getProfess().hasExperienceTable())
|
if (getProfess().hasExperienceTable())
|
||||||
getProfess().getExperienceTable().claimRemovableTrigger(this, getProfess());
|
getProfess().getExperienceTable().applyTemporaryTriggers(this, getProfess());
|
||||||
|
|
||||||
// Experience tables from professions
|
// Experience tables from professions
|
||||||
for (Profession profession : MMOCore.plugin.professionManager.getAll())
|
for (Profession profession : MMOCore.plugin.professionManager.getAll())
|
||||||
if (profession.hasExperienceTable())
|
if (profession.hasExperienceTable())
|
||||||
profession.getExperienceTable().claimRemovableTrigger(this, profession);
|
profession.getExperienceTable().applyTemporaryTriggers(this, profession);
|
||||||
|
|
||||||
// Experience tables from skill tree nodes
|
// Experience tables from skill tree nodes
|
||||||
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll())
|
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll())
|
||||||
for (SkillTreeNode node : skillTree.getNodes())
|
for (SkillTreeNode node : skillTree.getNodes())
|
||||||
node.getExperienceTable().claimRemovableTrigger(this, node);
|
node.getExperienceTable().applyTemporaryTriggers(this, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setupSkillTree() {
|
public void setupSkillTree() {
|
||||||
@ -383,7 +378,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
|
|
||||||
public void resetSkillTree(SkillTree skillTree) {
|
public void resetSkillTree(SkillTree skillTree) {
|
||||||
for (SkillTreeNode node : skillTree.getNodes()) {
|
for (SkillTreeNode node : skillTree.getNodes()) {
|
||||||
node.getExperienceTable().reset(this, node);
|
node.getExperienceTable().unclaim(this, node, true);
|
||||||
setNodeLevel(node, 0);
|
setNodeLevel(node, 0);
|
||||||
nodeStates.remove(node);
|
nodeStates.remove(node);
|
||||||
}
|
}
|
||||||
@ -1216,7 +1211,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
|||||||
// Clear bound skills
|
// Clear bound skills
|
||||||
boundSkills.forEach((slot, info) -> info.close());
|
boundSkills.forEach((slot, info) -> info.close());
|
||||||
boundSkills.clear();
|
boundSkills.clear();
|
||||||
updateTemporaryTriggers();
|
applyTemporaryTriggers();
|
||||||
|
|
||||||
// Update stats
|
// Update stats
|
||||||
if (isOnline()) getStats().updateStats();
|
if (isOnline()) getStats().updateStats();
|
||||||
|
@ -297,9 +297,9 @@ public class SavedClassInformation implements ClassDataContainer {
|
|||||||
// Remove perm stats for nodes and class
|
// Remove perm stats for nodes and class
|
||||||
for (SkillTree skillTree : player.getProfess().getSkillTrees())
|
for (SkillTree skillTree : player.getProfess().getSkillTrees())
|
||||||
for (SkillTreeNode node : skillTree.getNodes())
|
for (SkillTreeNode node : skillTree.getNodes())
|
||||||
node.getExperienceTable().removePermStats(player, node);
|
node.getExperienceTable().unclaim(player, node, false);
|
||||||
if (player.getProfess().hasExperienceTable())
|
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.
|
* Resets information which much be reset after everything is saved.
|
||||||
@ -356,7 +356,7 @@ public class SavedClassInformation implements ClassDataContainer {
|
|||||||
player.setMana(mana);
|
player.setMana(mana);
|
||||||
player.setStellium(stellium);
|
player.setStellium(stellium);
|
||||||
player.setStamina(stamina);
|
player.setStamina(stamina);
|
||||||
player.updateTemporaryTriggers();
|
player.applyTemporaryTriggers();
|
||||||
player.getStats().updateStats();
|
player.getStats().updateStats();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,13 @@ import io.lumine.mythic.lib.skill.handler.SkillHandler;
|
|||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
|
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 net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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 SkillModifier mod;
|
||||||
private final double amount;
|
private final double amount;
|
||||||
|
|
||||||
|
@ -5,9 +5,10 @@ import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
|
|||||||
import io.lumine.mythic.lib.player.modifier.ModifierType;
|
import io.lumine.mythic.lib.player.modifier.ModifierType;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
|
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.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 StatModifier modifier;
|
||||||
private final String stat;
|
private final String stat;
|
||||||
private final double amount;
|
private final double amount;
|
||||||
|
@ -2,8 +2,12 @@ package net.Indyuce.mmocore.api.quest.trigger.api;
|
|||||||
|
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
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 interface Removable {
|
||||||
public void remove(PlayerData playerData);
|
public void remove(PlayerData playerData);
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
}
|
@ -250,7 +250,7 @@ public class ResetCommandTreeNode extends CommandTreeNode {
|
|||||||
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
|
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
|
||||||
data.getCollectionSkills().setExperience(profession, 0);
|
data.getCollectionSkills().setExperience(profession, 0);
|
||||||
data.getCollectionSkills().setLevel(profession, 0);
|
data.getCollectionSkills().setLevel(profession, 0);
|
||||||
profession.getExperienceTable().reset(data, profession);
|
profession.getExperienceTable().unclaim(data, profession, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
|
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
|
||||||
|
@ -68,7 +68,6 @@ public class SkillCommandTreeNode extends CommandTreeNode {
|
|||||||
return CommandResult.FAILURE;
|
return CommandResult.FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int amount;
|
int amount;
|
||||||
try {
|
try {
|
||||||
amount = Integer.parseInt(args[5]);
|
amount = Integer.parseInt(args[5]);
|
||||||
|
@ -3,9 +3,9 @@ package net.Indyuce.mmocore.experience.droptable;
|
|||||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||||
import net.Indyuce.mmocore.MMOCore;
|
import net.Indyuce.mmocore.MMOCore;
|
||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
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.Trigger;
|
||||||
import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
|
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.apache.commons.lang.Validate;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
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.
|
* Used when a player logs back, in order to apply again
|
||||||
*
|
* all the temporary triggers.
|
||||||
* @param playerData
|
|
||||||
*/
|
*/
|
||||||
public void applyRemovableTrigger(PlayerData playerData) {
|
public void applyTemporaryTriggers(PlayerData playerData) {
|
||||||
for (Trigger trigger : triggers)
|
for (Trigger trigger : triggers)
|
||||||
if (trigger instanceof Removable) trigger.apply(playerData);
|
if (trigger instanceof Temporary) trigger.apply(playerData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,42 +55,30 @@ public class ExperienceTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a player changes its class.
|
* Called for example when a player changes its class. This takes
|
||||||
* Removes the perm stat but keeps the item claims in memory.
|
* 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) {
|
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++)
|
for (int i = 0; i < timesClaimed; i++)
|
||||||
item.removeTriggers(playerData);
|
item.removeTriggers(playerData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the progression is reset(e.g skill tree reallocation)
|
* Called when a player joins. All non-permanent/temporary triggers
|
||||||
*/
|
* must be granted back to the player, including player modifiers.
|
||||||
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.
|
|
||||||
*
|
*
|
||||||
* @param data PlayerData
|
* @param data PlayerData
|
||||||
* @param object Either profession, skillTreeNode or class leveling up
|
* @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) {
|
for (ExperienceItem item : items) {
|
||||||
int timesClaimed = data.getClaims(object, this, item);
|
int timesClaimed = data.getClaims(object, this, item);
|
||||||
for (int i = 0; i < timesClaimed; i++)
|
for (int i = 0; i < timesClaimed; i++)
|
||||||
item.applyRemovableTrigger(data);
|
item.applyTemporaryTriggers(data);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,19 +3,23 @@ package net.Indyuce.mmocore.player;
|
|||||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some item that can be unlocked. All unlockables are saved in the
|
* Some object that can be unlocked. All unlockables are saved in the
|
||||||
* same list in the player data. This useful list can be used for:
|
* same list in the player data, in the form of name-spaced keys. This
|
||||||
|
* tool is currently by:
|
||||||
|
* - skills
|
||||||
|
* - skill slots
|
||||||
* - waypoints
|
* - waypoints
|
||||||
* - skill tree nodes
|
* <p>
|
||||||
* - skills using skill books?
|
* These objects are specific to the player's class and will not be
|
||||||
* - external plugins that implement other unlockable items
|
* 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 {
|
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
|
* key format, e.g "skill_tree:strength_1_5" for readability
|
||||||
*/
|
*/
|
||||||
String getUnlockNamespacedKey();
|
String getUnlockNamespacedKey();
|
||||||
|
Loading…
Reference in New Issue
Block a user