It's pretty simple: it allows admins to config specific XP and SP rates to level ranges. If the config is empty or the level is missing inside the ranges the default RateXp or RateSp will be used to calc.
The code could be a little messy and be improved, but it's working as is.
Once more my Eclipse have some problems to create patches, then there's the instructions:
### Eclipse Workspace Patch 1.0
#P L2J_Mobius_Essence_6.3_Crusader
diff --git dist/game/config/Rates.ini dist/game/config/Rates.ini
index ed2da11..8a03bb5 100644
--- dist/game/config/Rates.ini
+++ dist/game/config/Rates.ini
@@ -18,6 +18,12 @@
# Skill points multiplier (Party)
RatePartySp = 10
+# Experience and Skill Points multipliers by level range
+# Format: start,end,rate;start2,end2,rate2;
+# Defatult: empty
+RateXpByLevelRange = 1,39,10;40,75,5;76,99,2;
+RateSpByLevelRange = 1,39,10;40,75,5;76,99,2;
+
# Instance rates
# Those rates are used as absolute rate within instances, does not applies on top of RateXp for example!
# Default: -1 (Uses the rates above)
On /L2J_Mobius_Essence_6.3_Crusader/java/org/l2jmobius/Config.java set
public static String RATE_XP_BY_LEVEL;
public static String RATE_SP_BY_LEVEL;
Then pull the configs @ line 2425:
RATE_XP_BY_LEVEL = ratesConfig.getString("RateXpByLevelRange", "");
RATE_SP_BY_LEVEL = ratesConfig.getString("RateSpByLevelRange", "");
On /L2J_Mobius_Essence_6.3_Crusader/java/org/l2jmobius/gameserver/model/actor/Npc.java find and replace the following methods starting at line 878:
/**
* @param charLevel
* @return the Exp Reward of this Npc (modified by RATE_XP or RATE_XP_BY_LEVEL).
*/
public double getExpReward(int charLevel)
{
final Instance instance = getInstanceWorld();
final float rateMul = instance != null ? instance.getExpRate() : Config.RATE_XP;
for (String listOfXpRate : Config.RATE_XP_BY_LEVEL.split(";"))
{
final String[] rateSplit = listOfXpRate.split(",");
if (rateSplit.length == 3)
{
if ((charLevel >= Integer.parseInt(rateSplit[0])) && (charLevel <= Integer.parseInt(rateSplit[1])))
{
return getTemplate().getExp() * Integer.parseInt(rateSplit[2]);
}
}
}
return getTemplate().getExp() * rateMul;
}
/**
* @param charLevel
* @return the SP Reward of this Npc (modified by RATE_SP or RATE_SP_BY_LEVEL).
*/
public double getSpReward(int charLevel)
{
final Instance instance = getInstanceWorld();
final float rateMul = instance != null ? instance.getSPRate() : Config.RATE_SP;
for (String listOfSpRate : Config.RATE_SP_BY_LEVEL.split(";"))
{
final String[] rateSplit = listOfSpRate.split(",");
if (rateSplit.length == 3)
{
if ((charLevel >= Integer.parseInt(rateSplit[0])) && (charLevel <= Integer.parseInt(rateSplit[1])))
{
return getTemplate().getSP() * Integer.parseInt(rateSplit[2]);
}
}
}
return getTemplate().getSP() * rateMul;
}
On /L2J_Mobius_Essence_6.3_Crusader/java/org/l2jmobius/gameserver/model/actor/Attackable.java at line 1787 replace as follow:
From:
if ((getLevel() <= 0) || (getExpReward() <= 0) || (isBoss && (Config.VITALITY_CONSUME_BY_BOSS == 0)))
To:
if ((getLevel() <= 0) || (getExpReward(level) <= 0) || (isBoss && (Config.VITALITY_CONSUME_BY_BOSS == 0)))