mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-22 21:26:46 +01:00
Rolling xp diminishing returns
This adds on top of the diminishing returns system a mechanic such that gains will expire the configured number of minutes after they occured, rather than all being reset at once. This prevents someone from not getting diminishing returns on the xp gain they recieved just before the reset would have occured. Obligatory explanatory graphs: http://i.imgur.com/uSzicIR.png
This commit is contained in:
parent
9d8aec7eca
commit
f4d1004d32
@ -1,7 +1,10 @@
|
||||
package com.gmail.nossr50.datatypes.player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -12,6 +15,7 @@ import com.gmail.nossr50.datatypes.MobHealthbarType;
|
||||
import com.gmail.nossr50.datatypes.experience.FormulaType;
|
||||
import com.gmail.nossr50.datatypes.skills.AbilityType;
|
||||
import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SkillXpGain;
|
||||
import com.gmail.nossr50.runnables.player.PlayerProfileSaveTask;
|
||||
import com.gmail.nossr50.skills.child.FamilyTree;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
@ -33,7 +37,8 @@ public class PlayerProfile {
|
||||
private final Map<AbilityType, Integer> abilityDATS = new HashMap<AbilityType, Integer>(); // Ability & Cooldown
|
||||
|
||||
// Store previous XP gains for diminished returns
|
||||
private Map<SkillType, Float> gainedSkillsXp = new HashMap<SkillType, Float>();
|
||||
private HashMap<SkillType, LinkedList<SkillXpGain>> gainedSkillsXp = new HashMap<SkillType, LinkedList<SkillXpGain>>();
|
||||
private HashMap<SkillType, Float> rollingSkillsXp = new HashMap<SkillType, Float>();
|
||||
|
||||
@Deprecated
|
||||
public PlayerProfile(String playerName) {
|
||||
@ -283,29 +288,15 @@ public class PlayerProfile {
|
||||
* @return xp Experience amount registered
|
||||
*/
|
||||
public float getRegisteredXpGain(SkillType skillType) {
|
||||
float xp;
|
||||
float xp = 0F;
|
||||
|
||||
if (gainedSkillsXp.get(skillType) == null) {
|
||||
xp = 0F;
|
||||
}
|
||||
else {
|
||||
xp = gainedSkillsXp.get(skillType);
|
||||
if (rollingSkillsXp.get(skillType) != null) {
|
||||
xp = rollingSkillsXp.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
|
||||
@ -314,7 +305,46 @@ public class PlayerProfile {
|
||||
* @param xp Experience amount to add
|
||||
*/
|
||||
public void registeredXpGain(SkillType skillType, float xp) {
|
||||
gainedSkillsXp.put(skillType, getRegisteredXpGain(skillType) + xp);
|
||||
LinkedList<SkillXpGain> gains = gainedSkillsXp.get(skillType);
|
||||
|
||||
if (gains == null) {
|
||||
gains = new LinkedList<SkillXpGain>(); // Maybe add an initial capacity?
|
||||
}
|
||||
gains.addLast(new SkillXpGain(System.currentTimeMillis(), xp));
|
||||
|
||||
gainedSkillsXp.put(skillType, gains);
|
||||
rollingSkillsXp.put(skillType, getRegisteredXpGain(skillType) + xp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove experience gains older than a given time
|
||||
* This is used for diminished XP returns
|
||||
*
|
||||
* @param age Age in milliseconds that gains older than should be removed
|
||||
*/
|
||||
public void removeXpGainsOlderThan(long age) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
Iterator<Entry<SkillType, LinkedList<SkillXpGain>>> iterator = gainedSkillsXp.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Entry<SkillType, LinkedList<SkillXpGain>> skillGains = iterator.next();
|
||||
|
||||
float xp = 0;
|
||||
// Because we are using a LinkedList and addLast ordering is guaranteed, so we loop through and remove things that are too old, and stop immediately once we find a young'n
|
||||
Iterator<SkillXpGain> gainsIterator = skillGains.getValue().iterator();
|
||||
while (gainsIterator.hasNext()) {
|
||||
SkillXpGain gain = gainsIterator.next();
|
||||
|
||||
if (now - gain.getTime() >= age) {
|
||||
gainsIterator.remove();
|
||||
xp += gain.getXp();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
rollingSkillsXp.put(skillGains.getKey(), rollingSkillsXp.get(skillGains.getKey()) - xp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,19 @@
|
||||
package com.gmail.nossr50.datatypes.skills;
|
||||
|
||||
public class SkillXpGain {
|
||||
private final long time;
|
||||
private final float xp;
|
||||
|
||||
public SkillXpGain(long time, float xp) {
|
||||
this.time = time;
|
||||
this.xp = xp;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public float getXp() {
|
||||
return xp;
|
||||
}
|
||||
}
|
@ -47,9 +47,15 @@ public class SelfListener implements Listener {
|
||||
int threshold = ExperienceConfig.getInstance().getDeminishedReturnsThreshold();
|
||||
|
||||
if (threshold <= 0) {
|
||||
// Diminished returns is turned off
|
||||
return;
|
||||
}
|
||||
|
||||
final float rawXp = event.getRawXpGained();
|
||||
if (rawXp < 0) {
|
||||
return; // Don't calculate for XP subtraction
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
SkillType skillType = event.getSkill();
|
||||
@ -58,18 +64,22 @@ public class SelfListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
float difference = (mcMMOPlayer.getProfile().getRegisteredXpGain(skillType) - threshold) / threshold;
|
||||
float modifiedThreshold = (float) (threshold / skillType.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
|
||||
float difference = (mcMMOPlayer.getProfile().getRegisteredXpGain(skillType) - modifiedThreshold) / modifiedThreshold;
|
||||
|
||||
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);
|
||||
float newValue = rawXp - (rawXp * difference);
|
||||
|
||||
event.setRawXpGained(newValue);
|
||||
if (newValue > 0) {
|
||||
event.setRawXpGained(newValue);
|
||||
}
|
||||
else {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
mcMMOPlayer.getProfile().registeredXpGain(skillType, event.getRawXpGained());
|
||||
}
|
||||
}
|
||||
|
@ -496,10 +496,8 @@ public class mcMMO extends JavaPlugin {
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (ExperienceConfig.getInstance().getDeminishedReturnsThreshold() > 0) {
|
||||
new ClearRegisteredXPGainTask().runTaskTimer(this, 60 * 20, 60 * 20);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,20 +2,15 @@ package com.gmail.nossr50.runnables.player;
|
||||
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
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.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);
|
||||
}
|
||||
mcMMOPlayer.getProfile().removeXpGainsOlderThan(ExperienceConfig.getInstance().getDeminishedReturnsTimeInterval() * 60 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,6 +161,7 @@ public class EventUtils {
|
||||
|
||||
if (!isCancelled) {
|
||||
UserManager.getPlayer(player).addXp(skill, event.getRawXpGained());
|
||||
UserManager.getPlayer(player).getProfile().registeredXpGain(skill, event.getRawXpGained());
|
||||
}
|
||||
|
||||
return !isCancelled;
|
||||
|
Loading…
Reference in New Issue
Block a user