From 4326123fd8084a24b076f48493888bf33bfa7108 Mon Sep 17 00:00:00 2001
From: Chris Kearney <chris@kearneymail.com>
Date: Thu, 27 Aug 2015 21:38:43 -0700
Subject: [PATCH] progress on new xp stuff

---
 .../java/com/comandante/creeper/Main.java     |  4 ++
 .../comandante/creeper/command/XpCommand.java |  3 +-
 .../creeper/player/ExperienceManager.java     | 71 +++++++++++++++++--
 .../com/comandante/creeper/player/Levels.java |  3 +-
 4 files changed, 72 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/comandante/creeper/Main.java b/src/main/java/com/comandante/creeper/Main.java
index 1704c5a2..b5957623 100644
--- a/src/main/java/com/comandante/creeper/Main.java
+++ b/src/main/java/com/comandante/creeper/Main.java
@@ -7,6 +7,7 @@ import com.codahale.metrics.graphite.GraphiteReporter;
 import com.codahale.metrics.graphite.PickledGraphite;
 import com.comandante.creeper.Items.ItemUseRegistry;
 import com.comandante.creeper.entity.EntityManager;
+import com.comandante.creeper.player.ExperienceManager;
 import com.comandante.creeper.player.PlayerManagementManager;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.managers.SessionManager;
