From f9a7b918685bfb5f577f230adf940d62f81ebf4e Mon Sep 17 00:00:00 2001
From: FatBoy-DOTC <justin.chucksinsulating@gmail.com>
Date: Sun, 23 Feb 2025 14:12:00 -0600
Subject: [PATCH] new XP system

---
 src/engine/objects/Experience.java        |  14 ++-
 src/engine/objects/PlayerCombatStats.java | 129 ++++++++++++----------
 2 files changed, 77 insertions(+), 66 deletions(-)

diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java
index 902c1855..23fc3192 100644
--- a/src/engine/objects/Experience.java
+++ b/src/engine/objects/Experience.java
@@ -121,6 +121,8 @@ public class Experience {
             190585732,  // Level 77
             201714185,  // Level 78
             213319687,  // Level 79
+
+            // R8
             225415457,   // Level 80
             238014819   // Level 81
 
@@ -352,13 +354,13 @@ public class Experience {
         if(killer.pvpKills.contains(mob.getObjectUUID()))
             return;
 
-        //if(true){
-        //    if(killer.combatStats == null)
-        //        killer.combatStats = new PlayerCombatStats(killer);
+        if(true){
+            if(killer.combatStats == null)
+                killer.combatStats = new PlayerCombatStats(killer);
 
-        //    killer.combatStats.grantExperience(mob,g);
-        //    return;
-        //}
+            killer.combatStats.grantExperience(mob,g);
+            return;
+        }
 
         double grantedExperience = 0.0;
 
diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java
index 78e0ced3..94f85b20 100644
--- a/src/engine/objects/PlayerCombatStats.java
+++ b/src/engine/objects/PlayerCombatStats.java
@@ -976,88 +976,97 @@ public class PlayerCombatStats {
         double grantedXP;
 
         if(group != null){
-            float leadership = 0.0f;
-            PlayerCharacter leader = group.getGroupLead();
-            if(leader.skills.containsKey("Leadership"))
-                leadership = leader.skills.get("Leadership").getModifiedAmount();
 
-            //Group XP
             for(PlayerCharacter member : group.members){
+                //white mob, early exit
+                if(Experience.getConMod(member,killed) <= 0)
+                    continue;
 
-                //cannot level higher than 75 unless killed is a player character
+                //can only get XP over level 75 for player kills
                 if(member.level >= 75 && !killed.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
                     continue;
 
-                //not in load range, do not grant XP
-                if(member.loc.distanceSquared(killed.loc) > MBServerStatics.CHARACTER_LOAD_RANGE * MBServerStatics.CHARACTER_LOAD_RANGE)
+                //cannot gain xp while dead
+                if(!member.isAlive())
                     continue;
 
-                //checking to make sure killed is better than "white"
-                double multiplier = Experience.getConMod(member,killed);
-
-                //stop if killed is not better than "white"
-                if(multiplier == 0)
+                //out of XP range
+                if(member.loc.distanceSquared(killed.loc) > MBServerStatics.CHARACTER_LOAD_RANGE * MBServerStatics.CHARACTER_LOAD_RANGE)
                     continue;
 
-                //get experience for current level
-                int currentLevel = Experience.LevelToExp[member.level];
-
-                //get experience required for next level
-                int nextLevel = Experience.LevelToExp[member.level + 1];
-
-                //get the required experience to go form current level to next level
-                int required = nextLevel - currentLevel;
-
-                //get group member divisor
-               // float divisor =
-                 //       switch (group.members.size()) {
-                 //   case 2 -> 16.0f;
-                ///    case 3 -> 18.0f;
-                //    case 4 -> 20.0f;
-                //    case 5 -> 21.0f;
-                 //   case 6 -> 23.0f;
-                //    case 7 -> 25.0f;
-                //    case 8 -> 26.0f;
-                //    case 9 -> 28.0f;
-                //    case 10 -> 30.0f;
-                //    default -> 15.0f;
-                //};
-
-                //apply the X mob kills required rule
-                //grantedXP = required / divisor;
-
-                if(leadership > 0)
-                    multiplier += (multiplier * (leadership * 0.01f));
-
-                //member.grantXP((int) Math.floor(grantedXP * multiplier));
+                float mod;
+                switch(group.members.size()){
+                    default:
+                        mod = 1.0f;
+                        break;
+                    case 2:
+                        mod = 0.8f;
+                        break;
+                    case 3:
+                        mod = 0.73f;
+                        break;
+                    case 4:
+                        mod = 0.69f;
+                        break;
+                    case 5:
+                        mod = 0.65f;
+                        break;
+                    case 6:
+                        mod = 0.58f;
+                        break;
+                    case 7:
+                        mod = 0.54f;
+                        break;
+                    case 8:
+                        mod = 0.50f;
+                        break;
+                    case 9:
+                        mod = 0.47f;
+                        break;
+                    case 10:
+                        mod = 0.45f;
+                        break;
+                }
+                double xp = getXP(member) * mod;
+
+                member.grantXP((int) xp);
             }
+
         }else{
             //Solo XP
-            //cannot level higher than 75 unless killed is a player character
-            if(this.owner.level >= 75 && !killed.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
+
+            //white mob, early exit
+            if(Experience.getConMod(this.owner,killed) <= 0)
                 return;
 
-            //checking to make sure killed is better than "white"
-            double multiplier = Experience.getConMod(this.owner,killed);
+            //can only get XP over level 75 for player kills
+            if(this.owner.level >= 75 && !killed.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
+                return;
 
-            //stop if killed is not better than "white"
-            if(multiplier == 0)
+            //cannot gain xp while dead
+            if(!this.owner.isAlive())
                 return;
 
-            //get experience for current level
-            int currentLevel = Experience.LevelToExp[this.owner.level];
+            this.owner.grantXP(getXP(this.owner));
+        }
+    }
 
-            //get experience required for next level
-            int nextLevel = Experience.LevelToExp[this.owner.level + 1];
+    public static int getXP(PlayerCharacter pc){
+        double xp = 0;
+        float mod = 0.10f;
 
-            //get the required experience to go form current level to next level
-            int required = nextLevel - currentLevel;
+        if (pc.level >= 26 && pc.level <= 75)
+        {
+            mod = 0.10f - (0.001f * (pc.level - 25));
+        }
+        else if (pc.level > 75)
+        {
+            mod = 0.05f;
+        }
 
-            //apply the 15 mob kills required rule
-            grantedXP = required / 15.0f;
+        xp = Experience.LevelToExp[pc.level] * mod;
 
-            this.owner.grantXP((int) Math.floor(grantedXP * multiplier));
-        }
+        return (int) xp;
     }
 
 }