From 143c4fe6aa1a0ea8fab8916760ef5a1112ed3e75 Mon Sep 17 00:00:00 2001 From: Aeadoin <109764533+Aeadoin@users.noreply.github.com> Date: Thu, 5 Jan 2023 20:38:08 -0500 Subject: [PATCH] [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. --- zone/client.h | 2 +- zone/exp.cpp | 131 +++++++++++++++++++------------------------ zone/lua_client.cpp | 12 ++++ zone/lua_client.h | 2 + zone/perl_client.cpp | 12 +++- 5 files changed, 82 insertions(+), 77 deletions(-) diff --git a/zone/client.h b/zone/client.h index 58087b772..85d8f6897 100644 --- a/zone/client.h +++ b/zone/client.h @@ -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); diff --git a/zone/exp.cpp b/zone/exp.cpp index ebf53700d..f87386bf9 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -104,101 +104,86 @@ 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(in_add_exp * (static_cast(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(RuleB(Character,UseRaceClassExpBonuses)) - { - if(GetBaseRace() == HALFLING){ - totalmod *= 1.05; + if (RuleR(Character, ExpMultiplier) >= 0) { + total_modifier *= RuleR(Character, ExpMultiplier); } - if(GetClass() == ROGUE || GetClass() == WARRIOR){ - totalmod *= 1.05; + if (zone->newzone_data.zone_exp_multiplier >= 0) { + zone_modifier *= zone->newzone_data.zone_exp_multiplier; } + + if (RuleB(Character, UseRaceClassExpBonuses)) { + if ( + GetClass() == WARRIOR || + GetClass() == ROGUE || + GetBaseRace() == HALFLING + ) { + total_modifier *= 1.05; + } + } + + if (zone->IsHotzone()) { + total_modifier += RuleR(Zone, HotZoneBonus); + } + + in_add_exp = uint64(float(in_add_exp) * total_modifier * zone_modifier); } - if(zone->IsHotzone()) - { - totalmod += RuleR(Zone, HotZoneBonus); - } - - in_add_exp = uint64(float(in_add_exp) * totalmod * zemmod); - - if(RuleB(Character,UseXPConScaling)) - { - if (conlevel != 0xFF) { - switch (conlevel) - { - case CON_GRAY: - in_add_exp = 0; - return 0; - case CON_GREEN: - in_add_exp = in_add_exp * RuleI(Character, GreenModifier) / 100; - break; - case CON_LIGHTBLUE: - in_add_exp = in_add_exp * RuleI(Character, LightBlueModifier)/100; - break; - case CON_BLUE: - in_add_exp = in_add_exp * RuleI(Character, BlueModifier)/100; - break; - case CON_WHITE: - in_add_exp = in_add_exp * RuleI(Character, WhiteModifier)/100; - break; - case CON_YELLOW: - in_add_exp = in_add_exp * RuleI(Character, YellowModifier)/100; - break; - case CON_RED: - in_add_exp = in_add_exp * RuleI(Character, RedModifier)/100; - break; + if (RuleB(Character,UseXPConScaling)) { + if (consider_level != 0xFF) { + switch (consider_level) { + case CON_GRAY: + in_add_exp = 0; + return 0; + case CON_GREEN: + in_add_exp = in_add_exp * RuleI(Character, GreenModifier) / 100; + break; + case CON_LIGHTBLUE: + in_add_exp = in_add_exp * RuleI(Character, LightBlueModifier) / 100; + break; + case CON_BLUE: + in_add_exp = in_add_exp * RuleI(Character, BlueModifier) / 100; + break; + case CON_WHITE: + in_add_exp = in_add_exp * RuleI(Character, WhiteModifier) / 100; + break; + case CON_YELLOW: + in_add_exp = in_add_exp * RuleI(Character, YellowModifier) / 100; + break; + case CON_RED: + 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 (!ignore_modifiers) { + if (RuleB(Zone, LevelBasedEXPMods)) { + if (zone->level_exp_mod[GetLevel()].ExpMod) { + in_add_exp *= zone->level_exp_mod[GetLevel()].ExpMod; + } } - if(GetClass() == ROGUE || GetClass() == WARRIOR){ - aatotalmod *= 1.05; + if (RuleR(Character, FinalExpMultiplier) >= 0) { + in_add_exp *= RuleR(Character, FinalExpMultiplier); } - } - if(RuleB(Zone, LevelBasedEXPMods)){ - if(zone->level_exp_mod[GetLevel()].ExpMod){ - in_add_exp *= zone->level_exp_mod[GetLevel()].ExpMod; + if (RuleB(Character, EnableCharacterEXPMods)) { + in_add_exp *= GetEXPModifier(zone->GetZoneID(), zone->GetInstanceVersion()); } } - if (RuleR(Character, FinalExpMultiplier) >= 0) { - in_add_exp *= RuleR(Character, FinalExpMultiplier); - } - return in_add_exp; } diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 7fdfbb199..b8d98e185 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -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) diff --git a/zone/lua_client.h b/zone/lua_client.h index 5a3032ed5..3e7df6e58 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -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); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 3b40d7659..3f38d67f7 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -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);