diff --git a/Changelog.txt b/Changelog.txt index 7140d3ed6..301df3de0 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -2,6 +2,8 @@ Version 2.2.000 mcMMO-API is now the library used for mcMMO API Parts of the API have been migrated to mcMMO-API (API) mcMMO makes use of jmal (Java Minecraft Abstraction Library) for some abstraction now + (API) Added skill register + (API) Skill hierarchy is now defined by Skill in mcMMO-API, and mcMMO needs a skill to be registered to be aware of it Codebase Stuff Many places that passed type Player now passes type McMMOPlayer instead diff --git a/src/main/java/com/gmail/nossr50/commands/player/McstatsCommand.java b/src/main/java/com/gmail/nossr50/commands/player/McstatsCommand.java index a0001e178..0a9bf6b52 100644 --- a/src/main/java/com/gmail/nossr50/commands/player/McstatsCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/player/McstatsCommand.java @@ -1,7 +1,9 @@ package com.gmail.nossr50.commands.player; import com.gmail.nossr50.config.Config; +import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.locale.LocaleLoader; +import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.util.commands.CommandUtils; import com.gmail.nossr50.util.scoreboards.ScoreboardManager; import com.google.common.collect.ImmutableList; @@ -25,12 +27,14 @@ public class McstatsCommand implements TabExecutor { } if (args.length == 0) { - if (mcMMO.getUserManager().getPlayer((Player) sender) == null) { + Player player = (Player) sender; + + if (mcMMO.getUserManager().queryPlayer(player) == null) { sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad")); return true; } - Player player = (Player) sender; + McMMOPlayer mmoPlayer = mcMMO.getUserManager().queryPlayer(player); if (Config.getInstance().getStatsUseBoard() && Config.getInstance().getScoreboardsEnabled()) { ScoreboardManager.enablePlayerStatsScoreboard(player); @@ -50,9 +54,9 @@ public class McstatsCommand implements TabExecutor { int powerLevelCap = Config.getInstance().getPowerLevelCap(); if (powerLevelCap != Integer.MAX_VALUE) { - player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", mcMMO.getUserManager().getPlayer(player).getPowerLevel(), powerLevelCap)); + player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", mmoPlayer.getPowerLevel(), powerLevelCap)); } else { - player.sendMessage(LocaleLoader.getString("Commands.PowerLevel", mcMMO.getUserManager().getPlayer(player).getPowerLevel())); + player.sendMessage(LocaleLoader.getString("Commands.PowerLevel", mmoPlayer.getPowerLevel())); } return true; diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/AbstractMMOPlayer.java b/src/main/java/com/gmail/nossr50/datatypes/player/AbstractMMOPlayer.java new file mode 100644 index 000000000..1866ee55d --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/player/AbstractMMOPlayer.java @@ -0,0 +1,52 @@ +package com.gmail.nossr50.datatypes.player; + +import com.gmail.nossr50.datatypes.experience.ExperienceManager; +import com.neetgames.mcmmo.player.MMOPlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public abstract class AbstractMMOPlayer implements MMOPlayer { + /* All of the persistent data for a player that gets saved and loaded from DB */ + protected final @NotNull PersistentPlayerData persistentPlayerData; //All persistent data is kept here + + /* Managers */ + protected final @NotNull ExperienceManager experienceManager; + protected final @NotNull CooldownManager cooldownManager; + + /** + * Create a new AbstractMMOPlayer for a {@link Player} with default values + * + * @param player target player + */ + public AbstractMMOPlayer(@NotNull Player player) { + /* New Data */ + this(player.getUniqueId(), player.getName()); + } + + /** + * Create a new AbstractMMOPlayer for a {@link Player} with default values + * + * @param playerUUID target player's UUID + * @param playerName target player's name + */ + public AbstractMMOPlayer(@NotNull UUID playerUUID, @NotNull String playerName) { + /* New Data */ + this.persistentPlayerData = new PersistentPlayerData(playerUUID, playerName); + this.experienceManager = new ExperienceManager(persistentPlayerData); + this.cooldownManager = new CooldownManager(persistentPlayerData); + } + + /** + * Initialize an AbstractMMOPlayer for {@link PersistentPlayerData} + * This will be used for existing data + * + * @param persistentPlayerData target persistent player data + */ + public AbstractMMOPlayer(@NotNull PersistentPlayerData persistentPlayerData) { + this.persistentPlayerData = persistentPlayerData; + this.experienceManager = new ExperienceManager(persistentPlayerData); + this.cooldownManager = new CooldownManager(persistentPlayerData); + } +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/CooldownManager.java b/src/main/java/com/gmail/nossr50/datatypes/player/CooldownManager.java index b541f57bf..7b70ca374 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/CooldownManager.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/CooldownManager.java @@ -1,6 +1,7 @@ package com.gmail.nossr50.datatypes.player; import com.gmail.nossr50.util.Misc; +import com.neetgames.mcmmo.UniqueDataType; import org.bukkit.Location; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -22,7 +23,7 @@ public class CooldownManager { } public void actualizeChimeraWingLastUse() { - playerProfile.setChimaeraWingDATS((int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR)); + playerDataRef.setChimaeraWingDATS((int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR)); } public @Nullable Location getTeleportCommenceLocation() { diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/MMODataSnapshot.java b/src/main/java/com/gmail/nossr50/datatypes/player/MMODataSnapshot.java index cfd11884f..af191cc1d 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/MMODataSnapshot.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/MMODataSnapshot.java @@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.skills.SuperAbilityType; import com.google.common.collect.ImmutableMap; import com.neetgames.mcmmo.MobHealthBarType; import com.neetgames.mcmmo.UniqueDataType; +import com.neetgames.mcmmo.skill.RootSkill; import com.neetgames.mcmmo.skill.SkillBossBarState; import org.jetbrains.annotations.NotNull; @@ -22,8 +23,8 @@ public class MMODataSnapshot { private final @NotNull MobHealthBarType mobHealthBarType; /* Skill Data */ - private final @NotNull ImmutableMap skillLevelValues; - private final @NotNull ImmutableMap skillExperienceValues; + private final @NotNull ImmutableMap skillLevelValues; + private final @NotNull ImmutableMap skillExperienceValues; private final @NotNull ImmutableMap abilityDeactivationTimestamps; // Ability & Cooldown private final @NotNull ImmutableMap uniquePlayerData; //Misc data that doesn't fit into other categories (chimaera wing, etc..) private final @NotNull ImmutableMap barStateMap; @@ -36,7 +37,7 @@ public class MMODataSnapshot { private final @NotNull Integer scoreboardTipsShown; - public MMODataSnapshot(PersistentPlayerData persistentPlayerData) { + public MMODataSnapshot(@NotNull PersistentPlayerData persistentPlayerData) { playerName = persistentPlayerData.getPlayerName(); playerUUID = persistentPlayerData.getPlayerUUID(); lastLogin = persistentPlayerData.getLastLogin(); @@ -71,11 +72,11 @@ public class MMODataSnapshot { return mobHealthBarType; } - public @NotNull ImmutableMap getSkillLevelValues() { + public @NotNull ImmutableMap getSkillLevelValues() { return skillLevelValues; } - public @NotNull ImmutableMap getSkillExperienceValues() { + public @NotNull ImmutableMap getSkillExperienceValues() { return skillExperienceValues; } @@ -87,7 +88,7 @@ public class MMODataSnapshot { return uniquePlayerData; } - public @NotNull ImmutableMap getBarStateMap() { + public @NotNull ImmutableMap getBarStateMap() { return barStateMap; } diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java index 427016369..1930b3773 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java @@ -49,7 +49,7 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; -public class McMMOPlayer implements OnlineMMOPlayer, Identified { +public class McMMOPlayer extends PlayerProfile implements OnlineMMOPlayer, Identified { private final @NotNull Player player; private final @NotNull Identity identity; private @Nullable Party playerPartyRef; @@ -605,7 +605,17 @@ public class McMMOPlayer implements OnlineMMOPlayer, Identified { } @Override - public UUID getUUID() { - return ; + public boolean inParty() { + return false; + } + + @Override + public boolean isGodMode() { + return false; + } + + @Override + public boolean isChatSpying() { + return false; } } diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/PersistentPlayerData.java b/src/main/java/com/gmail/nossr50/datatypes/player/PersistentPlayerData.java index bd0d35b75..a88ffc226 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PersistentPlayerData.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PersistentPlayerData.java @@ -1,21 +1,19 @@ package com.gmail.nossr50.datatypes.player; import com.gmail.nossr50.config.AdvancedConfig; -import com.gmail.nossr50.config.Config; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.SuperAbilityType; import com.gmail.nossr50.datatypes.validation.NonNullRule; import com.gmail.nossr50.datatypes.validation.PositiveIntegerRule; import com.gmail.nossr50.datatypes.validation.Validator; +import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.util.experience.MMOExperienceBarManager; import com.google.common.collect.ImmutableMap; import com.neetgames.mcmmo.MobHealthBarType; import com.neetgames.mcmmo.UniqueDataType; import com.neetgames.mcmmo.exceptions.UnexpectedValueException; -import com.neetgames.mcmmo.skill.Skill; -import com.neetgames.mcmmo.skill.SkillBossBarState; +import com.neetgames.mcmmo.skill.*; import com.neetgames.mcmmo.player.MMOPlayerData; -import com.neetgames.mcmmo.skill.SuperSkill; import com.neetgames.neetlib.dirtydata.DirtyData; import com.neetgames.neetlib.dirtydata.DirtyMap; import com.neetgames.neetlib.mutableprimitives.MutableBoolean; @@ -25,6 +23,7 @@ import com.neetgames.neetlib.mutableprimitives.MutableString; import org.apache.commons.lang.NullArgumentException; import org.jetbrains.annotations.NotNull; import java.util.EnumMap; +import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -39,15 +38,12 @@ public class PersistentPlayerData implements MMOPlayerData { /* Records */ private final DirtyData lastLogin; - /* HUDs */ - private final @NotNull DirtyData mobHealthBarType; - /* Skill Data */ - private final @NotNull DirtyMap skillLevelValues; - private final @NotNull DirtyMap skillExperienceValues; - private final @NotNull DirtyMap abilityDeactivationTimestamps; // Ability & Cooldown + private final @NotNull DirtyMap skillLevelValues; + private final @NotNull DirtyMap skillExperienceValues; + private final @NotNull DirtyMap abilityDeactivationTimestamps; // Ability & Cooldown private final @NotNull DirtyMap uniquePlayerData; //Misc data that doesn't fit into other categories (chimaera wing, etc..) - private final @NotNull DirtyMap barStateMap; + private final @NotNull DirtyMap barStateMap; /* Special Flags */ private final @NotNull DirtyData partyChatSpying; @@ -59,6 +55,7 @@ public class PersistentPlayerData implements MMOPlayerData { /** * Create new persistent player data for a player * Initialized with default values + * * @param playerUUID target player's UUID * @param playerName target player's name * @throws NullArgumentException thrown when never null arguments are null @@ -71,16 +68,15 @@ public class PersistentPlayerData implements MMOPlayerData { this.playerUUID = playerUUID; this.playerName = new DirtyData<>(new MutableString(playerName), dirtyFlag); - this.skillLevelValues = new DirtyMap<>(new EnumMap<>(PrimarySkillType.class), dirtyFlag); - this.skillExperienceValues = new DirtyMap<>(new EnumMap<>(PrimarySkillType.class), dirtyFlag); - this.abilityDeactivationTimestamps = new DirtyMap<>(new EnumMap<>(SuperAbilityType.class), dirtyFlag); + this.skillLevelValues = new DirtyMap<>(new HashMap<>(SkillIdentity.class), dirtyFlag); + this.skillExperienceValues = new DirtyMap<>(new HashMap<>(SkillIdentity.class), dirtyFlag); + this.abilityDeactivationTimestamps = new DirtyMap<>(new EnumMap<>(SkillIdentity.class), dirtyFlag); this.uniquePlayerData = new DirtyMap<>(new EnumMap<>(UniqueDataType.class), dirtyFlag); - this.mobHealthBarType = new DirtyData<>(Config.getInstance().getMobHealthbarDefault(), dirtyFlag); this.scoreboardTipsShown = new DirtyData<>(new MutableInteger(0), dirtyFlag); - for(SuperAbilityType superAbilityType : SuperAbilityType.values()) { - abilityDeactivationTimestamps.put(superAbilityType, 0); + for(RootSkill rootSkill : mcMMO.p.getSkillRegister().getRootSkills()) { + abilityDeactivationTimestamps.put(rootSkill.getSkillIdentity(), 0); } for(PrimarySkillType primarySkillType : PrimarySkillType.values()) { @@ -192,12 +188,12 @@ public class PersistentPlayerData implements MMOPlayerData { } @Override - public void setSkillLevel(Skill skill, int i) { + public void setSkillLevel(@NotNull RootSkill rootSkill, int i) { } @Override - public int getSkillLevel(Skill skill) { + public int getSkillLevel(@NotNull RootSkill rootSkill) { return 0; } diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java index 1f55e42d2..652d63856 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java @@ -13,51 +13,42 @@ import org.jetbrains.annotations.Nullable; import java.util.UUID; -public class PlayerProfile implements OfflineMMOPlayer { - - /* All of the persistent data for a player that gets saved and loaded from DB */ - private final @NotNull PersistentPlayerData persistentPlayerData; //All persistent data is kept here - - /* Managers */ - private final @NotNull ExperienceManager experienceManager; - private final @NotNull CooldownManager cooldownManager; +public class PlayerProfile extends AbstractMMOPlayer { /** - * Create a new PlayerProfile for a {@link Player} + * Create a new {@link PlayerProfile} for a {@link Player} with default values + * * @param player target player */ public PlayerProfile(@NotNull Player player) { - /* New Data */ - this(player.getUniqueId(), player.getName()); + super(player); } /** - * Create a new PlayerProfile for a {@link Player} + * Create a new {@link PlayerProfile} for a {@link Player} with default values + * * @param playerUUID target player's UUID * @param playerName target player's name */ public PlayerProfile(@NotNull UUID playerUUID, @NotNull String playerName) { - /* New Data */ - this.persistentPlayerData = new PersistentPlayerData(playerUUID, playerName); - this.experienceManager = new ExperienceManager(persistentPlayerData); - this.cooldownManager = new CooldownManager(persistentPlayerData); + super(playerUUID, playerName); } /** - * Create a PlayerProfile for {@link PersistentPlayerData} + * Initialize an {@link PlayerProfile} for {@link PersistentPlayerData} * This will be used for existing data + * * @param persistentPlayerData target persistent player data */ public PlayerProfile(@NotNull PersistentPlayerData persistentPlayerData) { - this.persistentPlayerData = persistentPlayerData; - this.experienceManager = new ExperienceManager(persistentPlayerData); - this.cooldownManager = new CooldownManager(persistentPlayerData); + super(persistentPlayerData); } /** * Get the saved player name for this profile * @return the saved player name for this profile */ + @Override public @NotNull String getPlayerName() { return getPersistentPlayerData().getPlayerName(); } @@ -162,7 +153,7 @@ public class PlayerProfile implements OfflineMMOPlayer { @Override public int getPowerLevel() { - return persistentPlayerData + return experienceManager.getPowerLevel(); } @Override @@ -171,8 +162,8 @@ public class PlayerProfile implements OfflineMMOPlayer { } @Override - public int getSkillExperience() { - return 0; + public int getSkillExperience(@NotNull Skill skill) { + return persistentPlayerData; } @Override @@ -181,12 +172,12 @@ public class PlayerProfile implements OfflineMMOPlayer { } @Override - public void savePlayerData() { - + public boolean isOnline() { + return false; } @Override public @NotNull MMOPlayerData getMMOPlayerData() { - return null; + return persistentPlayerData; } } diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/CoreRootSkill.java b/src/main/java/com/gmail/nossr50/datatypes/skills/CoreRootSkill.java new file mode 100644 index 000000000..ddecf38ee --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/CoreRootSkill.java @@ -0,0 +1,14 @@ +package com.gmail.nossr50.datatypes.skills; + +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.util.text.StringUtils; +import com.neetgames.mcmmo.skill.RootSkillImpl; +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; + +class CoreRootSkill extends RootSkillImpl { + public CoreRootSkill(@NotNull String skillName) { + super(mcMMO.p.getName(), StringUtils.getCapitalized(skillName), "mcmmo.skills." + skillName.toLowerCase(Locale.ENGLISH)); + } +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/CoreSkillConstants.java b/src/main/java/com/gmail/nossr50/datatypes/skills/CoreSkillConstants.java new file mode 100644 index 000000000..130931734 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/CoreSkillConstants.java @@ -0,0 +1,69 @@ +package com.gmail.nossr50.datatypes.skills; + +import com.google.common.collect.ImmutableSet; +import com.neetgames.mcmmo.skill.SkillIdentity; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Set; + +public class CoreSkillConstants { + + private static final @NotNull ImmutableSet immutableCoreRootSkillSet; + + public static @NotNull CoreRootSkill ACROBATICS, ALCHEMY, ARCHERY, AXES, EXCAVATION, + FISHING, HERBALISM, MINING, REPAIR, SALVAGE, SMELTING, SWORDS, TAMING, UNARMED, + WOODCUTTING, TRIDENTS, CROSSBOWS; + + static { + HashSet rootSkillSet = new HashSet<>(); + + ACROBATICS = new CoreRootSkill("acrobatics"); + ALCHEMY = new CoreRootSkill("alchemy"); + ARCHERY = new CoreRootSkill("archery"); + AXES = new CoreRootSkill("axes"); + EXCAVATION = new CoreRootSkill("excavation"); + FISHING = new CoreRootSkill("fishing"); + HERBALISM = new CoreRootSkill("herbalism"); + MINING = new CoreRootSkill("mining"); + REPAIR = new CoreRootSkill("repair"); + SALVAGE = new CoreRootSkill("salvage"); + SMELTING = new CoreRootSkill("smelting"); + SWORDS = new CoreRootSkill("swords"); + TAMING = new CoreRootSkill("taming"); + UNARMED = new CoreRootSkill("unarmed"); + WOODCUTTING = new CoreRootSkill("woodcutting"); + TRIDENTS = new CoreRootSkill("tridents"); + CROSSBOWS = new CoreRootSkill("crossbows"); + + rootSkillSet.add(ACROBATICS); + rootSkillSet.add(ALCHEMY); + rootSkillSet.add(ARCHERY); + rootSkillSet.add(AXES); + rootSkillSet.add(EXCAVATION); + rootSkillSet.add(FISHING); + rootSkillSet.add(HERBALISM); + rootSkillSet.add(MINING); + rootSkillSet.add(REPAIR); + rootSkillSet.add(SALVAGE); + rootSkillSet.add(SMELTING); + rootSkillSet.add(SWORDS); + rootSkillSet.add(TAMING); + rootSkillSet.add(UNARMED); + rootSkillSet.add(WOODCUTTING); + rootSkillSet.add(TRIDENTS); + rootSkillSet.add(CROSSBOWS); + + immutableCoreRootSkillSet = ImmutableSet.copyOf(rootSkillSet); + } + + /** + * Returns a set of built in skills for mcMMO + * No guarantees for whether or not the skills are registered or active or inactive + * + * @return a set of all root skills built into mcMMO + */ + public static @NotNull Set getImmutableCoreRootSkillSet() { + return immutableCoreRootSkillSet; + } +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/SkillIdentity.java b/src/main/java/com/gmail/nossr50/datatypes/skills/SkillIdentity.java deleted file mode 100644 index afa59ae71..000000000 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/SkillIdentity.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.gmail.nossr50.datatypes.skills; - -import com.google.common.base.Objects; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -//TODO: This documentation is a rough draft and will be rewritten -/** - * Used to identify skills - * The goal of this class is to avoid namespace conflicts and clearly identify a skill with its established relationship to other skills as needed - * - * This class will include representation of the relationship between skills, which includes whether or not one skill is parented by another - * Skills are not aware of their children, but they can be aware of their parents - * You will be able to use the skill register to grab all children of a skill, but no SkillIdentity will be defined with children, the burden of the relationship declaration is on the children - * - * Any skill with a null parent skill within its SkillIdentity will be considered the skill at the top of the food chain, which at this point has been referred to as a {@link PrimarySkill} - * Any skill with a parent will be considered a SubSkill and treated completely differently - * - * Skills with parents do not gain experience, and instead their intended effects will be based on the strength of the parent skill (its level) - * Skills are registered, no two skills can share the same fully qualified name (in this case, a combination of the namespace and skill name) - * - * A fully qualified name is generated based on the namespace and skill name - * @see #genFullyQualifiedName() - */ -public class SkillIdentity { - @NotNull private final String nameSpace; - @NotNull private final String skillName; - @Nullable private final SkillIdentity parentSkill; - - @NotNull private final String fullyQualifiedName; - - public SkillIdentity(@NotNull String nameSpace, @NotNull String skillName, @Nullable SkillIdentity parentSkill) { - this.nameSpace = nameSpace; - this.skillName = skillName; - this.parentSkill = parentSkill; - - fullyQualifiedName = genFullyQualifiedName(); - } - - public SkillIdentity(@NotNull String nameSpace, @NotNull String skillName) { - this.nameSpace = nameSpace; - this.skillName = skillName; - this.parentSkill = null; - - fullyQualifiedName = genFullyQualifiedName(); - } - - /** - * Creates a fully qualified name for this skill - * @return the fully qualified name for this skill - */ - private String genFullyQualifiedName() { - return nameSpace + ":" + "skillName"; - } - - /** - * Whether or not this skill has a parent - * @return true if this skill has a parent - */ - public boolean hasParent() { - return parentSkill != null; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - SkillIdentity that = (SkillIdentity) o; - return Objects.equal(nameSpace, that.nameSpace) && Objects.equal(skillName, that.skillName) && Objects.equal(parentSkill, that.parentSkill) && Objects.equal(fullyQualifiedName, that.fullyQualifiedName); - } - - @Override - public int hashCode() { - return Objects.hashCode(nameSpace, skillName, parentSkill, fullyQualifiedName); - } -} diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/SkillRegisterImpl.java b/src/main/java/com/gmail/nossr50/datatypes/skills/SkillRegisterImpl.java new file mode 100644 index 000000000..47a61cf00 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/SkillRegisterImpl.java @@ -0,0 +1,156 @@ +package com.gmail.nossr50.datatypes.skills; + +import com.gmail.nossr50.mcMMO; +import com.neetgames.mcmmo.api.SkillRegister; +import com.neetgames.mcmmo.skill.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +/** + * Skills mcMMO is aware of are registered here + * The skill register will be used for a few things in mcMMO + * Removing a skill from the register doesn't mean it isn't doing anything as the register is simply for mcMMO's own awareness + * When a player uses certain commands, such as checking their skill levels, if the skill isn't registered it won't be added to the resulting output of that command + */ +public class SkillRegisterImpl implements SkillRegister { + //TODO: Move maps and collections to their own container + private final @NotNull HashMap skillNameMap; + private final @NotNull Set registeredSkills; + private final @NotNull Set superSkills; + private final @NotNull Set rankedSkills; + private final @NotNull Set rootSkills; //Can include not-official root skills + private final @NotNull Set coreRootSkills; //Only includes official root skills + + public SkillRegisterImpl() { + skillNameMap = new HashMap<>(); + registeredSkills = new HashSet<>(); + rootSkills = new HashSet<>(); + superSkills = new HashSet<>(); + rankedSkills = new HashSet<>(); + coreRootSkills = new HashSet<>(); + + //TODO: allow config to turn off certain core skills + registerCoreSkills(); + } + + @Override + public @Nullable Skill getSkill(@NotNull String fullyQualifiedName) { + return skillNameMap.get(fullyQualifiedName); + } + + @Override + public @Nullable Skill getSkill(@NotNull SkillIdentity skillIdentity) { + return skillNameMap.get(skillIdentity.getFullyQualifiedName()); + } + + @Override + public @NotNull Set getSuperSkills() { + return superSkills; + } + + @Override + public @NotNull Set getRankedSkills() { + return rankedSkills; + } + + @Override + public @NotNull Set getRootSkills() { + return rootSkills; + } + + @Override + public boolean isSkillRegistered(@NotNull Skill skill) { + return registeredSkills.contains(skill); + } + + @Override + public void registerSkill(@NotNull Skill skill) { + registeredSkills.add(skill); + addedSkillRegisterProcessing(skill); + } + + @Override + public void registerSkill(@NotNull Skill skill, boolean override) { + if(isSkillRegistered(skill) && override) { + registeredSkills.remove(skill); + } + + registeredSkills.add(skill); + addedSkillRegisterProcessing(skill); + } + + @Override + public @NotNull Set getRegisteredSkills() { + return registeredSkills; + } + + private void postRemovalSkillRegisterProcessing(@NotNull Skill skill) { + removeSkillNameLookup(skill); + removeCollectionCache(skill); + } + + private void removeCollectionCache(@NotNull Skill skill) { + //Add to collections for cached lookups + if(skill instanceof RootSkill) { + rootSkills.remove(skill); + } else if (skill instanceof SuperSkill) { + superSkills.remove(skill); + } else if(skill instanceof RankedSkill) { + rankedSkills.remove( skill); + } + } + + private void removeSkillNameLookup(@NotNull Skill skill) { + skillNameMap.remove(skill.getSkillIdentity().getFullyQualifiedName()); + } + + private void addedSkillRegisterProcessing(@NotNull Skill skill) { + addSkillNameLookup(skill); + addCollectionCache(skill); + } + + private void addCollectionCache(@NotNull Skill skill) { + //Add to various collections for cached lookups + if(skill instanceof CoreRootSkill) { + coreRootSkills.add((CoreRootSkill) skill); + } + + if(skill instanceof RootSkill) { + rootSkills.add((RootSkill) skill); + } else if (skill instanceof SuperSkill) { + superSkills.add((SuperSkill) skill); + } else if(skill instanceof RankedSkill) { + rankedSkills.add((RankedSkill) skill); + } + } + + private void addSkillNameLookup(@NotNull Skill skill) { + skillNameMap.put(skill.getSkillIdentity().getFullyQualifiedName(), skill); + } + + @Override + public void unregisterSkill(@NotNull Skill skill) { + mcMMO.p.getLogger().info("Skill "+skill.toString()+" has been removed from the skill register."); + registeredSkills.remove(skill); + skillNameMap.remove(skill.getSkillIdentity().getFullyQualifiedName()); + + //Collection cache cleanup + postRemovalSkillRegisterProcessing(skill); + } + + private void registerCoreSkills() { + for(CoreRootSkill coreRootSkill : CoreSkillConstants.getImmutableCoreRootSkillSet()) { + mcMMO.p.getLogger().info("Registering core skill: "+coreRootSkill.getSkillName()); + registerSkill(coreRootSkill); + } + } + + @Override + public @NotNull Set getCoreRootSkills() { + return coreRootSkills; + } +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/ChildSkill.java b/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/ChildSkill.java deleted file mode 100644 index 0bfee0108..000000000 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/ChildSkill.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.gmail.nossr50.datatypes.skills.interfaces; - -import com.gmail.nossr50.datatypes.skills.PrimarySkillType; - -public interface ChildSkill extends Skill { - /** - * Get's the other parent for this Skill - * @return the other parent - */ - PrimarySkillType getSecondParent(); -} diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/CoreSkill.java b/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/CoreSkill.java deleted file mode 100644 index 51d4913ce..000000000 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/CoreSkill.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gmail.nossr50.datatypes.skills.interfaces; - -import com.gmail.nossr50.datatypes.skills.SubSkillType; - -/** - * This interface is mostly here to maintain backwards compatibility with other mcMMO plugins - * Only Core Skills will make use of this - * Previously in mcMMO subskills were basically defined by the SecondaryAbility ENUM - * In the new system which I'm gradually converting all the existing skills to, skills instead are unique instances of AbstractSubSkill - */ -public interface CoreSkill { - /** - * Gets the associated SubSkillType for this subskill - * @return the associated SubSkillType ENUM definition - */ - SubSkillType getSubSkillType(); -} diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/Localized.java b/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/Localized.java deleted file mode 100644 index 468e19c1d..000000000 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/Localized.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.gmail.nossr50.datatypes.skills.interfaces; - -/** - * Localized interface represents skills which have localizations - * Skills with localizations will use their localization names/descriptions when being printed - */ -public interface Localized { - /** - * The translated name for this locale - * @return the translated name for this locale - */ - String getLocaleName(); - - /** - * The translated name for this subskill description - * @return - */ - String getLocaleDescription(); -} diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/Skill.java b/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/Skill.java deleted file mode 100644 index 68cf7180e..000000000 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/Skill.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gmail.nossr50.datatypes.skills.interfaces; - -import com.gmail.nossr50.datatypes.skills.PrimarySkillType; - -public interface Skill { - /** - * The primary skill - * @return this primary skill - */ - PrimarySkillType getPrimarySkill(); - - /** - * Returns the key name used for this skill in conjunction with config files - * @return config file key name - */ - String getPrimaryKeyName(); -} diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/Toolable.java b/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/Toolable.java deleted file mode 100644 index 7b817bea1..000000000 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/interfaces/Toolable.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gmail.nossr50.datatypes.skills.interfaces; - -import org.bukkit.inventory.ItemStack; - -import java.util.Collection; - -public interface Toolable { - /** - * Whether or not this Skill requires a tool - * Not all skills will require a tool - * @return true if tool is required - */ - boolean requiresTool(); - - /** - * The tools associated with this Skill - * @return the tools - */ - Collection getTools(); -} diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 72a9686da..afe8c7740 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -11,6 +11,7 @@ import com.gmail.nossr50.config.treasure.TreasureConfig; import com.gmail.nossr50.database.DatabaseManager; import com.gmail.nossr50.database.DatabaseManagerFactory; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; +import com.gmail.nossr50.datatypes.skills.SkillRegisterImpl; import com.gmail.nossr50.datatypes.skills.subskills.acrobatics.Roll; import com.gmail.nossr50.listeners.*; import com.gmail.nossr50.party.PartyManager; @@ -48,6 +49,7 @@ import com.gmail.nossr50.util.skills.SmeltingTracker; import com.gmail.nossr50.util.upgrade.UpgradeManager; import com.gmail.nossr50.worldguard.WorldGuardManager; import com.google.common.base.Charsets; +import com.neetgames.mcmmo.api.SkillRegister; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.shatteredlands.shatt.backup.ZipLibrary; import org.bstats.bukkit.Metrics; @@ -86,6 +88,7 @@ public class mcMMO extends JavaPlugin { private static TransientMetadataTools transientMetadataTools; private static ChatManager chatManager; private static CommandManager commandManager; //ACF + private static SkillRegister skillRegister; /* Adventure */ private static BukkitAudiences audiences; @@ -154,6 +157,9 @@ public class mcMMO extends JavaPlugin { @Override public void onEnable() { try { + //Skill Register + skillRegister = new SkillRegisterImpl(); + //Platform Manager platformManager = new PlatformManager(); @@ -182,7 +188,6 @@ public class mcMMO extends JavaPlugin { //Store this value so other plugins can check it isRetroModeEnabled = Config.getInstance().getIsRetroMode(); - if(projectKorraEnabled) { getLogger().info("ProjectKorra was detected, this can cause some issues with weakness potions and combat skills for mcMMO"); } @@ -694,4 +699,6 @@ public class mcMMO extends JavaPlugin { public CommandManager getCommandManager() { return commandManager; } + + public SkillRegister getSkillRegister() { return skillRegister; } } diff --git a/src/main/java/com/gmail/nossr50/util/experience/ExperienceBarWrapper.java b/src/main/java/com/gmail/nossr50/util/experience/ExperienceBarWrapper.java index 6039947e7..f2bb34265 100644 --- a/src/main/java/com/gmail/nossr50/util/experience/ExperienceBarWrapper.java +++ b/src/main/java/com/gmail/nossr50/util/experience/ExperienceBarWrapper.java @@ -6,10 +6,13 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.util.player.PlayerLevelUtils; import com.gmail.nossr50.util.text.StringUtils; +import com.neetgames.mcmmo.player.MMOPlayerData; +import com.neetgames.mcmmo.player.OnlineMMOPlayer; import org.bukkit.boss.BarColor; import org.bukkit.boss.BarStyle; import org.bukkit.boss.BossBar; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -18,9 +21,9 @@ import java.util.List; */ public class ExperienceBarWrapper { - private final PrimarySkillType primarySkillType; //Primary Skill - private BossBar bossBar; - protected final PersistentPlayerData persistentPlayerData; + private final @NotNull PrimarySkillType primarySkillType; //Primary Skill + private @NotNull BossBar bossBar; + protected final @NotNull MMOPlayerData mmoPlayerData; private int lastLevelUpdated; /* @@ -29,9 +32,8 @@ public class ExperienceBarWrapper { protected String niceSkillName; protected String title; - public ExperienceBarWrapper(PrimarySkillType primarySkillType, PersistentPlayerData persistentPlayerData) - { - this.persistentPlayerData = persistentPlayerData; + public ExperienceBarWrapper(@NotNull PrimarySkillType primarySkillType, @NotNull OnlineMMOPlayer mmoPlayer) { + this.mmoPlayerData = mmoPlayer.getMMOPlayerData(); this.primarySkillType = primarySkillType; title = ""; lastLevelUpdated = 0; @@ -43,8 +45,7 @@ public class ExperienceBarWrapper { initBar(); } - private void initBar() - { + private void initBar() { title = getTitleTemplate(); createBossBar(); } diff --git a/src/main/java/com/gmail/nossr50/util/player/PlayerLevelUtils.java b/src/main/java/com/gmail/nossr50/util/player/PlayerLevelUtils.java index 211602578..6096f6271 100644 --- a/src/main/java/com/gmail/nossr50/util/player/PlayerLevelUtils.java +++ b/src/main/java/com/gmail/nossr50/util/player/PlayerLevelUtils.java @@ -3,34 +3,10 @@ package com.gmail.nossr50.util.player; import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.mcMMO; +import org.jetbrains.annotations.NotNull; public class PlayerLevelUtils { -// HashMap earlyGameBoostCutoffs; -// -// public PlayerLevelUtils() -// { -// earlyGameBoostCutoffs = new HashMap<>(); -// calculateEarlyGameBoostCutoffs(); -// } -// private void calculateEarlyGameBoostCutoffs() -// { -// for(PrimarySkillType primarySkillType : PrimarySkillType.values()) -// { -// int levelCap = Config.getInstance().getLevelCap(primarySkillType); -// int cap; -// -// if(levelCap == Integer.MAX_VALUE || levelCap <= 0) -// { -// cap = Config.getInstance().getIsRetroMode() ? 50 : 5; -// } else { -// cap = (int) (levelCap * ExperienceConfig.getInstance().getEarlyGameBoostMultiplier()); -// } -// -// earlyGameBoostCutoffs.put(primarySkillType, cap); -// } -// } - - public int getEarlyGameCutoff(PrimarySkillType primarySkillType) + public int getEarlyGameCutoff(@NotNull PrimarySkillType primarySkillType) { return 1; } @@ -42,7 +18,7 @@ public class PlayerLevelUtils { * @param primarySkillType target skill * @return if the player would qualify for the XP boost if its enabled */ - public static boolean qualifiesForEarlyGameBoost(McMMOPlayer mmoPlayer, PrimarySkillType primarySkillType) { + public static boolean qualifiesForEarlyGameBoost(@NotNull McMMOPlayer mmoPlayer, @NotNull PrimarySkillType primarySkillType) { return mmoPlayer.getSkillLevel(primarySkillType) < mcMMO.getPlayerLevelUtils().getEarlyGameCutoff(primarySkillType); } }