diff --git a/src/main/java/com/gmail/nossr50/config/Config.java b/src/main/java/com/gmail/nossr50/config/Config.java index cc2f28182..d89b07917 100644 --- a/src/main/java/com/gmail/nossr50/config/Config.java +++ b/src/main/java/com/gmail/nossr50/config/Config.java @@ -281,6 +281,9 @@ public class Config extends AutoUpdateConfigLoader { */ /* General Settings */ + public boolean getExperienceGainsMobspawnersEnabled() { return config.getBoolean("Experience.Gains.Mobspawners.Enabled", false); } + public int getExperienceDeminishedReturnsThreshold() { return config.getInt("Experience.Gains.Deminished_Returns.Threshold", 20000); } + public int getExperienceDeminishedReturnsTimeInterval() { return config.getInt("Experience.Gains.Deminished_Returns.Time_Interval", 10); } public boolean getExperienceGainsPlayerVersusPlayerEnabled() { return config.getBoolean("Experience.PVP.Rewards", true); } public double getExperienceGainsGlobalMultiplier() { return config.getDouble("Experience.Gains.Multiplier.Global", 1.0); } diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java index 328e6f8e7..2835b341c 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java @@ -39,6 +39,9 @@ public class PlayerProfile { private final Map skillsXp = new HashMap(); // Skill & XP private final Map skillsDATS = new HashMap(); // Ability & Cooldown + // Store previous XP gains for deminished returns + private Map gainedSkillsXp = new HashMap(); + public PlayerProfile(String playerName, boolean addNew) { this.playerName = playerName; @@ -246,6 +249,47 @@ public class PlayerProfile { skillsXp.put(skillType, skillsXp.get(skillType) + experience); } + /** + * Get the registered amount of experience gained + * This is used for diminished XP returns + * + * @return xp Experience amount registered + */ + public float getRegisteredXpGain(SkillType skillType) { + float xp; + + if (gainedSkillsXp.get(skillType) == null) { + xp = 0F; + } + else { + xp = gainedSkillsXp.get(skillType); + } + + return xp; + } + + /** + * Set registered experience gains + * This is used for diminished XP returns + * + * @param skillType Skill being used + * @param xp Experience amount to set + */ + public void setRegisteredXpGain(SkillType skillType, float xp) { + gainedSkillsXp.put(skillType, xp); + } + + /** + * Register an experience gain + * This is used for diminished XP returns + * + * @param skillType Skill being used + * @param xp Experience amount to add + */ + public void registeredXpGain(SkillType skillType, float xp) { + gainedSkillsXp.put(skillType, getRegisteredXpGain(skillType) + xp); + } + /** * Get the amount of Xp remaining before the next level. * diff --git a/src/main/java/com/gmail/nossr50/listeners/SelfListener.java b/src/main/java/com/gmail/nossr50/listeners/SelfListener.java index 76479f112..2b9bdfd14 100644 --- a/src/main/java/com/gmail/nossr50/listeners/SelfListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/SelfListener.java @@ -6,7 +6,11 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import com.gmail.nossr50.config.Config; +import com.gmail.nossr50.datatypes.player.McMMOPlayer; +import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.events.experience.McMMOPlayerLevelUpEvent; +import com.gmail.nossr50.events.experience.McMMOPlayerXpGainEvent; +import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.skills.ParticleEffectUtils; public class SelfListener implements Listener { @@ -29,4 +33,35 @@ public class SelfListener implements Listener { ParticleEffectUtils.runescapeModeCelebration(player, event.getSkill()); } } -} + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerXpGain(McMMOPlayerXpGainEvent event) { + int threshold = Config.getInstance().getExperienceDeminishedReturnsThreshold(); + + if (threshold <= 0) { + return; + } + + Player player = event.getPlayer(); + McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); + SkillType skillType = event.getSkill(); + + if (skillType.isChildSkill()) { + return; + } + + float difference = (mcMMOPlayer.getProfile().getRegisteredXpGain(skillType) - threshold) / threshold; + + if (difference > 0) { +// System.out.println("Total XP Earned: " + mcMMOPlayer.getProfile().getRegisteredXpGain(skillType) + " / Threshold value: " + threshold); +// System.out.println(difference * 100 + "% over the threshold!"); +// System.out.println("Previous: " + event.getRawXpGained()); +// System.out.println("Adjusted XP " + (event.getRawXpGained() - (event.getRawXpGained() * difference))); + float newValue = event.getRawXpGained() - (event.getRawXpGained() * difference); + + event.setRawXpGained(newValue); + } + + mcMMOPlayer.getProfile().registeredXpGain(skillType, event.getRawXpGained()); + } +} \ No newline at end of file diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 989057dc2..002d7dd13 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -36,6 +36,7 @@ import com.gmail.nossr50.party.PartyManager; import com.gmail.nossr50.runnables.SaveTimerTask; import com.gmail.nossr50.runnables.database.UserPurgeTask; import com.gmail.nossr50.runnables.party.PartyAutoKickTask; +import com.gmail.nossr50.runnables.player.ClearRegisteredXPGainTask; import com.gmail.nossr50.runnables.skills.BleedTimerTask; import com.gmail.nossr50.skills.child.ChildConfig; import com.gmail.nossr50.skills.repair.Repairable; @@ -365,5 +366,12 @@ public class mcMMO extends JavaPlugin { else if (kickIntervalTicks > 0) { new PartyAutoKickTask().runTaskTimer(this, kickIntervalTicks, kickIntervalTicks); } + + // Clear the registered XP data so players can earn XP again + long clearRegisteredXPGainInterval = Config.getInstance().getExperienceDeminishedReturnsTimeInterval() * 60 * 20; + + if (kickIntervalTicks > 0 && Config.getInstance().getExperienceDeminishedReturnsThreshold() > 0) { + new ClearRegisteredXPGainTask().runTaskTimer(this, clearRegisteredXPGainInterval, clearRegisteredXPGainInterval); + } } } diff --git a/src/main/java/com/gmail/nossr50/runnables/player/ClearRegisteredXPGainTask.java b/src/main/java/com/gmail/nossr50/runnables/player/ClearRegisteredXPGainTask.java new file mode 100644 index 000000000..5c3c433c2 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/runnables/player/ClearRegisteredXPGainTask.java @@ -0,0 +1,21 @@ +package com.gmail.nossr50.runnables.player; + +import org.bukkit.scheduler.BukkitRunnable; + +import com.gmail.nossr50.datatypes.player.McMMOPlayer; +import com.gmail.nossr50.datatypes.skills.SkillType; +import com.gmail.nossr50.util.player.UserManager; + +public class ClearRegisteredXPGainTask extends BukkitRunnable { + @Override + public void run() { + for (McMMOPlayer mcMMOPlayer : UserManager.getPlayers().values()) { + for (SkillType skillType : SkillType.values()) { + if (skillType.isChildSkill()) { + continue; + } + mcMMOPlayer.getProfile().setRegisteredXpGain(skillType, 0F); + } + } + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index f708af2ee..23d4aa26e 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -284,6 +284,12 @@ Experience: Mobspawners: Multiplier: 0 + # Limit the amount of experience a player can earn: + # Threshold (amount of experience) per Time_Interval (in minutes) + Deminished_Returns: + Threshold: 20000 + Time_Interval: 10 + # Experience gained in every skill will get multiplied by this value. 1.0 by default, 2.0 means two times as much Multiplier: PVP: 1.0