From 9d8aec7ecac1b515ab93cc99747712f8f3f417e6 Mon Sep 17 00:00:00 2001 From: TfT_02 Date: Fri, 3 May 2013 21:26:20 +0200 Subject: [PATCH] Add diminished returns when a player has earned too much XP When a player reaches a certain (configurable) threshold value of total XP earned in a specific skill, his earned XP in this skill will be decreased. Depending on how far the player has exceeded the threshold value, his XP will decrease more. After the (configurable) time interval of 10 minutes, the registered data will be cleared and the player can earn XP as normal again. --- .../config/experience/ExperienceConfig.java | 4 ++ .../datatypes/player/PlayerProfile.java | 46 ++++++++++++++++++- .../gmail/nossr50/listeners/SelfListener.java | 34 ++++++++++++++ src/main/java/com/gmail/nossr50/mcMMO.java | 9 ++++ .../player/ClearRegisteredXPGainTask.java | 21 +++++++++ src/main/resources/experience.yml | 9 ++++ 6 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/gmail/nossr50/runnables/player/ClearRegisteredXPGainTask.java diff --git a/src/main/java/com/gmail/nossr50/config/experience/ExperienceConfig.java b/src/main/java/com/gmail/nossr50/config/experience/ExperienceConfig.java index 6db77ce2c..bb540a631 100644 --- a/src/main/java/com/gmail/nossr50/config/experience/ExperienceConfig.java +++ b/src/main/java/com/gmail/nossr50/config/experience/ExperienceConfig.java @@ -179,6 +179,10 @@ public class ExperienceConfig extends AutoUpdateConfigLoader { /* Custom XP perk */ public double getCustomXpPerkBoost() { return config.getDouble("Experience_Formula.Custom_XP_Perk.Boost", 1.25); } + /* Deminished Returns */ + public int getDeminishedReturnsThreshold() { return config.getInt("Deminished_Returns.Threshold", 20000); } + public int getDeminishedReturnsTimeInterval() { return config.getInt("Deminished_Returns.Time_Interval", 10); } + /* Conversion */ public double getExpModifier() { return config.getDouble("Conversion.Exp_Modifier", 1); } 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 53686c5e5..24eb86ada 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java @@ -32,6 +32,9 @@ public class PlayerProfile { private final Map skillsXp = new HashMap(); // Skill & XP private final Map abilityDATS = new HashMap(); // Ability & Cooldown + // Store previous XP gains for diminished returns + private Map gainedSkillsXp = new HashMap(); + @Deprecated public PlayerProfile(String playerName) { this(playerName, null); @@ -274,7 +277,48 @@ public class PlayerProfile { } /** - * Get the total amount of Xp before the next level. + * 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. * * @param skillType Type of skill to check * @return the total amount of Xp until 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 f844cf68e..7b9c3e975 100644 --- a/src/main/java/com/gmail/nossr50/listeners/SelfListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/SelfListener.java @@ -6,10 +6,13 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; 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.events.experience.McMMOPlayerLevelUpEvent; import com.gmail.nossr50.events.experience.McMMOPlayerXpGainEvent; import com.gmail.nossr50.events.skills.abilities.McMMOPlayerAbilityActivateEvent; +import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.scoreboards.ScoreboardManager; public class SelfListener implements Listener { @@ -38,4 +41,35 @@ public class SelfListener implements Listener { public void onAbility(McMMOPlayerAbilityActivateEvent event) { ScoreboardManager.cooldownUpdate(event.getPlayer(), event.getSkill()); } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerXpGain(McMMOPlayerXpGainEvent event) { + int threshold = ExperienceConfig.getInstance().getDeminishedReturnsThreshold(); + + 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()); + } } diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index bf3a91276..ff201eaa0 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -14,6 +14,7 @@ import org.bukkit.plugin.java.JavaPlugin; import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.HiddenConfig; +import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.config.mods.ArmorConfigManager; import com.gmail.nossr50.config.mods.BlockConfigManager; import com.gmail.nossr50.config.mods.EntityConfigManager; @@ -38,6 +39,7 @@ import com.gmail.nossr50.runnables.UpdaterResultAsyncTask; import com.gmail.nossr50.runnables.backups.CleanBackupsTask; 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.player.PlayerProfileLoadingTask; import com.gmail.nossr50.runnables.player.PowerLevelUpdatingTask; import com.gmail.nossr50.runnables.skills.BleedTimerTask; @@ -492,6 +494,13 @@ public class mcMMO extends JavaPlugin { if (getHolidayManager().nearingAprilFirst()) { new CheckDateTask().runTaskTimer(this, 10L * Misc.TICK_CONVERSION_FACTOR, 1L * 60L * 60L * Misc.TICK_CONVERSION_FACTOR); } + + // Clear the registered XP data so players can earn XP again + long clearRegisteredXPGainInterval = ExperienceConfig.getInstance().getDeminishedReturnsTimeInterval() * 60 * 20; + + if (clearRegisteredXPGainInterval > 0 && ExperienceConfig.getInstance().getDeminishedReturnsThreshold() > 0) { + new ClearRegisteredXPGainTask().runTaskTimer(this, clearRegisteredXPGainInterval, clearRegisteredXPGainInterval); + } } private void checkModConfigs() { 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..f1d2d73d0 --- /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()) { + for (SkillType skillType : SkillType.values()) { + if (skillType.isChildSkill()) { + continue; + } + mcMMOPlayer.getProfile().setRegisteredXpGain(skillType, 0F); + } + } + } +} diff --git a/src/main/resources/experience.yml b/src/main/resources/experience.yml index e1e47006e..dfd1e2a20 100644 --- a/src/main/resources/experience.yml +++ b/src/main/resources/experience.yml @@ -59,6 +59,15 @@ Experience_Formula: Custom_XP_Perk: Boost: 1.25 +# +# Settings for Deminished Returns +### +Deminished_Returns: + # Limit the amount of experience a player can earn: + # Threshold (amount of experience) per Time_Interval (in minutes) + Threshold: 20000 + Time_Interval: 10 + # # Settings for XP conversion with '/mcconvert experience' ###