@@ -129,6 +130,9 @@ public class Main {
 
         BackportCommands.configureFibsHealth(entityManager, gameManager);
 
+        ExperienceManager.calculateXpRanges();
+        startUpMessage("Calculated XP Ranges");
+
         startUpMessage("Creeper MUD engine started");
 
         creeperServer.run(gameManager);
diff --git a/src/main/java/com/comandante/creeper/command/XpCommand.java b/src/main/java/com/comandante/creeper/command/XpCommand.java
index 869b816b..3c60a83a 100644
--- a/src/main/java/com/comandante/creeper/command/XpCommand.java
+++ b/src/main/java/com/comandante/creeper/command/XpCommand.java
@@ -3,6 +3,7 @@ package com.comandante.creeper.command;
 import com.codahale.metrics.Meter;
 import com.comandante.creeper.Main;
 import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.player.ExperienceManager;
 import com.comandante.creeper.player.Levels;
 import com.comandante.creeper.player.PlayerMetadata;
 import org.jboss.netty.channel.ChannelHandlerContext;
@@ -35,7 +36,7 @@ public class XpCommand extends Command {
         try {
             PlayerMetadata playerMetadata = playerManager.getPlayerMetadata(player.getPlayerId());
             long nextLevel = Levels.getLevel(playerMetadata.getStats().getExperience()) + 1;
-            long expToNextLevel = Levels.getXp(nextLevel) - playerMetadata.getStats().getExperience();
+            long expToNextLevel = ExperienceManager.getXpToLevel(playerMetadata.getStats().getExperience());
             Meter meter = Main.metrics.meter("experience-" + player.getPlayerName());
             StringBuilder sb = new StringBuilder();
             sb.append(NumberFormat.getNumberInstance(Locale.US).format(expToNextLevel)).append(" experience to level ").append(nextLevel).append(".\r\n");
diff --git a/src/main/java/com/comandante/creeper/player/ExperienceManager.java b/src/main/java/com/comandante/creeper/player/ExperienceManager.java
index 4c88a998..517c14f3 100644
--- a/src/main/java/com/comandante/creeper/player/ExperienceManager.java
+++ b/src/main/java/com/comandante/creeper/player/ExperienceManager.java
@@ -2,10 +2,15 @@ package com.comandante.creeper.player;
 
 import com.comandante.creeper.npc.Npc;
 import com.comandante.creeper.server.Color;
+import com.google.api.client.util.Maps;
+import com.google.common.collect.Range;
+
+import java.util.Iterator;
+import java.util.Map;
 
 public class ExperienceManager {
 
-    // http://wowwiki.wikia.com/wiki/Formulas:Mob_XP
+    public static final Map<Range<Long>, Long> rangeMap = Maps.newHashMap();
 
     public enum ExperienceType {
         RED(Color.RED),
@@ -70,7 +75,7 @@ public class ExperienceManager {
     }
 
     private static long getZeroDifference(long playerLevel) {
-        if (playerLevel >= 1 && playerLevel <= 7){
+        if (playerLevel >= 1 && playerLevel <= 7) {
             return 5;
         } else if (playerLevel >= 8 && playerLevel <= 9) {
             return 6;
@@ -100,7 +105,7 @@ public class ExperienceManager {
     }
 
     public static long getBaseXp(long playerLevel) {
-        return (playerLevel * 5) + 235;
+        return (playerLevel * 5) + 45;
     }
 
     public static long getHigherLevelNpcXp(long npcLevel, long playerLevel) {
@@ -111,12 +116,66 @@ public class ExperienceManager {
         if (getGrayLevel(playerLevel) >= npcLevel) {
             return 0;
         }
-        return getBaseXp(playerLevel) * (1 - (playerLevel - npcLevel)/getZeroDifference(playerLevel));
+        return getBaseXp(playerLevel) * (1 - (playerLevel - npcLevel) / getZeroDifference(playerLevel));
     }
 
     public static void main(String[] args) {
-        for (int i = 0; i < 70; i++) {
-            System.out.println("Level: " + i + " Gray Level: " + getGrayLevel(i) + " zero-difference:" + getZeroDifference(i) );
+        calculateXpRanges();
+        for (int i = 1; i <= 80; i++) {
+            System.out.println("Level: " + i + " Gray Level: " + getGrayLevel(i) + " zero-difference:" + getZeroDifference(i) + " xp to next level: " + getXpToNextLevel(i) + " total xp: " + totalXpNeeded(i));
+       }
+    }
+
+    private static long getXpToNextLevel(long playerLevel) {
+        if (playerLevel <= 10) {
+            return (long) ((40 * Math.pow(playerLevel, 2)) + (360 * playerLevel));
+        } else if (playerLevel >= 11 && playerLevel <= 30) {
+            return (long) ((-.4 * Math.pow(playerLevel, 3)) + (40.4 * Math.pow(playerLevel, 2)) + (396 * playerLevel));
+        } else if (playerLevel >= 31 && playerLevel <= 69) {
+            return (long) ((65 * Math.pow(playerLevel, 2) - (165 * playerLevel) - 6750) * .82);
+        } else if (playerLevel == 70) {
+            return 155 + getBaseXp(playerLevel) * (1344 - 79 - ((79 - playerLevel) * (3 + (79 - playerLevel) * 4)));
+        } else {
+            return 155 + getBaseXp(playerLevel) * (1344 - ((79 - playerLevel) * (3 + (79 - playerLevel) * 4)));
+        }
+    }
+
+    public static long totalXpNeeded(long playerLevel) {
+        long totalXp = 0;
+        if (playerLevel == 1) {
+            return 0;
+        }
+        for (int i = 1; i <= playerLevel; i++) {
+            totalXp += getXpToNextLevel(i);
+        }
+        return totalXp;
+    }
+
+    public static void calculateXpRanges() {
+        for (int i = 1; i <= 80; i++) {
+            rangeMap.put(Range.closedOpen(totalXpNeeded(i), totalXpNeeded(i + 1)), (long) i);
+        }
+    }
+
+    public static long getLevel(long experience) {
+        for (Map.Entry<Range<Long>, Long> next : rangeMap.entrySet()) {
+            if (next.getKey().contains(experience)) {
+                return next.getValue();
+            }
         }
+        return 80;
+    }
+
+    public static Range<Long> getRange(long experience) {
+        for (Map.Entry<Range<Long>, Long> next : rangeMap.entrySet()) {
+            if (next.getKey().contains(experience)) {
+                return next.getKey();
+            }
+        }
+        return Range.closedOpen(0L,0L);
+    }
+
+    public static long getXpToLevel(long experience) {
+        return getRange(experience).upperEndpoint() - experience;
     }
 }
diff --git a/src/main/java/com/comandante/creeper/player/Levels.java b/src/main/java/com/comandante/creeper/player/Levels.java
index 123a27eb..4aee9934 100644
--- a/src/main/java/com/comandante/creeper/player/Levels.java
+++ b/src/main/java/com/comandante/creeper/player/Levels.java
@@ -8,8 +8,7 @@ public class Levels {
     private static double CONSTANT_MODIFIER = 0.005;
 
     public static long getLevel(long experience) {
-        double v = CONSTANT_MODIFIER * sqrt(experience);
-        return (long) Math.floor(v);
+        return ExperienceManager.getLevel(experience);
     }
 
     public static long getXp(long level) {
-- 
GitLab