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.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).
|
||||
* <p>
|
||||
* This method should go through ALL {@link ExperienceTable}
|
||||
* that the player has spent points into and register all
|
||||
* 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}
|
||||
* 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();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()) {
|
||||
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,
|
||||
|
@ -68,7 +68,6 @@ public class SkillCommandTreeNode extends CommandTreeNode {
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
|
||||
int amount;
|
||||
try {
|
||||
amount = Integer.parseInt(args[5]);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
* <p>
|
||||
* 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();
|
||||
|
Loading…
Reference in New Issue
Block a user