diff --git a/common/ruletypes.h b/common/ruletypes.h index 06cefa84f..8f8c4e3a0 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -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, 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, 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(Mercs) @@ -678,6 +674,12 @@ RULE_CATEGORY_END() 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_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(Console) diff --git a/zone/client.h b/zone/client.h index 88622fcff..77a76fc18 100644 --- a/zone/client.h +++ b/zone/client.h @@ -606,6 +606,10 @@ public: uint32 GetExperienceForKill(Mob *against); void AddEXP(uint32 in_add_exp, uint8 conlevel = 0xFF, bool resexp = false); 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 AddLevelBasedExp(uint8 exp_percentage, uint8 max_level=0); void SetLeadershipEXP(uint32 group_exp, uint32 raid_exp); diff --git a/zone/exp.cpp b/zone/exp.cpp index 4e43d6c1d..d351ab0a2 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -37,14 +37,11 @@ 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); - int aaMinimum = RuleI(Character, ModernAAScalingAAMinimum); - int aaLimit = RuleI(Character, ModernAAScalingAALimit); - - // Calculate the current total before checking if we will add additional xp. - uint32 totalWithoutExpMod = (uint32)add_aaxp * aatotalmod; + float baseModifier = RuleR(AA, ModernAAScalingStartPercent); + int aaMinimum = RuleI(AA, ModernAAScalingAAMinimum); + int aaLimit = RuleI(AA, ModernAAScalingAALimit); // Are we within the scaling window? 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."); // At or past the limit. We're done. - return totalWithoutExpMod; + return add_aaxp; } // 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; // 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 // will happen when we get very close to the limit. In this case, just grant the unscaled // amount. - if (totalWithExpMod < totalWithoutExpMod) + if (totalWithExpMod < add_aaxp) { - return totalWithoutExpMod; + return add_aaxp; } Log(Logs::Detail, Logs::None, "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; } @@ -220,22 +217,198 @@ uint32 Client::GetExperienceForKill(Mob *against) 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(); - - uint32 add_exp = in_add_exp; - - if(!resexp && (XPRate != 0)) - add_exp = static_cast(in_add_exp * (static_cast(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) { +void Client::CalculateNormalizedAAExp(uint32 &add_aaxp, uint8 conlevel, bool resexp) +{ + // Functionally this is the same as having the case in the switch, but this is + // cleaner to read. + if (CON_GRAY == conlevel || resexp) + { 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(static_cast(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(in_add_exp * (static_cast(XPRate) / 100.0f)); + } + + // Make sure it was initialized. + add_aaxp = 0; + + if (!resexp) + { //figure out how much of this goes to AAs 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; //get modifiers - if(RuleR(Character, ExpMultiplier) >= 0){ + if (RuleR(Character, ExpMultiplier) >= 0) { totalmod *= RuleR(Character, ExpMultiplier); } //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; } - if(RuleB(Character,UseRaceClassExpBonuses)) + if (RuleB(Character, UseRaceClassExpBonuses)) { - if(GetBaseRace() == HALFLING){ + if (GetBaseRace() == HALFLING) { totalmod *= 1.05; } - if(GetClass() == ROGUE || GetClass() == WARRIOR){ + if (GetClass() == ROGUE || GetClass() == WARRIOR) { totalmod *= 1.05; } } //add hotzone modifier if one has been set. - if(zone->IsHotzone()) + if (zone->IsHotzone()) { 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); //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) { - 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 (conlevel != 0xFF && !resexp) + { + add_exp = add_exp * GetConLevelModifierPercent(conlevel); } } - if (IsLeadershipEXPOn() && (conlevel == CON_BLUE || conlevel == CON_WHITE || conlevel == CON_YELLOW || conlevel == CON_RED)) { - add_exp = static_cast(static_cast(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); - } - } - } - - } - + // Calculate any changes to leadership experience. + CalculateLeadershipExp(add_exp, 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){ + 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; + 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; - // if using modernAA and this character has AA XP enabled. - if (RuleB(Character, ModernAAScalingEnabled) && add_aaxp > 0) + if (m_epp.perAA<0 || m_epp.perAA>100) + 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, do the existing calculation. - aaexp = (uint32)(RuleR(Character, AAExpMultiplier) * add_aaxp * aatotalmod); + CalculateNormalizedAAExp(aaexp, conlevel, resexp); + } + + // Are we also doing linear AA acceleration? + if (RuleB(AA, ModernAAScalingEnabled) && aaexp > 0) + { + aaexp = ScaleAAXPBasedOnCurrentAATotal(GetAAPoints(), aaexp); } // 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 // existing total. If it is, we overflowed the bounds of uint32 and wrapped. // Reset to the existing total. - if(aaexp < had_aaexp) + if (aaexp < had_aaexp) + { aaexp = had_aaexp; //watch for wrap + } // Now update our character's normal and AA xp SetEXP(exp, aaexp, resexp); + + //this->EVENT_ITEM_ScriptStopReturn(); + + //uint32 add_exp = in_add_exp; + + //if(!resexp && (XPRate != 0)) + // add_exp = static_cast(in_add_exp * (static_cast(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(static_cast(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) {