From 450d09e9e483a679ea110d3205ef45e0ccd2b95f Mon Sep 17 00:00:00 2001 From: nossr50 Date: Mon, 16 Nov 2020 13:43:47 -0800 Subject: [PATCH] wip expmanager/party/mcmmo player rewrites --- .../commands/party/PartyCreateCommand.java | 2 +- .../commands/party/PartyRenameCommand.java | 2 +- .../nossr50/database/SQLDatabaseManager.java | 2 + .../datatypes/player/ExperienceManager.java | 332 +++++++++--------- .../nossr50/datatypes/player/McMMOPlayer.java | 20 ++ .../player/PersistentPlayerData.java | 9 + .../datatypes/player/PlayerProfile.java | 7 +- .../com/gmail/nossr50/party/PartyManager.java | 45 ++- .../com/gmail/nossr50/party/ShareHandler.java | 16 +- .../util/experience/ExperienceUtils.java | 46 +++ 10 files changed, 299 insertions(+), 182 deletions(-) create mode 100644 src/main/java/com/gmail/nossr50/util/experience/ExperienceUtils.java diff --git a/src/main/java/com/gmail/nossr50/commands/party/PartyCreateCommand.java b/src/main/java/com/gmail/nossr50/commands/party/PartyCreateCommand.java index 5d34437b7..cc03740ef 100644 --- a/src/main/java/com/gmail/nossr50/commands/party/PartyCreateCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/party/PartyCreateCommand.java @@ -25,7 +25,7 @@ public class PartyCreateCommand implements CommandExecutor { } // Check to see if the party exists, and if it does cancel creating a new party - if (mcMMO.getPartyManager().checkPartyExistence(args[1])) { + if (mcMMO.getPartyManager().isParty(args[1])) { player.sendMessage(LocaleLoader.getString("Commands.Party.AlreadyExists", args[1])); return true; } diff --git a/src/main/java/com/gmail/nossr50/commands/party/PartyRenameCommand.java b/src/main/java/com/gmail/nossr50/commands/party/PartyRenameCommand.java index ebc188e33..9096b4d4d 100644 --- a/src/main/java/com/gmail/nossr50/commands/party/PartyRenameCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/party/PartyRenameCommand.java @@ -36,7 +36,7 @@ public class PartyRenameCommand implements CommandExecutor { Player player = mmoPlayer.getPlayer(); // Check to see if the party exists, and if it does cancel renaming the party - if (mcMMO.getPartyManager().checkPartyExistence(newPartyName)) { + if (mcMMO.getPartyManager().isParty(newPartyName)) { player.sendMessage(LocaleLoader.getString("Commands.Party.AlreadyExists", newPartyName)); return true; } diff --git a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java index 82d4b36e5..e8c6bf5ea 100644 --- a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java @@ -602,10 +602,12 @@ public final class SQLDatabaseManager extends AbstractDatabaseManager { @Override public @Nullable PlayerProfile queryPlayerDataByPlayer(@NotNull Player player) throws ProfileRetrievalException, NullArgumentException { + return loadPlayerProfile(player, player.getName(), player.getUniqueId()); } @Override public @Nullable PlayerProfile queryPlayerDataByUUID(@NotNull UUID uuid, @NotNull String playerName) throws ProfileRetrievalException, NullArgumentException { + return loadPlayerProfile(null, playerName, uuid); } private @Nullable PlayerProfile loadPlayerProfile(@Nullable Player player, @NotNull String playerName, @Nullable UUID playerUUID) { diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/ExperienceManager.java b/src/main/java/com/gmail/nossr50/datatypes/player/ExperienceManager.java index 8619aefbe..ce5eb5e9a 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/ExperienceManager.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/ExperienceManager.java @@ -6,11 +6,13 @@ import com.gmail.nossr50.datatypes.experience.FormulaType; import com.gmail.nossr50.datatypes.experience.SkillXpGain; import com.gmail.nossr50.datatypes.experience.XPGainReason; import com.gmail.nossr50.datatypes.experience.XPGainSource; +import com.gmail.nossr50.datatypes.party.Party; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.party.ShareHandler; import com.gmail.nossr50.skills.child.FamilyTree; import com.gmail.nossr50.util.EventUtils; +import com.gmail.nossr50.util.experience.ExperienceUtils; import com.gmail.nossr50.util.player.NotificationManager; import com.gmail.nossr50.util.skills.PerksUtils; import com.gmail.nossr50.util.sounds.SoundManager; @@ -20,6 +22,8 @@ import org.apache.commons.lang.Validate; import org.bukkit.GameMode; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Set; @@ -27,10 +31,12 @@ public class ExperienceManager { private boolean isUsingUnarmed = false; - private final PersistentPlayerData persistentPlayerDataRef; + private final @NotNull PersistentPlayerData persistentPlayerDataRef; + private final @NotNull McMMOPlayer mmoPlayer; - public ExperienceManager(PersistentPlayerData persistentPlayerData) { - this.persistentPlayerDataRef = persistentPlayerData; + public ExperienceManager(@NotNull McMMOPlayer mmoPlayer) { + this.mmoPlayer = mmoPlayer; + this.persistentPlayerDataRef = mmoPlayer.getPersistentPlayerData(); } /** @@ -64,7 +70,7 @@ public class ExperienceManager { * @param primarySkillType target skill * @return the value for XP the player has accumulated in target skill */ - public int getSkillXpValue(PrimarySkillType primarySkillType) { + public int getSkillXpValue(@NotNull PrimarySkillType primarySkillType) { if(primarySkillType.isChildSkill()) { return 0; } @@ -72,21 +78,19 @@ public class ExperienceManager { return (int) Math.floor(getSkillXpLevelRaw(primarySkillType)); } - public void setSkillXpValue(PrimarySkillType skill, float xpLevel) { - if (skill.isChildSkill()) { + public void setSkillXpValue(@NotNull PrimarySkillType primarySkillType, float xpLevel) { + if (primarySkillType.isChildSkill()) { return; } - persistentPlayerDataRef.getSkillsExperienceMap().put(skill, xpLevel); + persistentPlayerDataRef.getSkillsExperienceMap().put(primarySkillType, xpLevel); } - public float levelUp(PrimarySkillType skill) { - float xpRemoved = getXpToLevel(skill); + public float levelUp(@NotNull PrimarySkillType primarySkillType) { + float xpRemoved = getXpToLevel(primarySkillType); - markProfileDirty(); - - skills.put(skill, skills.get(skill) + 1); - skillsXp.put(skill, skillsXp.get(skill) - xpRemoved); + setSkillLevel(primarySkillType, getSkillLevel(primarySkillType) + 1); + setSkillXpValue(primarySkillType, getSkillXpValue(primarySkillType) - xpRemoved); return xpRemoved; } @@ -94,14 +98,15 @@ public class ExperienceManager { /** * Whether or not a player is level capped * If they are at the power level cap, this will return true, otherwise it checks their skill level + * * @param primarySkillType * @return */ - public boolean hasReachedLevelCap(PrimarySkillType primarySkillType) { + public boolean hasReachedLevelCap(@NotNull PrimarySkillType primarySkillType) { if(hasReachedPowerLevelCap()) return true; - return playerDataRef.getSkillLevel(primarySkillType) >= Config.getInstance().getLevelCap(primarySkillType); + return getSkillLevel(primarySkillType) >= Config.getInstance().getLevelCap(primarySkillType); } /** @@ -119,7 +124,7 @@ public class ExperienceManager { * @param primarySkillType Skill being used * @param xp Experience amount to process */ - public void beginXpGain(Player player, PrimarySkillType primarySkillType, float xp, XPGainReason xpGainReason, XPGainSource xpGainSource) { + public void beginXpGain(@NotNull PrimarySkillType primarySkillType, float xp, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) { Validate.isTrue(xp >= 0.0, "XP gained should be greater than or equal to zero."); if (xp <= 0.0) { @@ -131,137 +136,45 @@ public class ExperienceManager { float splitXp = xp / parentSkills.size(); for (PrimarySkillType parentSkill : parentSkills) { - beginXpGain(player, parentSkill, splitXp, xpGainReason, xpGainSource); + beginXpGain(parentSkill, splitXp, xpGainReason, xpGainSource); } return; } + //TODO: The logic here is so stupid... rewrite later + // Return if the experience has been shared - if (party != null && ShareHandler.handleXpShare(xp, this, primarySkillType, ShareHandler.getSharedXpGainReason(xpGainReason))) { + if (mmoPlayer.getParty() != null && ShareHandler.handleXpShare(xp, mmoPlayer, mmoPlayer.getParty(), primarySkillType, ShareHandler.getSharedXpGainReason(xpGainReason))) { return; } - beginUnsharedXpGain(player, primarySkillType, xp, xpGainReason, xpGainSource); + beginUnsharedXpGain(primarySkillType, xp, xpGainReason, xpGainSource); } /** - * Begins an experience gain. The amount will be affected by skill modifiers, global rate and perks - * - * @param skill Skill being used - * @param xp Experience amount to process - */ - public void beginUnsharedXpGain(Player player, PrimarySkillType skill, float xp, XPGainReason xpGainReason, XPGainSource xpGainSource) { - if(player.getGameMode() == GameMode.CREATIVE) - return; - - applyXpGain(skill, modifyXpGain(player, skill, xp), xpGainReason, xpGainSource); - - if (party == null) { - return; - } - - if (!Config.getInstance().getPartyXpNearMembersNeeded() || !mcMMO.getPartyManager().getNearMembers(this).isEmpty()) { - party.applyXpGain(modifyXpGain(player, skill, xp)); - } - } - - /** - * Applies an experience gain + * Begins an experience gain. The amount will be affected by primarySkillType modifiers, global rate and perks * * @param primarySkillType Skill being used - * @param xp Experience amount to add + * @param xp Experience amount to process */ - public void applyXpGain(Player player, PrimarySkillType primarySkillType, float xp, XPGainReason xpGainReason, XPGainSource xpGainSource) { - if (!primarySkillType.getPermissions(player)) { + public void beginUnsharedXpGain(@NotNull PrimarySkillType primarySkillType, float xp, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) { + if(mmoPlayer.getPlayer().getGameMode() == GameMode.CREATIVE) return; - } - if (primarySkillType.isChildSkill()) { - Set parentSkills = FamilyTree.getParents(primarySkillType); + ExperienceUtils.applyXpGain(mmoPlayer, primarySkillType, modifyXpGain(primarySkillType, xp), xpGainReason, xpGainSource); - for (PrimarySkillType parentSkill : parentSkills) { - applyXpGain(player, parentSkill, xp / parentSkills.size(), xpGainReason, xpGainSource); + Party party = mmoPlayer.getParty(); + + if (party != null) { + if (!Config.getInstance().getPartyXpNearMembersNeeded() || !mcMMO.getPartyManager().getNearMembers(mmoPlayer).isEmpty()) { + party.getPartyExperienceManager().applyXpGain(modifyXpGain(primarySkillType, xp)); } - - return; } - - if (!EventUtils.handleXpGainEvent(player, primarySkillType, xp, xpGainReason)) { - return; - } - - isUsingUnarmed = (primarySkillType == PrimarySkillType.UNARMED); - checkXp(primarySkillType, xpGainReason, xpGainSource); } - /** - * Check the XP of a skill. - * - * @param primarySkillType The skill to check - */ - private void checkXp(McMMOPlayer mmoPlayer, PrimarySkillType primarySkillType, XPGainReason xpGainReason, XPGainSource xpGainSource) { - if(hasReachedLevelCap(primarySkillType)) - return; - - if (getSkillXpLevelRaw(primarySkillType) < getXpToLevel(primarySkillType)) { - processPostXpEvent(mmoPlayer.getPlayer(), primarySkillType, mcMMO.p, xpGainSource); - return; - } - - int levelsGained = 0; - float xpRemoved = 0; - - while (getSkillXpLevelRaw(primarySkillType) >= getXpToLevel(primarySkillType)) { - if (hasReachedLevelCap(primarySkillType)) { - setSkillXpValue(primarySkillType, 0); - break; - } - - xpRemoved += levelUp(primarySkillType); - levelsGained++; - } - - if (EventUtils.tryLevelChangeEvent(mmoPlayer.getPlayer(), primarySkillType, levelsGained, xpRemoved, true, xpGainReason)) { - return; - } - - if (Config.getInstance().getLevelUpSoundsEnabled()) { - SoundManager.sendSound(mmoPlayer.getPlayer(), mmoPlayer.getPlayer().getLocation(), SoundType.LEVEL_UP); - } - - /* - * Check to see if the player unlocked any new skills - */ - - NotificationManager.sendPlayerLevelUpNotification(player, primarySkillType, levelsGained, getSkillLevel(primarySkillType)); - - //UPDATE XP BARS - processPostXpEvent(player, primarySkillType, mcMMO.p, xpGainSource); - } - - public void processPostXpEvent(McMMOPlayer mmoPlayer, PrimarySkillType primarySkillType, Plugin plugin, XPGainSource xpGainSource) - { - //Check if they've reached the power level cap just now - if(hasReachedPowerLevelCap()) { - NotificationManager.sendPlayerInformationChatOnly(mmoPlayer.getPlayer(), "LevelCap.PowerLevel", String.valueOf(Config.getInstance().getPowerLevelCap())); - } else if(hasReachedLevelCap(primarySkillType)) { - NotificationManager.sendPlayerInformationChatOnly(mmoPlayer.getPlayer(), "LevelCap.Skill", String.valueOf(Config.getInstance().getLevelCap(primarySkillType)), primarySkillType.getName()); - } - - //Updates from Party sources - if(xpGainSource == XPGainSource.PARTY_MEMBERS && !ExperienceConfig.getInstance().isPartyExperienceBarsEnabled()) - return; - - //Updates from passive sources (Alchemy, Smelting, etc...) - if(xpGainSource == XPGainSource.PASSIVE && !ExperienceConfig.getInstance().isPassiveGainsExperienceBarsEnabled()) - return; - - mmoPlayer.updateXPBar(primarySkillType, plugin); - } - - public int getSkillLevel(PrimarySkillType skill) { - return skill.isChildSkill() ? getChildSkillLevel(skill) : skills.get(skill); + public int getSkillLevel(@NotNull PrimarySkillType skill) { + return skill.isChildSkill() ? getChildSkillLevel(skill) : getSkillLevel(skill); } /** @@ -270,18 +183,18 @@ public class ExperienceManager { * @param primarySkillType Type of skill to check * @return the total amount of Xp until next level */ - public int getXpToLevel(PrimarySkillType primarySkillType) { + public int getXpToLevel(@NotNull PrimarySkillType primarySkillType) { if(primarySkillType.isChildSkill()) { return 0; } - int level = (ExperienceConfig.getInstance().getCumulativeCurveEnabled()) ? getPowerLevel() : playerDataRef..get(primarySkillType); + int level = (ExperienceConfig.getInstance().getCumulativeCurveEnabled()) ? getPowerLevel() : getSkillLevel(primarySkillType); FormulaType formulaType = ExperienceConfig.getInstance().getFormulaType(); return mcMMO.getFormulaManager().getXPtoNextLevel(level, formulaType); } - private int getChildSkillLevel(PrimarySkillType primarySkillType) { + private int getChildSkillLevel(@NotNull PrimarySkillType primarySkillType) { Set parents = FamilyTree.getParents(primarySkillType); int sum = 0; @@ -302,14 +215,12 @@ public class ExperienceManager { * @param skill Type of skill to modify * @param xp Amount of xp to remove */ - public void removeXp(PrimarySkillType skill, int xp) { + public void removeXp(@NotNull PrimarySkillType skill, int xp) { if (skill.isChildSkill()) { return; } - markProfileDirty(); - - skillsXp.put(skill, skillsXp.get(skill) - xp); + setSkillXpValue(skill, getSkillXpValue(skill) - xp); } public void removeXp(PrimarySkillType skill, float xp) { @@ -317,19 +228,17 @@ public class ExperienceManager { return; } - markProfileDirty(); - - skillsXp.put(skill, skillsXp.get(skill) - xp); + setSkillXpValue(skill, getSkillXpValue(skill) - xp); } /** - * Modify a skill level. + * Modify a primarySkillType level. * - * @param skill Type of skill to modify - * @param level New level value for the skill + * @param primarySkillType Type of primarySkillType to modify + * @param level New level value for the primarySkillType */ - public void setSkillLevel(PrimarySkillType skill, int level) { - if (skill.isChildSkill()) { + public void setSkillLevel(@NotNull PrimarySkillType primarySkillType, int level) { + if (primarySkillType.isChildSkill()) { return; } @@ -337,39 +246,37 @@ public class ExperienceManager { if(level < 0) level = 0; - skills.put(skill, level); - skillsXp.put(skill, 0F); + setSkillLevel(primarySkillType, level); + setSkillXpValue(primarySkillType, 0F); } /** - * Add levels to a skill. + * Add levels to a primarySkillType. * - * @param skill Type of skill to add levels to + * @param primarySkillType Type of primarySkillType to add levels to * @param levels Number of levels to add */ - public void addLevels(PrimarySkillType skill, int levels) { - setSkillLevel(skill, skills.get(skill) + levels); + public void addLevels(@NotNull PrimarySkillType primarySkillType, int levels) { + setSkillLevel(primarySkillType, getSkillLevel(primarySkillType) + levels); } /** - * Add Experience to a skill. + * Add Experience to a primarySkillType. * - * @param skill Type of skill to add experience to + * @param primarySkillType Type of primarySkillType to add experience to * @param xp Number of experience to add */ - public void addXp(PrimarySkillType skill, float xp) { - markProfileDirty(); - - if (skill.isChildSkill()) { - Set parentSkills = FamilyTree.getParents(skill); + public void addXp(@NotNull PrimarySkillType primarySkillType, float xp) { + if (primarySkillType.isChildSkill()) { + Set parentSkills = FamilyTree.getParents(primarySkillType); float dividedXP = (xp / parentSkills.size()); for (PrimarySkillType parentSkill : parentSkills) { - skillsXp.put(parentSkill, skillsXp.get(parentSkill) + dividedXP); + setSkillXpValue(parentSkill, getSkillXpValue(parentSkill) + dividedXP); } } else { - skillsXp.put(skill, skillsXp.get(skill) + xp); + setSkillXpValue(primarySkillType, getSkillXpValue(primarySkillType) + xp); } } @@ -379,7 +286,7 @@ public class ExperienceManager { * * @return xp Experience amount registered */ - public float getRegisteredXpGain(PrimarySkillType primarySkillType) { + public float getRegisteredXpGain(@NotNull PrimarySkillType primarySkillType) { float xp = 0F; if (rollingSkillsXp.get(primarySkillType) != null) { @@ -396,7 +303,7 @@ public class ExperienceManager { * @param primarySkillType Skill being used * @param xp Experience amount to add */ - public void registerXpGain(PrimarySkillType primarySkillType, float xp) { + public void registerXpGain(@NotNull PrimarySkillType primarySkillType, float xp) { gainedSkillsXp.add(new SkillXpGain(primarySkillType, xp)); rollingSkillsXp.put(primarySkillType, getRegisteredXpGain(primarySkillType) + xp); } @@ -412,14 +319,6 @@ public class ExperienceManager { } } - public ImmutableMap copyPrimarySkillLevelsMap() { - return ImmutableMap.copyOf(primarySkillLevelMap); - } - - public ImmutableMap copyPrimarySkillExperienceValuesMap() { - return ImmutableMap.copyOf(primarySkillCurrentExpMap); - } - /** * Modifies an experience gain using skill modifiers, global rate and perks * @@ -427,14 +326,14 @@ public class ExperienceManager { * @param xp Experience amount to process * @return Modified experience */ - private float modifyXpGain(Player player, PrimarySkillType primarySkillType, float xp) { + private float modifyXpGain(PrimarySkillType primarySkillType, float xp) { if ((primarySkillType.getMaxLevel() <= getSkillLevel(primarySkillType)) || (Config.getInstance().getPowerLevelCap() <= getPowerLevel())) { return 0; } xp = (float) (xp / primarySkillType.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()); - return PerksUtils.handleXpPerks(player, xp, primarySkillType); + return PerksUtils.handleXpPerks(mmoPlayer.getPlayer(), xp, primarySkillType); } public double getProgressInCurrentSkillLevel(PrimarySkillType primarySkillType) @@ -449,5 +348,104 @@ public class ExperienceManager { return (currentXP / maxXP); } + public void setUsingUnarmed(boolean bool) { + isUsingUnarmed = bool; + } + + /** + * Applies an experience gain + * + * @param primarySkillType Skill being used + * @param xp Experience amount to add + */ + public void applyXpGain(@NotNull PrimarySkillType primarySkillType, float xp, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) { + if (!primarySkillType.getPermissions(mmoPlayer.getPlayer())) { + return; + } + + if (primarySkillType.isChildSkill()) { + Set parentSkills = FamilyTree.getParents(primarySkillType); + + for (PrimarySkillType parentSkill : parentSkills) { + applyXpGain(mmoPlayer, parentSkill, xp / parentSkills.size(), xpGainReason, xpGainSource); + } + + return; + } + + if (!EventUtils.handleXpGainEvent(mmoPlayer.getPlayer(), primarySkillType, xp, xpGainReason)) { + return; + } + + mmoPlayer.getExperienceManager().setUsingUnarmed(primarySkillType == PrimarySkillType.UNARMED); + updateLevelStats(mmoPlayer, primarySkillType, xpGainReason, xpGainSource); + } + + public void processPostXpEvent(@NotNull PrimarySkillType primarySkillType, @NotNull Plugin plugin, @NotNull XPGainSource xpGainSource) + { + //Check if they've reached the power level cap just now + if(mmoPlayer.getExperienceManager().hasReachedPowerLevelCap()) { + NotificationManager.sendPlayerInformationChatOnly(mmoPlayer.getPlayer(), "LevelCap.PowerLevel", String.valueOf(Config.getInstance().getPowerLevelCap())); + } else if(mmoPlayer.getExperienceManager().hasReachedLevelCap(primarySkillType)) { + NotificationManager.sendPlayerInformationChatOnly(mmoPlayer.getPlayer(), "LevelCap.Skill", String.valueOf(Config.getInstance().getLevelCap(primarySkillType)), primarySkillType.getName()); + } + + //Updates from Party sources + if(xpGainSource == XPGainSource.PARTY_MEMBERS && !ExperienceConfig.getInstance().isPartyExperienceBarsEnabled()) + return; + + //Updates from passive sources (Alchemy, Smelting, etc...) + if(xpGainSource == XPGainSource.PASSIVE && !ExperienceConfig.getInstance().isPassiveGainsExperienceBarsEnabled()) + return; + + mmoPlayer.updateXPBar(primarySkillType, plugin); + } + + /** + * Updates a players level + * + * @param primarySkillType The skill to check + */ + public void updateLevelStats(@NotNull PrimarySkillType primarySkillType, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) { + ExperienceManager em = mmoPlayer.getExperienceManager(); + if(em.hasReachedLevelCap(primarySkillType)) + return; + + if (em.getSkillXpLevelRaw(primarySkillType) < em.getXpToLevel(primarySkillType)) { + processPostXpEvent(mmoPlayer, primarySkillType, mcMMO.p, xpGainSource); + return; + } + + int levelsGained = 0; + float xpRemoved = 0; + + while (em.getSkillXpLevelRaw(primarySkillType) >= em.getXpToLevel(primarySkillType)) { + if (em.hasReachedLevelCap(primarySkillType)) { + em.setSkillXpValue(primarySkillType, 0); + break; + } + + xpRemoved += em.levelUp(primarySkillType); + levelsGained++; + } + + if (EventUtils.tryLevelChangeEvent(mmoPlayer.getPlayer(), primarySkillType, levelsGained, xpRemoved, true, xpGainReason)) { + return; + } + + if (Config.getInstance().getLevelUpSoundsEnabled()) { + SoundManager.sendSound(mmoPlayer.getPlayer(), mmoPlayer.getPlayer().getLocation(), SoundType.LEVEL_UP); + } + + /* + * Check to see if the player unlocked any new skills + */ + + NotificationManager.sendPlayerLevelUpNotification(mmoPlayer, primarySkillType, levelsGained, em.getSkillLevel(primarySkillType)); + + //UPDATE XP BARS + processPostXpEvent(mmoPlayer, primarySkillType, mcMMO.p, xpGainSource); + } + } 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 3e86e20cf..33bae343b 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java @@ -9,6 +9,7 @@ import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.datatypes.chat.ChatChannel; import com.gmail.nossr50.datatypes.experience.XPGainSource; import com.gmail.nossr50.datatypes.interactions.NotificationType; +import com.gmail.nossr50.datatypes.party.Party; import com.gmail.nossr50.datatypes.party.PartyTeleportRecord; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType; @@ -58,6 +59,7 @@ import java.util.UUID; public class McMMOPlayer extends PlayerProfile implements Identified { private final @NotNull Player player; private final @NotNull Identity identity; + private @Nullable Party playerPartyRef; //Used in our chat systems for chat messages private final @NotNull PlayerAuthor playerAuthor; @@ -117,6 +119,8 @@ public class McMMOPlayer extends PlayerProfile implements Identified { chatSpy = true; } + assignParty(); + //Update last login updateLastLogin(); @@ -167,10 +171,18 @@ public class McMMOPlayer extends PlayerProfile implements Identified { chatSpy = true; } + assignParty(); + //Update last login updateLastLogin(); } + private void assignParty() { + if(mcMMO.getPartyManager() != null) { + + } + } + /** * Update the last login to the current system time */ @@ -590,4 +602,12 @@ public class McMMOPlayer extends PlayerProfile implements Identified { public void setChatMode(@NotNull ChatChannel chatChannel) { this.chatChannel = chatChannel; } + + /** + * Gets the {@link Party} for the player if it exists + * @return the player's party or null if one doesn't exist + */ + public @Nullable Party getPlayerPartyRef() { + return playerPartyRef; + } } 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 f430b565e..5a87d049e 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PersistentPlayerData.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PersistentPlayerData.java @@ -16,6 +16,7 @@ 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.util.experience.MMOExperienceBarManager; +import com.google.common.collect.ImmutableMap; import org.apache.commons.lang.NullArgumentException; import org.jetbrains.annotations.NotNull; @@ -453,4 +454,12 @@ public class PersistentPlayerData { public void setLeaderBoardExclusion(boolean bool) { leaderBoardExclusion.getData(true).setBoolean(bool); } + + public ImmutableMap copyPrimarySkillLevelsMap() { + return ImmutableMap.copyOf(getSkillLevelsMap()); + } + + public ImmutableMap copyPrimarySkillExperienceValuesMap() { + return ImmutableMap.copyOf(getSkillsExperienceMap()); + } } 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 8040288fe..05f4203d7 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java @@ -137,8 +137,13 @@ public class PlayerProfile { return cooldownManager; } + /** + * Attempt to get a party for this PlayerProfile + * @return get a party for this PlayerProfile + */ public @Nullable Party getParty(){ - return mcMMO.getPartyManager().getParty(persistentPlayerData.getPlayerUUID()); + //TODO: This can be optimized + return mcMMO.getPartyManager().queryParty(persistentPlayerData.getPlayerUUID()); } /** diff --git a/src/main/java/com/gmail/nossr50/party/PartyManager.java b/src/main/java/com/gmail/nossr50/party/PartyManager.java index 5f652bdb7..41aab0108 100644 --- a/src/main/java/com/gmail/nossr50/party/PartyManager.java +++ b/src/main/java/com/gmail/nossr50/party/PartyManager.java @@ -24,11 +24,18 @@ import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.*; import java.util.Map.Entry; +/** + * About mcMMO parties + * Parties are identified by a {@link String} name + * Parties always have a party leader, if the party leader is not defined mcMMO will force party leadership onto someone in the party + */ +//TODO: Needs to be optimized, currently all parties are loaded into memory, it should be changed to as needed, but then we need to handle loading asynchronously and accommodate for that public final class PartyManager { private final @NotNull HashMap parties; private final @NotNull File partyFile; @@ -36,12 +43,39 @@ public final class PartyManager { public PartyManager() { String partiesFilePath = mcMMO.getFlatFileDirectory() + "parties.yml"; partyFile = new File(partiesFilePath); - parties = new HashMap<>(); } + /** + * Attempts to find a party for a player by UUID + * + * @param playerUUID target uuid + * @return the party if it exists otherwise null + */ + public @Nullable Party queryParty(@NotNull UUID playerUUID) { + for(Party party : parties.values()) { + if(party.hasMember(playerUUID)) { + return party; + } + } + + return null; //No party + } + + /** + * Attempts to find a party by party name + * Party names are not case sensitive + * + * @param partyName party name + * @return the party if it exists otherwise null + */ + public @Nullable Party queryParty(@NotNull String partyName) { + return parties.get(partyName.toLowerCase()); + } + /** * Get the level of a party + * * @param party target party * @return the level value of the target party */ @@ -55,17 +89,18 @@ public final class PartyManager { * @param partyName The name of the party to check * @return true if a party with that name exists, false otherwise */ - public boolean checkPartyExistence(String partyName) { + public boolean isParty(@NotNull String partyName) { return getParty(partyName) != null; } /** * Checks if the player can join a party, parties can have a size limit, although there is a permission to bypass this + * * @param player player who is attempting to join the party * @param targetParty the target party * @return true if party is full and cannot be joined */ - public boolean isPartyFull(Player player, Party targetParty) + public boolean isPartyFull(@NotNull Player player, @NotNull Party targetParty) { return !Permissions.partySizeBypass(player) && targetParty.getPartyMembers().size() >= Config.getInstance().getPartyMaxSize(); @@ -78,7 +113,7 @@ public final class PartyManager { * @param newPartyName The name of the party being joined * @return true if the party was joined successfully, false otherwise */ - public boolean changeOrJoinParty(McMMOPlayer mmoPlayer, String newPartyName) { + public boolean changeOrJoinParty(@NotNull McMMOPlayer mmoPlayer, @NotNull String newPartyName) { Player player = mmoPlayer.getPlayer(); if (inParty(mmoPlayer)) { @@ -149,7 +184,7 @@ public final class PartyManager { return nearMembers; } - public List getNearVisibleMembers(McMMOPlayer mmoPlayer) { + public List getNearVisibleMembers(@NotNull McMMOPlayer mmoPlayer) { List nearMembers = new ArrayList<>(); Party party = mmoPlayer.getParty(); diff --git a/src/main/java/com/gmail/nossr50/party/ShareHandler.java b/src/main/java/com/gmail/nossr50/party/ShareHandler.java index 362fe88fc..6e052d361 100644 --- a/src/main/java/com/gmail/nossr50/party/ShareHandler.java +++ b/src/main/java/com/gmail/nossr50/party/ShareHandler.java @@ -9,10 +9,12 @@ import com.gmail.nossr50.datatypes.party.Party; import com.gmail.nossr50.datatypes.party.ShareMode; import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; +import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.util.Misc; import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -27,10 +29,9 @@ public final class ShareHandler { * @param primarySkillType Skill being used * @return True is the xp has been shared */ - public static boolean handleXpShare(float xp, McMMOPlayer mmoPlayer, PrimarySkillType primarySkillType, XPGainReason xpGainReason) { - Party party = mmoPlayer.getParty(); + public static boolean handleXpShare(float xp, @NotNull McMMOPlayer mmoPlayer, @NotNull Party party, @NotNull PrimarySkillType primarySkillType, @NotNull XPGainReason xpGainReason) { - if (party.getXpShareMode() != ShareMode.EQUAL) { + if (party.getPartyExperienceManager().getXpShareMode() != ShareMode.EQUAL) { return false; } @@ -46,14 +47,15 @@ public final class ShareHandler { double shareBonus = Math.min(Config.getInstance().getPartyShareBonusBase() + (partySize * Config.getInstance().getPartyShareBonusIncrease()), Config.getInstance().getPartyShareBonusCap()); float splitXp = (float) (xp / partySize * shareBonus); - for (Player member : nearMembers) { + for (Player otherMember : nearMembers) { + McMMOPlayer partyMember = mcMMO.getUserManager().queryMcMMOPlayer(otherMember); + //Profile not loaded - if(mcMMO.getUserManager().getPlayer(member) == null) - { + if(partyMember == null) { continue; } - mcMMO.getUserManager().getPlayer(member).beginUnsharedXpGain(primarySkillType, splitXp, xpGainReason, XPGainSource.PARTY_MEMBERS); + partyMember.getExperienceManager().beginUnsharedXpGain(primarySkillType, splitXp, xpGainReason, XPGainSource.PARTY_MEMBERS); } return true; diff --git a/src/main/java/com/gmail/nossr50/util/experience/ExperienceUtils.java b/src/main/java/com/gmail/nossr50/util/experience/ExperienceUtils.java new file mode 100644 index 000000000..8204ac156 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/util/experience/ExperienceUtils.java @@ -0,0 +1,46 @@ +package com.gmail.nossr50.util.experience; + +import com.gmail.nossr50.config.Config; +import com.gmail.nossr50.config.experience.ExperienceConfig; +import com.gmail.nossr50.datatypes.experience.XPGainReason; +import com.gmail.nossr50.datatypes.experience.XPGainSource; +import com.gmail.nossr50.datatypes.player.ExperienceManager; +import com.gmail.nossr50.datatypes.player.McMMOPlayer; +import com.gmail.nossr50.datatypes.skills.PrimarySkillType; +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.skills.child.FamilyTree; +import com.gmail.nossr50.util.EventUtils; +import com.gmail.nossr50.util.player.NotificationManager; +import com.gmail.nossr50.util.sounds.SoundManager; +import com.gmail.nossr50.util.sounds.SoundType; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +public class ExperienceUtils { + private ExperienceUtils() {} + + /** + * Applies an experience gain + * + * @param primarySkillType Skill being used + * @param xp Experience amount to add + */ + public static void applyXpGain(@NotNull McMMOPlayer mmoPlayer, @NotNull PrimarySkillType primarySkillType, float xp, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) { + mmoPlayer.getExperienceManager().applyXpGain(primarySkillType, xp, xpGainReason, xpGainSource); + } + + public static void processPostXpEvent(@NotNull McMMOPlayer mmoPlayer, @NotNull PrimarySkillType primarySkillType, @NotNull Plugin plugin, @NotNull XPGainSource xpGainSource) { + mmoPlayer.getExperienceManager().processPostXpEvent(primarySkillType, plugin, xpGainSource); + } + + /** + * Updates a players level + * + * @param primarySkillType The skill to check + */ + public static void updateLevelStats(@NotNull McMMOPlayer mmoPlayer, @NotNull PrimarySkillType primarySkillType, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) { + mmoPlayer.getExperienceManager().updateLevelStats(primarySkillType, xpGainReason, xpGainSource); + } +}