Browse Source

Added API to XP events to get XP gain reason

TfT_02 11 years ago
parent
commit
9f53426511
31 changed files with 276 additions and 58 deletions
  1. 1 0
      Changelog.txt
  2. 89 4
      src/main/java/com/gmail/nossr50/api/ExperienceAPI.java
  3. 9 0
      src/main/java/com/gmail/nossr50/api/exceptions/InvalidXPGainReasonException.java
  4. 2 1
      src/main/java/com/gmail/nossr50/commands/experience/AddlevelsCommand.java
  5. 2 1
      src/main/java/com/gmail/nossr50/commands/experience/AddxpCommand.java
  6. 2 1
      src/main/java/com/gmail/nossr50/commands/experience/MmoeditCommand.java
  7. 2 1
      src/main/java/com/gmail/nossr50/commands/experience/SkillresetCommand.java
  8. 13 12
      src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java
  9. 21 0
      src/main/java/com/gmail/nossr50/datatypes/skills/XPGainReason.java
  10. 18 0
      src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerExperienceEvent.java
  11. 7 1
      src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerLevelChangeEvent.java
  12. 15 2
      src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerLevelDownEvent.java
  13. 15 2
      src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerLevelUpEvent.java
  14. 8 1
      src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerXpGainEvent.java
  15. 15 2
      src/main/java/com/gmail/nossr50/party/ShareHandler.java
  16. 5 2
      src/main/java/com/gmail/nossr50/runnables/skills/AwardCombatXpTask.java
  17. 9 2
      src/main/java/com/gmail/nossr50/skills/SkillManager.java
  18. 6 5
      src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java
  19. 2 1
      src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java
  20. 1 1
      src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java
  21. 2 1
      src/main/java/com/gmail/nossr50/skills/excavation/ExcavationManager.java
  22. 3 2
      src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java
  23. 2 1
      src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java
  24. 3 2
      src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java
  25. 2 1
      src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java
  26. 2 1
      src/main/java/com/gmail/nossr50/skills/smelting/SmeltingManager.java
  27. 4 3
      src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java
  28. 3 2
      src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java
  29. 5 4
      src/main/java/com/gmail/nossr50/util/EventUtils.java
  30. 2 1
      src/main/java/com/gmail/nossr50/util/HardcoreManager.java
  31. 6 1
      src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java

+ 1 - 0
Changelog.txt

@@ -11,6 +11,7 @@ Version 1.5.01-dev
  + Added new feature to Herbalism. Instantly-regrown crops are protected from being broken for 1 second
  + Added option to config.yml to show the /mcstats scoreboard automatically after logging in
  + Added support for `MATERIAL|data` format in treasures.yml
+ + Added API to experience events to get XP gain reason
  = Fixed bug where the Updater was running on the main thread.
  = Fixed bug when players would use /ptp without being in a party
  = Fixed bug where player didn't have a mcMMOPlayer object in AsyncPlayerChatEvent

+ 89 - 4
src/main/java/com/gmail/nossr50/api/ExperienceAPI.java

@@ -7,10 +7,12 @@ import org.bukkit.entity.Player;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.api.exceptions.InvalidPlayerException;
 import com.gmail.nossr50.api.exceptions.InvalidSkillException;
+import com.gmail.nossr50.api.exceptions.InvalidXPGainReasonException;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.skills.child.FamilyTree;
 import com.gmail.nossr50.util.player.UserManager;
 
