/mmocore admin reset all now properly resets skills

This commit is contained in:
Jules 2024-06-04 01:05:51 -07:00
parent fb84e2f96e
commit e2c9074084
13 changed files with 344 additions and 314 deletions

View File

@ -23,7 +23,10 @@ import net.Indyuce.mmocore.api.quest.PlayerQuests;
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.EXPSource;
import net.Indyuce.mmocore.experience.ExperienceObject;
import net.Indyuce.mmocore.experience.PlayerProfessions;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.experience.droptable.ExperienceItem;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import net.Indyuce.mmocore.guild.provided.Guild;
@ -62,7 +65,7 @@ import java.util.*;
import java.util.logging.Level;
import java.util.stream.Collectors;
public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerData, Closeable, ExperienceTableClaimer, ClassDataContainer {
public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerData, Closeable, ClassDataContainer {
/**
* Can be null, the {@link #getProfess()} method will return the
@ -271,7 +274,17 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
return mapped;
}
@Deprecated
public void clearSkillTrees() {
resetSkillTrees();
}
public void resetSkillTrees() {
// Un-apply triggers
for (SkillTree tree : getProfess().getSkillTrees())
for (SkillTreeNode node : tree.getNodes())
node.resetAdvancement(this, false);
// Node levels, states and points spent
nodeLevels.clear();
@ -298,9 +311,8 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
* global skill-tree points ('all')
*/
public void incrementNodeLevel(@NotNull SkillTreeNode node) {
nodeLevels.merge(node, 1, (level, ignored) -> level + 1);
// Claims the nodes experience table.
node.getExperienceTable().claim(this, getNodeLevel(node), node);
final int newLevel = nodeLevels.merge(node, 1, (level, ignored) -> level + 1);
node.updateAdvancement(this, newLevel); // Claim the node exp table
if (nodeStates.get(node) == SkillTreeStatus.UNLOCKABLE) setNodeState(node, SkillTreeStatus.UNLOCKED);
int cost = node.getSkillTreePointsConsumed();
@ -354,7 +366,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
public void resetSkillTree(SkillTree skillTree) {
for (SkillTreeNode node : skillTree.getNodes()) {
node.getExperienceTable().unclaim(this, node, true);
node.resetAdvancement(this, true);
setNodeLevel(node, 0);
nodeStates.remove(node);
}
@ -422,6 +434,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
this.unlockedItems.addAll(unlockedItems);
}
@Deprecated
public void resetTimesClaimed() {
tableItemClaims.clear();
}
@ -546,8 +559,8 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
return skillTreeReallocationPoints;
}
@Override
public int getClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item) {
public int getClaims(@NotNull ExperienceObject object, @NotNull ExperienceItem item) {
final ExperienceTable table = object.getExperienceTable();
return getClaims(object.getKey() + "." + table.getId() + "." + item.getId());
}
@ -555,13 +568,24 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
return tableItemClaims.getOrDefault(key, 0);
}
@Override
public void setClaims(@NotNull ExperienceObject object, @NotNull ExperienceItem item, int times) {
final ExperienceTable table = object.getExperienceTable();
setClaims(object.getKey() + "." + table.getId() + "." + item.getId(), times);
}
public void setClaims(@NotNull String itemKey, int times) {
if (times <= 0) tableItemClaims.remove(itemKey);
else tableItemClaims.put(itemKey, times);
}
@Deprecated
public void setClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item, int times) {
setClaims(object.getKey() + "." + table.getId() + "." + item.getId(), times);
}
public void setClaims(String key, int times) {
tableItemClaims.put(key, times);
@Deprecated
public int getClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item) {
return getClaims(object.getKey() + "." + table.getId() + "." + item.getId());
}
public Map<String, Integer> getItemClaims() {
@ -877,8 +901,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
level = getLevel() + 1;
// Apply class experience table
if (getProfess().hasExperienceTable())
getProfess().getExperienceTable().claim(this, level, getProfess());
getProfess().updateAdvancement(this, level);
}
if (level > oldLevel) {
@ -1104,7 +1127,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
@Deprecated
public void setAttribute(String id, int value) {
attributes.setBaseAttribute(id, value);
attributes.getInstance(id).setBase(value);
}
@Override

View File

@ -1,14 +1,14 @@
package net.Indyuce.mmocore.api.player.attribute;
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 io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.api.stat.StatInstance;
import io.lumine.mythic.lib.player.modifier.Closeable;
import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.modifier.ModifierType;
import io.lumine.mythic.lib.util.Closeable;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;
@ -33,11 +33,9 @@ public class PlayerAttributes {
public void load(ConfigurationSection config) {
for (String key : config.getKeys(false))
try {
String id = key.toLowerCase().replace("_", "-").replace(" ", "-");
Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute '" + id + "'");
PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
AttributeInstance ins = new AttributeInstance(attribute.getId());
final String id = key.toLowerCase().replace("_", "-").replace(" ", "-");
Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute called '" + id + "'");
final AttributeInstance ins = new AttributeInstance(id);
ins.setBase(config.getInt(key));
instances.put(id, ins);
} catch (IllegalArgumentException exception) {
@ -57,15 +55,12 @@ public class PlayerAttributes {
}
public void load(String json) {
Gson parser = new Gson();
JsonObject jo = parser.fromJson(json, JsonObject.class);
JsonObject jo = MythicLib.plugin.getGson().fromJson(json, JsonObject.class);
for (Entry<String, JsonElement> entry : jo.entrySet()) {
try {
String id = entry.getKey().toLowerCase().replace("_", "-").replace(" ", "-");
Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute '" + id + "'");
PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
AttributeInstance ins = new AttributeInstance(attribute.getId());
final String id = entry.getKey().toLowerCase().replace("_", "-").replace(" ", "-");
Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute called '" + id + "'");
final AttributeInstance ins = new AttributeInstance(id);
ins.setBase(entry.getValue().getAsInt());
instances.put(id, ins);
} catch (IllegalArgumentException exception) {
@ -121,7 +116,7 @@ public class PlayerAttributes {
private final String id, enumName;
private final Map<String, AttributeModifier> map = new HashMap<>();
public AttributeInstance(String id) {
public AttributeInstance(@NotNull String id) {
this.id = id;
this.enumName = UtilityMethods.enumName(this.id);
}
@ -143,7 +138,7 @@ public class PlayerAttributes {
}
public void addBase(int value) {
setBase(spent + value);
setBase(getBase() + value);
}
/*
@ -183,8 +178,7 @@ public class PlayerAttributes {
public AttributeModifier addModifier(AttributeModifier modifier) {
final AttributeModifier current = map.put(modifier.getKey(), modifier);
if (current != null && current instanceof Closeable)
((Closeable) current).close();
if (current instanceof Closeable) ((Closeable) current).close();
updateStats();
return current;

View File

@ -294,20 +294,18 @@ public class SavedClassInformation implements ClassDataContainer {
if (!player.getProfess().hasOption(ClassOption.DEFAULT) || MMOCore.plugin.configManager.saveDefaultClassInfo)
player.applyClassInfo(player.getProfess(), new SavedClassInformation(player));
// Remove perm stats for nodes and class
for (SkillTree skillTree : player.getProfess().getSkillTrees())
for (SkillTreeNode node : skillTree.getNodes())
node.getExperienceTable().unclaim(player, node, false);
if (player.getProfess().hasExperienceTable())
player.getProfess().getExperienceTable().unclaim(player, player.getProfess(), false);
// Remove class permanent buffs
player.getProfess().resetAdvancement(player, false);
/*
* Resets information which much be reset after everything is saved.
*/
player.mapSkillLevels().forEach((skill, level) -> player.resetSkillLevel(skill));
for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll())
for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll()) {
attribute.resetAdvancement(player, false);
player.getAttributes().getInstance(attribute).setBase(0);
player.clearSkillTrees();
}
player.resetSkillTrees();
/*
* Reads this class info, applies it to the player. set class after

View File

@ -1,8 +1,8 @@
package net.Indyuce.mmocore.api.quest;
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.util.Closeable;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
@ -99,8 +99,7 @@ public class PlayerQuests implements Closeable {
}
public void load(String json) {
Gson parser = new Gson();
JsonObject jo = parser.fromJson(json, JsonObject.class);
JsonObject jo = MythicLib.plugin.getGson().fromJson(json, JsonObject.class);
if (jo.has("current")) {
JsonObject cur = jo.getAsJsonObject("current");
try {

View File

@ -8,5 +8,5 @@ package net.Indyuce.mmocore.api.quest.trigger.api;
*
* @author jules
*/
public interface Temporary {
public interface Temporary extends Removable {
}

View File

@ -20,8 +20,6 @@ import java.util.stream.Collectors;
public class SkillTreesCommand extends RegisteredCommand {
public SkillTreesCommand(ConfigurationSection config) {
super(config, ToggleableCommand.SKILL_TREES);
}
@Override
@ -74,7 +72,5 @@ public class SkillTreesCommand extends RegisteredCommand {
sender.sendMessage(ChatColor.RED + "Usage: /skilltrees");
return false;
}
}
}

View File

@ -1,29 +1,33 @@
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.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttributes;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import net.Indyuce.mmocore.command.api.CommandVerbose;
import net.Indyuce.mmocore.experience.Profession;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import net.Indyuce.mmocore.command.api.CommandVerbose;
import io.lumine.mythic.lib.command.api.CommandTreeNode;
import io.lumine.mythic.lib.command.api.Parameter;
import java.util.HashSet;
public class ResetCommandTreeNode extends CommandTreeNode {
public ResetCommandTreeNode(CommandTreeNode parent) {
super(parent, "reset");
addChild(new ResetClassesCommandTreeNode(this));
addChild(new ResetLevelsCommandTreeNode(this));
addChild(new ResetSkillsCommandTreeNode(this));
addChild(new ResetAllCommandTreeNode(this));
addChild(new ResetQuestsCommandTreeNode(this));
addChild(new ResetAttributesCommandTreeNode(this));
addChild(new ResetWaypointsCommandTreeNode(this));
addChild(new ResetSkillTreesCommandTreeNode(this));
addChild(new ResetAllCommandTreeNode(this));
}
@Override
@ -40,8 +44,7 @@ public class ResetCommandTreeNode extends CommandTreeNode {
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4)
return CommandResult.THROW_USAGE;
if (args.length < 4) return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
@ -49,34 +52,23 @@ public class ResetCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
PlayerData data = PlayerData.get(player);
MMOCore.plugin.playerDataManager.getDefaultData().apply(data);
data.setExperience(0);
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
data.getCollectionSkills().setExperience(profession, 0);
data.getCollectionSkills().setLevel(profession, 0);
}
MMOCore.plugin.classManager.getAll().forEach(data::unloadClassInfo);
data.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
data.mapSkillLevels().forEach((skill, level) -> data.resetSkillLevel(skill));
data.setSkillTreePoints("global", 0);
for (SkillTree skillTree : data.getProfess().getSkillTrees()) {
data.resetSkillTree(skillTree);
data.setSkillTreePoints(skillTree.getId(), 0);
}
final boolean givePoints = args.length > 4 && args[4].equalsIgnoreCase("-reallocate");
data.resetTimesClaimed();
for(int slot:data.mapBoundSkills().keySet())
data.unbindSkill(slot);
data.getQuestData().resetFinishedQuests();
data.getQuestData().start(null);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s data was succesfully reset.");
PlayerData data = PlayerData.get(player);
ResetClassesCommandTreeNode.resetClasses(data);
ResetLevelsCommandTreeNode.resetLevels(data);
ResetSkillsCommandTreeNode.resetSkills(data);
ResetQuestsCommandTreeNode.resetQuests(data);
ResetAttributesCommandTreeNode.resetAttributes(data, givePoints);
ResetWaypointsCommandTreeNode.resetWaypoints(data);
ResetSkillTreesCommandTreeNode.resetSkillTrees(data);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s data was successfully reset.");
return CommandResult.SUCCESS;
}
}
}
public static class ResetWaypointsCommandTreeNode extends CommandTreeNode {
class ResetWaypointsCommandTreeNode extends CommandTreeNode {
public ResetWaypointsCommandTreeNode(CommandTreeNode parent) {
super(parent, "waypoints");
@ -85,8 +77,7 @@ public class ResetCommandTreeNode extends CommandTreeNode {
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4)
return CommandResult.THROW_USAGE;
if (args.length < 4) return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
@ -94,13 +85,17 @@ public class ResetCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
PlayerData data = PlayerData.get(player);
data.getWaypoints().clear();
resetWaypoints(PlayerData.get(player));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s waypoints were successfully reset.");
return CommandResult.SUCCESS;
}
static void resetWaypoints(@NotNull PlayerData playerData) {
playerData.getWaypoints().clear();
}
}
public static class ResetQuestsCommandTreeNode extends CommandTreeNode {
class ResetQuestsCommandTreeNode extends CommandTreeNode {
public ResetQuestsCommandTreeNode(CommandTreeNode parent) {
super(parent, "quests");
@ -109,8 +104,7 @@ public class ResetCommandTreeNode extends CommandTreeNode {
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4)
return CommandResult.THROW_USAGE;
if (args.length < 4) return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
@ -118,14 +112,18 @@ public class ResetCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
PlayerData data = PlayerData.get(player);
resetQuests(PlayerData.get(player));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s quests were successfully reset.");
return CommandResult.SUCCESS;
}
static void resetQuests(@NotNull PlayerData data) {
data.getQuestData().resetFinishedQuests();
data.getQuestData().start(null);
return CommandResult.SUCCESS;
}
}
public static class ResetSkillsCommandTreeNode extends CommandTreeNode {
class ResetSkillsCommandTreeNode extends CommandTreeNode {
public ResetSkillsCommandTreeNode(CommandTreeNode parent) {
super(parent, "skills");
@ -134,8 +132,7 @@ public class ResetCommandTreeNode extends CommandTreeNode {
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4)
return CommandResult.THROW_USAGE;
if (args.length < 4) return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
@ -143,18 +140,19 @@ public class ResetCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
PlayerData data = PlayerData.get(player);
data.mapSkillLevels().forEach((skill, level) -> data.resetSkillLevel(skill));
while (data.hasSkillBound(0))
data.unbindSkill(0);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s skill data was succesfully reset.");
resetSkills(PlayerData.get(player));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s skill data was successfully reset.");
return CommandResult.SUCCESS;
}
static void resetSkills(@NotNull PlayerData data) {
data.mapSkillLevels().forEach((skill, ignored) -> data.resetSkillLevel(skill));
while (data.hasSkillBound(0)) data.unbindSkill(0);
data.setUnlockedItems(new HashSet<>()); // TODO class-specific unlockables etc.
}
}
public static class ResetSkillTreesCommandTreeNode extends CommandTreeNode {
class ResetSkillTreesCommandTreeNode extends CommandTreeNode {
public ResetSkillTreesCommandTreeNode(CommandTreeNode parent) {
super(parent, "skill-trees");
@ -163,8 +161,7 @@ public class ResetCommandTreeNode extends CommandTreeNode {
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4)
return CommandResult.THROW_USAGE;
if (args.length < 4) return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
@ -172,16 +169,18 @@ public class ResetCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
PlayerData data = PlayerData.get(player);
for (SkillTree skillTree : data.getProfess().getSkillTrees())
data.resetSkillTree(skillTree);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s skill-tree data was succesfully reset.");
resetSkillTrees(PlayerData.get(player));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s skill-tree data was successfully reset.");
return CommandResult.SUCCESS;
}
// TODO option to reallocate skill tree points instead of not giving any back
static void resetSkillTrees(@NotNull PlayerData data) {
data.resetSkillTrees();
}
}
public class ResetAttributesCommandTreeNode extends CommandTreeNode {
class ResetAttributesCommandTreeNode extends CommandTreeNode {
public ResetAttributesCommandTreeNode(CommandTreeNode parent) {
super(parent, "attributes");
@ -191,8 +190,7 @@ public class ResetCommandTreeNode extends CommandTreeNode {
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4)
return CommandResult.THROW_USAGE;
if (args.length < 4) return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
@ -200,12 +198,16 @@ public class ResetCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
PlayerData data = PlayerData.get(player);
final boolean givePoints = args.length > 4 && args[4].equalsIgnoreCase("-reallocate");
resetAttributes(PlayerData.get(player), givePoints);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s attributes were successfully reset.");
return CommandResult.SUCCESS;
}
/*
* force reallocating of player attribute points
*/
if (args.length > 4 && args[4].equalsIgnoreCase("-reallocate")) {
static void resetAttributes(@NotNull PlayerData data, boolean givePoints) {
// Give back attribute points
if (givePoints) {
int points = 0;
for (PlayerAttributes.AttributeInstance ins : data.getAttributes().getInstances()) {
@ -214,19 +216,17 @@ public class ResetCommandTreeNode extends CommandTreeNode {
}
data.giveAttributePoints(points);
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s attribute points spendings were successfully reset.");
return CommandResult.SUCCESS;
return;
}
data.getAttributes().getInstances().forEach(ins -> ins.setBase(0));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s attributes were succesfully reset.");
return CommandResult.SUCCESS;
for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll()) {
attribute.resetAdvancement(data, true);
data.getAttributes().getInstance(attribute).setBase(0);
}
}
}
public static class ResetLevelsCommandTreeNode extends CommandTreeNode {
class ResetLevelsCommandTreeNode extends CommandTreeNode {
public ResetLevelsCommandTreeNode(CommandTreeNode parent) {
super(parent, "levels");
@ -235,8 +235,7 @@ public class ResetCommandTreeNode extends CommandTreeNode {
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4)
return CommandResult.THROW_USAGE;
if (args.length < 4) return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
@ -244,19 +243,52 @@ public class ResetCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
PlayerData data = PlayerData.get(player);
resetLevels(PlayerData.get(player));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s levels were successfully reset.");
return CommandResult.SUCCESS;
}
static void resetLevels(@NotNull PlayerData data) {
// Class
data.setLevel(MMOCore.plugin.playerDataManager.getDefaultData().getLevel());
data.setExperience(0);
data.getProfess().resetAdvancement(data, true);
// Professions
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
data.getCollectionSkills().setExperience(profession, 0);
data.getCollectionSkills().setLevel(profession, 0);
profession.getExperienceTable().unclaim(data, profession, true);
profession.resetAdvancement(data, true);
}
}
}
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET,
ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s levels were succesfully reset.");
class ResetClassesCommandTreeNode extends CommandTreeNode {
public ResetClassesCommandTreeNode(CommandTreeNode parent) {
super(parent, "classes");
addParameter(Parameter.PLAYER);
}
@Override
public CommandResult execute(CommandSender sender, String[] args) {
if (args.length < 4) return CommandResult.THROW_USAGE;
Player player = Bukkit.getPlayer(args[3]);
if (player == null) {
sender.sendMessage(ChatColor.RED + "Could not find the player called " + args[3] + ".");
return CommandResult.FAILURE;
}
resetClasses(PlayerData.get(player));
CommandVerbose.verbose(sender, CommandVerbose.CommandType.RESET, ChatColor.GOLD + player.getName() + ChatColor.YELLOW + "'s classes were successfully reset.");
return CommandResult.SUCCESS;
}
static void resetClasses(@NotNull PlayerData data) {
MMOCore.plugin.classManager.getAll().forEach(data::unloadClassInfo);
MMOCore.plugin.playerDataManager.getDefaultData().apply(data);
data.setClass(MMOCore.plugin.classManager.getDefaultClass());
}
}

View File

@ -1,5 +1,6 @@
package net.Indyuce.mmocore.experience;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import org.jetbrains.annotations.NotNull;
@ -10,7 +11,8 @@ import javax.annotation.Nullable;
* General implementation for professions, classes and attributes.
* <p>
* An experience object is a type of object that can level up.
* It has an experience curve and table and can receive EXP
* It has an experience curve and table and can receive EXP. It
* is what most resembles the Mythic abstraction of "archetypes".
*
* @author jules
*/
@ -36,4 +38,17 @@ public interface ExperienceObject extends ExperienceDispenser {
ExperienceTable getExperienceTable();
boolean hasExperienceTable();
/**
* Resets the advancement of an archetype for a player. This only
* applies to the object's experience table though, and does not
* actually decrease class level/profession level & exp bar.
*/
public default void resetAdvancement(@NotNull PlayerData playerData, boolean levels) {
if (hasExperienceTable()) getExperienceTable().unclaim(playerData, this, levels);
}
public default void updateAdvancement(@NotNull PlayerData playerData, int newLevel) {
if (hasExperienceTable()) getExperienceTable().claim(playerData, newLevel, this);
}
}

View File

@ -1,21 +0,0 @@
package net.Indyuce.mmocore.experience;
import net.Indyuce.mmocore.experience.droptable.ExperienceItem;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
/**
* Professions and classes share the same properties because
* they have both exp curves and tables.
* <p>
* A 'claimer' is an object that can claim exp tables and therefore
* needs to save how many times it has already claimed some item
* before.
* <p>
* Since MMOCore 1.9 it's all centralized in the player class data
*/
public interface ExperienceTableClaimer {
int getClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item);
void setClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item, int claims);
}

View File

@ -1,6 +1,5 @@
package net.Indyuce.mmocore.experience;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.lumine.mythic.lib.MythicLib;
@ -86,7 +85,7 @@ public class PlayerProfessions {
* When loading data through SQL
*/
public void load(String json) {
JsonObject obj = new Gson().fromJson(json, JsonObject.class);
JsonObject obj = MythicLib.plugin.getGson().fromJson(json, JsonObject.class);
// Load profession exp and levels
for (Entry<String, JsonElement> entry : obj.entrySet())
@ -215,8 +214,7 @@ public class PlayerProfessions {
playerData.giveExperience(profession.getExperience().calculate(level), null);
// Apply profession experience table
if (profession.hasExperienceTable())
profession.getExperienceTable().claim(playerData, level, profession);
profession.updateAdvancement(playerData, level);
}
if (check) {

View File

@ -5,6 +5,7 @@ import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.ExperienceObject;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@ -36,34 +37,34 @@ public class ExperienceTable {
}
/**
* Called when a player levels up one of his professions
* Called when a player levels up something.
*
* @param levelingUp Player leveling up
* @param professionLevel New profession level
* @param object Either profession or class leveling up
* @param object The object being level up. This MUST be the parent object
* owning the calling experience table! In other words,
* <code>object.getExperienceTable() == this</code> must remain true.
*/
public void claim(PlayerData levelingUp, int professionLevel, ExperienceObject object) {
public void claim(@NotNull PlayerData levelingUp, int professionLevel, @NotNull ExperienceObject object) {
for (ExperienceItem item : items) {
int timesClaimed = levelingUp.getClaims(object, this, item);
if (!item.roll(professionLevel, timesClaimed))
continue;
final int timesClaimed = levelingUp.getClaims(object, item);
if (!item.roll(professionLevel, timesClaimed)) continue;
levelingUp.setClaims(object, this, item, timesClaimed + 1);
levelingUp.setClaims(object, item, timesClaimed + 1);
item.applyTriggers(levelingUp);
}
}
/**
* Called for example when a player changes its class. This takes
* off triggers which can be canceled.
*/
public void unclaim(PlayerData playerData, ExperienceObject object, boolean reset) {
public void unclaim(@NotNull PlayerData playerData, @NotNull ExperienceObject object, boolean reset) {
for (ExperienceItem item : items) {
final int timesClaimed = playerData.getClaims(object, this, item);
if (reset) playerData.setClaims(object, this, item, 0);
for (int i = 0; i < timesClaimed; i++)
// Undo triggers
for (int i = 0; i < playerData.getClaims(object, item); i++)
item.removeTriggers(playerData);
// Reset levels
if (reset) playerData.setClaims(object, item, 0);
}
}
@ -74,9 +75,9 @@ public class ExperienceTable {
* @param data PlayerData
* @param object Either profession, skillTreeNode or class leveling up
*/
public void applyTemporaryTriggers(PlayerData data, ExperienceObject object) {
public void applyTemporaryTriggers(@NotNull PlayerData data, @NotNull ExperienceObject object) {
for (ExperienceItem item : items) {
int timesClaimed = data.getClaims(object, this, item);
final int timesClaimed = data.getClaims(object, item);
for (int i = 0; i < timesClaimed; i++)
item.applyTemporaryTriggers(data);
}

View File

@ -147,9 +147,8 @@ public class AttributeView extends EditableInventory {
playerData.giveAttributePoints(-pointsSpent);
// Apply exp table as many times as required
if (attribute.hasExperienceTable())
while (pointsSpent-- > 0)
attribute.getExperienceTable().claim(playerData, ins.getBase(), attribute);
attribute.updateAdvancement(playerData, ins.getBase());
ConfigMessage.fromKey("attribute-level-up", "attribute", attribute.getName(), "level", String.valueOf(ins.getBase())).send(player);
MMOCore.plugin.soundManager.getSound(SoundEvent.LEVEL_ATTRIBUTE).playTo(getPlayer());

View File

@ -27,7 +27,7 @@ public class SkillTreeNode implements ExperienceObject {
private final SkillTree tree;
private final String name, id;
private String permissionRequired;
private final String permissionRequired;
private final Map<SkillTreeStatus, Icon> icons = new HashMap<>();
@ -57,11 +57,6 @@ public class SkillTreeNode implements ExperienceObject {
**/
private final Map<ParentInformation, Integer> parents = new HashMap<>();
/**
* Prefix used in node key
*/
public static final String KEY_PREFIX = "node";
public SkillTreeNode(SkillTree tree, ConfigurationSection config) {
Validate.notNull(config, "Config cannot be null");
this.id = config.getName();
@ -136,7 +131,6 @@ public class SkillTreeNode implements ExperienceObject {
this.coordinates = coordinates;
}
public int getParentNeededLevel(SkillTreeNode parent) {
for (Map.Entry<ParentInformation, Integer> entry : parents.entrySet())
if (entry.getKey().node().equals(parent))
@ -202,6 +196,8 @@ public class SkillTreeNode implements ExperienceObject {
return coordinates;
}
public static final String KEY_PREFIX = "node";
@Override
public String getKey() {
return KEY_PREFIX + ":" + getFullId().replace("-", "_");