mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-11-04 02:53:43 +01:00 
			
		
		
		
	McMMOPlayer & PlayerProfile redesigned
This is part 1 of a huge refactor, I'm going to be separating this refactor into a few commits for a cleaner history.
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,449 +1,136 @@
 | 
			
		||||
package com.gmail.nossr50.datatypes.player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.config.AdvancedConfig;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
 | 
			
		||||
import com.gmail.nossr50.datatypes.MobHealthbarType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.experience.FormulaType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.experience.SkillXpGain;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.runnables.player.PlayerProfileSaveTask;
 | 
			
		||||
import com.gmail.nossr50.skills.child.FamilyTree;
 | 
			
		||||
import com.gmail.nossr50.util.experience.ExperienceBarManager;
 | 
			
		||||
import com.gmail.nossr50.util.player.UserManager;
 | 
			
		||||
import com.gmail.nossr50.util.skills.SkillUtils;
 | 
			
		||||
import com.google.common.collect.ImmutableMap;
 | 
			
		||||
import com.gmail.nossr50.datatypes.MobHealthBarType;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.concurrent.DelayQueue;
 | 
			
		||||
 | 
			
		||||
public class PlayerProfile {
 | 
			
		||||
    private final String playerName;
 | 
			
		||||
    private UUID uuid;
 | 
			
		||||
    private boolean loaded;
 | 
			
		||||
    private volatile boolean changed;
 | 
			
		||||
 | 
			
		||||
    /* HUDs */
 | 
			
		||||
    private MobHealthbarType mobHealthbarType;
 | 
			
		||||
    private int scoreboardTipsShown;
 | 
			
		||||
    private int saveAttempts = 0;
 | 
			
		||||
    /* All of the persistent data for a player that gets saved and loaded from DB */
 | 
			
		||||
    private final @NotNull PersistentPlayerData persistentPlayerData; //All persistent data is kept here
 | 
			
		||||
 | 
			
		||||
    /* Skill Data */
 | 
			
		||||
    private final Map<PrimarySkillType, Integer>   skills     = new HashMap<>();   // Skill & Level
 | 
			
		||||
    private final Map<PrimarySkillType, Float>     skillsXp   = new HashMap<>();     // Skill & XP
 | 
			
		||||
    private final Map<SuperAbilityType, Integer> abilityDATS = new HashMap<>(); // Ability & Cooldown
 | 
			
		||||
    private final Map<UniqueDataType, Integer> uniquePlayerData = new HashMap<>(); //Misc data that doesn't fit into other categories (chimaera wing, etc..)
 | 
			
		||||
    private Map<PrimarySkillType, ExperienceBarManager.BarState> xpBarState = new HashMap<>();
 | 
			
		||||
    /* Managers */
 | 
			
		||||
    private final @NotNull ExperienceManager experienceManager;
 | 
			
		||||
    private final @NotNull CooldownManager cooldownManager;
 | 
			
		||||
 | 
			
		||||
    // Store previous XP gains for diminished returns
 | 
			
		||||
    private final DelayQueue<SkillXpGain> gainedSkillsXp = new DelayQueue<>();
 | 
			