@@ -62,8 +64,26 @@ public final class ExperienceAPI {
      *
      * @throws InvalidSkillException if the given skill is not valid
      */
+    @Deprecated
     public static void addRawXP(Player player, String skillType, float XP) {
-        UserManager.getPlayer(player).applyXpGain(getSkillType(skillType), XP);
+        addRawXP(player, skillType, XP, "UNKNOWN");
+    }
+
+    /**
+     * Adds raw XP to the player.
+     * </br>
+     * This function is designed for API usage.
+     *
+     * @param player The player to add XP to
+     * @param skillType The skill to add XP to
+     * @param XP The amount of XP to add
+     * @param xpGainReason The reason to gain XP
+     *
+     * @throws InvalidSkillException if the given skill is not valid
+     * @throws InvalidXPGainReasonException if the given xpGainReason is not valid
+     */
+    public static void addRawXP(Player player, String skillType, float XP, String xpGainReason) {
+        UserManager.getPlayer(player).applyXpGain(getSkillType(skillType), XP, getXPGainReason(xpGainReason));
     }
 
     @Deprecated
@@ -98,8 +118,26 @@ public final class ExperienceAPI {
      *
      * @throws InvalidSkillException if the given skill is not valid
      */
+    @Deprecated
     public static void addMultipliedXP(Player player, String skillType, int XP) {
-        UserManager.getPlayer(player).applyXpGain(getSkillType(skillType), (int) (XP * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()));
+        addMultipliedXP(player, skillType, XP, "UNKNOWN");
+    }
+
+    /**
+     * Adds XP to the player, calculates for XP Rate only.
+     * </br>
+     * This function is designed for API usage.
+     *
+     * @param player The player to add XP to
+     * @param skillType The skill to add XP to
+     * @param XP The amount of XP to add
+     * @param xpGainReason The reason to gain XP
+     *
+     * @throws InvalidSkillException if the given skill is not valid
+     * @throws InvalidXPGainReasonException if the given xpGainReason is not valid
+     */
+    public static void addMultipliedXP(Player player, String skillType, int XP, String xpGainReason) {
+        UserManager.getPlayer(player).applyXpGain(getSkillType(skillType), (int) (XP * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()), getXPGainReason(xpGainReason));
     }
 
     /**
@@ -129,10 +167,28 @@ public final class ExperienceAPI {
      *
      * @throws InvalidSkillException if the given skill is not valid
      */
+    @Deprecated
     public static void addModifiedXP(Player player, String skillType, int XP) {
+        addModifiedXP(player, skillType, XP, "UNKNOWN");
+    }
+
+    /**
+     * Adds XP to the player, calculates for XP Rate and skill modifier.
+     * </br>
+     * This function is designed for API usage.
+     *
+     * @param player The player to add XP to
+     * @param skillType The skill to add XP to
+     * @param XP The amount of XP to add
+     * @param xpGainReason The reason to gain XP
+     *
+     * @throws InvalidSkillException if the given skill is not valid
+     * @throws InvalidXPGainReasonException if the given xpGainReason is not valid
+     */
+    public static void addModifiedXP(Player player, String skillType, int XP, String xpGainReason) {
         SkillType skill = getSkillType(skillType);
 
-        UserManager.getPlayer(player).applyXpGain(skill, (int) (XP / skill.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()));
+        UserManager.getPlayer(player).applyXpGain(skill, (int) (XP / skill.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()), getXPGainReason(xpGainReason));
     }
 
     /**
@@ -165,8 +221,27 @@ public final class ExperienceAPI {
      *
      * @throws InvalidSkillException if the given skill is not valid
      */
+    @Deprecated
     public static void addXP(Player player, String skillType, int XP) {
-        UserManager.getPlayer(player).beginXpGain(getSkillType(skillType), XP);
+        addXP(player, skillType, XP, "UNKNOWN");
+    }
+
+    /**
+     * Adds XP to the player, calculates for XP Rate, skill modifiers, perks, child skills,
+     * and party sharing.
+     * </br>
+     * This function is designed for API usage.
+     *
+     * @param player The player to add XP to
+     * @param skillType The skill to add XP to
+     * @param XP The amount of XP to add
+     * @param xpGainReason The reason to gain XP
+     *
+     * @throws InvalidSkillException if the given skill is not valid
+     * @throws InvalidXPGainReasonException if the given xpGainReason is not valid
+     */
+    public static void addXP(Player player, String skillType, int XP, String xpGainReason) {
+        UserManager.getPlayer(player).beginXpGain(getSkillType(skillType), XP, getXPGainReason(xpGainReason));
     }
 
     /**
@@ -613,4 +688,14 @@ public final class ExperienceAPI {
 
         return skill;
     }
+
+    private static XPGainReason getXPGainReason(String reason) throws InvalidXPGainReasonException {
+        XPGainReason xpGainReason = XPGainReason.getXPGainReason(reason);
+
+        if (xpGainReason == null) {
+            throw new InvalidXPGainReasonException();
+        }
+
+        return xpGainReason;
+    }
 }

+ 9 - 0
src/main/java/com/gmail/nossr50/api/exceptions/InvalidXPGainReasonException.java

@@ -0,0 +1,9 @@
+package com.gmail.nossr50.api.exceptions;
+
+public class InvalidXPGainReasonException extends RuntimeException {
+    private static final long serialVersionUID = 4427052841957931157L;
+
+    public InvalidXPGainReasonException() {
+        super("That is not a valid XPGainReason.");
+    }
+}

+ 2 - 1
src/main/java/com/gmail/nossr50/commands/experience/AddlevelsCommand.java

@@ -5,6 +5,7 @@ import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.EventUtils;
 import com.gmail.nossr50.util.Permissions;
@@ -30,7 +31,7 @@ public class AddlevelsCommand extends ExperienceCommand {
             return;
         }
 
-        EventUtils.handleLevelChangeEvent(player, skill, value, xpRemoved, true);
+        EventUtils.handleLevelChangeEvent(player, skill, value, xpRemoved, true, XPGainReason.COMMAND);
     }
 
     @Override

+ 2 - 1
src/main/java/com/gmail/nossr50/commands/experience/AddxpCommand.java

@@ -5,6 +5,7 @@ import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.player.UserManager;
@@ -23,7 +24,7 @@ public class AddxpCommand extends ExperienceCommand {
     @Override
     protected void handleCommand(Player player, PlayerProfile profile, SkillType skill, int value) {
         if (player != null) {
-            UserManager.getPlayer(player).applyXpGain(skill, value);
+            UserManager.getPlayer(player).applyXpGain(skill, value, XPGainReason.COMMAND);
         }
         else {
             profile.addXp(skill, value);

+ 2 - 1
src/main/java/com/gmail/nossr50/commands/experience/MmoeditCommand.java

@@ -5,6 +5,7 @@ import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.EventUtils;
 import com.gmail.nossr50.util.Permissions;
@@ -36,7 +37,7 @@ public class MmoeditCommand extends ExperienceCommand {
             return;
         }
 
-        EventUtils.handleLevelChangeEvent(player, skill, value, xpRemoved, value > skillLevel);
+        EventUtils.handleLevelChangeEvent(player, skill, value, xpRemoved, value > skillLevel, XPGainReason.COMMAND);
     }
 
     @Override

+ 2 - 1
src/main/java/com/gmail/nossr50/commands/experience/SkillresetCommand.java

@@ -9,6 +9,7 @@ import org.bukkit.command.TabExecutor;
 import org.bukkit.entity.Player;
 import org.bukkit.util.StringUtil;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
@@ -113,7 +114,7 @@ public class SkillresetCommand implements TabExecutor {
             return;
         }
 
-        EventUtils.handleLevelChangeEvent(player, skill, levelsRemoved, xpRemoved, false);
+        EventUtils.handleLevelChangeEvent(player, skill, levelsRemoved, xpRemoved, false, XPGainReason.COMMAND);
     }
 
     protected boolean permissionsCheckSelf(CommandSender sender) {

+ 13 - 12
src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java

@@ -13,6 +13,7 @@ import org.bukkit.inventory.ItemStack;
 import org.bukkit.metadata.FixedMetadataValue;
 import org.bukkit.scheduler.BukkitRunnable;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.AdvancedConfig;
 import com.gmail.nossr50.config.Config;
@@ -453,7 +454,7 @@ public class McMMOPlayer {
      * @param skill Skill being used
      * @param xp Experience amount to process
      */
-    public void beginXpGain(SkillType skill, float xp) {
+    public void beginXpGain(SkillType skill, float xp, XPGainReason xpGainReason) {
         Validate.isTrue(xp >= 0.0, "XP gained should be greater than or equal to zero.");
 
         if (xp <= 0.0) {
@@ -466,7 +467,7 @@ public class McMMOPlayer {
 
             for (SkillType parentSkill : parentSkills) {
                 if (parentSkill.getPermissions(player)) {
-                    beginXpGain(parentSkill, splitXp);
+                    beginXpGain(parentSkill, splitXp, xpGainReason);
                 }
             }
 
@@ -474,11 +475,11 @@ public class McMMOPlayer {
         }
 
         // Return if the experience has been shared
-        if (party != null && ShareHandler.handleXpShare(xp, this, skill)) {
+        if (party != null && ShareHandler.handleXpShare(xp, this, skill, ShareHandler.getSharedXpGainReason(xpGainReason))) {
             return;
         }
 
-        beginUnsharedXpGain(skill, xp);
+        beginUnsharedXpGain(skill, xp, xpGainReason);
     }
 
     /**
@@ -487,8 +488,8 @@ public class McMMOPlayer {
      * @param skill Skill being used
      * @param xp Experience amount to process
      */
-    public void beginUnsharedXpGain(SkillType skill, float xp) {
-        applyXpGain(skill, modifyXpGain(skill, xp));
+    public void beginUnsharedXpGain(SkillType skill, float xp, XPGainReason xpGainReason) {
+        applyXpGain(skill, modifyXpGain(skill, xp), xpGainReason);
 
         if (party == null) {
             return;
@@ -505,7 +506,7 @@ public class McMMOPlayer {
      * @param skillType Skill being used
      * @param xp Experience amount to add
      */
-    public void applyXpGain(SkillType skillType, float xp) {
+    public void applyXpGain(SkillType skillType, float xp, XPGainReason xpGainReason) {
         if (!skillType.getPermissions(player)) {
             return;
         }
@@ -514,18 +515,18 @@ public class McMMOPlayer {
             Set<SkillType> parentSkills = FamilyTree.getParents(skillType);
 
             for (SkillType parentSkill : parentSkills) {
-                applyXpGain(parentSkill, xp / parentSkills.size());
+                applyXpGain(parentSkill, xp / parentSkills.size(), xpGainReason);
             }
 
             return;
         }
 
-        if (!EventUtils.handleXpGainEvent(player, skillType, xp)) {
+        if (!EventUtils.handleXpGainEvent(player, skillType, xp, xpGainReason)) {
             return;
         }
 
         isUsingUnarmed = (skillType == SkillType.UNARMED);
-        checkXp(skillType);
+        checkXp(skillType, xpGainReason);
     }
 
     /**
@@ -533,7 +534,7 @@ public class McMMOPlayer {
      *
      * @param skillType The skill to check
      */
-    private void checkXp(SkillType skillType) {
+    private void checkXp(SkillType skillType, XPGainReason xpGainReason) {
         if (getSkillXpLevelRaw(skillType) < getXpToLevel(skillType)) {
             return;
         }
@@ -551,7 +552,7 @@ public class McMMOPlayer {
             levelsGained++;
         }
 
-        if (!EventUtils.handleLevelChangeEvent(player, skillType, levelsGained, xpRemoved, true)) {
+        if (!EventUtils.handleLevelChangeEvent(player, skillType, levelsGained, xpRemoved, true, xpGainReason)) {
             return;
         }
 

+ 21 - 0
src/main/java/com/gmail/nossr50/datatypes/skills/XPGainReason.java

@@ -0,0 +1,21 @@
+package com.gmail.nossr50.datatypes.skills;
+
+public enum XPGainReason {
+    PVP,
+    PVE,
+    VAMPIRISM,
+    SHARED_PVP,
+    SHARED_PVE,
+    COMMAND,
+    UNKNOWN;
+
+    public static XPGainReason getXPGainReason(String reason) {
+        for (XPGainReason type : values()) {
+            if (type.name().equalsIgnoreCase(reason)) {
+                return type;
+            }
+        }
+
+        return null;
+    }
+}

+ 18 - 0
src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerExperienceEvent.java

@@ -5,6 +5,7 @@ import org.bukkit.event.Cancellable;
 import org.bukkit.event.HandlerList;
 import org.bukkit.event.player.PlayerEvent;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.util.player.UserManager;
 
@@ -15,11 +16,21 @@ public abstract class McMMOPlayerExperienceEvent extends PlayerEvent implements
     private boolean cancelled;
     protected SkillType skill;
     protected int skillLevel;
+    protected XPGainReason xpGainReason;
 
+    @Deprecated
     protected McMMOPlayerExperienceEvent(Player player, SkillType skill) {
         super(player);
         this.skill = skill;
         this.skillLevel = UserManager.getPlayer(player).getSkillLevel(skill);
+        this.xpGainReason = XPGainReason.UNKNOWN;
+    }
+
+    protected McMMOPlayerExperienceEvent(Player player, SkillType skill, XPGainReason xpGainReason) {
+        super(player);
+        this.skill = skill;
+        this.skillLevel = UserManager.getPlayer(player).getSkillLevel(skill);
+        this.xpGainReason = xpGainReason;
     }
 
     /**
@@ -36,6 +47,13 @@ public abstract class McMMOPlayerExperienceEvent extends PlayerEvent implements
         return skillLevel;
     }
 
+    /**
+     * @return The combat type involved in this event
+     */
+    public XPGainReason getXpGainReason() {
+        return xpGainReason;
+    }
+
     /** Following are required for Cancellable **/
     @Override
     public boolean isCancelled() {

+ 7 - 1
src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerLevelChangeEvent.java

@@ -2,13 +2,19 @@ package com.gmail.nossr50.events.experience;
 
 import org.bukkit.entity.Player;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 
 /**
  * Called when a user levels change
  */
 public abstract class McMMOPlayerLevelChangeEvent extends McMMOPlayerExperienceEvent {
+    @Deprecated
     public McMMOPlayerLevelChangeEvent(Player player, SkillType skill) {
-        super(player, skill);
+        super(player, skill, XPGainReason.UNKNOWN);
+    }
+
+    public McMMOPlayerLevelChangeEvent(Player player, SkillType skill, XPGainReason xpGainReason) {
+        super(player, skill, xpGainReason);
     }
 }

+ 15 - 2
src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerLevelDownEvent.java

@@ -2,6 +2,7 @@ package com.gmail.nossr50.events.experience;
 
 import org.bukkit.entity.Player;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 
 /**
@@ -10,13 +11,25 @@ import com.gmail.nossr50.datatypes.skills.SkillType;
 public class McMMOPlayerLevelDownEvent extends McMMOPlayerLevelChangeEvent {
     private int levelsLost;
 
+    @Deprecated
     public McMMOPlayerLevelDownEvent(Player player, SkillType skill) {
-        super(player, skill);
+        super(player, skill, XPGainReason.UNKNOWN);
         this.levelsLost = 1;
     }
 
+    @Deprecated
     public McMMOPlayerLevelDownEvent(Player player, SkillType skill, int levelsLost) {
-        super(player, skill);
+        super(player, skill, XPGainReason.UNKNOWN);
+        this.levelsLost = levelsLost;
+    }
+
+    public McMMOPlayerLevelDownEvent(Player player, SkillType skill, XPGainReason xpGainReason) {
+        super(player, skill, xpGainReason);
+        this.levelsLost = 1;
+    }
+
+    public McMMOPlayerLevelDownEvent(Player player, SkillType skill, int levelsLost, XPGainReason xpGainReason) {
+        super(player, skill, xpGainReason);
         this.levelsLost = levelsLost;
     }
 

+ 15 - 2
src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerLevelUpEvent.java

@@ -2,6 +2,7 @@ package com.gmail.nossr50.events.experience;
 
 import org.bukkit.entity.Player;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 
 /**
@@ -10,13 +11,25 @@ import com.gmail.nossr50.datatypes.skills.SkillType;
 public class McMMOPlayerLevelUpEvent extends McMMOPlayerLevelChangeEvent {
     private int levelsGained;
 
+    @Deprecated
     public McMMOPlayerLevelUpEvent(Player player, SkillType skill) {
-        super(player, skill);
+        super(player, skill, XPGainReason.UNKNOWN);
         this.levelsGained = 1;
     }
 
+    @Deprecated
     public McMMOPlayerLevelUpEvent(Player player, SkillType skill, int levelsGained) {
-        super(player, skill);
+        super(player, skill, XPGainReason.UNKNOWN);
+        this.levelsGained = levelsGained;
+    }
+
+    public McMMOPlayerLevelUpEvent(Player player, SkillType skill, XPGainReason xpGainReason) {
+        super(player, skill, xpGainReason);
+        this.levelsGained = 1;
+    }
+
+    public McMMOPlayerLevelUpEvent(Player player, SkillType skill, int levelsGained, XPGainReason xpGainReason) {
+        super(player, skill, xpGainReason);
         this.levelsGained = levelsGained;
     }
 

+ 8 - 1
src/main/java/com/gmail/nossr50/events/experience/McMMOPlayerXpGainEvent.java

@@ -2,6 +2,7 @@ package com.gmail.nossr50.events.experience;
 
 import org.bukkit.entity.Player;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 
 /**
@@ -10,8 +11,14 @@ import com.gmail.nossr50.datatypes.skills.SkillType;
 public class McMMOPlayerXpGainEvent extends McMMOPlayerExperienceEvent {
     private float xpGained;
 
+    @Deprecated
     public McMMOPlayerXpGainEvent(Player player, SkillType skill, float xpGained) {
-        super(player, skill);
+        super(player, skill, XPGainReason.UNKNOWN);
+        this.xpGained = xpGained;
+    }
+
+    public McMMOPlayerXpGainEvent(Player player, SkillType skill, float xpGained, XPGainReason xpGainReason) {
+        super(player, skill, xpGainReason);
         this.xpGained = xpGained;
     }
 

+ 15 - 2
src/main/java/com/gmail/nossr50/party/ShareHandler.java

@@ -13,6 +13,7 @@ import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.ShareMode;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.player.UserManager;
 
@@ -27,7 +28,7 @@ public final class ShareHandler {
      * @param skillType Skill being used
      * @return True is the xp has been shared
      */
-    public static boolean handleXpShare(float xp, McMMOPlayer mcMMOPlayer, SkillType skillType) {
+    public static boolean handleXpShare(float xp, McMMOPlayer mcMMOPlayer, SkillType skillType, XPGainReason xpGainReason) {
         Party party = mcMMOPlayer.getParty();
 
         if (party.getXpShareMode() != ShareMode.EQUAL) {
@@ -47,7 +48,7 @@ public final class ShareHandler {
         float splitXp = (float) (xp / partySize * shareBonus);
 
         for (Player member : nearMembers) {
-            UserManager.getPlayer(member).beginUnsharedXpGain(skillType, splitXp);
+            UserManager.getPlayer(member).beginUnsharedXpGain(skillType, splitXp, xpGainReason);
         }
 
         return true;
@@ -142,6 +143,18 @@ public final class ShareHandler {
         }
     }
 
+    public static XPGainReason getSharedXpGainReason(XPGainReason xpGainReason) {
+        if (xpGainReason == XPGainReason.PVE) {
+            return XPGainReason.SHARED_PVE;
+        }
+        else if (xpGainReason == XPGainReason.PVP) {
+            return XPGainReason.SHARED_PVP;
+        }
+        else {
+            return xpGainReason;
+        }
+    }
+
     private static void awardDrop(Player winningPlayer, ItemStack drop) {
         if (winningPlayer.getInventory().addItem(drop).size() != 0) {
             winningPlayer.getWorld().dropItemNaturally(winningPlayer.getLocation(), drop);

+ 5 - 2
src/main/java/com/gmail/nossr50/runnables/skills/AwardCombatXpTask.java

@@ -5,19 +5,22 @@ import org.bukkit.scheduler.BukkitRunnable;
 
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 
 public class AwardCombatXpTask extends BukkitRunnable {
     private McMMOPlayer mcMMOPlayer;
     private double baseXp;
     private SkillType skillType;
     private LivingEntity target;
+    private XPGainReason xpGainReason;
     private double baseHealth;
 
-    public AwardCombatXpTask(McMMOPlayer mcMMOPlayer, SkillType skillType, double baseXp, LivingEntity target) {
+    public AwardCombatXpTask(McMMOPlayer mcMMOPlayer, SkillType skillType, double baseXp, LivingEntity target, XPGainReason xpGainReason) {
         this.mcMMOPlayer = mcMMOPlayer;
         this.skillType = skillType;
         this.baseXp = baseXp;
         this.target = target;
+        this.xpGainReason = xpGainReason;
         baseHealth = target.getHealth();
     }
 
@@ -36,6 +39,6 @@ public class AwardCombatXpTask extends BukkitRunnable {
             damage += health;
         }
 
-        mcMMOPlayer.beginXpGain(skillType, (int) (damage * baseXp));
+        mcMMOPlayer.beginXpGain(skillType, (int) (damage * baseXp), xpGainReason);
     }
 }

+ 9 - 2
src/main/java/com/gmail/nossr50/skills/SkillManager.java

@@ -1,9 +1,12 @@
 package com.gmail.nossr50.skills;
 
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.LivingEntity;
 import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.util.skills.PerksUtils;
 
 public abstract class SkillManager {
@@ -25,7 +28,11 @@ public abstract class SkillManager {
         return mcMMOPlayer.getSkillLevel(skill);
     }
 
-    public void applyXpGain(float xp) {
-        mcMMOPlayer.beginXpGain(skill, xp);
+    public void applyXpGain(float xp, XPGainReason xpGainReason) {
+        mcMMOPlayer.beginXpGain(skill, xp, xpGainReason);
+    }
+
+    public XPGainReason getXPGainReason(LivingEntity target, Entity damager) {
+        return (damager instanceof Player && target instanceof Player) ? XPGainReason.PVP : XPGainReason.PVE;
     }
 }

+ 6 - 5
src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java

@@ -12,6 +12,7 @@ import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.SecondaryAbility;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.SkillManager;
 import com.gmail.nossr50.util.Misc;
@@ -62,7 +63,7 @@ public class AcrobaticsManager extends SkillManager {
 
             // Why do we check respawn cooldown here?
             if (SkillUtils.cooldownExpired(mcMMOPlayer.getRespawnATS(), Misc.PLAYER_RESPAWN_COOLDOWN_SECONDS)) {
-                applyXpGain((float) (damage * Acrobatics.dodgeXpModifier));
+                applyXpGain((float) (damage * Acrobatics.dodgeXpModifier), XPGainReason.PVP);
             }
 
             return modifiedDamage;
@@ -88,12 +89,12 @@ public class AcrobaticsManager extends SkillManager {
 
         if (!isFatal(modifiedDamage) && SkillUtils.activationSuccessful(SecondaryAbility.ROLL, player, getSkillLevel(), activationChance)) {
             player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.Text"));
-            applyXpGain(calculateRollXP(damage, true));
+            applyXpGain(calculateRollXP(damage, true), XPGainReason.PVE);
 
             return modifiedDamage;
         }
         else if (!isFatal(damage)) {
-            applyXpGain(calculateRollXP(damage, false));
+            applyXpGain(calculateRollXP(damage, false), XPGainReason.PVE);
         }
 
         lastFallLocation = player.getLocation();
@@ -112,12 +113,12 @@ public class AcrobaticsManager extends SkillManager {
 
         if (!isFatal(modifiedDamage) && SkillUtils.activationSuccessful(SecondaryAbility.GRACEFUL_ROLL, getPlayer(), getSkillLevel(), activationChance)) {
             getPlayer().sendMessage(LocaleLoader.getString("Acrobatics.Ability.Proc"));
-            applyXpGain(calculateRollXP(damage, true));
+            applyXpGain(calculateRollXP(damage, true), XPGainReason.PVE);
 
             return modifiedDamage;
         }
         else if (!isFatal(damage)) {
-            applyXpGain(calculateRollXP(damage, false));
+            applyXpGain(calculateRollXP(damage, false), XPGainReason.PVE);
         }
 
         return damage;

+ 2 - 1
src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java

@@ -8,6 +8,7 @@ import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.skills.SkillManager;
 import com.gmail.nossr50.util.StringUtils;
 
@@ -64,6 +65,6 @@ public class AlchemyManager extends SkillManager {
     }
 
     public void handlePotionBrewSuccesses(int amount) {
-        applyXpGain((float) (ExperienceConfig.getInstance().getPotionXP() * amount));
+        applyXpGain((float) (ExperienceConfig.getInstance().getPotionXP() * amount), XPGainReason.PVE);
     }
 }

+ 1 - 1
src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java

@@ -52,7 +52,7 @@ public class ArcheryManager extends SkillManager {
             return;
         }
 
-        applyXpGain((int) (firedLocation.distanceSquared(targetLocation) * Archery.DISTANCE_XP_MULTIPLIER));
+        applyXpGain((int) (firedLocation.distanceSquared(targetLocation) * Archery.DISTANCE_XP_MULTIPLIER), getXPGainReason(target, damager));
     }
 
     /**

+ 2 - 1
src/main/java/com/gmail/nossr50/skills/excavation/ExcavationManager.java

@@ -9,6 +9,7 @@ import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.SecondaryAbility;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.datatypes.treasure.ExcavationTreasure;
 import com.gmail.nossr50.skills.SkillManager;
 import com.gmail.nossr50.util.Misc;
@@ -44,7 +45,7 @@ public class ExcavationManager extends SkillManager {
             }
         }
 
-        applyXpGain(xp);
+        applyXpGain(xp, XPGainReason.PVE);
     }
 
     /**

+ 3 - 2
src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java

@@ -34,6 +34,7 @@ import org.bukkit.potion.Potion;
 import org.bukkit.potion.PotionType;
 import org.bukkit.util.Vector;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.AdvancedConfig;
 import com.gmail.nossr50.config.Config;
@@ -348,7 +349,7 @@ public class FishingManager extends SkillManager {
             }
         }
 
-        applyXpGain(fishXp + treasureXp);
+        applyXpGain(fishXp + treasureXp, XPGainReason.PVE);
     }
 
     /**
@@ -436,7 +437,7 @@ public class FishingManager extends SkillManager {
 
             Misc.dropItem(target.getLocation(), drop);
             CombatUtils.dealDamage(target, Math.max(target.getMaxHealth() / 4, 1)); // Make it so you can shake a mob no more than 4 times.
-            applyXpGain(ExperienceConfig.getInstance().getFishingShakeXP());
+            applyXpGain(ExperienceConfig.getInstance().getFishingShakeXP(), XPGainReason.PVE);
         }
     }
 

+ 2 - 1
src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java

@@ -16,6 +16,7 @@ import org.bukkit.material.Crops;
 import org.bukkit.material.NetherWarts;
 import org.bukkit.metadata.FixedMetadataValue;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.experience.ExperienceConfig;
@@ -166,7 +167,7 @@ public class HerbalismManager extends SkillManager {
             }
         }
 
-        applyXpGain(xp);
+        applyXpGain(xp, XPGainReason.PVE);
 
         if (drops == null) {
             return;

+ 3 - 2
src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java

@@ -10,6 +10,7 @@ import org.bukkit.enchantments.Enchantment;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.TNTPrimed;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -57,7 +58,7 @@ public class MiningManager extends SkillManager {
     public void miningBlockCheck(BlockState blockState) {
         Player player = getPlayer();
 
-        applyXpGain(Mining.getBlockXp(blockState));
+        applyXpGain(Mining.getBlockXp(blockState), XPGainReason.PVE);
 
         if (!Permissions.secondaryAbilityEnabled(player, SecondaryAbility.MINING_DOUBLE_DROPS)) {
             return;
@@ -164,7 +165,7 @@ public class MiningManager extends SkillManager {
             }
         }
 
-        applyXpGain(xp);
+        applyXpGain(xp, XPGainReason.PVE);
     }
 
     /**

+ 2 - 1
src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java

@@ -12,6 +12,7 @@ import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.PlayerInventory;
 import org.bukkit.material.MaterialData;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.experience.ExperienceConfig;
@@ -144,7 +145,7 @@ public class RepairManager extends SkillManager {
         inventory.removeItem(toRemove);
 
         // Give out XP like candy
-        applyXpGain((float) ((getPercentageRepaired(startDurability, newDurability, repairable.getMaximumDurability()) * repairable.getXpMultiplier()) * ExperienceConfig.getInstance().getRepairXPBase() * ExperienceConfig.getInstance().getRepairXP(repairable.getRepairMaterialType())));
+        applyXpGain((float) ((getPercentageRepaired(startDurability, newDurability, repairable.getMaximumDurability()) * repairable.getXpMultiplier()) * ExperienceConfig.getInstance().getRepairXPBase() * ExperienceConfig.getInstance().getRepairXP(repairable.getRepairMaterialType())), XPGainReason.PVE);
 
         // BWONG BWONG BWONG
         if (Config.getInstance().getRepairAnvilUseSoundsEnabled()) {

+ 2 - 1
src/main/java/com/gmail/nossr50/skills/smelting/SmeltingManager.java

@@ -6,6 +6,7 @@ import org.bukkit.entity.Player;
 import org.bukkit.event.inventory.FurnaceBurnEvent;
 import org.bukkit.inventory.ItemStack;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.SecondaryAbility;
@@ -85,7 +86,7 @@ public class SmeltingManager extends SkillManager {
     }
 
     public ItemStack smeltProcessing(ItemStack smelting, ItemStack result) {
-        applyXpGain(Smelting.getResourceXp(smelting));
+        applyXpGain(Smelting.getResourceXp(smelting), XPGainReason.PVE);
 
         if (isSecondSmeltSuccessful()) {
             ItemStack newResult = result.clone();

+ 4 - 3
src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java

@@ -10,6 +10,7 @@ import org.bukkit.entity.Tameable;
 import org.bukkit.entity.Wolf;
 import org.bukkit.inventory.ItemStack;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.AdvancedConfig;
 import com.gmail.nossr50.config.Config;
@@ -72,15 +73,15 @@ public class TamingManager extends SkillManager {
     public void awardTamingXP(LivingEntity entity) {
         switch (entity.getType()) {
             case HORSE:
-                applyXpGain(Taming.horseXp);
+                applyXpGain(Taming.horseXp, XPGainReason.PVE);
                 return;
 
             case WOLF:
-                applyXpGain(Taming.wolfXp);
+                applyXpGain(Taming.wolfXp, XPGainReason.PVE);
                 return;
 
             case OCELOT:
-                applyXpGain(Taming.ocelotXp);
+                applyXpGain(Taming.ocelotXp, XPGainReason.PVE);
                 return;
 
             default:

+ 3 - 2
src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java

@@ -11,6 +11,7 @@ import org.bukkit.entity.Player;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.material.Tree;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.datatypes.mods.CustomBlock;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -63,7 +64,7 @@ public class WoodcuttingManager extends SkillManager {
                 }
         }
 
-        applyXpGain(xp);
+        applyXpGain(xp, XPGainReason.PVE);
     }
 
     /**
@@ -170,7 +171,7 @@ public class WoodcuttingManager extends SkillManager {
             blockState.update(true);
         }
 
-        applyXpGain(xp);
+        applyXpGain(xp, XPGainReason.PVE);
     }
 
 }

+ 5 - 4
src/main/java/com/gmail/nossr50/util/EventUtils.java

@@ -10,6 +10,7 @@ import org.bukkit.event.player.PlayerFishEvent;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.plugin.PluginManager;
 
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -52,8 +53,8 @@ public class EventUtils {
         return event;
     }
 
-    public static boolean handleLevelChangeEvent(Player player, SkillType skill, int levelsChanged, float xpRemoved, boolean isLevelUp) {
-        McMMOPlayerLevelChangeEvent event = isLevelUp ? new McMMOPlayerLevelUpEvent(player, skill, levelsChanged) : new McMMOPlayerLevelDownEvent(player, skill, levelsChanged);
+    public static boolean handleLevelChangeEvent(Player player, SkillType skill, int levelsChanged, float xpRemoved, boolean isLevelUp, XPGainReason xpGainReason) {
+        McMMOPlayerLevelChangeEvent event = isLevelUp ? new McMMOPlayerLevelUpEvent(player, skill, levelsChanged, xpGainReason) : new McMMOPlayerLevelDownEvent(player, skill, levelsChanged, xpGainReason);
         mcMMO.p.getServer().getPluginManager().callEvent(event);
 
         boolean isCancelled = event.isCancelled();
@@ -139,8 +140,8 @@ public class EventUtils {
         return !isCancelled;
     }
 
-    public static boolean handleXpGainEvent(Player player, SkillType skill, float xpGained) {
-        McMMOPlayerXpGainEvent event = new McMMOPlayerXpGainEvent(player, skill, xpGained);
+    public static boolean handleXpGainEvent(Player player, SkillType skill, float xpGained, XPGainReason xpGainReason) {
+        McMMOPlayerXpGainEvent event = new McMMOPlayerXpGainEvent(player, skill, xpGained, xpGainReason);
         mcMMO.p.getServer().getPluginManager().callEvent(event);
 
         boolean isCancelled = event.isCancelled();

+ 2 - 1
src/main/java/com/gmail/nossr50/util/HardcoreManager.java

@@ -6,6 +6,7 @@ import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.player.UserManager;
 
@@ -82,7 +83,7 @@ public final class HardcoreManager {
             totalLevelsStolen += levelsStolen;
 
             killerPlayer.addLevels(skillType, levelsStolen);
-            killerPlayer.beginUnsharedXpGain(skillType, xpStolen);
+            killerPlayer.beginUnsharedXpGain(skillType, xpStolen, XPGainReason.VAMPIRISM);
 
             victimProfile.modifySkill(skillType, victimSkillLevel - levelsStolen);
             victimProfile.removeXp(skillType, xpStolen);

+ 6 - 1
src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java

@@ -23,6 +23,7 @@ import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.datatypes.skills.XPGainReason;
 import com.gmail.nossr50.events.fake.FakeEntityDamageByEntityEvent;
 import com.gmail.nossr50.events.fake.FakeEntityDamageEvent;
 import com.gmail.nossr50.locale.LocaleLoader;
@@ -399,12 +400,14 @@ public final class CombatUtils {
      */
     private static void startGainXp(McMMOPlayer mcMMOPlayer, LivingEntity target, SkillType skillType, double multiplier) {
         double baseXP = 0;
+        XPGainReason xpGainReason;
 
         if (target instanceof Player) {
             if (!ExperienceConfig.getInstance().getExperienceGainsPlayerVersusPlayerEnabled()) {
                 return;
             }
 
+            xpGainReason = XPGainReason.PVP;
             Player defender = (Player) target;
 
             if (defender.isOnline() && SkillUtils.cooldownExpired(mcMMOPlayer.getRespawnATS(), Misc.PLAYER_RESPAWN_COOLDOWN_SECONDS)) {
@@ -473,13 +476,15 @@ public final class CombatUtils {
                 baseXP *= ExperienceConfig.getInstance().getSpawnedMobXpMultiplier();
             }
 
+            xpGainReason = XPGainReason.PVE;
+
             baseXP *= 10;
         }
 
         baseXP *= multiplier;
 
         if (baseXP != 0) {
-            new AwardCombatXpTask(mcMMOPlayer, skillType, baseXP, target).runTaskLater(mcMMO.p, 0);
+            new AwardCombatXpTask(mcMMOPlayer, skillType, baseXP, target, xpGainReason).runTaskLater(mcMMO.p, 0);
         }
     }