[Quest API] Add option to Ignore Mods to CalcEXP (#2704)

# Perl
- Add `$client->CalcEXP(consider_level, ignore_modifiers)`.

# Lua
- Add `client:CalcEXP(consider_level)`.
- Add `client:CalcEXP(consider_level, ignore_modifiers)`.

# Notes
- Allows operators to calculate experience based on consider level as well as ignore modifiers to get a baseline of experience that should be expected when killing a mob.
This commit is contained in:
Aeadoin 2023-01-05 20:38:08 -05:00 committed by GitHub
parent d9f437d90f
commit 143c4fe6aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 77 deletions

View File

@ -627,7 +627,7 @@ public:
uint64 GetExperienceForKill(Mob *against);
void AddEXP(uint64 in_add_exp, uint8 conlevel = 0xFF, bool resexp = false);
uint64 CalcEXP(uint8 conlevel = 0xFF);
uint64 CalcEXP(uint8 conlevel = 0xFF, bool ignore_mods = false);
void CalculateNormalizedAAExp(uint64 &add_aaxp, uint8 conlevel, bool resexp);
void CalculateStandardAAExp(uint64 &add_aaxp, uint8 conlevel, bool resexp);
void CalculateLeadershipExp(uint64 &add_exp, uint8 conlevel);

View File

@ -104,48 +104,45 @@ static uint32 MaxBankedRaidLeadershipPoints(int Level)
return 10;
}
uint64 Client::CalcEXP(uint8 conlevel) {
uint64 Client::CalcEXP(uint8 consider_level, bool ignore_modifiers) {
uint64 in_add_exp = EXP_FORMULA;
if((XPRate != 0))
if (XPRate != 0) {
in_add_exp = static_cast<uint64>(in_add_exp * (static_cast<float>(XPRate) / 100.0f));
float totalmod = 1.0;
float zemmod = 1.0;
//get modifiers
if(RuleR(Character, ExpMultiplier) >= 0){
totalmod *= RuleR(Character, ExpMultiplier);
}
if(zone->newzone_data.zone_exp_multiplier >= 0){
zemmod *= zone->newzone_data.zone_exp_multiplier;
if (!ignore_modifiers) {
auto total_modifier = 1.0f;
auto zone_modifier = 1.0f;
if (RuleR(Character, ExpMultiplier) >= 0) {
total_modifier *= RuleR(Character, ExpMultiplier);
}
if(RuleB(Character,UseRaceClassExpBonuses))
{
if(GetBaseRace() == HALFLING){
totalmod *= 1.05;
if (zone->newzone_data.zone_exp_multiplier >= 0) {
zone_modifier *= zone->newzone_data.zone_exp_multiplier;
}
if(GetClass() == ROGUE || GetClass() == WARRIOR){
totalmod *= 1.05;
if (RuleB(Character, UseRaceClassExpBonuses)) {
if (
GetClass() == WARRIOR ||
GetClass() == ROGUE ||
GetBaseRace() == HALFLING
) {
total_modifier *= 1.05;
}
}
if(zone->IsHotzone())
{
totalmod += RuleR(Zone, HotZoneBonus);
if (zone->IsHotzone()) {
total_modifier += RuleR(Zone, HotZoneBonus);
}
in_add_exp = uint64(float(in_add_exp) * totalmod * zemmod);
in_add_exp = uint64(float(in_add_exp) * total_modifier * zone_modifier);
}
if(RuleB(Character,UseXPConScaling))
{
if (conlevel != 0xFF) {
switch (conlevel)
{
if (RuleB(Character,UseXPConScaling)) {
if (consider_level != 0xFF) {
switch (consider_level) {
case CON_GRAY:
in_add_exp = 0;
return 0;
@ -153,44 +150,27 @@ uint64 Client::CalcEXP(uint8 conlevel) {
in_add_exp = in_add_exp * RuleI(Character, GreenModifier) / 100;
break;
case CON_LIGHTBLUE:
in_add_exp = in_add_exp * RuleI(Character, LightBlueModifier)/100;
in_add_exp = in_add_exp * RuleI(Character, LightBlueModifier) / 100;
break;
case CON_BLUE:
in_add_exp = in_add_exp * RuleI(Character, BlueModifier)/100;
in_add_exp = in_add_exp * RuleI(Character, BlueModifier) / 100;
break;
case CON_WHITE:
in_add_exp = in_add_exp * RuleI(Character, WhiteModifier)/100;
in_add_exp = in_add_exp * RuleI(Character, WhiteModifier) / 100;
break;
case CON_YELLOW:
in_add_exp = in_add_exp * RuleI(Character, YellowModifier)/100;
in_add_exp = in_add_exp * RuleI(Character, YellowModifier) / 100;
break;
case CON_RED:
in_add_exp = in_add_exp * RuleI(Character, RedModifier)/100;
in_add_exp = in_add_exp * RuleI(Character, RedModifier) / 100;
break;
}
}
}
float aatotalmod = 1.0;
if(zone->newzone_data.zone_exp_multiplier >= 0){
aatotalmod *= zone->newzone_data.zone_exp_multiplier;
}
if(RuleB(Character,UseRaceClassExpBonuses))
{
if(GetBaseRace() == HALFLING){
aatotalmod *= 1.05;
}
if(GetClass() == ROGUE || GetClass() == WARRIOR){
aatotalmod *= 1.05;
}
}
if(RuleB(Zone, LevelBasedEXPMods)){
if(zone->level_exp_mod[GetLevel()].ExpMod){
if (!ignore_modifiers) {
if (RuleB(Zone, LevelBasedEXPMods)) {
if (zone->level_exp_mod[GetLevel()].ExpMod) {
in_add_exp *= zone->level_exp_mod[GetLevel()].ExpMod;
}
}
@ -199,6 +179,11 @@ uint64 Client::CalcEXP(uint8 conlevel) {
in_add_exp *= RuleR(Character, FinalExpMultiplier);
}
if (RuleB(Character, EnableCharacterEXPMods)) {
in_add_exp *= GetEXPModifier(zone->GetZoneID(), zone->GetInstanceVersion());
}
}
return in_add_exp;
}

View File

@ -2916,6 +2916,16 @@ void Lua_Client::SetEXPEnabled(bool is_exp_enabled) {
self->SetEXPEnabled(is_exp_enabled);
}
uint64 Lua_Client::CalcEXP(uint8 consider_level) {
Lua_Safe_Call_Int();
return self->CalcEXP(consider_level);
}
uint64 Lua_Client::CalcEXP(uint8 consider_level, bool ignore_modifiers) {
Lua_Safe_Call_Int();
return self->CalcEXP(consider_level, ignore_modifiers);
}
#ifdef BOTS
int Lua_Client::GetBotRequiredLevel()
@ -3047,6 +3057,8 @@ luabind::scope lua_register_client() {
.def("BreakInvis", (void(Lua_Client::*)(void))&Lua_Client::BreakInvis)
.def("CalcATK", &Lua_Client::CalcATK)
.def("CalcCurrentWeight", &Lua_Client::CalcCurrentWeight)
.def("CalcEXP", (uint64(Lua_Client::*)(uint8))&Lua_Client::CalcEXP)
.def("CalcEXP", (uint64(Lua_Client::*)(uint8,bool))&Lua_Client::CalcEXP)
.def("CalcPriceMod", (float(Lua_Client::*)(Lua_Mob,bool))&Lua_Client::CalcPriceMod)
.def("CanHaveSkill", (bool(Lua_Client::*)(int))&Lua_Client::CanHaveSkill)
.def("CashReward", &Lua_Client::CashReward)

View File

@ -457,6 +457,8 @@ public:
luabind::object GetAugmentIDsBySlotID(lua_State* L, int16 slot_id);
bool IsEXPEnabled();
void SetEXPEnabled(bool is_exp_enabled);
uint64 CalcEXP(uint8 consider_level);
uint64 CalcEXP(uint8 consider_level, bool ignore_modifiers);
void ApplySpell(int spell_id);
void ApplySpell(int spell_id, int duration);

View File

@ -1597,9 +1597,14 @@ float Perl_Client_GetTargetRingZ(Client* self) // @categories Script Utility
return self->GetTargetRingZ();
}
uint32_t Perl_Client_CalcEXP(Client* self, uint8 conlevel)
uint64_t Perl_Client_CalcEXP(Client* self, uint8 consider_level)
{
return self->CalcEXP(conlevel);
return self->CalcEXP(consider_level);
}
uint64_t Perl_Client_CalcEXP(Client* self, uint8 consider_level, bool ignore_modifiers)
{
return self->CalcEXP(consider_level, ignore_modifiers);
}
void Perl_Client_QuestReward(Client* self, Mob* mob) // @categories Currency and Points, Experience and Level, Inventory and Items, Faction
@ -2914,7 +2919,8 @@ void perl_register_client()
package.add("AssignToInstance", &Perl_Client_AssignToInstance);
package.add("AutoSplitEnabled", &Perl_Client_AutoSplitEnabled);
package.add("BreakInvis", &Perl_Client_BreakInvis);
package.add("CalcEXP", &Perl_Client_CalcEXP);
package.add("CalcEXP", (uint64(*)(Client*, uint8))&Perl_Client_CalcEXP);
package.add("CalcEXP", (uint64(*)(Client*, uint8, bool))&Perl_Client_CalcEXP);
package.add("CalcPriceMod", (float(*)(Client*))&Perl_Client_CalcPriceMod);
package.add("CalcPriceMod", (float(*)(Client*, Mob*))&Perl_Client_CalcPriceMod);
package.add("CalcPriceMod", (float(*)(Client*, Mob*, bool))&Perl_Client_CalcPriceMod);