mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-11-04 02:53:43 +01:00 
			
		
		
		
	wip expmanager/party/mcmmo player rewrites
This commit is contained in:
		@@ -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
 | 
					                // 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]));
 | 
					                    player.sendMessage(LocaleLoader.getString("Commands.Party.AlreadyExists", args[1]));
 | 
				
			||||||
                    return true;
 | 
					                    return true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@ public class PartyRenameCommand implements CommandExecutor {
 | 
				
			|||||||
            Player player = mmoPlayer.getPlayer();
 | 
					            Player player = mmoPlayer.getPlayer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Check to see if the party exists, and if it does cancel renaming the party
 | 
					            // 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));
 | 
					                player.sendMessage(LocaleLoader.getString("Commands.Party.AlreadyExists", newPartyName));
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -602,10 +602,12 @@ public final class SQLDatabaseManager extends AbstractDatabaseManager {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public @Nullable PlayerProfile queryPlayerDataByPlayer(@NotNull Player player) throws ProfileRetrievalException, NullArgumentException {
 | 
					    public @Nullable PlayerProfile queryPlayerDataByPlayer(@NotNull Player player) throws ProfileRetrievalException, NullArgumentException {
 | 
				
			||||||
 | 
					        return loadPlayerProfile(player, player.getName(), player.getUniqueId());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public @Nullable PlayerProfile queryPlayerDataByUUID(@NotNull UUID uuid, @NotNull String playerName) throws ProfileRetrievalException, NullArgumentException {
 | 
					    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) {
 | 
					    private @Nullable PlayerProfile loadPlayerProfile(@Nullable Player player, @NotNull String playerName, @Nullable UUID playerUUID) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,11 +6,13 @@ import com.gmail.nossr50.datatypes.experience.FormulaType;
 | 
				
			|||||||
import com.gmail.nossr50.datatypes.experience.SkillXpGain;
 | 
					import com.gmail.nossr50.datatypes.experience.SkillXpGain;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.experience.XPGainReason;
 | 
					import com.gmail.nossr50.datatypes.experience.XPGainReason;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.experience.XPGainSource;
 | 
					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.datatypes.skills.PrimarySkillType;
 | 
				
			||||||
import com.gmail.nossr50.mcMMO;
 | 
					import com.gmail.nossr50.mcMMO;
 | 
				
			||||||
import com.gmail.nossr50.party.ShareHandler;
 | 
					import com.gmail.nossr50.party.ShareHandler;
 | 
				
			||||||
import com.gmail.nossr50.skills.child.FamilyTree;
 | 
					import com.gmail.nossr50.skills.child.FamilyTree;
 | 
				
			||||||
import com.gmail.nossr50.util.EventUtils;
 | 
					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.player.NotificationManager;
 | 
				
			||||||
import com.gmail.nossr50.util.skills.PerksUtils;
 | 
					import com.gmail.nossr50.util.skills.PerksUtils;
 | 
				
			||||||
import com.gmail.nossr50.util.sounds.SoundManager;
 | 
					import com.gmail.nossr50.util.sounds.SoundManager;
 | 
				
			||||||
@@ -20,6 +22,8 @@ import org.apache.commons.lang.Validate;
 | 
				
			|||||||
import org.bukkit.GameMode;
 | 
					import org.bukkit.GameMode;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.bukkit.plugin.Plugin;
 | 
					import org.bukkit.plugin.Plugin;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Set;
 | 
					import java.util.Set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,10 +31,12 @@ public class ExperienceManager {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private boolean isUsingUnarmed = false;
 | 
					    private boolean isUsingUnarmed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final PersistentPlayerData persistentPlayerDataRef;
 | 
					    private final @NotNull PersistentPlayerData persistentPlayerDataRef;
 | 
				
			||||||
 | 
					    private final @NotNull McMMOPlayer mmoPlayer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ExperienceManager(PersistentPlayerData persistentPlayerData) {
 | 
					    public ExperienceManager(@NotNull McMMOPlayer mmoPlayer) {
 | 
				
			||||||
        this.persistentPlayerDataRef = persistentPlayerData;
 | 
					        this.mmoPlayer = mmoPlayer;
 | 
				
			||||||
 | 
					        this.persistentPlayerDataRef = mmoPlayer.getPersistentPlayerData();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -64,7 +70,7 @@ public class ExperienceManager {
 | 
				
			|||||||
     * @param primarySkillType target skill
 | 
					     * @param primarySkillType target skill
 | 
				
			||||||
     * @return the value for XP the player has accumulated in 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()) {
 | 
					        if(primarySkillType.isChildSkill()) {
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -72,21 +78,19 @@ public class ExperienceManager {
 | 
				
			|||||||
        return (int) Math.floor(getSkillXpLevelRaw(primarySkillType));
 | 
					        return (int) Math.floor(getSkillXpLevelRaw(primarySkillType));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void setSkillXpValue(PrimarySkillType skill, float xpLevel) {
 | 
					    public void setSkillXpValue(@NotNull PrimarySkillType primarySkillType, float xpLevel) {
 | 
				
			||||||
        if (skill.isChildSkill()) {
 | 
					        if (primarySkillType.isChildSkill()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        persistentPlayerDataRef.getSkillsExperienceMap().put(skill, xpLevel);
 | 
					        persistentPlayerDataRef.getSkillsExperienceMap().put(primarySkillType, xpLevel);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public float levelUp(PrimarySkillType skill) {
 | 
					    public float levelUp(@NotNull PrimarySkillType primarySkillType) {
 | 
				
			||||||
        float xpRemoved = getXpToLevel(skill);
 | 
					        float xpRemoved = getXpToLevel(primarySkillType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        markProfileDirty();
 | 
					        setSkillLevel(primarySkillType, getSkillLevel(primarySkillType) + 1);
 | 
				
			||||||
 | 
					        setSkillXpValue(primarySkillType, getSkillXpValue(primarySkillType) - xpRemoved);
 | 
				
			||||||
        skills.put(skill, skills.get(skill) + 1);
 | 
					 | 
				
			||||||
        skillsXp.put(skill, skillsXp.get(skill) - xpRemoved);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return xpRemoved;
 | 
					        return xpRemoved;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -94,14 +98,15 @@ public class ExperienceManager {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Whether or not a player is level capped
 | 
					     * 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
 | 
					     * If they are at the power level cap, this will return true, otherwise it checks their skill level
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
     * @param primarySkillType
 | 
					     * @param primarySkillType
 | 
				
			||||||
     * @return
 | 
					     * @return
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public boolean hasReachedLevelCap(PrimarySkillType primarySkillType) {
 | 
					    public boolean hasReachedLevelCap(@NotNull PrimarySkillType primarySkillType) {
 | 
				
			||||||
        if(hasReachedPowerLevelCap())
 | 
					        if(hasReachedPowerLevelCap())
 | 
				
			||||||
            return true;
 | 
					            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 primarySkillType Skill being used
 | 
				
			||||||
     * @param xp Experience amount to process
 | 
					     * @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.");
 | 
					        Validate.isTrue(xp >= 0.0, "XP gained should be greater than or equal to zero.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (xp <= 0.0) {
 | 
					        if (xp <= 0.0) {
 | 
				
			||||||
@@ -131,137 +136,45 @@ public class ExperienceManager {
 | 
				
			|||||||
            float splitXp = xp / parentSkills.size();
 | 
					            float splitXp = xp / parentSkills.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (PrimarySkillType parentSkill : parentSkills) {
 | 
					            for (PrimarySkillType parentSkill : parentSkills) {
 | 
				
			||||||
                beginXpGain(player, parentSkill, splitXp, xpGainReason, xpGainSource);
 | 
					                beginXpGain(parentSkill, splitXp, xpGainReason, xpGainSource);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //TODO: The logic here is so stupid... rewrite later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Return if the experience has been shared
 | 
					        // 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;
 | 
					            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
 | 
					     * Begins an experience gain. The amount will be affected by primarySkillType 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
 | 
					 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param primarySkillType Skill being used
 | 
					     * @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) {
 | 
					    public void beginUnsharedXpGain(@NotNull PrimarySkillType primarySkillType, float xp, @NotNull XPGainReason xpGainReason, @NotNull XPGainSource xpGainSource) {
 | 
				
			||||||
        if (!primarySkillType.getPermissions(player)) {
 | 
					        if(mmoPlayer.getPlayer().getGameMode() == GameMode.CREATIVE)
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (primarySkillType.isChildSkill()) {
 | 
					        ExperienceUtils.applyXpGain(mmoPlayer, primarySkillType, modifyXpGain(primarySkillType, xp), xpGainReason, xpGainSource);
 | 
				
			||||||
            Set<PrimarySkillType> parentSkills = FamilyTree.getParents(primarySkillType);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (PrimarySkillType parentSkill : parentSkills) {
 | 
					        Party party = mmoPlayer.getParty();
 | 
				
			||||||
                applyXpGain(player, parentSkill, xp / parentSkills.size(), xpGainReason, xpGainSource);
 | 
					
 | 
				
			||||||
 | 
					        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);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    public int getSkillLevel(@NotNull PrimarySkillType skill) {
 | 
				
			||||||
     * Check the XP of a skill.
 | 
					        return skill.isChildSkill() ? getChildSkillLevel(skill) : getSkillLevel(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);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -270,18 +183,18 @@ public class ExperienceManager {
 | 
				
			|||||||
     * @param primarySkillType Type of skill to check
 | 
					     * @param primarySkillType Type of skill to check
 | 
				
			||||||
     * @return the total amount of Xp until next level
 | 
					     * @return the total amount of Xp until next level
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public int getXpToLevel(PrimarySkillType primarySkillType) {
 | 
					    public int getXpToLevel(@NotNull PrimarySkillType primarySkillType) {
 | 
				
			||||||
        if(primarySkillType.isChildSkill()) {
 | 
					        if(primarySkillType.isChildSkill()) {
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int level = (ExperienceConfig.getInstance().getCumulativeCurveEnabled()) ? getPowerLevel() : playerDataRef..get(primarySkillType);
 | 
					        int level = (ExperienceConfig.getInstance().getCumulativeCurveEnabled()) ? getPowerLevel() : getSkillLevel(primarySkillType);
 | 
				
			||||||
        FormulaType formulaType = ExperienceConfig.getInstance().getFormulaType();
 | 
					        FormulaType formulaType = ExperienceConfig.getInstance().getFormulaType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return mcMMO.getFormulaManager().getXPtoNextLevel(level, formulaType);
 | 
					        return mcMMO.getFormulaManager().getXPtoNextLevel(level, formulaType);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private int getChildSkillLevel(PrimarySkillType primarySkillType) {
 | 
					    private int getChildSkillLevel(@NotNull PrimarySkillType primarySkillType) {
 | 
				
			||||||
        Set<PrimarySkillType> parents = FamilyTree.getParents(primarySkillType);
 | 
					        Set<PrimarySkillType> parents = FamilyTree.getParents(primarySkillType);
 | 
				
			||||||
        int sum = 0;
 | 
					        int sum = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -302,14 +215,12 @@ public class ExperienceManager {
 | 
				
			|||||||
     * @param skill Type of skill to modify
 | 
					     * @param skill Type of skill to modify
 | 
				
			||||||
     * @param xp Amount of xp to remove
 | 
					     * @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()) {
 | 
					        if (skill.isChildSkill()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        markProfileDirty();
 | 
					        setSkillXpValue(skill, getSkillXpValue(skill) - xp);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        skillsXp.put(skill, skillsXp.get(skill) - xp);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void removeXp(PrimarySkillType skill, float xp) {
 | 
					    public void removeXp(PrimarySkillType skill, float xp) {
 | 
				
			||||||
@@ -317,19 +228,17 @@ public class ExperienceManager {
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        markProfileDirty();
 | 
					        setSkillXpValue(skill, getSkillXpValue(skill) - xp);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        skillsXp.put(skill, skillsXp.get(skill) - xp);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Modify a skill level.
 | 
					     * Modify a primarySkillType level.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param skill Type of skill to modify
 | 
					     * @param primarySkillType Type of primarySkillType to modify
 | 
				
			||||||
     * @param level New level value for the skill
 | 
					     * @param level New level value for the primarySkillType
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void setSkillLevel(PrimarySkillType skill, int level) {
 | 
					    public void setSkillLevel(@NotNull PrimarySkillType primarySkillType, int level) {
 | 
				
			||||||
        if (skill.isChildSkill()) {
 | 
					        if (primarySkillType.isChildSkill()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -337,39 +246,37 @@ public class ExperienceManager {
 | 
				
			|||||||
        if(level < 0)
 | 
					        if(level < 0)
 | 
				
			||||||
            level = 0;
 | 
					            level = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        skills.put(skill, level);
 | 
					        setSkillLevel(primarySkillType, level);
 | 
				
			||||||
        skillsXp.put(skill, 0F);
 | 
					        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
 | 
					     * @param levels Number of levels to add
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void addLevels(PrimarySkillType skill, int levels) {
 | 
					    public void addLevels(@NotNull PrimarySkillType primarySkillType, int levels) {
 | 
				
			||||||
        setSkillLevel(skill, skills.get(skill) + 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
 | 
					     * @param xp Number of experience to add
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void addXp(PrimarySkillType skill, float xp) {
 | 
					    public void addXp(@NotNull PrimarySkillType primarySkillType, float xp) {
 | 
				
			||||||
        markProfileDirty();
 | 
					        if (primarySkillType.isChildSkill()) {
 | 
				
			||||||
 | 
					            Set<PrimarySkillType> parentSkills = FamilyTree.getParents(primarySkillType);
 | 
				
			||||||
        if (skill.isChildSkill()) {
 | 
					 | 
				
			||||||
            Set<PrimarySkillType> parentSkills = FamilyTree.getParents(skill);
 | 
					 | 
				
			||||||
            float dividedXP = (xp / parentSkills.size());
 | 
					            float dividedXP = (xp / parentSkills.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (PrimarySkillType parentSkill : parentSkills) {
 | 
					            for (PrimarySkillType parentSkill : parentSkills) {
 | 
				
			||||||
                skillsXp.put(parentSkill, skillsXp.get(parentSkill) + dividedXP);
 | 
					                setSkillXpValue(parentSkill, getSkillXpValue(parentSkill) + dividedXP);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        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
 | 
					     * @return xp Experience amount registered
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public float getRegisteredXpGain(PrimarySkillType primarySkillType) {
 | 
					    public float getRegisteredXpGain(@NotNull PrimarySkillType primarySkillType) {
 | 
				
			||||||
        float xp = 0F;
 | 
					        float xp = 0F;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (rollingSkillsXp.get(primarySkillType) != null) {
 | 
					        if (rollingSkillsXp.get(primarySkillType) != null) {
 | 
				
			||||||
@@ -396,7 +303,7 @@ public class ExperienceManager {
 | 
				
			|||||||
     * @param primarySkillType Skill being used
 | 
					     * @param primarySkillType Skill being used
 | 
				
			||||||
     * @param xp Experience amount to add
 | 
					     * @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));
 | 
					        gainedSkillsXp.add(new SkillXpGain(primarySkillType, xp));
 | 
				
			||||||
        rollingSkillsXp.put(primarySkillType, getRegisteredXpGain(primarySkillType) + xp);
 | 
					        rollingSkillsXp.put(primarySkillType, getRegisteredXpGain(primarySkillType) + xp);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -412,14 +319,6 @@ public class ExperienceManager {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ImmutableMap<PrimarySkillType, Integer> copyPrimarySkillLevelsMap() {
 | 
					 | 
				
			||||||
        return ImmutableMap.copyOf(primarySkillLevelMap);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public ImmutableMap<PrimarySkillType, Float> copyPrimarySkillExperienceValuesMap() {
 | 
					 | 
				
			||||||
        return ImmutableMap.copyOf(primarySkillCurrentExpMap);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Modifies an experience gain using skill modifiers, global rate and perks
 | 
					     * Modifies an experience gain using skill modifiers, global rate and perks
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@@ -427,14 +326,14 @@ public class ExperienceManager {
 | 
				
			|||||||
     * @param xp Experience amount to process
 | 
					     * @param xp Experience amount to process
 | 
				
			||||||
     * @return Modified experience
 | 
					     * @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())) {
 | 
					        if ((primarySkillType.getMaxLevel() <= getSkillLevel(primarySkillType)) || (Config.getInstance().getPowerLevelCap() <= getPowerLevel())) {
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        xp = (float) (xp / primarySkillType.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
 | 
					        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)
 | 
					    public double getProgressInCurrentSkillLevel(PrimarySkillType primarySkillType)
 | 
				
			||||||
@@ -449,5 +348,104 @@ public class ExperienceManager {
 | 
				
			|||||||
        return (currentXP / maxXP);
 | 
					        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<PrimarySkillType> 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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ import com.gmail.nossr50.config.experience.ExperienceConfig;
 | 
				
			|||||||
import com.gmail.nossr50.datatypes.chat.ChatChannel;
 | 
					import com.gmail.nossr50.datatypes.chat.ChatChannel;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.experience.XPGainSource;
 | 
					import com.gmail.nossr50.datatypes.experience.XPGainSource;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
 | 
					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.party.PartyTeleportRecord;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 | 
					import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
 | 
					import com.gmail.nossr50.datatypes.skills.SubSkillType;
 | 
				
			||||||
@@ -58,6 +59,7 @@ import java.util.UUID;
 | 
				
			|||||||
public class McMMOPlayer extends PlayerProfile implements Identified {
 | 
					public class McMMOPlayer extends PlayerProfile implements Identified {
 | 
				
			||||||
    private final @NotNull Player player;
 | 
					    private final @NotNull Player player;
 | 
				
			||||||
    private final @NotNull Identity identity;
 | 
					    private final @NotNull Identity identity;
 | 
				
			||||||
 | 
					    private @Nullable Party playerPartyRef;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //Used in our chat systems for chat messages
 | 
					    //Used in our chat systems for chat messages
 | 
				
			||||||
    private final @NotNull PlayerAuthor playerAuthor;
 | 
					    private final @NotNull PlayerAuthor playerAuthor;
 | 
				
			||||||
@@ -117,6 +119,8 @@ public class McMMOPlayer extends PlayerProfile implements Identified {
 | 
				
			|||||||
            chatSpy = true;
 | 
					            chatSpy = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assignParty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Update last login
 | 
					        //Update last login
 | 
				
			||||||
        updateLastLogin();
 | 
					        updateLastLogin();
 | 
				
			||||||
@@ -167,10 +171,18 @@ public class McMMOPlayer extends PlayerProfile implements Identified {
 | 
				
			|||||||
            chatSpy = true;
 | 
					            chatSpy = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assignParty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Update last login
 | 
					        //Update last login
 | 
				
			||||||
        updateLastLogin();
 | 
					        updateLastLogin();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void assignParty() {
 | 
				
			||||||
 | 
					        if(mcMMO.getPartyManager() != null) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Update the last login to the current system time
 | 
					     * 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) {
 | 
					    public void setChatMode(@NotNull ChatChannel chatChannel) {
 | 
				
			||||||
        this.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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ import com.gmail.nossr50.datatypes.validation.NonNullRule;
 | 
				
			|||||||
import com.gmail.nossr50.datatypes.validation.PositiveIntegerRule;
 | 
					import com.gmail.nossr50.datatypes.validation.PositiveIntegerRule;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.validation.Validator;
 | 
					import com.gmail.nossr50.datatypes.validation.Validator;
 | 
				
			||||||
import com.gmail.nossr50.util.experience.MMOExperienceBarManager;
 | 
					import com.gmail.nossr50.util.experience.MMOExperienceBarManager;
 | 
				
			||||||
 | 
					import com.google.common.collect.ImmutableMap;
 | 
				
			||||||
import org.apache.commons.lang.NullArgumentException;
 | 
					import org.apache.commons.lang.NullArgumentException;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -453,4 +454,12 @@ public class PersistentPlayerData {
 | 
				
			|||||||
    public void setLeaderBoardExclusion(boolean bool) {
 | 
					    public void setLeaderBoardExclusion(boolean bool) {
 | 
				
			||||||
        leaderBoardExclusion.getData(true).setBoolean(bool);
 | 
					        leaderBoardExclusion.getData(true).setBoolean(bool);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public ImmutableMap<PrimarySkillType, Integer> copyPrimarySkillLevelsMap() {
 | 
				
			||||||
 | 
					        return ImmutableMap.copyOf(getSkillLevelsMap());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public ImmutableMap<PrimarySkillType, Float> copyPrimarySkillExperienceValuesMap() {
 | 
				
			||||||
 | 
					        return ImmutableMap.copyOf(getSkillsExperienceMap());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -137,8 +137,13 @@ public class PlayerProfile {
 | 
				
			|||||||
        return cooldownManager;
 | 
					        return cooldownManager;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Attempt to get a party for this PlayerProfile
 | 
				
			||||||
 | 
					     * @return get a party for this PlayerProfile
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public @Nullable Party getParty(){
 | 
					    public @Nullable Party getParty(){
 | 
				
			||||||
        return mcMMO.getPartyManager().getParty(persistentPlayerData.getPlayerUUID());
 | 
					        //TODO: This can be optimized
 | 
				
			||||||
 | 
					        return mcMMO.getPartyManager().queryParty(persistentPlayerData.getPlayerUUID());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,11 +24,18 @@ import org.bukkit.OfflinePlayer;
 | 
				
			|||||||
import org.bukkit.configuration.file.YamlConfiguration;
 | 
					import org.bukkit.configuration.file.YamlConfiguration;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
import java.util.*;
 | 
					import java.util.*;
 | 
				
			||||||
import java.util.Map.Entry;
 | 
					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 {
 | 
					public final class PartyManager {
 | 
				
			||||||
    private final @NotNull HashMap<String, Party> parties;
 | 
					    private final @NotNull HashMap<String, Party> parties;
 | 
				
			||||||
    private final @NotNull File partyFile;
 | 
					    private final @NotNull File partyFile;
 | 
				
			||||||
@@ -36,12 +43,39 @@ public final class PartyManager {
 | 
				
			|||||||
    public PartyManager() {
 | 
					    public PartyManager() {
 | 
				
			||||||
        String partiesFilePath = mcMMO.getFlatFileDirectory() + "parties.yml";
 | 
					        String partiesFilePath = mcMMO.getFlatFileDirectory() + "parties.yml";
 | 
				
			||||||
        partyFile = new File(partiesFilePath);
 | 
					        partyFile = new File(partiesFilePath);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        parties = new HashMap<>();
 | 
					        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
 | 
					     * Get the level of a party
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
     * @param party target party
 | 
					     * @param party target party
 | 
				
			||||||
     * @return the level value of the 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
 | 
					     * @param partyName The name of the party to check
 | 
				
			||||||
     * @return true if a party with that name exists, false otherwise
 | 
					     * @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;
 | 
					        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
 | 
					     * 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 player player who is attempting to join the party
 | 
				
			||||||
     * @param targetParty the target party
 | 
					     * @param targetParty the target party
 | 
				
			||||||
     * @return true if party is full and cannot be joined
 | 
					     * @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)
 | 
					        return !Permissions.partySizeBypass(player)
 | 
				
			||||||
                && targetParty.getPartyMembers().size() >= Config.getInstance().getPartyMaxSize();
 | 
					                && targetParty.getPartyMembers().size() >= Config.getInstance().getPartyMaxSize();
 | 
				
			||||||
@@ -78,7 +113,7 @@ public final class PartyManager {
 | 
				
			|||||||
     * @param newPartyName The name of the party being joined
 | 
					     * @param newPartyName The name of the party being joined
 | 
				
			||||||
     * @return true if the party was joined successfully, false otherwise
 | 
					     * @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();
 | 
					        Player player = mmoPlayer.getPlayer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (inParty(mmoPlayer)) {
 | 
					        if (inParty(mmoPlayer)) {
 | 
				
			||||||
@@ -149,7 +184,7 @@ public final class PartyManager {
 | 
				
			|||||||
        return nearMembers;
 | 
					        return nearMembers;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public List<Player> getNearVisibleMembers(McMMOPlayer mmoPlayer) {
 | 
					    public List<Player> getNearVisibleMembers(@NotNull McMMOPlayer mmoPlayer) {
 | 
				
			||||||
        List<Player> nearMembers = new ArrayList<>();
 | 
					        List<Player> nearMembers = new ArrayList<>();
 | 
				
			||||||
        Party party = mmoPlayer.getParty();
 | 
					        Party party = mmoPlayer.getParty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,10 +9,12 @@ import com.gmail.nossr50.datatypes.party.Party;
 | 
				
			|||||||
import com.gmail.nossr50.datatypes.party.ShareMode;
 | 
					import com.gmail.nossr50.datatypes.party.ShareMode;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 | 
					import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 | 
					import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.mcMMO;
 | 
				
			||||||
import com.gmail.nossr50.util.Misc;
 | 
					import com.gmail.nossr50.util.Misc;
 | 
				
			||||||
import org.bukkit.entity.Item;
 | 
					import org.bukkit.entity.Item;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.bukkit.inventory.ItemStack;
 | 
					import org.bukkit.inventory.ItemStack;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,10 +29,9 @@ public final class ShareHandler {
 | 
				
			|||||||
     * @param primarySkillType Skill being used
 | 
					     * @param primarySkillType Skill being used
 | 
				
			||||||
     * @return True is the xp has been shared
 | 
					     * @return True is the xp has been shared
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static boolean handleXpShare(float xp, McMMOPlayer mmoPlayer, PrimarySkillType primarySkillType, XPGainReason xpGainReason) {
 | 
					    public static boolean handleXpShare(float xp, @NotNull McMMOPlayer mmoPlayer, @NotNull Party party, @NotNull PrimarySkillType primarySkillType, @NotNull XPGainReason xpGainReason) {
 | 
				
			||||||
        Party party = mmoPlayer.getParty();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (party.getXpShareMode() != ShareMode.EQUAL) {
 | 
					        if (party.getPartyExperienceManager().getXpShareMode() != ShareMode.EQUAL) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -46,14 +47,15 @@ public final class ShareHandler {
 | 
				
			|||||||
        double shareBonus = Math.min(Config.getInstance().getPartyShareBonusBase() + (partySize * Config.getInstance().getPartyShareBonusIncrease()), Config.getInstance().getPartyShareBonusCap());
 | 
					        double shareBonus = Math.min(Config.getInstance().getPartyShareBonusBase() + (partySize * Config.getInstance().getPartyShareBonusIncrease()), Config.getInstance().getPartyShareBonusCap());
 | 
				
			||||||
        float splitXp = (float) (xp / partySize * shareBonus);
 | 
					        float splitXp = (float) (xp / partySize * shareBonus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (Player member : nearMembers) {
 | 
					        for (Player otherMember : nearMembers) {
 | 
				
			||||||
 | 
					            McMMOPlayer partyMember = mcMMO.getUserManager().queryMcMMOPlayer(otherMember);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //Profile not loaded
 | 
					            //Profile not loaded
 | 
				
			||||||
            if(mcMMO.getUserManager().getPlayer(member) == null)
 | 
					            if(partyMember == null) {
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            mcMMO.getUserManager().getPlayer(member).beginUnsharedXpGain(primarySkillType, splitXp, xpGainReason, XPGainSource.PARTY_MEMBERS);
 | 
					            partyMember.getExperienceManager().beginUnsharedXpGain(primarySkillType, splitXp, xpGainReason, XPGainSource.PARTY_MEMBERS);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user