		||||
    private final HashMap<PrimarySkillType, Float> rollingSkillsXp = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public PlayerProfile(String playerName) {
 | 
			
		||||
        this(playerName, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PlayerProfile(String playerName, UUID uuid) {
 | 
			
		||||
        this.uuid = uuid;
 | 
			
		||||
        this.playerName = playerName;
 | 
			
		||||
 | 
			
		||||
        mobHealthbarType = Config.getInstance().getMobHealthbarDefault();
 | 
			
		||||
        scoreboardTipsShown = 0;
 | 
			
		||||
 | 
			
		||||
        for (SuperAbilityType superAbilityType : SuperAbilityType.values()) {
 | 
			
		||||
            abilityDATS.put(superAbilityType, 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
 | 
			
		||||
            skills.put(primarySkillType, AdvancedConfig.getInstance().getStartingLevel());
 | 
			
		||||
            skillsXp.put(primarySkillType, 0F);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Misc Cooldowns
 | 
			
		||||
        uniquePlayerData.put(UniqueDataType.CHIMAERA_WING_DATS, 0); //Chimaera wing
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public PlayerProfile(String playerName, boolean isLoaded) {
 | 
			
		||||
        this(playerName);
 | 
			
		||||
        this.loaded = isLoaded;
 | 
			
		||||
        this.xpBarState = SkillUtils.generateDefaultBarStateMap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PlayerProfile(String playerName, UUID uuid, boolean isLoaded) {
 | 
			
		||||
        this(playerName, uuid);
 | 
			
		||||
        this.loaded = isLoaded;
 | 
			
		||||
        this.xpBarState = SkillUtils.generateDefaultBarStateMap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PlayerProfile(String playerName, UUID uuid, Map<PrimarySkillType, Integer> levelData, Map<PrimarySkillType, Float> xpData, Map<SuperAbilityType, Integer> cooldownData, MobHealthbarType mobHealthbarType, int scoreboardTipsShown, Map<UniqueDataType, Integer> uniqueProfileData, Map<PrimarySkillType, ExperienceBarManager.BarState> barStateMap) {
 | 
			
		||||
        this.playerName = playerName;
 | 
			
		||||
        this.uuid = uuid;
 | 
			
		||||
        this.mobHealthbarType = mobHealthbarType;
 | 
			
		||||
        this.scoreboardTipsShown = scoreboardTipsShown;
 | 
			
		||||
 | 
			
		||||
        skills.putAll(levelData);
 | 
			
		||||
        skillsXp.putAll(xpData);
 | 
			
		||||
        abilityDATS.putAll(cooldownData);
 | 
			
		||||
        uniquePlayerData.putAll(uniqueProfileData);
 | 
			
		||||
        xpBarState.putAll(barStateMap);
 | 
			
		||||
 | 
			
		||||
        loaded = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void scheduleAsyncSave() {
 | 
			
		||||
        new PlayerProfileSaveTask(this, false).runTaskAsynchronously(mcMMO.p);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void scheduleSyncSave() {
 | 
			
		||||
        new PlayerProfileSaveTask(this, true).runTask(mcMMO.p);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void scheduleAsyncSaveDelay() {
 | 
			
		||||
        new PlayerProfileSaveTask(this, false).runTaskLaterAsynchronously(mcMMO.p, 20);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public void scheduleSyncSaveDelay() {
 | 
			
		||||
        new PlayerProfileSaveTask(this, true).runTaskLater(mcMMO.p, 20);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void save(boolean useSync) {
 | 
			
		||||
        if (!changed || !loaded) {
 | 
			
		||||
            saveAttempts = 0;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // TODO should this part be synchronized?
 | 
			
		||||
        PlayerProfile profileCopy = new PlayerProfile(playerName, uuid, ImmutableMap.copyOf(skills), ImmutableMap.copyOf(skillsXp), ImmutableMap.copyOf(abilityDATS), mobHealthbarType, scoreboardTipsShown, ImmutableMap.copyOf(uniquePlayerData), ImmutableMap.copyOf(xpBarState));
 | 
			
		||||
        changed = !mcMMO.getDatabaseManager().saveUser(profileCopy);
 | 
			
		||||
 | 
			
		||||
        if (changed) {
 | 
			
		||||
            mcMMO.p.getLogger().severe("PlayerProfile saving failed for player: " + playerName + " " + uuid);
 | 
			
		||||
 | 
			
		||||
            if(saveAttempts > 0)
 | 
			
		||||
            {
 | 
			
		||||
                mcMMO.p.getLogger().severe("Attempted to save profile for player "+getPlayerName()
 | 
			
		||||
                        + " resulted in failure. "+saveAttempts+" have been made so far.");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(saveAttempts < 10)
 | 
			
		||||
            {
 | 
			
		||||
                saveAttempts++;
 | 
			
		||||
 | 
			
		||||
                if(useSync)
 | 
			
		||||
                    scheduleSyncSave(); //Execute sync saves immediately
 | 
			
		||||
                else
 | 
			
		||||
                    scheduleAsyncSaveDelay();
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                mcMMO.p.getLogger().severe("mcMMO has failed to save the profile for "
 | 
			
		||||
                        +getPlayerName()+" numerous times." +
 | 
			
		||||
                        " mcMMO will now stop attempting to save this profile." +
 | 
			
		||||
                        " Check your console for errors and inspect your DB for issues.");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            saveAttempts = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getPlayerName() {
 | 
			
		||||
        return playerName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public UUID getUniqueId() {
 | 
			
		||||
        return uuid;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setUniqueId(UUID uuid) {
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
 | 
			
		||||
        this.uuid = uuid;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isLoaded() {
 | 
			
		||||
        return loaded;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Mob Healthbars
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new PlayerProfile for a {@link Player}
 | 
			
		||||
     * @param player target player
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    public MobHealthbarType getMobHealthbarType() {
 | 
			
		||||
        return mobHealthbarType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMobHealthbarType(MobHealthbarType mobHealthbarType) {
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
 | 
			
		||||
        this.mobHealthbarType = mobHealthbarType;
 | 
			
		||||
    public PlayerProfile(@NotNull Player player) {
 | 
			
		||||
        /* New Data */
 | 
			
		||||
        this(player.getUniqueId(), player.getName());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Marks the profile as "dirty" which flags a profile to be saved in the next save operation
 | 
			
		||||
     * Create a new PlayerProfile for a {@link Player}
 | 
			
		||||
     * @param playerUUID target player's UUID
 | 
			
		||||
     * @param playerName target player's name
 | 
			
		||||
     */
 | 
			
		||||
    public void markProfileDirty() {
 | 
			
		||||
        changed = true;
 | 
			
		||||
    public PlayerProfile(@NotNull UUID playerUUID, @NotNull String playerName) {
 | 
			
		||||
        /* New Data */
 | 
			
		||||
        this.persistentPlayerData = new PersistentPlayerData(playerUUID, playerName);
 | 
			
		||||
        this.experienceManager = new ExperienceManager(persistentPlayerData);
 | 
			
		||||
        this.cooldownManager = new CooldownManager(persistentPlayerData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a PlayerProfile for {@link PersistentPlayerData}
 | 
			
		||||
     * This will be used for existing data
 | 
			
		||||
     * @param persistentPlayerData target persistent player data
 | 
			
		||||
     */
 | 
			
		||||
    public PlayerProfile(@NotNull PersistentPlayerData persistentPlayerData) {
 | 
			
		||||
        this.persistentPlayerData = persistentPlayerData;
 | 
			
		||||
        this.experienceManager = new ExperienceManager(persistentPlayerData);
 | 
			
		||||
        this.cooldownManager = new CooldownManager(persistentPlayerData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the saved player name for this profile
 | 
			
		||||
     * @return the saved player name for this profile
 | 
			
		||||
     */
 | 
			
		||||
    public @NotNull String getPlayerName() {
 | 
			
		||||
        return getPersistentPlayerData().getPlayerName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the saved {@link UUID} for this profile
 | 
			
		||||
     * @return the saved {@link UUID} for this profile
 | 
			
		||||
     */
 | 
			
		||||
    public @NotNull UUID getUniqueId() {
 | 
			
		||||
        return getPersistentPlayerData().getPlayerUUID();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the current {@link MobHealthBarType} for this profile
 | 
			
		||||
     * @return the mob health bar setting for this profile
 | 
			
		||||
     */
 | 
			
		||||
    public @NotNull MobHealthBarType getMobHealthBarType() {
 | 
			
		||||
        return getPersistentPlayerData().getMobHealthBarType();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the {@link MobHealthBarType} for this profile
 | 
			
		||||
     * @param mobHealthbarType desired mob health bar type
 | 
			
		||||
     */
 | 
			
		||||
    public void setMobHealthBarType(@NotNull MobHealthBarType mobHealthbarType) {
 | 
			
		||||
        getPersistentPlayerData().setMobHealthBarType(mobHealthbarType);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The number of times scoreboard tips have been shown to this profile
 | 
			
		||||
     * @return the scoreboard tips view count
 | 
			
		||||
     */
 | 
			
		||||
    public int getScoreboardTipsShown() {
 | 
			
		||||
        return scoreboardTipsShown;
 | 
			
		||||
        return getPersistentPlayerData().getScoreboardTipsShown();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Replace the scoreboard view count
 | 
			
		||||
     * @param scoreboardTipsShown new value
 | 
			
		||||
     */
 | 
			
		||||
    public void setScoreboardTipsShown(int scoreboardTipsShown) {
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
        getPersistentPlayerData().setScoreboardTipsShown(scoreboardTipsShown);
 | 
			
		||||
 | 
			
		||||
        this.scoreboardTipsShown = scoreboardTipsShown;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Increments the scoreboard tip view count by 1
 | 
			
		||||
     */
 | 
			
		||||
    public void increaseTipsShown() {
 | 
			
		||||
        setScoreboardTipsShown(getScoreboardTipsShown() + 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Cooldowns
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    public int getChimaerWingDATS() { return uniquePlayerData.get(UniqueDataType.CHIMAERA_WING_DATS);}
 | 
			
		||||
 | 
			
		||||
    protected void setChimaeraWingDATS(int DATS) {
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
        uniquePlayerData.put(UniqueDataType.CHIMAERA_WING_DATS, DATS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setUniqueData(UniqueDataType uniqueDataType, int newData) {
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
        uniquePlayerData.put(uniqueDataType, newData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long getUniqueData(UniqueDataType uniqueDataType) { return uniquePlayerData.get(uniqueDataType); }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the current deactivation timestamp of an ability.
 | 
			
		||||
     *
 | 
			
		||||
     * @param ability The {@link SuperAbilityType} to get the DATS for
 | 
			
		||||
     * @return the deactivation timestamp for the ability
 | 
			
		||||
     * Retrieves a reference to the {@link PersistentPlayerData} for this profile
 | 
			
		||||
     * @return the persistent data for this profile
 | 
			
		||||
     */
 | 
			
		||||
    public long getAbilityDATS(SuperAbilityType ability) {
 | 
			
		||||
        return abilityDATS.get(ability);
 | 
			
		||||
    public @NotNull PersistentPlayerData getPersistentPlayerData() {
 | 
			
		||||
        return persistentPlayerData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the current deactivation timestamp of an ability.
 | 
			
		||||
     *
 | 
			
		||||
     * @param ability The {@link SuperAbilityType} to set the DATS for
 | 
			
		||||
     * @param DATS the DATS of the ability
 | 
			
		||||
     * Invert the current value of the party chat spy toggle
 | 
			
		||||
     */
 | 
			
		||||
    public void setAbilityDATS(SuperAbilityType ability, long DATS) {
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
 | 
			
		||||
        abilityDATS.put(ability, (int) (DATS * .001D));
 | 
			
		||||
    public void togglePartyChatSpying() {
 | 
			
		||||
        persistentPlayerData.togglePartyChatSpying();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reset all ability cooldowns.
 | 
			
		||||
     * Retrieve the {@link ExperienceManager} for this profile
 | 
			
		||||
     * @return the experience manager for this profile
 | 
			
		||||
     */
 | 
			
		||||
    public void resetCooldowns() {
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
 | 
			
		||||
        abilityDATS.replaceAll((a, v) -> 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Xp Functions
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    public int getSkillLevel(PrimarySkillType skill) {
 | 
			
		||||
        return skill.isChildSkill() ? getChildSkillLevel(skill) : skills.get(skill);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public float getSkillXpLevelRaw(PrimarySkillType skill) {
 | 
			
		||||
        return skillsXp.get(skill);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getSkillXpLevel(PrimarySkillType skill) {
 | 
			
		||||
        if(skill.isChildSkill()) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return (int) Math.floor(getSkillXpLevelRaw(skill));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setSkillXpLevel(PrimarySkillType skill, float xpLevel) {
 | 
			
		||||
        if (skill.isChildSkill()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
 | 
			
		||||
        skillsXp.put(skill, xpLevel);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public float levelUp(PrimarySkillType skill) {
 | 
			
		||||
        float xpRemoved = getXpToLevel(skill);
 | 
			
		||||
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
 | 
			
		||||
        skills.put(skill, skills.get(skill) + 1);
 | 
			
		||||
        skillsXp.put(skill, skillsXp.get(skill) - xpRemoved);
 | 
			
		||||
 | 
			
		||||
        return xpRemoved;
 | 
			
		||||
    public @NotNull ExperienceManager getExperienceManager() {
 | 
			
		||||
        return experienceManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Remove Xp from a skill.
 | 
			
		||||
     *
 | 
			
		||||
     * @param skill Type of skill to modify
 | 
			
		||||
     * @param xp Amount of xp to remove
 | 
			
		||||
     * Retrieve the {@link CooldownManager} for this profile
 | 
			
		||||
     * @return the cooldown manager for this profile
 | 
			
		||||
     */
 | 
			
		||||
    public void removeXp(PrimarySkillType skill, int xp) {
 | 
			
		||||
        if (skill.isChildSkill()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
 | 
			
		||||
        skillsXp.put(skill, skillsXp.get(skill) - xp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void removeXp(PrimarySkillType skill, float xp) {
 | 
			
		||||
        if (skill.isChildSkill()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
 | 
			
		||||
        skillsXp.put(skill, skillsXp.get(skill) - xp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Modify a skill level.
 | 
			
		||||
     *
 | 
			
		||||
     * @param skill Type of skill to modify
 | 
			
		||||
     * @param level New level value for the skill
 | 
			
		||||
     */
 | 
			
		||||
    public void modifySkill(PrimarySkillType skill, int level) {
 | 
			
		||||
        if (skill.isChildSkill()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
 | 
			
		||||
        //Don't allow levels to be negative
 | 
			
		||||
        if(level < 0)
 | 
			
		||||
            level = 0;
 | 
			
		||||
 | 
			
		||||
        skills.put(skill, level);
 | 
			
		||||
        skillsXp.put(skill, 0F);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add levels to a skill.
 | 
			
		||||
     *
 | 
			
		||||
     * @param skill Type of skill to add levels to
 | 
			
		||||
     * @param levels Number of levels to add
 | 
			
		||||
     */
 | 
			
		||||
    public void addLevels(PrimarySkillType skill, int levels) {
 | 
			
		||||
        modifySkill(skill, skills.get(skill) + levels);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add Experience to a skill.
 | 
			
		||||
     *
 | 
			
		||||
     * @param skill Type of skill to add experience to
 | 
			
		||||
     * @param xp Number of experience to add
 | 
			
		||||
     */
 | 
			
		||||
    public void addXp(PrimarySkillType skill, float xp) {
 | 
			
		||||
        markProfileDirty();
 | 
			
		||||
 | 
			
		||||
        if (skill.isChildSkill()) {
 | 
			
		||||
            Set<PrimarySkillType> parentSkills = FamilyTree.getParents(skill);
 | 
			
		||||
            float dividedXP = (xp / parentSkills.size());
 | 
			
		||||
 | 
			
		||||
            for (PrimarySkillType parentSkill : parentSkills) {
 | 
			
		||||
                skillsXp.put(parentSkill, skillsXp.get(parentSkill) + dividedXP);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            skillsXp.put(skill, skillsXp.get(skill) + xp);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the registered amount of experience gained
 | 
			
		||||
     * This is used for diminished XP returns
 | 
			
		||||
     *
 | 
			
		||||
     * @return xp Experience amount registered
 | 
			
		||||
     */
 | 
			
		||||
    public float getRegisteredXpGain(PrimarySkillType primarySkillType) {
 | 
			
		||||
        float xp = 0F;
 | 
			
		||||
 | 
			
		||||
        if (rollingSkillsXp.get(primarySkillType) != null) {
 | 
			
		||||
            xp = rollingSkillsXp.get(primarySkillType);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return xp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register an experience gain
 | 
			
		||||
     * This is used for diminished XP returns
 | 
			
		||||
     *
 | 
			
		||||
     * @param primarySkillType Skill being used
 | 
			
		||||
     * @param xp Experience amount to add
 | 
			
		||||
     */
 | 
			
		||||
    public void registerXpGain(PrimarySkillType primarySkillType, float xp) {
 | 
			
		||||
        gainedSkillsXp.add(new SkillXpGain(primarySkillType, xp));
 | 
			
		||||
        rollingSkillsXp.put(primarySkillType, getRegisteredXpGain(primarySkillType) + xp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Remove experience gains older than a given time
 | 
			
		||||
     * This is used for diminished XP returns
 | 
			
		||||
     */
 | 
			
		||||
    public void purgeExpiredXpGains() {
 | 
			
		||||
        SkillXpGain gain;
 | 
			
		||||
        while ((gain = gainedSkillsXp.poll()) != null) {
 | 
			
		||||
            rollingSkillsXp.put(gain.getSkill(), getRegisteredXpGain(gain.getSkill()) - gain.getXp());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the amount of Xp remaining before the next level.
 | 
			
		||||
     *
 | 
			
		||||
     * @param primarySkillType Type of skill to check
 | 
			
		||||
     * @return the total amount of Xp until next level
 | 
			
		||||
     */
 | 
			
		||||
    public int getXpToLevel(PrimarySkillType primarySkillType) {
 | 
			
		||||
        if(primarySkillType.isChildSkill()) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int level = (ExperienceConfig.getInstance().getCumulativeCurveEnabled()) ? UserManager.getPlayer(playerName).getPowerLevel() : skills.get(primarySkillType);
 | 
			
		||||
        FormulaType formulaType = ExperienceConfig.getInstance().getFormulaType();
 | 
			
		||||
 | 
			
		||||
        return mcMMO.getFormulaManager().getXPtoNextLevel(level, formulaType);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private int getChildSkillLevel(PrimarySkillType primarySkillType) {
 | 
			
		||||
        Set<PrimarySkillType> parents = FamilyTree.getParents(primarySkillType);
 | 
			
		||||
        int sum = 0;
 | 
			
		||||
 | 
			
		||||
        for (PrimarySkillType parent : parents) {
 | 
			
		||||
            sum += Math.min(getSkillLevel(parent), parent.getMaxLevel());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return sum / parents.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public HashMap<PrimarySkillType, ExperienceBarManager.BarState> getXpBarStateMap() {
 | 
			
		||||
        return (HashMap<PrimarySkillType, ExperienceBarManager.BarState>) xpBarState;
 | 
			
		||||
    public @NotNull CooldownManager getCooldownManager() {
 | 
			
		||||
        return cooldownManager;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user