Changed bonus exp/sp calculations.

This commit is contained in:
MobiusDev 2018-04-11 07:18:25 +00:00
parent 765ca8f160
commit f96eacc903
26 changed files with 549 additions and 502 deletions

View File

@ -473,6 +473,10 @@ public class L2Attackable extends L2Npc
// Calculate Exp and SP rewards
if (isInSurroundingRegion(attacker))
{
// Calculate the difference of level between this attacker (player or servitor owner) and the L2Attackable
// mob = 24, atk = 10, diff = -14 (full xp)
// mob = 24, atk = 28, diff = 4 (some xp)
// mob = 24, atk = 50, diff = 26 (no xp)
final double[] expSp = calculateExpAndSp(attacker.getLevel(), damage, totalDamage);
double exp = expSp[0];
double sp = expSp[1];
@ -1356,67 +1360,70 @@ public class L2Attackable extends L2Npc
*/
private double[] calculateExpAndSp(int charLevel, int damage, long totalDamage)
{
final int levelDiff = Math.abs(charLevel - getLevel());
double xp = Math.max(0, (getExpReward() * damage) / totalDamage);
double sp = Math.max(0, (getSpReward() * damage) / totalDamage);
double mul;
switch (levelDiff)
final int levelDiff = charLevel - getLevel();
double xp = 0;
double sp = 0;
if ((levelDiff < 11) && (levelDiff > -11))
{
case 0:
case 1:
case 2:
xp = Math.max(0, (getExpReward() * damage) / totalDamage);
sp = Math.max(0, (getSpReward() * damage) / totalDamage);
if ((charLevel > 84) && (levelDiff <= -3))
{
mul = 1.;
break;
}
case 3:
{
mul = 0.97;
break;
}
case 4:
{
mul = 0.67;
break;
}
case 5:
{
mul = 0.42;
break;
}
case 6:
{
mul = 0.25;
break;
}
case 7:
{
mul = 0.15;
break;
}
case 8:
{
mul = 0.09;
break;
}
case 9:
{
mul = 0.05;
break;
}
case 10:
{
mul = 0.03;
break;
}
default:
{
mul = 0.;
break;
double mul;
switch (levelDiff)
{
case -3:
{
mul = 0.97;
break;
}
case -4:
{
mul = 0.67;
break;
}
case -5:
{
mul = 0.42;
break;
}
case -6:
{
mul = 0.25;
break;
}
case -7:
{
mul = 0.15;
break;
}
case -8:
{
mul = 0.09;
break;
}
case -9:
{
mul = 0.05;
break;
}
case -10:
{
mul = 0.03;
break;
}
default:
{
mul = 1.;
break;
}
}
xp *= mul;
sp *= mul;
}
}
xp *= mul;
sp *= mul;
return new double[]
{

View File

@ -469,6 +469,10 @@ public class L2Attackable extends L2Npc
// Calculate Exp and SP rewards
if (isInSurroundingRegion(attacker))
{
// Calculate the difference of level between this attacker (player or servitor owner) and the L2Attackable
// mob = 24, atk = 10, diff = -14 (full xp)
// mob = 24, atk = 28, diff = 4 (some xp)
// mob = 24, atk = 50, diff = 26 (no xp)
final double[] expSp = calculateExpAndSp(attacker.getLevel(), damage, totalDamage);
double exp = expSp[0];
double sp = expSp[1];
@ -1302,67 +1306,70 @@ public class L2Attackable extends L2Npc
*/
private double[] calculateExpAndSp(int charLevel, int damage, long totalDamage)
{
final int levelDiff = Math.abs(charLevel - getLevel());
double xp = Math.max(0, (getExpReward() * damage) / totalDamage);
double sp = Math.max(0, (getSpReward() * damage) / totalDamage);
double mul;
switch (levelDiff)
final int levelDiff = charLevel - getLevel();
double xp = 0;
double sp = 0;
if ((levelDiff < 11) && (levelDiff > -11))
{
case 0:
case 1:
case 2:
xp = Math.max(0, (getExpReward() * damage) / totalDamage);
sp = Math.max(0, (getSpReward() * damage) / totalDamage);
if ((charLevel > 84) && (levelDiff <= -3))
{
mul = 1.;
break;
}
case 3:
{
mul = 0.97;
break;
}
case 4:
{
mul = 0.67;
break;
}
case 5:
{
mul = 0.42;
break;
}
case 6:
{
mul = 0.25;
break;
}
case 7:
{
mul = 0.15;
break;
}
case 8:
{
mul = 0.09;
break;
}
case 9:
{
mul = 0.05;
break;
}
case 10:
{
mul = 0.03;
break;
}
default:
{
mul = 0.;
break;
double mul;
switch (levelDiff)
{
case -3:
{
mul = 0.97;
break;
}
case -4:
{
mul = 0.67;
break;
}
case -5:
{
mul = 0.42;
break;
}
case -6:
{
mul = 0.25;
break;
}
case -7:
{
mul = 0.15;
break;
}
case -8:
{
mul = 0.09;
break;
}
case -9:
{
mul = 0.05;
break;
}
case -10:
{
mul = 0.03;
break;
}
default:
{
mul = 1.;
break;
}
}
xp *= mul;
sp *= mul;
}
}
xp *= mul;
sp *= mul;
return new double[]
{

View File

@ -469,6 +469,10 @@ public class L2Attackable extends L2Npc
// Calculate Exp and SP rewards
if (isInSurroundingRegion(attacker))
{
// Calculate the difference of level between this attacker (player or servitor owner) and the L2Attackable
// mob = 24, atk = 10, diff = -14 (full xp)
// mob = 24, atk = 28, diff = 4 (some xp)
// mob = 24, atk = 50, diff = 26 (no xp)
final double[] expSp = calculateExpAndSp(attacker.getLevel(), damage, totalDamage);
double exp = expSp[0];
double sp = expSp[1];
@ -1302,67 +1306,70 @@ public class L2Attackable extends L2Npc
*/
private double[] calculateExpAndSp(int charLevel, int damage, long totalDamage)
{
final int levelDiff = Math.abs(charLevel - getLevel());
double xp = Math.max(0, (getExpReward() * damage) / totalDamage);
double sp = Math.max(0, (getSpReward() * damage) / totalDamage);
double mul;
switch (levelDiff)
final int levelDiff = charLevel - getLevel();
double xp = 0;
double sp = 0;
if ((levelDiff < 11) && (levelDiff > -11))
{
case 0:
case 1:
case 2:
xp = Math.max(0, (getExpReward() * damage) / totalDamage);
sp = Math.max(0, (getSpReward() * damage) / totalDamage);
if ((charLevel > 84) && (levelDiff <= -3))
{
mul = 1.;
break;
}
case 3:
{
mul = 0.97;
break;
}
case 4:
{
mul = 0.67;
break;
}
case 5:
{
mul = 0.42;
break;
}
case 6:
{
mul = 0.25;
break;
}
case 7:
{
mul = 0.15;
break;
}
case 8:
{
mul = 0.09;
break;
}
case 9:
{
mul = 0.05;
break;
}
case 10:
{
mul = 0.03;
break;
}
default:
{
mul = 0.;
break;
double mul;
switch (levelDiff)
{
case -3:
{
mul = 0.97;
break;
}
case -4:
{
mul = 0.67;
break;
}
case -5:
{
mul = 0.42;
break;
}
case -6:
{
mul = 0.25;
break;
}
case -7:
{
mul = 0.15;
break;
}
case -8:
{
mul = 0.09;
break;
}
case -9:
{
mul = 0.05;
break;
}
case -10:
{
mul = 0.03;
break;
}
default:
{
mul = 1.;
break;
}
}
xp *= mul;
sp *= mul;
}
}
xp *= mul;
sp *= mul;
return new double[]
{

View File

@ -469,6 +469,10 @@ public class L2Attackable extends L2Npc
// Calculate Exp and SP rewards
if (isInSurroundingRegion(attacker))
{
// Calculate the difference of level between this attacker (player or servitor owner) and the L2Attackable
// mob = 24, atk = 10, diff = -14 (full xp)
// mob = 24, atk = 28, diff = 4 (some xp)
// mob = 24, atk = 50, diff = 26 (no xp)
final double[] expSp = calculateExpAndSp(attacker.getLevel(), damage, totalDamage);
double exp = expSp[0];
double sp = expSp[1];
@ -1302,67 +1306,70 @@ public class L2Attackable extends L2Npc
*/
private double[] calculateExpAndSp(int charLevel, int damage, long totalDamage)
{
final int levelDiff = Math.abs(charLevel - getLevel());
double xp = Math.max(0, (getExpReward() * damage) / totalDamage);
double sp = Math.max(0, (getSpReward() * damage) / totalDamage);
double mul;
switch (levelDiff)
final int levelDiff = charLevel - getLevel();
double xp = 0;
double sp = 0;
if ((levelDiff < 11) && (levelDiff > -11))
{
case 0:
case 1:
case 2:
xp = Math.max(0, (getExpReward() * damage) / totalDamage);
sp = Math.max(0, (getSpReward() * damage) / totalDamage);
if ((charLevel > 84) && (levelDiff <= -3))
{
mul = 1.;
break;
}
case 3:
{
mul = 0.97;
break;
}
case 4:
{
mul = 0.67;
break;
}
case 5:
{
mul = 0.42;
break;
}
case 6:
{
mul = 0.25;
break;
}
case 7:
{
mul = 0.15;
break;
}
case 8:
{
mul = 0.09;
break;
}
case 9:
{
mul = 0.05;
break;
}
case 10:
{
mul = 0.03;
break;
}
default:
{
mul = 0.;
break;
double mul;
switch (levelDiff)
{
case -3:
{
mul = 0.97;
break;
}
case -4:
{
mul = 0.67;
break;
}
case -5:
{
mul = 0.42;
break;
}
case -6:
{
mul = 0.25;
break;
}
case -7:
{
mul = 0.15;
break;
}
case -8:
{
mul = 0.09;
break;
}
case -9:
{
mul = 0.05;
break;
}
case -10:
{
mul = 0.03;
break;
}
default:
{
mul = 1.;
break;
}
}
xp *= mul;
sp *= mul;
}
}
xp *= mul;
sp *= mul;
return new double[]
{

View File

@ -1,8 +1,8 @@
CREATE TABLE IF NOT EXISTS `character_subclasses` (
`charId` INT UNSIGNED NOT NULL DEFAULT 0,
`class_id` int(2) NOT NULL DEFAULT 0,
`exp` decimal(20,0) NOT NULL DEFAULT 0,
`sp` decimal(11,0) NOT NULL DEFAULT 0,
`exp` bigint(20) NOT NULL DEFAULT 0,
`sp` bigint(10) NOT NULL DEFAULT 0,
`level` int(2) NOT NULL DEFAULT 40,
`class_index` int(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`charId`,`class_id`)

View File

@ -19,7 +19,7 @@ CREATE TABLE IF NOT EXISTS `characters` (
`z` MEDIUMINT DEFAULT NULL,
`exp` BIGINT UNSIGNED DEFAULT 0,
`expBeforeDeath` BIGINT UNSIGNED DEFAULT 0,
`sp` INT UNSIGNED NOT NULL DEFAULT 0,
`sp` BIGINT(10) UNSIGNED NOT NULL DEFAULT 0,
`karma` INT UNSIGNED DEFAULT NULL,
`fame` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
`pvpkills` SMALLINT UNSIGNED DEFAULT NULL,

View File

@ -345,6 +345,11 @@ MaxEvasion = 250
MinAbnormalStateSuccessRate = 10
MaxAbnormalStateSuccessRate = 90
# Maximum amount of SP a character can posses.
# Current retail limit is 50 billion, use -1 to set it to unlimited.
# Default: 50000000000
MaxSp = 50000000000
# Maximum number of allowed subclasses for every player.
# Default: 3
MaxSubclass = 3
@ -789,17 +794,6 @@ FreeTeleporting = False
# Default: 7
DeleteCharAfterDays = 7
# Alternative Xp/Sp rewards, if not 0, then calculated as 2^((mob.level-player.level) / coef). Coef are the 2 numbers set below.
# A few examples for "AltGameExponentXp = 5." and "AltGameExponentSp = 3.":
# diff = 0 (player and mob has the same level), XP bonus rate = 1, SP bonus rate = 1
# diff = 3 (mob is 3 levels above), XP bonus rate = 1.52, SP bonus rate = 2
# diff = 5 (mob is 5 levels above), XP bonus rate = 2, SP bonus rate = 3.17
# diff = -8 (mob is 8 levels below), XP bonus rate = 0.4, SP bonus rate = 0.16
# Default: 0, 0
AltGameExponentXp = 0
AltGameExponentSp = 0
# PARTY XP DISTRIBUTION
# With "auto method" member is cut from Exp/SP distribution when his share is lower than party bonus acquired for him (30% for 2 member party).
# In that case he will not receive any Exp/SP from party and is not counted for party bonus.

View File

@ -192,6 +192,7 @@ public final class Config
public static int MAX_EVASION;
public static int MIN_ABNORMAL_STATE_SUCCESS_RATE;
public static int MAX_ABNORMAL_STATE_SUCCESS_RATE;
public static long MAX_SP;
public static byte MAX_SUBCLASS;
public static byte BASE_SUBCLASS_LEVEL;
public static byte MAX_SUBCLASS_LEVEL;
@ -269,8 +270,6 @@ public final class Config
public static int MAX_PETITIONS_PENDING;
public static boolean FREE_TELEPORTING;
public static int DELETE_DAYS;
public static float ALT_GAME_EXPONENT_XP;
public static float ALT_GAME_EXPONENT_SP;
public static String PARTY_XP_CUTOFF_METHOD;
public static double PARTY_XP_CUTOFF_PERCENT;
public static int PARTY_XP_CUTOFF_LEVEL;
@ -1641,6 +1640,7 @@ public final class Config
MAX_EVASION = Character.getInt("MaxEvasion", 250);
MIN_ABNORMAL_STATE_SUCCESS_RATE = Character.getInt("MinAbnormalStateSuccessRate", 10);
MAX_ABNORMAL_STATE_SUCCESS_RATE = Character.getInt("MaxAbnormalStateSuccessRate", 90);
MAX_SP = Character.getLong("MaxSp", 50000000000L) >= 0 ? Character.getLong("MaxSp", 50000000000L) : Long.MAX_VALUE;
MAX_SUBCLASS = Character.getByte("MaxSubclass", (byte) 3);
BASE_SUBCLASS_LEVEL = Character.getByte("BaseSubclassLevel", (byte) 40);
MAX_SUBCLASS_LEVEL = Character.getByte("MaxSubclassLevel", (byte) 80);
@ -1804,8 +1804,6 @@ public final class Config
MAX_PETITIONS_PENDING = Character.getInt("MaxPetitionsPending", 25);
FREE_TELEPORTING = Character.getBoolean("FreeTeleporting", false);
DELETE_DAYS = Character.getInt("DeleteCharAfterDays", 7);
ALT_GAME_EXPONENT_XP = Character.getFloat("AltGameExponentXp", 0);
ALT_GAME_EXPONENT_SP = Character.getFloat("AltGameExponentSp", 0);
PARTY_XP_CUTOFF_METHOD = Character.getString("PartyXpCutoffMethod", "highfive");
PARTY_XP_CUTOFF_PERCENT = Character.getDouble("PartyXpCutoffPercent", 3);
PARTY_XP_CUTOFF_LEVEL = Character.getInt("PartyXpCutoffLevel", 20);

View File

@ -2702,7 +2702,7 @@ public class L2Clan implements IIdentifiable, INamable
// the player should know that he has less sp now :p
final StatusUpdate su = new StatusUpdate(player);
su.addAttribute(StatusUpdate.SP, player.getSp());
su.addAttribute(StatusUpdate.SP, (int) player.getSp());
player.sendPacket(su);
player.sendPacket(new ItemList(player, false));

View File

@ -741,7 +741,7 @@ public class L2Party extends AbstractPlayerGroup
* @param partyDmg
* @param target
*/
public void distributeXpAndSp(long xpReward, int spReward, List<L2PcInstance> rewardedMembers, int topLvl, int partyDmg, L2Attackable target)
public void distributeXpAndSp(double xpReward, double spReward, List<L2PcInstance> rewardedMembers, int topLvl, int partyDmg, L2Attackable target)
{
final List<L2PcInstance> validMembers = getValidMembers(rewardedMembers, topLvl);
@ -774,8 +774,8 @@ public class L2Party extends AbstractPlayerGroup
final double preCalculation = (sqLevel / sqLevelSum) * penalty;
// Add the XP/SP points to the requested party member
long addexp = Math.round(member.calcStat(Stats.EXPSP_RATE, xpReward * preCalculation, null, null));
final int addsp = (int) member.calcStat(Stats.EXPSP_RATE, spReward * preCalculation, null, null);
double addexp = Math.round(member.calcStat(Stats.EXPSP_RATE, xpReward * preCalculation, null, null));
final double addsp = member.calcStat(Stats.EXPSP_RATE, spReward * preCalculation, null, null);
addexp = calculateExpSpPartyCutoff(member.getActingPlayer(), topLvl, addexp, addsp, useVitalityRate);
if (addexp > 0)
@ -790,10 +790,10 @@ public class L2Party extends AbstractPlayerGroup
}
}
private final long calculateExpSpPartyCutoff(L2PcInstance player, int topLvl, long addExp, int addSp, boolean vit)
private double calculateExpSpPartyCutoff(L2PcInstance player, int topLvl, double addExp, double addSp, boolean vit)
{
long xp = addExp;
int sp = addSp;
double xp = addExp;
double sp = addSp;
if (Config.PARTY_XP_CUTOFF_METHOD.equalsIgnoreCase("highfive"))
{
int i = 0;

View File

@ -447,11 +447,9 @@ public class L2Attackable extends L2Npc
// mob = 24, atk = 10, diff = -14 (full xp)
// mob = 24, atk = 28, diff = 4 (some xp)
// mob = 24, atk = 50, diff = 26 (no xp)
final int levelDiff = attacker.getLevel() - getLevel();
final int[] expSp = calculateExpAndSp(levelDiff, damage, totalDamage);
long exp = expSp[0];
int sp = expSp[1];
final double[] expSp = calculateExpAndSp(attacker.getLevel(), damage, totalDamage);
double exp = expSp[0];
double sp = expSp[1];
if (Config.CHAMPION_ENABLE && isChampion())
{
@ -487,7 +485,7 @@ public class L2Attackable extends L2Npc
{
// share with party members
int partyDmg = 0;
float partyMul = 1;
double partyMul = 1;
int partyLvl = 0;
// Get all L2Character that can be rewarded in the party
@ -551,16 +549,13 @@ public class L2Attackable extends L2Npc
// If the party didn't killed this L2Attackable alone
if (partyDmg < totalDamage)
{
partyMul = (float) partyDmg / totalDamage;
partyMul = ((double) partyDmg / totalDamage);
}
// Calculate the level difference between Party and L2Attackable
final int levelDiff = partyLvl - getLevel();
// Calculate Exp and SP rewards
final int[] expSp = calculateExpAndSp(levelDiff, partyDmg, totalDamage);
long exp = expSp[0];
int sp = expSp[1];
final double[] expSp = calculateExpAndSp(partyLvl, partyDmg, totalDamage);
double exp = expSp[0];
double sp = expSp[1];
if (Config.CHAMPION_ENABLE && isChampion())
{
@ -1282,61 +1277,86 @@ public class L2Attackable extends L2Npc
/**
* Calculate the Experience and SP to distribute to attacker (L2PcInstance, L2ServitorInstance or L2Party) of the L2Attackable.
* @param diff The difference of level between attacker (L2PcInstance, L2ServitorInstance or L2Party) and the L2Attackable
* @param charLevel The killer level
* @param damage The damages given by the attacker (L2PcInstance, L2ServitorInstance or L2Party)
* @param totalDamage The total damage done
* @return
*/
private int[] calculateExpAndSp(int diff, int damage, long totalDamage)
private double[] calculateExpAndSp(int charLevel, int damage, long totalDamage)
{
double xp;
double sp;
final int levelDiff = charLevel - getLevel();
double xp = 0;
double sp = 0;
if (diff < -5)
if ((levelDiff < 11) && (levelDiff > -11))
{
diff = -5; // makes possible to use ALT_GAME_EXPONENT configuration
}
xp = ((double) getExpReward() * damage) / totalDamage;
if (Config.ALT_GAME_EXPONENT_XP != 0)
{
xp *= Math.pow(2., -diff / Config.ALT_GAME_EXPONENT_XP);
}
sp = ((double) getSpReward() * damage) / totalDamage;
if (Config.ALT_GAME_EXPONENT_SP != 0)
{
sp *= Math.pow(2., -diff / Config.ALT_GAME_EXPONENT_SP);
}
if ((Config.ALT_GAME_EXPONENT_XP == 0) && (Config.ALT_GAME_EXPONENT_SP == 0))
{
if (diff > 5) // formula revised May 07
{
final double pow = Math.pow((double) 5 / 6, diff - 5);
xp = xp * pow;
sp = sp * pow;
}
xp = Math.max(0, (getExpReward() * damage) / totalDamage);
sp = Math.max(0, (getSpReward() * damage) / totalDamage);
if (xp <= 0)
if ((charLevel > 84) && (levelDiff <= -3))
{
xp = 0;
sp = 0;
}
else if (sp <= 0)
{
sp = 0;
double mul;
switch (levelDiff)
{
case -3:
{
mul = 0.97;
break;
}
case -4:
{
mul = 0.67;
break;
}
case -5:
{
mul = 0.42;
break;
}
case -6:
{
mul = 0.25;
break;
}
case -7:
{
mul = 0.15;
break;
}
case -8:
{
mul = 0.09;
break;
}
case -9:
{
mul = 0.05;
break;
}
case -10:
{
mul = 0.03;
break;
}
default:
{
mul = 1.;
break;
}
}
xp *= mul;
sp *= mul;
}
}
final int[] tmp =
return new double[]
{
(int) xp,
(int) sp
xp,
sp
};
return tmp;
}
public long calculateOverhitExp(long normalExp)
public double calculateOverhitExp(double exp)
{
// Get the percentage based on the total of extra (over-hit) damage done relative to the total (maximum) ammount of HP on the L2Attackable
double overhitPercentage = ((getOverhitDamage() * 100) / getMaxHp());
@ -1349,11 +1369,7 @@ public class L2Attackable extends L2Npc
// Get the overhit exp bonus according to the above over-hit damage percentage
// (1/1 basis - 13% of over-hit damage, 13% of extra exp is given, and so on...)
final double overhitExp = ((overhitPercentage / 100) * normalExp);
// Return the rounded ammount of exp points to be added to the player's normal exp reward
final long bonusOverhit = Math.round(overhitExp);
return bonusOverhit;
return (overhitPercentage / 100) * exp;
}
/**

View File

@ -4554,7 +4554,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
* @param addToExp
* @param addToSp
*/
public void addExpAndSp(long addToExp, int addToSp)
public void addExpAndSp(double addToExp, double addToSp)
{
// Dummy method (overridden by players and pets)
}

View File

@ -2668,7 +2668,7 @@ public final class L2PcInstance extends L2Playable
/**
* @return the SP amount of the L2PcInstance.
*/
public int getSp()
public long getSp()
{
return getStat().getSp();
}
@ -2677,7 +2677,7 @@ public final class L2PcInstance extends L2Playable
* Set the SP amount of the L2PcInstance.
* @param sp
*/
public void setSp(int sp)
public void setSp(long sp)
{
if (sp < 0)
{
@ -6647,7 +6647,7 @@ public final class L2PcInstance extends L2Playable
ps.setInt(13, getAppearance().getHairColor());
ps.setInt(14, getAppearance().getSex() ? 1 : 0);
ps.setLong(15, getExp());
ps.setInt(16, getSp());
ps.setLong(16, getSp());
ps.setInt(17, getKarma());
ps.setInt(18, getFame());
ps.setInt(19, getPvpKills());
@ -7246,7 +7246,7 @@ public final class L2PcInstance extends L2Playable
// Get the exp, level, and sp of base class to store in base table
final long exp = getStat().getBaseExp();
final int level = getStat().getBaseLevel();
final int sp = getStat().getBaseSp();
final long sp = getStat().getBaseSp();
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(UPDATE_CHARACTER))
{
@ -7267,7 +7267,7 @@ public final class L2PcInstance extends L2Playable
ps.setInt(15, _observerMode ? _lastLoc.getZ() : getZ());
ps.setLong(16, exp);
ps.setLong(17, getExpBeforeDeath());
ps.setInt(18, sp);
ps.setLong(18, sp);
ps.setInt(19, getKarma());
ps.setInt(20, getFame());
ps.setInt(21, getPvpKills());
@ -7341,7 +7341,7 @@ public final class L2PcInstance extends L2Playable
for (SubClass subClass : getSubClasses().values())
{
ps.setLong(1, subClass.getExp());
ps.setInt(2, subClass.getSp());
ps.setLong(2, subClass.getSp());
ps.setInt(3, subClass.getLevel());
ps.setInt(4, subClass.getClassId());
ps.setInt(5, getObjectId());
@ -10026,7 +10026,7 @@ public final class L2PcInstance extends L2Playable
ps.setInt(1, getObjectId());
ps.setInt(2, newClass.getClassId());
ps.setLong(3, newClass.getExp());
ps.setInt(4, newClass.getSp());
ps.setLong(4, newClass.getSp());
ps.setInt(5, newClass.getLevel());
ps.setInt(6, newClass.getClassIndex()); // <-- Added
ps.execute();
@ -10830,22 +10830,22 @@ public final class L2PcInstance extends L2Playable
}
@Override
public void addExpAndSp(long addToExp, int addToSp)
public void addExpAndSp(double addToExp, double addToSp)
{
getStat().addExpAndSp(addToExp, addToSp, false);
}
public void addExpAndSp(long addToExp, int addToSp, boolean useVitality)
public void addExpAndSp(double addToExp, double addToSp, boolean useVitality)
{
getStat().addExpAndSp(addToExp, addToSp, useVitality);
}
public void removeExpAndSp(long removeExp, int removeSp)
public void removeExpAndSp(long removeExp, long removeSp)
{
getStat().removeExpAndSp(removeExp, removeSp, true);
}
public void removeExpAndSp(long removeExp, int removeSp, boolean sendMessage)
public void removeExpAndSp(long removeExp, long removeSp, boolean sendMessage)
{
getStat().removeExpAndSp(removeExp, removeSp, sendMessage);
}

View File

@ -934,7 +934,7 @@ public class L2PetInstance extends L2Summon
ps.setDouble(3, getStatus().getCurrentHp());
ps.setDouble(4, getStatus().getCurrentMp());
ps.setLong(5, getStat().getExp());
ps.setInt(6, getStat().getSp());
ps.setLong(6, getStat().getSp());
ps.setInt(7, getCurrentFed());
ps.setInt(8, getOwner().getObjectId());
ps.setString(9, String.valueOf(_restoreSummon)); // True restores pet on login
@ -1154,7 +1154,7 @@ public class L2PetInstance extends L2Summon
}
@Override
public void addExpAndSp(long addToExp, int addToSp)
public void addExpAndSp(double addToExp, double addToSp)
{
if (getId() == 12564)
{

View File

@ -37,7 +37,7 @@ public class CharStat
private final L2Character _activeChar;
private long _exp = 0;
private int _sp = 0;
private long _sp = 0;
private byte _level = 1;
private final float[] _attackTraits = new float[TraitType.values().length];
private final int[] _attackTraitsCount = new int[TraitType.values().length];
@ -592,12 +592,12 @@ public class CharStat
return (int) calcStat(Stats.SHIELD_DEFENCE, 0);
}
public int getSp()
public long getSp()
{
return _sp;
}
public void setSp(int value)
public void setSp(long value)
{
_sp = value;
}

View File

@ -113,7 +113,7 @@ public class PcStat extends PlayableStat
return true;
}
public boolean addExpAndSp(long addToExp, int addToSp, boolean useBonuses)
public boolean addExpAndSp(double addToExp, double addToSp, boolean useBonuses)
{
final L2PcInstance activeChar = getActiveChar();
@ -130,8 +130,8 @@ public class PcStat extends PlayableStat
addToSp *= Config.PREMIUM_RATE_SP;
}
final long baseExp = addToExp;
final int baseSp = addToSp;
final double baseExp = addToExp;
final double baseSp = addToSp;
double bonusExp = 1.;
double bonusSp = 1.;
@ -161,7 +161,7 @@ public class PcStat extends PlayableStat
addToExp *= bonusExp;
addToSp *= bonusSp;
float ratioTakenByPlayer = 0;
double ratioTakenByPlayer = 0;
// if this player has a pet and it is in his range he takes from the owner's Exp, give the pet Exp now
if (activeChar.hasPet() && Util.checkIfInShortRange(Config.ALT_PARTY_RANGE, activeChar, activeChar.getSummon(), false))
@ -178,55 +178,45 @@ public class PcStat extends PlayableStat
if (!pet.isDead())
{
pet.addExpAndSp((long) (addToExp * (1 - ratioTakenByPlayer)), (int) (addToSp * (1 - ratioTakenByPlayer)));
pet.addExpAndSp(addToExp * (1 - ratioTakenByPlayer), addToSp * (1 - ratioTakenByPlayer));
}
// now adjust the max ratio to avoid the owner earning negative exp/sp
addToExp = (long) (addToExp * ratioTakenByPlayer);
addToSp = (int) (addToSp * ratioTakenByPlayer);
addToExp *= ratioTakenByPlayer;
addToSp *= ratioTakenByPlayer;
}
if (!addExp(addToExp))
{
addToExp = 0;
}
if (!addSp(addToSp))
{
addToSp = 0;
}
if ((addToExp == 0) && (addToSp == 0))
{
return false;
}
final long finalExp = Math.round(addToExp);
final long finalSp = Math.round(addToSp);
final boolean expAdded = addExp(finalExp);
final boolean spAdded = addSp(finalSp);
SystemMessage sm = null;
if ((addToExp == 0) && (addToSp != 0))
if (!expAdded && spAdded)
{
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_ACQUIRED_S1_SP);
sm.addInt(addToSp);
sm.addLong(finalSp);
}
else if ((addToSp == 0) && (addToExp != 0))
else if (expAdded && !spAdded)
{
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S1_EXPERIENCE);
sm.addLong(addToExp);
sm.addLong(finalExp);
}
else
{
if ((addToExp - baseExp) > 0)
{
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_ACQUIRED_S1_EXP_BONUS_S2_AND_S3_SP_BONUS_S4);
sm.addLong(addToExp);
sm.addLong(addToExp - baseExp);
sm.addInt(addToSp);
sm.addInt(addToSp - baseSp);
sm.addLong(finalExp);
sm.addLong(Math.round(addToExp - baseExp));
sm.addLong(finalSp);
sm.addLong(Math.round(addToSp - baseSp));
}
else
{
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S1_EXPERIENCE_AND_S2_SP);
sm.addLong(addToExp);
sm.addInt(addToSp);
sm.addLong((long) addToExp);
sm.addLong((long) addToSp);
}
}
activeChar.sendPacket(sm);
@ -234,12 +224,12 @@ public class PcStat extends PlayableStat
}
@Override
public boolean removeExpAndSp(long addToExp, int addToSp)
public boolean removeExpAndSp(long addToExp, long addToSp)
{
return removeExpAndSp(addToExp, addToSp, true);
}
public boolean removeExpAndSp(long addToExp, int addToSp, boolean sendMessage)
public boolean removeExpAndSp(long addToExp, long addToSp, boolean sendMessage)
{
final int level = getLevel();
if (!super.removeExpAndSp(addToExp, addToSp))
@ -254,7 +244,7 @@ public class PcStat extends PlayableStat
sm.addLong(addToExp);
getActiveChar().sendPacket(sm);
sm = SystemMessage.getSystemMessage(SystemMessageId.YOUR_SP_HAS_DECREASED_BY_S1);
sm.addInt(addToSp);
sm.addLong(addToSp);
getActiveChar().sendPacket(sm);
if (getLevel() < level)
{
@ -349,7 +339,7 @@ public class PcStat extends PlayableStat
}
@Override
public boolean addSp(int value)
public boolean addSp(long value)
{
if (!super.addSp(value))
{
@ -357,7 +347,7 @@ public class PcStat extends PlayableStat
}
final StatusUpdate su = new StatusUpdate(getActiveChar());
su.addAttribute(StatusUpdate.SP, getSp());
su.addAttribute(StatusUpdate.SP, (int) getSp());
getActiveChar().sendPacket(su);
return true;
@ -562,7 +552,7 @@ public class PcStat extends PlayableStat
}
@Override
public final int getSp()
public final long getSp()
{
if (getActiveChar().isSubClassActive())
{
@ -572,13 +562,13 @@ public class PcStat extends PlayableStat
return super.getSp();
}
public final int getBaseSp()
public final long getBaseSp()
{
return super.getSp();
}
@Override
public final void setSp(int value)
public final void setSp(long value)
{
if (getActiveChar().isSubClassActive())
{
@ -907,7 +897,10 @@ public class PcStat extends PlayableStat
// Check for abnormal bonuses
bonus = Math.max(bonus, 1);
bonus = Math.min(bonus, Config.MAX_BONUS_EXP);
if (Config.MAX_BONUS_EXP > 0)
{
bonus = Math.min(bonus, Config.MAX_BONUS_EXP);
}
return bonus;
}
@ -951,7 +944,10 @@ public class PcStat extends PlayableStat
// Check for abnormal bonuses
bonus = Math.max(bonus, 1);
bonus = Math.min(bonus, Config.MAX_BONUS_SP);
if (Config.MAX_BONUS_SP > 0)
{
bonus = Math.min(bonus, Config.MAX_BONUS_SP);
}
return bonus;
}

View File

@ -48,15 +48,16 @@ public class PetStat extends SummonStat
return true;
}
public boolean addExpAndSp(long addToExp, int addToSp)
public boolean addExpAndSp(double addToExp, double addToSp)
{
if (getActiveChar().isUncontrollable() || !addExp(addToExp))
final long finalExp = Math.round(addToExp);
if (getActiveChar().isUncontrollable() || !addExp(finalExp))
{
return false;
}
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOUR_PET_GAINED_S1_EXPERIENCE_POINTS);
sm.addLong(addToExp);
sm.addLong(finalExp);
getActiveChar().updateAndBroadcastStatus(1);
getActiveChar().sendPacket(sm);
return true;

View File

@ -119,7 +119,7 @@ public class PlayableStat extends CharStat
return true;
}
public boolean removeExpAndSp(long removeExp, int removeSp)
public boolean removeExpAndSp(long removeExp, long removeSp)
{
boolean expRemoved = false;
boolean spRemoved = false;
@ -175,31 +175,31 @@ public class PlayableStat extends CharStat
return true;
}
public boolean addSp(int value)
public boolean addSp(long value)
{
if (value < 0)
{
_log.warning("wrong usage");
return false;
}
final int currentSp = getSp();
if (currentSp == Integer.MAX_VALUE)
final long currentSp = getSp();
if (currentSp >= Config.MAX_SP)
{
return false;
}
if (currentSp > (Integer.MAX_VALUE - value))
if (currentSp > (Config.MAX_SP - value))
{
value = Integer.MAX_VALUE - currentSp;
value = Config.MAX_SP - currentSp;
}
setSp(currentSp + value);
return true;
}
public boolean removeSp(int value)
public boolean removeSp(long value)
{
final int currentSp = getSp();
final long currentSp = getSp();
if (currentSp < value)
{
value = currentSp;

View File

@ -30,7 +30,7 @@ public final class SubClass
private PlayerClass _class;
private long _exp = ExperienceData.getInstance().getExpForLevel(Config.BASE_SUBCLASS_LEVEL);
private int _sp = 0;
private long _sp = 0;
private byte _level = Config.BASE_SUBCLASS_LEVEL;
private int _classIndex = 1;
@ -71,7 +71,7 @@ public final class SubClass
return _exp;
}
public int getSp()
public long getSp()
{
return _sp;
}
@ -105,7 +105,7 @@ public final class SubClass
_exp = expValue;
}
public void setSp(int spValue)
public void setSp(long spValue)
{
_sp = spValue;
}

View File

@ -499,7 +499,7 @@ public final class RequestAcquireSkill implements IClientIncomingPacket
{
player.setSp(player.getSp() - levelUpSp);
final StatusUpdate su = new StatusUpdate(player);
su.addAttribute(StatusUpdate.SP, player.getSp());
su.addAttribute(StatusUpdate.SP, (int) player.getSp());
player.sendPacket(su);
}
return true;

View File

@ -57,7 +57,7 @@ public class CharSelected implements IClientOutgoingPacket
packet.writeF(_activeChar.getCurrentHp());
packet.writeF(_activeChar.getCurrentMp());
packet.writeD(_activeChar.getSp());
packet.writeD((int) _activeChar.getSp());
packet.writeQ(_activeChar.getExp());
packet.writeD(_activeChar.getLevel());
packet.writeD(_activeChar.getKarma()); // thx evill33t

View File

@ -68,7 +68,7 @@ public class GMViewCharacterInfo implements IClientOutgoingPacket
packet.writeD((int) _activeChar.getCurrentHp());
packet.writeD(_activeChar.getMaxMp());
packet.writeD((int) _activeChar.getCurrentMp());
packet.writeD(_activeChar.getSp());
packet.writeD((int) _activeChar.getSp());
packet.writeD(_activeChar.getCurrentLoad());
packet.writeD(_activeChar.getMaxLoad());
packet.writeD(_activeChar.getPkKills());

View File

@ -127,7 +127,7 @@ public class PetInfo implements IClientOutgoingPacket
packet.writeD(_maxHp);// max hp
packet.writeD((int) _summon.getCurrentMp());// current mp
packet.writeD(_maxMp);// max mp
packet.writeD(_summon.getStat().getSp()); // sp
packet.writeD((int) _summon.getStat().getSp()); // sp
packet.writeD(_summon.getLevel());// lvl
packet.writeQ(_summon.getStat().getExp());

View File

@ -110,7 +110,7 @@ public final class UserInfo implements IClientOutgoingPacket
packet.writeD((int) Math.round(_activeChar.getCurrentHp()));
packet.writeD(_activeChar.getMaxMp());
packet.writeD((int) Math.round(_activeChar.getCurrentMp()));
packet.writeD(_activeChar.getSp());
packet.writeD((int) _activeChar.getSp());
packet.writeD(_activeChar.getCurrentLoad());
packet.writeD(_activeChar.getMaxLoad());

View File

@ -469,6 +469,10 @@ public class L2Attackable extends L2Npc
// Calculate Exp and SP rewards
if (isInSurroundingRegion(attacker))
{
// Calculate the difference of level between this attacker (player or servitor owner) and the L2Attackable
// mob = 24, atk = 10, diff = -14 (full xp)
// mob = 24, atk = 28, diff = 4 (some xp)
// mob = 24, atk = 50, diff = 26 (no xp)
final double[] expSp = calculateExpAndSp(attacker.getLevel(), damage, totalDamage);
double exp = expSp[0];
double sp = expSp[1];
@ -1302,67 +1306,70 @@ public class L2Attackable extends L2Npc
*/
private double[] calculateExpAndSp(int charLevel, int damage, long totalDamage)
{
final int levelDiff = Math.abs(charLevel - getLevel());
double xp = Math.max(0, (getExpReward() * damage) / totalDamage);
double sp = Math.max(0, (getSpReward() * damage) / totalDamage);
double mul;
switch (levelDiff)
final int levelDiff = charLevel - getLevel();
double xp = 0;
double sp = 0;
if ((levelDiff < 11) && (levelDiff > -11))
{
case 0:
case 1:
case 2:
xp = Math.max(0, (getExpReward() * damage) / totalDamage);
sp = Math.max(0, (getSpReward() * damage) / totalDamage);
if ((charLevel > 84) && (levelDiff <= -3))
{
mul = 1.;
break;
}
case 3:
{
mul = 0.97;
break;
}
case 4:
{
mul = 0.67;
break;
}
case 5:
{
mul = 0.42;
break;
}
case 6:
{
mul = 0.25;
break;
}
case 7:
{
mul = 0.15;
break;
}
case 8:
{
mul = 0.09;
break;
}
case 9:
{
mul = 0.05;
break;
}
case 10:
{
mul = 0.03;
break;
}
default:
{
mul = 0.;
break;
double mul;
switch (levelDiff)
{
case -3:
{
mul = 0.97;
break;
}
case -4:
{
mul = 0.67;
break;
}
case -5:
{
mul = 0.42;
break;
}
case -6:
{
mul = 0.25;
break;
}
case -7:
{
mul = 0.15;
break;
}
case -8:
{
mul = 0.09;
break;
}
case -9:
{
mul = 0.05;
break;
}
case -10:
{
mul = 0.03;
break;
}
default:
{
mul = 1.;
break;
}
}
xp *= mul;
sp *= mul;
}
}
xp *= mul;
sp *= mul;
return new double[]
{

View File

@ -469,6 +469,10 @@ public class L2Attackable extends L2Npc
// Calculate Exp and SP rewards
if (isInSurroundingRegion(attacker))
{
// Calculate the difference of level between this attacker (player or servitor owner) and the L2Attackable
// mob = 24, atk = 10, diff = -14 (full xp)
// mob = 24, atk = 28, diff = 4 (some xp)
// mob = 24, atk = 50, diff = 26 (no xp)
final double[] expSp = calculateExpAndSp(attacker.getLevel(), damage, totalDamage);
double exp = expSp[0];
double sp = expSp[1];
@ -1302,67 +1306,70 @@ public class L2Attackable extends L2Npc
*/
private double[] calculateExpAndSp(int charLevel, int damage, long totalDamage)
{
final int levelDiff = Math.abs(charLevel - getLevel());
double xp = Math.max(0, (getExpReward() * damage) / totalDamage);
double sp = Math.max(0, (getSpReward() * damage) / totalDamage);
double mul;
switch (levelDiff)
final int levelDiff = charLevel - getLevel();
double xp = 0;
double sp = 0;
if ((levelDiff < 11) && (levelDiff > -11))
{
case 0:
case 1:
case 2:
xp = Math.max(0, (getExpReward() * damage) / totalDamage);
sp = Math.max(0, (getSpReward() * damage) / totalDamage);
if ((charLevel > 84) && (levelDiff <= -3))
{
mul = 1.;
break;
}
case 3:
{
mul = 0.97;
break;
}
case 4:
{
mul = 0.67;
break;
}
case 5:
{
mul = 0.42;
break;
}
case 6:
{
mul = 0.25;
break;
}
case 7:
{
mul = 0.15;
break;
}
case 8:
{
mul = 0.09;
break;
}
case 9:
{
mul = 0.05;
break;
}
case 10:
{
mul = 0.03;
break;
}
default:
{
mul = 0.;
break;
double mul;
switch (levelDiff)
{
case -3:
{
mul = 0.97;
break;
}
case -4:
{
mul = 0.67;
break;
}
case -5:
{
mul = 0.42;
break;
}
case -6:
{
mul = 0.25;
break;
}
case -7:
{
mul = 0.15;
break;
}
case -8:
{
mul = 0.09;
break;
}
case -9:
{
mul = 0.05;
break;
}
case -10:
{
mul = 0.03;
break;
}
default:
{
mul = 1.;
break;
}
}
xp *= mul;
sp *= mul;
}
}
xp *= mul;
sp *= mul;
return new double[]
{