diff --git a/zone/attack.cpp b/zone/attack.cpp index 034605788..238b1d5bd 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -3964,6 +3964,18 @@ bool Mob::CheckDoubleAttack() } void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, const EQ::skills::SkillType skill_used, bool &avoidable, const int8 buffslot, const bool iBuffTic, eSpecialAttacks special) { +#ifdef LUA_EQEMU + int64 lua_ret = 0; + bool ignore_default = false; + lua_ret = LuaParser::Instance()->CommonDamage(this, attacker, damage, spell_id, static_cast(skill_used), avoidable, buffslot, iBuffTic, static_cast(special), ignore_default); + if (lua_ret != 0) { + damage = lua_ret; + } + + if (ignore_default) { + //return lua_ret; + } +#endif // This method is called with skill_used=ABJURE for Damage Shield damage. bool FromDamageShield = (skill_used == EQ::skills::SkillAbjuration); bool ignore_invul = false; @@ -4691,6 +4703,19 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons void Mob::HealDamage(uint64 amount, Mob* caster, uint16 spell_id) { +#ifdef LUA_EQEMU + uint64 lua_ret = 0; + bool ignore_default = false; + + lua_ret = LuaParser::Instance()->HealDamage(this, caster, amount, spell_id, ignore_default); + if (lua_ret != 0) { + amount = lua_ret; + } + + if (ignore_default) { + //return lua_ret; + } +#endif int64 maxhp = GetMaxHP(); int64 curhp = GetHP(); uint64 acthealed = 0; diff --git a/zone/lua_mod.cpp b/zone/lua_mod.cpp index 43071495c..11bdae719 100644 --- a/zone/lua_mod.cpp +++ b/zone/lua_mod.cpp @@ -749,4 +749,117 @@ void LuaMod::RegisterBug(Client *self, BaseBugReportsRepository::BugReports bug, lua_pop(L, n); } } + + +void LuaMod::CommonDamage(Mob *self, Mob* attacker, int64 value, uint16 spell_id, int skill_used, bool avoidable, int8 buff_slot, bool buff_tic, int special, int64 &return_value, bool &ignore_default) +{ + int start = lua_gettop(L); + + try { + if (!m_has_common_damage) { + return; + } + + lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str()); + lua_getfield(L, -1, "CommonDamage"); + + Lua_Mob l_self(self); + Lua_Mob l_other(attacker); + luabind::adl::object e = luabind::newtable(L); + e["self"] = l_self; + e["attacker"] = l_other; + e["value"] = value; + e["spell_id"] = spell_id; + e["skill_used"] = skill_used; + e["avoidable"] = avoidable; + e["buff_slot"] = buff_slot; + e["buff_tic"] = buff_tic; + e["special"] = special; + + 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_TNUMBER) { + 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::HealDamage(Mob *self, Mob* caster, uint64 value, uint16 spell_id, uint64 &return_value, bool &ignore_default) +{ + int start = lua_gettop(L); + + try { + if (!m_has_heal_damage) { + return; + } + + lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str()); + lua_getfield(L, -1, "HealDamage"); + + 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["value"] = value; + 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_TNUMBER) { + 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); + } +} #endif diff --git a/zone/lua_mod.h b/zone/lua_mod.h index cb0ec1888..c919088c2 100644 --- a/zone/lua_mod.h +++ b/zone/lua_mod.h @@ -29,6 +29,8 @@ public: 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); + void CommonDamage(Mob *self, Mob* attacker, int64 value, uint16 spell_id, int skill_used, bool avoidable, int8 buff_slot, bool buff_tic, int special, int64 &return_value, bool &ignore_default); + void HealDamage(Mob *self, Mob* caster, uint64 value, uint16 spell_id, uint64 &return_value, bool &ignore_default); private: LuaParser *parser_; lua_State *L; @@ -45,4 +47,6 @@ private: bool m_has_get_experience_for_kill; bool m_has_calc_spell_effect_value_formula; bool m_has_register_bug; + bool m_has_common_damage; + bool m_has_heal_damage; }; diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 945e40075..f5c284fd0 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -1579,6 +1579,25 @@ uint64 LuaParser::GetExperienceForKill(Client *self, Mob *against, bool &ignoreD return retval; } + +int64 LuaParser::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) +{ + int64 retval = 0; + for (auto &mod : mods_) { + mod.CommonDamage(self, attacker, value, spell_id, skill_used, avoidable, buff_slot, buff_tic, special, retval, ignore_default); + } + return retval; +} + +uint64 LuaParser::HealDamage(Mob *self, Mob* caster, uint64 value, uint16 spell_id, bool &ignore_default) +{ + uint64 retval = 0; + for (auto &mod : mods_) { + mod.HealDamage(self, caster, value, 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 9277e3e6b..8a6bd68a4 100644 --- a/zone/lua_parser.h +++ b/zone/lua_parser.h @@ -199,6 +199,8 @@ public: uint64 GetExperienceForKill(Client *self, Mob *against, bool &ignoreDefault); int64 CalcSpellEffectValue_formula(Mob *self, uint32 formula, int64 base_value, int64 max_value, int caster_level, uint16 spell_id, int ticsremaining, bool &ignoreDefault); 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); private: LuaParser();