mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 18:51:29 +00:00
* Refactored how XP is calculated
* Added ability to use normalized XP per AA (based on # of kills per AA per white con NPC -- TSS era change) * Added ability to use accelerated AA gain between a defined range (based on live, 0 - 4000 AA, linearly decreasing)
This commit is contained in:
parent
feafd43fdf
commit
b25c5d509d
@ -156,10 +156,6 @@ RULE_BOOL(Character, UseOldBindWound, false) // Uses the original bind wound beh
|
|||||||
RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Target leadership AA on character creation
|
RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Target leadership AA on character creation
|
||||||
RULE_BOOL(Character, UseOldConSystem, false) // Grant Health of Target's Target leadership AA on character creation
|
RULE_BOOL(Character, UseOldConSystem, false) // Grant Health of Target's Target leadership AA on character creation
|
||||||
RULE_BOOL(Character, OPClientUpdateVisualDebug, false) // Shows a pulse and forward directional particle each time the client sends its position to server
|
RULE_BOOL(Character, OPClientUpdateVisualDebug, false) // Shows a pulse and forward directional particle each time the client sends its position to server
|
||||||
RULE_BOOL(Character, ModernAAScalingEnabled, false) // Uses the newer approach to AA scaling based on total earned AA
|
|
||||||
RULE_REAL(Character, ModernAAScalingStartPercent, 1000) // 1000% or 10x AA XP at the start of the scaling range
|
|
||||||
RULE_INT(Character, ModernAAScalingAAMinimum, 0) // The minimum number of earned AA before AA XP scaling begins.
|
|
||||||
RULE_INT(Character, ModernAAScalingAALimit, 4000) // The number of earned AA when AA XP scaling ends.
|
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Mercs)
|
RULE_CATEGORY(Mercs)
|
||||||
@ -678,6 +674,12 @@ RULE_CATEGORY_END()
|
|||||||
RULE_CATEGORY(AA)
|
RULE_CATEGORY(AA)
|
||||||
RULE_INT(AA, ExpPerPoint, 23976503) //Amount of exp per AA. Is the same as the amount of exp to go from level 51 to level 52.
|
RULE_INT(AA, ExpPerPoint, 23976503) //Amount of exp per AA. Is the same as the amount of exp to go from level 51 to level 52.
|
||||||
RULE_BOOL(AA, Stacking, true) //Allow AA that belong to the same group to stack on SOF+ clients.
|
RULE_BOOL(AA, Stacking, true) //Allow AA that belong to the same group to stack on SOF+ clients.
|
||||||
|
RULE_BOOL(AA, NormalizedAAEnabled, false) // TSS+ change to AA that normalizes AA XP to a fixed # of white con kills independent of level.
|
||||||
|
RULE_INT(AA, NormalizedAANumberOfWhiteConPerAA, 25) // The number of white con kills per AA point.
|
||||||
|
RULE_BOOL(AA, ModernAAScalingEnabled, false) // Are we linearly scaling AA XP based on total # of earned AA?
|
||||||
|
RULE_REAL(AA, ModernAAScalingStartPercent, 1000) // 1000% or 10x AA XP at the start of the scaling range
|
||||||
|
RULE_INT(AA, ModernAAScalingAAMinimum, 0) // The minimum number of earned AA before AA XP scaling begins.
|
||||||
|
RULE_INT(AA, ModernAAScalingAALimit, 4000) // The number of earned AA when AA XP scaling ends
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Console)
|
RULE_CATEGORY(Console)
|
||||||
|
|||||||
@ -606,6 +606,10 @@ public:
|
|||||||
uint32 GetExperienceForKill(Mob *against);
|
uint32 GetExperienceForKill(Mob *against);
|
||||||
void AddEXP(uint32 in_add_exp, uint8 conlevel = 0xFF, bool resexp = false);
|
void AddEXP(uint32 in_add_exp, uint8 conlevel = 0xFF, bool resexp = false);
|
||||||
uint32 CalcEXP(uint8 conlevel = 0xFF);
|
uint32 CalcEXP(uint8 conlevel = 0xFF);
|
||||||
|
void CalculateNormalizedAAExp(uint32 &add_aaxp, uint8 conlevel, bool resexp);
|
||||||
|
void CalculateStandardAAExp(uint32 &add_aaxp, uint8 conlevel, bool resexp);
|
||||||
|
void CalculateLeadershipExp(uint32 &add_exp, uint8 conlevel);
|
||||||
|
void CalculateExp(uint32 in_add_exp, uint32 &add_exp, uint32 &add_aaxp, uint8 conlevel, bool resexp);
|
||||||
void SetEXP(uint32 set_exp, uint32 set_aaxp, bool resexp=false);
|
void SetEXP(uint32 set_exp, uint32 set_aaxp, bool resexp=false);
|
||||||
void AddLevelBasedExp(uint8 exp_percentage, uint8 max_level=0);
|
void AddLevelBasedExp(uint8 exp_percentage, uint8 max_level=0);
|
||||||
void SetLeadershipEXP(uint32 group_exp, uint32 raid_exp);
|
void SetLeadershipEXP(uint32 group_exp, uint32 raid_exp);
|
||||||
|
|||||||
605
zone/exp.cpp
605
zone/exp.cpp
@ -37,14 +37,11 @@
|
|||||||
|
|
||||||
extern QueryServ* QServ;
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
static uint32 ScaleAAXPBasedOnCurrentAATotal(int earnedAA, uint32 add_aaxp, float aatotalmod)
|
static uint32 ScaleAAXPBasedOnCurrentAATotal(int earnedAA, uint32 add_aaxp)
|
||||||
{
|
{
|
||||||
float baseModifier = RuleR(Character, ModernAAScalingStartPercent);
|
float baseModifier = RuleR(AA, ModernAAScalingStartPercent);
|
||||||
int aaMinimum = RuleI(Character, ModernAAScalingAAMinimum);
|
int aaMinimum = RuleI(AA, ModernAAScalingAAMinimum);
|
||||||
int aaLimit = RuleI(Character, ModernAAScalingAALimit);
|
int aaLimit = RuleI(AA, ModernAAScalingAALimit);
|
||||||
|
|
||||||
// Calculate the current total before checking if we will add additional xp.
|
|
||||||
uint32 totalWithoutExpMod = (uint32)add_aaxp * aatotalmod;
|
|
||||||
|
|
||||||
// Are we within the scaling window?
|
// Are we within the scaling window?
|
||||||
if (earnedAA >= aaLimit || earnedAA < aaMinimum)
|
if (earnedAA >= aaLimit || earnedAA < aaMinimum)
|
||||||
@ -52,7 +49,7 @@ static uint32 ScaleAAXPBasedOnCurrentAATotal(int earnedAA, uint32 add_aaxp, floa
|
|||||||
Log(Logs::Detail, Logs::None, "Not within AA scaling window.");
|
Log(Logs::Detail, Logs::None, "Not within AA scaling window.");
|
||||||
|
|
||||||
// At or past the limit. We're done.
|
// At or past the limit. We're done.
|
||||||
return totalWithoutExpMod;
|
return add_aaxp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're not at the limit yet. How close are we?
|
// We're not at the limit yet. How close are we?
|
||||||
@ -66,20 +63,20 @@ static uint32 ScaleAAXPBasedOnCurrentAATotal(int earnedAA, uint32 add_aaxp, floa
|
|||||||
float normalizedScale = (float)remainingAA / scaleRange;
|
float normalizedScale = (float)remainingAA / scaleRange;
|
||||||
|
|
||||||
// Scale.
|
// Scale.
|
||||||
uint32 totalWithExpMod = totalWithoutExpMod * (baseModifier / 100) * normalizedScale;
|
uint32 totalWithExpMod = add_aaxp * (baseModifier / 100) * normalizedScale;
|
||||||
|
|
||||||
// Are we so close to the scale limit that we're earning more XP without scaling? This
|
// Are we so close to the scale limit that we're earning more XP without scaling? This
|
||||||
// will happen when we get very close to the limit. In this case, just grant the unscaled
|
// will happen when we get very close to the limit. In this case, just grant the unscaled
|
||||||
// amount.
|
// amount.
|
||||||
if (totalWithExpMod < totalWithoutExpMod)
|
if (totalWithExpMod < add_aaxp)
|
||||||
{
|
{
|
||||||
return totalWithoutExpMod;
|
return add_aaxp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(Logs::Detail,
|
Log(Logs::Detail,
|
||||||
Logs::None,
|
Logs::None,
|
||||||
"Total before the modifier %d :: NewTotal %d :: ScaleRange: %d, SpentAA: %d, RemainingAA: %d, normalizedScale: %0.3f",
|
"Total before the modifier %d :: NewTotal %d :: ScaleRange: %d, SpentAA: %d, RemainingAA: %d, normalizedScale: %0.3f",
|
||||||
totalWithoutExpMod, totalWithExpMod, scaleRange, earnedAA, remainingAA, normalizedScale);
|
add_aaxp, totalWithExpMod, scaleRange, earnedAA, remainingAA, normalizedScale);
|
||||||
|
|
||||||
return totalWithExpMod;
|
return totalWithExpMod;
|
||||||
}
|
}
|
||||||
@ -220,22 +217,198 @@ uint32 Client::GetExperienceForKill(Mob *against)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
float static GetConLevelModifierPercent(uint8 conlevel)
|
||||||
|
{
|
||||||
|
switch (conlevel)
|
||||||
|
{
|
||||||
|
case CON_GREEN:
|
||||||
|
return (float)RuleI(Character, GreenModifier) / 100;
|
||||||
|
break;
|
||||||
|
case CON_LIGHTBLUE:
|
||||||
|
return (float)RuleI(Character, LightBlueModifier) / 100;
|
||||||
|
break;
|
||||||
|
case CON_BLUE:
|
||||||
|
return (float)RuleI(Character, BlueModifier) / 100;
|
||||||
|
break;
|
||||||
|
case CON_WHITE:
|
||||||
|
return (float)RuleI(Character, WhiteModifier) / 100;
|
||||||
|
break;
|
||||||
|
case CON_YELLOW:
|
||||||
|
return (float)RuleI(Character, YellowModifier) / 100;
|
||||||
|
break;
|
||||||
|
case CON_RED:
|
||||||
|
return (float)RuleI(Character, RedModifier) / 100;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this->EVENT_ITEM_ScriptStopReturn();
|
void Client::CalculateNormalizedAAExp(uint32 &add_aaxp, uint8 conlevel, bool resexp)
|
||||||
|
{
|
||||||
uint32 add_exp = in_add_exp;
|
// Functionally this is the same as having the case in the switch, but this is
|
||||||
|
// cleaner to read.
|
||||||
if(!resexp && (XPRate != 0))
|
if (CON_GRAY == conlevel || resexp)
|
||||||
add_exp = static_cast<uint32>(in_add_exp * (static_cast<float>(XPRate) / 100.0f));
|
{
|
||||||
|
|
||||||
if (m_epp.perAA<0 || m_epp.perAA>100)
|
|
||||||
m_epp.perAA=0; // stop exploit with sanity check
|
|
||||||
|
|
||||||
uint32 add_aaxp;
|
|
||||||
if(resexp) {
|
|
||||||
add_aaxp = 0;
|
add_aaxp = 0;
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For this, we ignore the provided value of add_aaxp because it doesn't
|
||||||
|
// apply. XP per AA is normalized such that there are X white con kills
|
||||||
|
// per AA.
|
||||||
|
|
||||||
|
uint32 whiteConKillsPerAA = RuleI(AA, NormalizedAANumberOfWhiteConPerAA);
|
||||||
|
uint32 xpPerAA = RuleI(AA, ExpPerPoint);
|
||||||
|
|
||||||
|
float colorModifier = GetConLevelModifierPercent(conlevel);
|
||||||
|
float percentToAAXp = (float)m_epp.perAA / 100;
|
||||||
|
|
||||||
|
// Normalize the amount of AA XP we earned for this kill.
|
||||||
|
add_aaxp = percentToAAXp * (xpPerAA / (whiteConKillsPerAA / colorModifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::CalculateStandardAAExp(uint32 &add_aaxp, uint8 conlevel, bool resexp)
|
||||||
|
{
|
||||||
|
if (!resexp)
|
||||||
|
{
|
||||||
|
//if XP scaling is based on the con of a monster, do that now.
|
||||||
|
if (RuleB(Character, UseXPConScaling))
|
||||||
|
{
|
||||||
|
if (conlevel != 0xFF && !resexp)
|
||||||
|
{
|
||||||
|
add_aaxp *= GetConLevelModifierPercent(conlevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} //end !resexp
|
||||||
|
|
||||||
|
float aatotalmod = 1.0;
|
||||||
|
if (zone->newzone_data.zone_exp_multiplier >= 0) {
|
||||||
|
aatotalmod *= zone->newzone_data.zone_exp_multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shouldn't race not affect AA XP?
|
||||||
|
if (RuleB(Character, UseRaceClassExpBonuses))
|
||||||
|
{
|
||||||
|
if (GetBaseRace() == HALFLING) {
|
||||||
|
aatotalmod *= 1.05;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetClass() == ROGUE || GetClass() == WARRIOR) {
|
||||||
|
aatotalmod *= 1.05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// why wasn't this here? Where should it be?
|
||||||
|
if (zone->IsHotzone())
|
||||||
|
{
|
||||||
|
aatotalmod += RuleR(Zone, HotZoneBonus);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RuleB(Zone, LevelBasedEXPMods)) {
|
||||||
|
if (zone->level_exp_mod[GetLevel()].ExpMod) {
|
||||||
|
add_aaxp *= zone->level_exp_mod[GetLevel()].AAExpMod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add_aaxp = (uint32)(RuleR(Character, AAExpMultiplier) * add_aaxp * aatotalmod);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::CalculateLeadershipExp(uint32 &add_exp, uint8 conlevel)
|
||||||
|
{
|
||||||
|
if (IsLeadershipEXPOn() && (conlevel == CON_BLUE || conlevel == CON_WHITE || conlevel == CON_YELLOW || conlevel == CON_RED))
|
||||||
|
{
|
||||||
|
add_exp = static_cast<uint32>(static_cast<float>(add_exp) * 0.8f);
|
||||||
|
|
||||||
|
if (GetGroup())
|
||||||
|
{
|
||||||
|
if (m_pp.group_leadership_points < MaxBankedGroupLeadershipPoints(GetLevel())
|
||||||
|
&& RuleI(Character, KillsPerGroupLeadershipAA) > 0)
|
||||||
|
{
|
||||||
|
uint32 exp = GROUP_EXP_PER_POINT / RuleI(Character, KillsPerGroupLeadershipAA);
|
||||||
|
Client *mentoree = GetGroup()->GetMentoree();
|
||||||
|
if (GetGroup()->GetMentorPercent() && mentoree &&
|
||||||
|
mentoree->GetGroupPoints() < MaxBankedGroupLeadershipPoints(mentoree->GetLevel()))
|
||||||
|
{
|
||||||
|
uint32 mentor_exp = exp * (GetGroup()->GetMentorPercent() / 100.0f);
|
||||||
|
exp -= mentor_exp;
|
||||||
|
mentoree->AddLeadershipEXP(mentor_exp, 0); // ends up rounded down
|
||||||
|
mentoree->Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
||||||
|
}
|
||||||
|
if (exp > 0)
|
||||||
|
{
|
||||||
|
// possible if you mentor 100% to the other client
|
||||||
|
AddLeadershipEXP(exp, 0); // ends up rounded up if mentored, no idea how live actually does it
|
||||||
|
Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Message_StringID(MT_Leadership, MAX_GROUP_LEADERSHIP_POINTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Raid *raid = GetRaid();
|
||||||
|
// Raid leaders CAN NOT gain group AA XP, other group leaders can though!
|
||||||
|
if (raid->IsLeader(this))
|
||||||
|
{
|
||||||
|
if (m_pp.raid_leadership_points < MaxBankedRaidLeadershipPoints(GetLevel())
|
||||||
|
&& RuleI(Character, KillsPerRaidLeadershipAA) > 0)
|
||||||
|
{
|
||||||
|
AddLeadershipEXP(0, RAID_EXP_PER_POINT / RuleI(Character, KillsPerRaidLeadershipAA));
|
||||||
|
Message_StringID(MT_Leadership, GAIN_RAID_LEADERSHIP_EXP);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Message_StringID(MT_Leadership, MAX_RAID_LEADERSHIP_POINTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_pp.group_leadership_points < MaxBankedGroupLeadershipPoints(GetLevel())
|
||||||
|
&& RuleI(Character, KillsPerGroupLeadershipAA) > 0)
|
||||||
|
{
|
||||||
|
uint32 group_id = raid->GetGroup(this);
|
||||||
|
uint32 exp = GROUP_EXP_PER_POINT / RuleI(Character, KillsPerGroupLeadershipAA);
|
||||||
|
Client *mentoree = raid->GetMentoree(group_id);
|
||||||
|
if (raid->GetMentorPercent(group_id) && mentoree &&
|
||||||
|
mentoree->GetGroupPoints() < MaxBankedGroupLeadershipPoints(mentoree->GetLevel()))
|
||||||
|
{
|
||||||
|
uint32 mentor_exp = exp * (raid->GetMentorPercent(group_id) / 100.0f);
|
||||||
|
exp -= mentor_exp;
|
||||||
|
mentoree->AddLeadershipEXP(mentor_exp, 0);
|
||||||
|
mentoree->Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
||||||
|
}
|
||||||
|
if (exp > 0)
|
||||||
|
{
|
||||||
|
AddLeadershipEXP(exp, 0);
|
||||||
|
Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Message_StringID(MT_Leadership, MAX_GROUP_LEADERSHIP_POINTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::CalculateExp(uint32 in_add_exp, uint32 &add_exp, uint32 &add_aaxp, uint8 conlevel, bool resexp)
|
||||||
|
{
|
||||||
|
add_exp = in_add_exp;
|
||||||
|
|
||||||
|
if (!resexp && (XPRate != 0))
|
||||||
|
{
|
||||||
|
add_exp = static_cast<uint32>(in_add_exp * (static_cast<float>(XPRate) / 100.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure it was initialized.
|
||||||
|
add_aaxp = 0;
|
||||||
|
|
||||||
|
if (!resexp)
|
||||||
|
{
|
||||||
//figure out how much of this goes to AAs
|
//figure out how much of this goes to AAs
|
||||||
add_aaxp = add_exp * m_epp.perAA / 100;
|
add_aaxp = add_exp * m_epp.perAA / 100;
|
||||||
|
|
||||||
@ -246,28 +419,28 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
|||||||
float zemmod = 1.0;
|
float zemmod = 1.0;
|
||||||
|
|
||||||
//get modifiers
|
//get modifiers
|
||||||
if(RuleR(Character, ExpMultiplier) >= 0){
|
if (RuleR(Character, ExpMultiplier) >= 0) {
|
||||||
totalmod *= RuleR(Character, ExpMultiplier);
|
totalmod *= RuleR(Character, ExpMultiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
//add the zone exp modifier.
|
//add the zone exp modifier.
|
||||||
if(zone->newzone_data.zone_exp_multiplier >= 0){
|
if (zone->newzone_data.zone_exp_multiplier >= 0) {
|
||||||
zemmod *= zone->newzone_data.zone_exp_multiplier;
|
zemmod *= zone->newzone_data.zone_exp_multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RuleB(Character,UseRaceClassExpBonuses))
|
if (RuleB(Character, UseRaceClassExpBonuses))
|
||||||
{
|
{
|
||||||
if(GetBaseRace() == HALFLING){
|
if (GetBaseRace() == HALFLING) {
|
||||||
totalmod *= 1.05;
|
totalmod *= 1.05;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetClass() == ROGUE || GetClass() == WARRIOR){
|
if (GetClass() == ROGUE || GetClass() == WARRIOR) {
|
||||||
totalmod *= 1.05;
|
totalmod *= 1.05;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//add hotzone modifier if one has been set.
|
//add hotzone modifier if one has been set.
|
||||||
if(zone->IsHotzone())
|
if (zone->IsHotzone())
|
||||||
{
|
{
|
||||||
totalmod += RuleR(Zone, HotZoneBonus);
|
totalmod += RuleR(Zone, HotZoneBonus);
|
||||||
}
|
}
|
||||||
@ -275,145 +448,54 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
|||||||
add_exp = uint32(float(add_exp) * totalmod * zemmod);
|
add_exp = uint32(float(add_exp) * totalmod * zemmod);
|
||||||
|
|
||||||
//if XP scaling is based on the con of a monster, do that now.
|
//if XP scaling is based on the con of a monster, do that now.
|
||||||
if(RuleB(Character,UseXPConScaling))
|
if (RuleB(Character, UseXPConScaling))
|
||||||
{
|
{
|
||||||
if (conlevel != 0xFF && !resexp) {
|
if (conlevel != 0xFF && !resexp)
|
||||||
switch (conlevel)
|
{
|
||||||
{
|
add_exp = add_exp * GetConLevelModifierPercent(conlevel);
|
||||||
case CON_GRAY:
|
|
||||||
add_exp = 0;
|
|
||||||
add_aaxp = 0;
|
|
||||||
return;
|
|
||||||
case CON_GREEN:
|
|
||||||
add_exp = add_exp * RuleI(Character, GreenModifier) / 100;
|
|
||||||
add_aaxp = add_aaxp * RuleI(Character, GreenModifier) / 100;
|
|
||||||
break;
|
|
||||||
case CON_LIGHTBLUE:
|
|
||||||
add_exp = add_exp * RuleI(Character, LightBlueModifier)/100;
|
|
||||||
add_aaxp = add_aaxp * RuleI(Character, LightBlueModifier)/100;
|
|
||||||
break;
|
|
||||||
case CON_BLUE:
|
|
||||||
add_exp = add_exp * RuleI(Character, BlueModifier)/100;
|
|
||||||
add_aaxp = add_aaxp * RuleI(Character, BlueModifier)/100;
|
|
||||||
break;
|
|
||||||
case CON_WHITE:
|
|
||||||
add_exp = add_exp * RuleI(Character, WhiteModifier)/100;
|
|
||||||
add_aaxp = add_aaxp * RuleI(Character, WhiteModifier)/100;
|
|
||||||
break;
|
|
||||||
case CON_YELLOW:
|
|
||||||
add_exp = add_exp * RuleI(Character, YellowModifier)/100;
|
|
||||||
add_aaxp = add_aaxp * RuleI(Character, YellowModifier)/100;
|
|
||||||
break;
|
|
||||||
case CON_RED:
|
|
||||||
add_exp = add_exp * RuleI(Character, RedModifier)/100;
|
|
||||||
add_aaxp = add_aaxp * RuleI(Character, RedModifier)/100;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsLeadershipEXPOn() && (conlevel == CON_BLUE || conlevel == CON_WHITE || conlevel == CON_YELLOW || conlevel == CON_RED)) {
|
// Calculate any changes to leadership experience.
|
||||||
add_exp = static_cast<uint32>(static_cast<float>(add_exp) * 0.8f);
|
CalculateLeadershipExp(add_exp, conlevel);
|
||||||
|
|
||||||
if (GetGroup()) {
|
|
||||||
if (m_pp.group_leadership_points < MaxBankedGroupLeadershipPoints(GetLevel())
|
|
||||||
&& RuleI(Character, KillsPerGroupLeadershipAA) > 0) {
|
|
||||||
uint32 exp = GROUP_EXP_PER_POINT / RuleI(Character, KillsPerGroupLeadershipAA);
|
|
||||||
Client *mentoree = GetGroup()->GetMentoree();
|
|
||||||
if (GetGroup()->GetMentorPercent() && mentoree &&
|
|
||||||
mentoree->GetGroupPoints() < MaxBankedGroupLeadershipPoints(mentoree->GetLevel())) {
|
|
||||||
uint32 mentor_exp = exp * (GetGroup()->GetMentorPercent() / 100.0f);
|
|
||||||
exp -= mentor_exp;
|
|
||||||
mentoree->AddLeadershipEXP(mentor_exp, 0); // ends up rounded down
|
|
||||||
mentoree->Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
|
||||||
}
|
|
||||||
if (exp > 0) { // possible if you mentor 100% to the other client
|
|
||||||
AddLeadershipEXP(exp, 0); // ends up rounded up if mentored, no idea how live actually does it
|
|
||||||
Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Message_StringID(MT_Leadership, MAX_GROUP_LEADERSHIP_POINTS);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Raid *raid = GetRaid();
|
|
||||||
// Raid leaders CAN NOT gain group AA XP, other group leaders can though!
|
|
||||||
if (raid->IsLeader(this)) {
|
|
||||||
if (m_pp.raid_leadership_points < MaxBankedRaidLeadershipPoints(GetLevel())
|
|
||||||
&& RuleI(Character, KillsPerRaidLeadershipAA) > 0) {
|
|
||||||
AddLeadershipEXP(0, RAID_EXP_PER_POINT / RuleI(Character, KillsPerRaidLeadershipAA));
|
|
||||||
Message_StringID(MT_Leadership, GAIN_RAID_LEADERSHIP_EXP);
|
|
||||||
} else {
|
|
||||||
Message_StringID(MT_Leadership, MAX_RAID_LEADERSHIP_POINTS);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (m_pp.group_leadership_points < MaxBankedGroupLeadershipPoints(GetLevel())
|
|
||||||
&& RuleI(Character, KillsPerGroupLeadershipAA) > 0) {
|
|
||||||
uint32 group_id = raid->GetGroup(this);
|
|
||||||
uint32 exp = GROUP_EXP_PER_POINT / RuleI(Character, KillsPerGroupLeadershipAA);
|
|
||||||
Client *mentoree = raid->GetMentoree(group_id);
|
|
||||||
if (raid->GetMentorPercent(group_id) && mentoree &&
|
|
||||||
mentoree->GetGroupPoints() < MaxBankedGroupLeadershipPoints(mentoree->GetLevel())) {
|
|
||||||
uint32 mentor_exp = exp * (raid->GetMentorPercent(group_id) / 100.0f);
|
|
||||||
exp -= mentor_exp;
|
|
||||||
mentoree->AddLeadershipEXP(mentor_exp, 0);
|
|
||||||
mentoree->Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
|
||||||
}
|
|
||||||
if (exp > 0) {
|
|
||||||
AddLeadershipEXP(exp, 0);
|
|
||||||
Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Message_StringID(MT_Leadership, MAX_GROUP_LEADERSHIP_POINTS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} //end !resexp
|
} //end !resexp
|
||||||
|
|
||||||
float aatotalmod = 1.0;
|
if (RuleB(Zone, LevelBasedEXPMods)) {
|
||||||
if(zone->newzone_data.zone_exp_multiplier >= 0){
|
if (zone->level_exp_mod[GetLevel()].ExpMod) {
|
||||||
aatotalmod *= zone->newzone_data.zone_exp_multiplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shouldn't race not affect AA XP?
|
|
||||||
if(RuleB(Character,UseRaceClassExpBonuses))
|
|
||||||
{
|
|
||||||
if(GetBaseRace() == HALFLING){
|
|
||||||
aatotalmod *= 1.05;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(GetClass() == ROGUE || GetClass() == WARRIOR){
|
|
||||||
aatotalmod *= 1.05;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// why wasn't this here? Where should it be?
|
|
||||||
if(zone->IsHotzone())
|
|
||||||
{
|
|
||||||
aatotalmod += RuleR(Zone, HotZoneBonus);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(RuleB(Zone, LevelBasedEXPMods)){
|
|
||||||
if(zone->level_exp_mod[GetLevel()].ExpMod){
|
|
||||||
add_exp *= zone->level_exp_mod[GetLevel()].ExpMod;
|
add_exp *= zone->level_exp_mod[GetLevel()].ExpMod;
|
||||||
add_aaxp *= zone->level_exp_mod[GetLevel()].AAExpMod;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 exp = GetEXP() + add_exp;
|
add_exp = GetEXP() + add_exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||||
|
|
||||||
|
this->EVENT_ITEM_ScriptStopReturn();
|
||||||
|
|
||||||
|
uint32 exp = 0;
|
||||||
uint32 aaexp = 0;
|
uint32 aaexp = 0;
|
||||||
|
|
||||||
// if using modernAA and this character has AA XP enabled.
|
if (m_epp.perAA<0 || m_epp.perAA>100)
|
||||||
if (RuleB(Character, ModernAAScalingEnabled) && add_aaxp > 0)
|
m_epp.perAA=0; // stop exploit with sanity check
|
||||||
|
|
||||||
|
// Calculate regular XP
|
||||||
|
CalculateExp(in_add_exp, exp, aaexp, conlevel, resexp);
|
||||||
|
|
||||||
|
// Calculate regular AA XP
|
||||||
|
if (!RuleB(AA, NormalizedAAEnabled))
|
||||||
{
|
{
|
||||||
aaexp = ScaleAAXPBasedOnCurrentAATotal(GetAAPoints(), add_aaxp, aatotalmod);
|
CalculateStandardAAExp(aaexp, conlevel, resexp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// else, do the existing calculation.
|
CalculateNormalizedAAExp(aaexp, conlevel, resexp);
|
||||||
aaexp = (uint32)(RuleR(Character, AAExpMultiplier) * add_aaxp * aatotalmod);
|
}
|
||||||
|
|
||||||
|
// Are we also doing linear AA acceleration?
|
||||||
|
if (RuleB(AA, ModernAAScalingEnabled) && aaexp > 0)
|
||||||
|
{
|
||||||
|
aaexp = ScaleAAXPBasedOnCurrentAATotal(GetAAPoints(), aaexp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current AA XP total
|
// Get current AA XP total
|
||||||
@ -425,11 +507,222 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
|||||||
// Make sure our new total (existing + just earned) isn't lower than the
|
// Make sure our new total (existing + just earned) isn't lower than the
|
||||||
// existing total. If it is, we overflowed the bounds of uint32 and wrapped.
|
// existing total. If it is, we overflowed the bounds of uint32 and wrapped.
|
||||||
// Reset to the existing total.
|
// Reset to the existing total.
|
||||||
if(aaexp < had_aaexp)
|
if (aaexp < had_aaexp)
|
||||||
|
{
|
||||||
aaexp = had_aaexp; //watch for wrap
|
aaexp = had_aaexp; //watch for wrap
|
||||||
|
}
|
||||||
|
|
||||||
// Now update our character's normal and AA xp
|
// Now update our character's normal and AA xp
|
||||||
SetEXP(exp, aaexp, resexp);
|
SetEXP(exp, aaexp, resexp);
|
||||||
|
|
||||||
|
//this->EVENT_ITEM_ScriptStopReturn();
|
||||||
|
|
||||||
|
//uint32 add_exp = in_add_exp;
|
||||||
|
|
||||||
|
//if(!resexp && (XPRate != 0))
|
||||||
|
// add_exp = static_cast<uint32>(in_add_exp * (static_cast<float>(XPRate) / 100.0f));
|
||||||
|
|
||||||
|
//if (m_epp.perAA<0 || m_epp.perAA>100)
|
||||||
|
// m_epp.perAA=0; // stop exploit with sanity check
|
||||||
|
|
||||||
|
//uint32 add_aaxp;
|
||||||
|
//if(resexp) {
|
||||||
|
// add_aaxp = 0;
|
||||||
|
//} else {
|
||||||
|
// //figure out how much of this goes to AAs
|
||||||
|
// add_aaxp = add_exp * m_epp.perAA / 100;
|
||||||
|
|
||||||
|
// //take that amount away from regular exp
|
||||||
|
// add_exp -= add_aaxp;
|
||||||
|
|
||||||
|
// float totalmod = 1.0;
|
||||||
|
// float zemmod = 1.0;
|
||||||
|
|
||||||
|
// //get modifiers
|
||||||
|
// if(RuleR(Character, ExpMultiplier) >= 0){
|
||||||
|
// totalmod *= RuleR(Character, ExpMultiplier);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //add the zone exp modifier.
|
||||||
|
// if(zone->newzone_data.zone_exp_multiplier >= 0){
|
||||||
|
// zemmod *= zone->newzone_data.zone_exp_multiplier;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if(RuleB(Character,UseRaceClassExpBonuses))
|
||||||
|
// {
|
||||||
|
// if(GetBaseRace() == HALFLING){
|
||||||
|
// totalmod *= 1.05;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if(GetClass() == ROGUE || GetClass() == WARRIOR){
|
||||||
|
// totalmod *= 1.05;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //add hotzone modifier if one has been set.
|
||||||
|
// if(zone->IsHotzone())
|
||||||
|
// {
|
||||||
|
// totalmod += RuleR(Zone, HotZoneBonus);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// add_exp = uint32(float(add_exp) * totalmod * zemmod);
|
||||||
|
|
||||||
|
// //if XP scaling is based on the con of a monster, do that now.
|
||||||
|
// if(RuleB(Character,UseXPConScaling))
|
||||||
|
// {
|
||||||
|
// if (conlevel != 0xFF && !resexp) {
|
||||||
|
// switch (conlevel)
|
||||||
|
// {
|
||||||
|
// case CON_GRAY:
|
||||||
|
// add_exp = 0;
|
||||||
|
// add_aaxp = 0;
|
||||||
|
// return;
|
||||||
|
// case CON_GREEN:
|
||||||
|
// add_exp = add_exp * RuleI(Character, GreenModifier) / 100;
|
||||||
|
// add_aaxp = add_aaxp * RuleI(Character, GreenModifier) / 100;
|
||||||
|
// break;
|
||||||
|
// case CON_LIGHTBLUE:
|
||||||
|
// add_exp = add_exp * RuleI(Character, LightBlueModifier)/100;
|
||||||
|
// add_aaxp = add_aaxp * RuleI(Character, LightBlueModifier)/100;
|
||||||
|
// break;
|
||||||
|
// case CON_BLUE:
|
||||||
|
// add_exp = add_exp * RuleI(Character, BlueModifier)/100;
|
||||||
|
// add_aaxp = add_aaxp * RuleI(Character, BlueModifier)/100;
|
||||||
|
// break;
|
||||||
|
// case CON_WHITE:
|
||||||
|
// add_exp = add_exp * RuleI(Character, WhiteModifier)/100;
|
||||||
|
// add_aaxp = add_aaxp * RuleI(Character, WhiteModifier)/100;
|
||||||
|
// break;
|
||||||
|
// case CON_YELLOW:
|
||||||
|
// add_exp = add_exp * RuleI(Character, YellowModifier)/100;
|
||||||
|
// add_aaxp = add_aaxp * RuleI(Character, YellowModifier)/100;
|
||||||
|
// break;
|
||||||
|
// case CON_RED:
|
||||||
|
// add_exp = add_exp * RuleI(Character, RedModifier)/100;
|
||||||
|
// add_aaxp = add_aaxp * RuleI(Character, RedModifier)/100;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (IsLeadershipEXPOn() && (conlevel == CON_BLUE || conlevel == CON_WHITE || conlevel == CON_YELLOW || conlevel == CON_RED)) {
|
||||||
|
// add_exp = static_cast<uint32>(static_cast<float>(add_exp) * 0.8f);
|
||||||
|
|
||||||
|
// if (GetGroup()) {
|
||||||
|
// if (m_pp.group_leadership_points < MaxBankedGroupLeadershipPoints(GetLevel())
|
||||||
|
// && RuleI(Character, KillsPerGroupLeadershipAA) > 0) {
|
||||||
|
// uint32 exp = GROUP_EXP_PER_POINT / RuleI(Character, KillsPerGroupLeadershipAA);
|
||||||
|
// Client *mentoree = GetGroup()->GetMentoree();
|
||||||
|
// if (GetGroup()->GetMentorPercent() && mentoree &&
|
||||||
|
// mentoree->GetGroupPoints() < MaxBankedGroupLeadershipPoints(mentoree->GetLevel())) {
|
||||||
|
// uint32 mentor_exp = exp * (GetGroup()->GetMentorPercent() / 100.0f);
|
||||||
|
// exp -= mentor_exp;
|
||||||
|
// mentoree->AddLeadershipEXP(mentor_exp, 0); // ends up rounded down
|
||||||
|
// mentoree->Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
||||||
|
// }
|
||||||
|
// if (exp > 0) { // possible if you mentor 100% to the other client
|
||||||
|
// AddLeadershipEXP(exp, 0); // ends up rounded up if mentored, no idea how live actually does it
|
||||||
|
// Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// Message_StringID(MT_Leadership, MAX_GROUP_LEADERSHIP_POINTS);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// Raid *raid = GetRaid();
|
||||||
|
// // Raid leaders CAN NOT gain group AA XP, other group leaders can though!
|
||||||
|
// if (raid->IsLeader(this)) {
|
||||||
|
// if (m_pp.raid_leadership_points < MaxBankedRaidLeadershipPoints(GetLevel())
|
||||||
|
// && RuleI(Character, KillsPerRaidLeadershipAA) > 0) {
|
||||||
|
// AddLeadershipEXP(0, RAID_EXP_PER_POINT / RuleI(Character, KillsPerRaidLeadershipAA));
|
||||||
|
// Message_StringID(MT_Leadership, GAIN_RAID_LEADERSHIP_EXP);
|
||||||
|
// } else {
|
||||||
|
// Message_StringID(MT_Leadership, MAX_RAID_LEADERSHIP_POINTS);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// if (m_pp.group_leadership_points < MaxBankedGroupLeadershipPoints(GetLevel())
|
||||||
|
// && RuleI(Character, KillsPerGroupLeadershipAA) > 0) {
|
||||||
|
// uint32 group_id = raid->GetGroup(this);
|
||||||
|
// uint32 exp = GROUP_EXP_PER_POINT / RuleI(Character, KillsPerGroupLeadershipAA);
|
||||||
|
// Client *mentoree = raid->GetMentoree(group_id);
|
||||||
|
// if (raid->GetMentorPercent(group_id) && mentoree &&
|
||||||
|
// mentoree->GetGroupPoints() < MaxBankedGroupLeadershipPoints(mentoree->GetLevel())) {
|
||||||
|
// uint32 mentor_exp = exp * (raid->GetMentorPercent(group_id) / 100.0f);
|
||||||
|
// exp -= mentor_exp;
|
||||||
|
// mentoree->AddLeadershipEXP(mentor_exp, 0);
|
||||||
|
// mentoree->Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
||||||
|
// }
|
||||||
|
// if (exp > 0) {
|
||||||
|
// AddLeadershipEXP(exp, 0);
|
||||||
|
// Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// Message_StringID(MT_Leadership, MAX_GROUP_LEADERSHIP_POINTS);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
//} //end !resexp
|
||||||
|
|
||||||
|
//float aatotalmod = 1.0;
|
||||||
|
//if(zone->newzone_data.zone_exp_multiplier >= 0){
|
||||||
|
// aatotalmod *= zone->newzone_data.zone_exp_multiplier;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//// Shouldn't race not affect AA XP?
|
||||||
|
//if(RuleB(Character,UseRaceClassExpBonuses))
|
||||||
|
//{
|
||||||
|
// if(GetBaseRace() == HALFLING){
|
||||||
|
// aatotalmod *= 1.05;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if(GetClass() == ROGUE || GetClass() == WARRIOR){
|
||||||
|
// aatotalmod *= 1.05;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//// why wasn't this here? Where should it be?
|
||||||
|
//if(zone->IsHotzone())
|
||||||
|
//{
|
||||||
|
// aatotalmod += RuleR(Zone, HotZoneBonus);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if(RuleB(Zone, LevelBasedEXPMods)){
|
||||||
|
// if(zone->level_exp_mod[GetLevel()].ExpMod){
|
||||||
|
// add_exp *= zone->level_exp_mod[GetLevel()].ExpMod;
|
||||||
|
// add_aaxp *= zone->level_exp_mod[GetLevel()].AAExpMod;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//uint32 exp = GetEXP() + add_exp;
|
||||||
|
//uint32 aaexp = 0;
|
||||||
|
|
||||||
|
//// if using modernAA and this character has AA XP enabled.
|
||||||
|
//if (RuleB(Character, ModernAAScalingEnabled) && add_aaxp > 0)
|
||||||
|
//{
|
||||||
|
// aaexp = ScaleAAXPBasedOnCurrentAATotal(GetAAPoints(), add_aaxp, aatotalmod);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// // else, do the existing calculation.
|
||||||
|
// aaexp = (uint32)(RuleR(Character, AAExpMultiplier) * add_aaxp * aatotalmod);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//// Get current AA XP total
|
||||||
|
//uint32 had_aaexp = GetAAXP();
|
||||||
|
|
||||||
|
//// Add it to the XP we just earned.
|
||||||
|
//aaexp += had_aaexp;
|
||||||
|
|
||||||
|
//// Make sure our new total (existing + just earned) isn't lower than the
|
||||||
|
//// existing total. If it is, we overflowed the bounds of uint32 and wrapped.
|
||||||
|
//// Reset to the existing total.
|
||||||
|
//if(aaexp < had_aaexp)
|
||||||
|
// aaexp = had_aaexp; //watch for wrap
|
||||||
|
|
||||||
|
//// Now update our character's normal and AA xp
|
||||||
|
//SetEXP(exp, aaexp, resexp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user