diff --git a/zone/attack.cpp b/zone/attack.cpp index 4ac29fdc0..39fceb568 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -780,7 +780,7 @@ int Mob::GetClassRaceACBonus() return ac_bonus; } -int Mob::ACSum() +int Mob::ACSum(bool skip_caps) { int ac = 0; // this should be base AC whenever shrouds come around ac += itembonuses.AC; // items + food + tribute @@ -799,7 +799,7 @@ int Mob::ACSum() // EQ math ac = (ac * 4) / 3; // anti-twink - if (IsClient() && GetLevel() < RuleI(Combat, LevelToStopACTwinkControl)) + if (!skip_caps && IsClient() && GetLevel() < RuleI(Combat, LevelToStopACTwinkControl)) ac = std::min(ac, 25 + 6 * GetLevel()); ac = std::max(0, ac + GetClassRaceACBonus()); if (IsNPC()) { @@ -835,11 +835,11 @@ int Mob::ACSum() if (ac < 0) ac = 0; - if (IsClient() + if (!skip_caps && (IsClient() #ifdef BOTS || IsBot() #endif - ) { + )) { auto softcap = GetACSoftcap(); auto returns = GetSoftcapReturns(); int total_aclimitmod = aabonuses.CombatStability + itembonuses.CombatStability + spellbonuses.CombatStability; diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 69742c655..53658e63d 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -532,6 +532,11 @@ int Lua_Mob::GetAC() { return self->GetAC(); } +int Lua_Mob::GetDisplayAC() { + Lua_Safe_Call_Int(); + return self->GetDisplayAC(); +} + int Lua_Mob::GetATK() { Lua_Safe_Call_Int(); return self->GetATK(); @@ -2344,6 +2349,7 @@ luabind::scope lua_register_mob() { .def("SetMana", &Lua_Mob::SetMana) .def("GetManaRatio", &Lua_Mob::GetManaRatio) .def("GetAC", &Lua_Mob::GetAC) + .def("GetDisplayAC", &Lua_Mob::GetDisplayAC) .def("GetATK", &Lua_Mob::GetATK) .def("GetSTR", &Lua_Mob::GetSTR) .def("GetSTA", &Lua_Mob::GetSTA) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 592ac6243..e2dbf9e24 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -124,6 +124,7 @@ public: int SetMana(int mana); double GetManaRatio(); int GetAC(); + int GetDisplayAC(); int GetATK(); int GetSTR(); int GetSTA(); diff --git a/zone/mob.h b/zone/mob.h index efdf68012..b07f51ceb 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -211,7 +211,8 @@ public: int TryAssassinate(Mob* defender, EQ::skills::SkillType skillInUse); virtual void DoRiposte(Mob* defender); void ApplyMeleeDamageMods(uint16 skill, int &damage, Mob * defender = nullptr, ExtraAttackOptions *opts = nullptr); - int ACSum(); + int ACSum(bool skip_caps = false); + inline int GetDisplayAC() { return 1000 * (ACSum(true) + compute_defense()) / 847; } int offense(EQ::skills::SkillType skill); int GetBestMeleeSkill(); void CalcAC() { mitigation_ac = ACSum(); } diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 12f3b1886..f90435887 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -2506,6 +2506,31 @@ XS(XS_Mob_GetAC) { XSRETURN(1); } +XS(XS_Mob_GetDisplayAC); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Mob_GetDisplayAC) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Mob::GetDisplayAC(THIS)"); + { + Mob *THIS; + uint32 RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Mob"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetDisplayAC(); + XSprePUSH; + PUSHu((UV) RETVAL); + } + XSRETURN(1); +} + XS(XS_Mob_GetATK); /* prototype to pass -Wmissing-prototypes */ XS(XS_Mob_GetATK) { dXSARGS; @@ -8676,6 +8701,7 @@ XS(boot_Mob) { newXSproto(strcpy(buf, "SetMana"), XS_Mob_SetMana, file, "$$"); newXSproto(strcpy(buf, "GetManaRatio"), XS_Mob_GetManaRatio, file, "$"); newXSproto(strcpy(buf, "GetAC"), XS_Mob_GetAC, file, "$"); + newXSproto(strcpy(buf, "GetDisplayAC"), XS_Mob_GetDisplayAC, file, "$"); newXSproto(strcpy(buf, "GetATK"), XS_Mob_GetATK, file, "$"); newXSproto(strcpy(buf, "GetSTR"), XS_Mob_GetSTR, file, "$"); newXSproto(strcpy(buf, "GetSTA"), XS_Mob_GetSTA, file, "$");