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' ###