From 39bb7e1723421b24b895ef56866cb50346f3dfbd Mon Sep 17 00:00:00 2001 From: Xackery Date: Sun, 28 Apr 2024 05:20:34 -0700 Subject: [PATCH] [Lua] Add IsImmuneToSpell Lua Mod (#4278) * Add IsImmuneToSpell lua mod * Add lua_parser.h include in spells.cpp --- zone/lua_mod.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++ zone/lua_mod.h | 2 ++ zone/lua_parser.cpp | 9 ++++++++ zone/lua_parser.h | 1 + zone/spells.cpp | 11 ++++++++++ 5 files changed, 76 insertions(+) diff --git a/zone/lua_mod.cpp b/zone/lua_mod.cpp index 0a71ed168..9d04c724a 100644 --- a/zone/lua_mod.cpp +++ b/zone/lua_mod.cpp @@ -40,6 +40,7 @@ void LuaMod::Init() m_has_register_bug = parser_->HasFunction("RegisterBug", package_name_); m_has_common_damage = parser_->HasFunction("CommonDamage", package_name_); m_has_heal_damage = parser_->HasFunction("HealDamage", package_name_); + m_has_is_immune_to_spell = parser_->HasFunction("IsImmuneToSpell", package_name_); } void PutDamageHitInfo(lua_State *L, luabind::adl::object &e, DamageHitInfo &hit) { @@ -626,6 +627,58 @@ void LuaMod::GetExperienceForKill(Client *self, Mob *against, uint64 &returnValu } } +void LuaMod::IsImmuneToSpell(Mob *self, Mob* caster, uint16 spell_id, bool &return_value, bool &ignore_default) +{ + int start = lua_gettop(L); + + try { + if (!m_has_is_immune_to_spell) { + return; + } + + lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str()); + lua_getfield(L, -1, "IsImmuneToSpell"); + + Lua_Mob l_self(self); + Lua_Mob l_other(caster); + luabind::adl::object e = luabind::newtable(L); + e["self"] = l_self; + e["caster"] = l_other; + e["spell_id"] = spell_id; + + e.push(L); + + if (lua_pcall(L, 1, 1, 0)) { + std::string error = lua_tostring(L, -1); + parser_->AddError(error); + lua_pop(L, 2); + return; + } + + if (lua_type(L, -1) == LUA_TTABLE) { + luabind::adl::object ret(luabind::from_stack(L, -1)); + auto ignore_default_obj = ret["ignore_default"]; + if (luabind::type(ignore_default_obj) == LUA_TBOOLEAN) { + ignore_default = ignore_default || luabind::object_cast(ignore_default_obj); + } + + auto return_value_obj = ret["return_value"]; + if (luabind::type(return_value_obj) == LUA_TBOOLEAN) { + return_value = luabind::object_cast(return_value_obj); + } + } + } + catch (std::exception &ex) { + parser_->AddError(ex.what()); + } + + int end = lua_gettop(L); + int n = end - start; + if (n > 0) { + lua_pop(L, n); + } +} + void LuaMod::CalcSpellEffectValue_formula(Mob *self, uint32 formula, int64 base_value, int64 max_value, int caster_level, uint16 spell_id, int ticsremaining, int64 &returnValue, bool &ignoreDefault) { int start = lua_gettop(L); diff --git a/zone/lua_mod.h b/zone/lua_mod.h index c919088c2..09960a690 100644 --- a/zone/lua_mod.h +++ b/zone/lua_mod.h @@ -26,6 +26,7 @@ public: void TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault); void GetRequiredAAExperience(Client *self, uint32 &returnValue, bool &ignoreDefault); void GetEXPForLevel(Client *self, uint16 level, uint32 &returnValue, bool &ignoreDefault); + void IsImmuneToSpell(Mob *self, Mob* caster, uint16 spell_id, bool &return_value, bool &ignore_default); void GetExperienceForKill(Client *self, Mob *against, uint64 &returnValue, bool &ignoreDefault); void CalcSpellEffectValue_formula(Mob *self, uint32 formula, int64 base_value, int64 max_value, int caster_level, uint16 spell_id, int ticsremaining, int64 &returnValue, bool &ignoreDefault); void RegisterBug(Client *self, BaseBugReportsRepository::BugReports bug, bool &ignore_default); @@ -49,4 +50,5 @@ private: bool m_has_register_bug; bool m_has_common_damage; bool m_has_heal_damage; + bool m_has_is_immune_to_spell; }; diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 77d01df3c..0b4f8287f 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -1602,6 +1602,15 @@ uint64 LuaParser::HealDamage(Mob *self, Mob* caster, uint64 value, uint16 spell_ return retval; } +bool LuaParser::IsImmuneToSpell(Mob *self, Mob *caster, uint16 spell_id, bool &ignore_default) +{ + bool retval = false; + for (auto &mod : mods_) { + mod.IsImmuneToSpell(self, caster, spell_id, retval, ignore_default); + } + return retval; +} + int64 LuaParser::CalcSpellEffectValue_formula(Mob *self, uint32 formula, int64 base_value, int64 max_value, int caster_level, uint16 spell_id, int ticsremaining, bool &ignoreDefault) { int64 retval = 0; diff --git a/zone/lua_parser.h b/zone/lua_parser.h index 8a6bd68a4..d32cf092d 100644 --- a/zone/lua_parser.h +++ b/zone/lua_parser.h @@ -201,6 +201,7 @@ public: void RegisterBug(Client *self, BaseBugReportsRepository::BugReports bug, bool &ignore_default); int64 CommonDamage(Mob *self, Mob* attacker, int64 value, uint16 spell_id, int skill_used, bool avoidable, int8 buff_slot, bool buff_tic, int special, bool &ignore_default); uint64 HealDamage(Mob *self, Mob* caster, uint64 value, uint16 spell_id, bool &ignore_default); + bool IsImmuneToSpell(Mob *self, Mob* caster, uint16 spell_id, bool &ignore_default); private: LuaParser(); diff --git a/zone/spells.cpp b/zone/spells.cpp index ce40a9e46..96f16285d 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -84,6 +84,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org) #include "string_ids.h" #include "worldserver.h" #include "fastmath.h" +#include "lua_parser.h" #include #include @@ -4958,6 +4959,16 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) LogSpells("Checking to see if we are immune to spell [{}] cast by [{}]", spell_id, caster->GetName()); +#ifdef LUA_EQEMU + bool is_immune = false; + bool ignore_default = false; + is_immune = LuaParser::Instance()->IsImmuneToSpell(this, caster, spell_id, ignore_default); + + if (ignore_default) { + return is_immune; + } +#endif + if(!IsValidSpell(spell_id)) return true;