mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-26 07:06:45 +01:00
Use a DelayQueue to manage rolling diminished returns
This commit is contained in:
parent
2a443cd9db
commit
332860b9ce
@ -1,12 +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;
|
||||
import java.util.concurrent.DelayQueue;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
@ -36,8 +34,8 @@ public class PlayerProfile {
|
||||
private final Map<SkillType, Float> skillsXp = new HashMap<SkillType, Float>(); // Skill & XP
|
||||
private final Map<AbilityType, Integer> abilityDATS = new HashMap<AbilityType, Integer>(); // Ability & Cooldown
|
||||
|
||||
// Store previous XP gains for diminished returns
|
||||
private HashMap<SkillType, LinkedList<SkillXpGain>> gainedSkillsXp = new HashMap<SkillType, LinkedList<SkillXpGain>>();
|
||||
// Store previous XP gains for deminished returns
|
||||
private DelayQueue<SkillXpGain> gainedSkillsXp = new DelayQueue<SkillXpGain>();
|
||||
private HashMap<SkillType, Float> rollingSkillsXp = new HashMap<SkillType, Float>();
|
||||
|
||||
@Deprecated
|
||||
@ -304,15 +302,8 @@ public class PlayerProfile {
|
||||
* @param skillType Skill being used
|
||||
* @param xp Experience amount to add
|
||||
*/
|
||||
public void registeredXpGain(SkillType skillType, float 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);
|
||||
public void registerXpGain(SkillType skillType, float xp) {
|
||||
gainedSkillsXp.add(new SkillXpGain(skillType, xp));
|
||||
rollingSkillsXp.put(skillType, getRegisteredXpGain(skillType) + xp);
|
||||
}
|
||||
|
||||
@ -322,28 +313,10 @@ public class PlayerProfile {
|
||||
*
|
||||
* @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);
|
||||
public void purgeExpiredXpGains() {
|
||||
SkillXpGain gain = null;
|
||||
while ((gain = gainedSkillsXp.poll()) != null) {
|
||||
rollingSkillsXp.put(gain.getSkill(), getRegisteredXpGain(gain.getSkill()) - gain.getXp());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,54 @@
|
||||
package com.gmail.nossr50.datatypes.skills;
|
||||
|
||||
public class SkillXpGain {
|
||||
private final long time;
|
||||
private final float xp;
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public SkillXpGain(long time, float xp) {
|
||||
this.time = time;
|
||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
|
||||
|
||||
public class SkillXpGain implements Delayed {
|
||||
private final long expiryTime;
|
||||
private final float xp;
|
||||
private final SkillType type;
|
||||
|
||||
public SkillXpGain(SkillType type, float xp) {
|
||||
this.expiryTime = System.currentTimeMillis() + getDuration();
|
||||
this.xp = xp;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
public SkillType getSkill() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public float getXp() {
|
||||
return xp;
|
||||
}
|
||||
|
||||
private static long getDuration() {
|
||||
return TimeUnit.MINUTES.toMillis(ExperienceConfig.getInstance().getDiminishedReturnsTimeInterval());
|
||||
}
|
||||
|
||||
public int compareTo(SkillXpGain other) {
|
||||
if (this.expiryTime < other.expiryTime) {
|
||||
return -1;
|
||||
}
|
||||
else if (this.expiryTime > other.expiryTime) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Delayed other) {
|
||||
if (other instanceof SkillXpGain) {
|
||||
// Use more efficient method if possible (private fields)
|
||||
return this.compareTo((SkillXpGain) other);
|
||||
}
|
||||
return (int) (getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDelay(TimeUnit arg0) {
|
||||
return arg0.convert(expiryTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
@ -497,7 +497,7 @@ public class mcMMO extends JavaPlugin {
|
||||
|
||||
// Clear the registered XP data so players can earn XP again
|
||||
if (ExperienceConfig.getInstance().getDiminishedReturnsThreshold() > 0) {
|
||||
new ClearRegisteredXPGainTask().runTaskTimer(this, 60 * 20, 60 * 20);
|
||||
new ClearRegisteredXPGainTask().runTaskTimer(this, 60, 60);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ 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.util.player.UserManager;
|
||||
|
||||
@ -10,7 +9,7 @@ public class ClearRegisteredXPGainTask extends BukkitRunnable {
|
||||
@Override
|
||||
public void run() {
|
||||
for (McMMOPlayer mcMMOPlayer : UserManager.getPlayers()) {
|
||||
mcMMOPlayer.getProfile().removeXpGainsOlderThan(ExperienceConfig.getInstance().getDiminishedReturnsTimeInterval() * 60 * 1000);
|
||||
mcMMOPlayer.getProfile().purgeExpiredXpGains();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ public class EventUtils {
|
||||
|
||||
if (!isCancelled) {
|
||||
UserManager.getPlayer(player).addXp(skill, event.getRawXpGained());
|
||||
UserManager.getPlayer(player).getProfile().registeredXpGain(skill, event.getRawXpGained());
|
||||
UserManager.getPlayer(player).getProfile().registerXpGain(skill, event.getRawXpGained());
|
||||
}
|
||||
|
||||
return !isCancelled;
|
||||
|
Loading…
Reference in New Issue
Block a user