From b29f70ad3f8f52988395ca661318730d10f7cba4 Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 12 Jun 2017 13:01:01 -0700 Subject: [PATCH] Add mod hook for CommonOutgoingHitSuccess --- utils/mods/legacy_combat.lua | 7 +++-- zone/attack.cpp | 9 ++++++ zone/lua_mod.cpp | 53 ++++++++++++++++++++++++++++++++++++ zone/lua_mod.h | 2 ++ zone/lua_parser.cpp | 7 +++++ zone/lua_parser.h | 1 + 6 files changed, 76 insertions(+), 3 deletions(-) diff --git a/utils/mods/legacy_combat.lua b/utils/mods/legacy_combat.lua index 6ce193c7d..a27435be9 100644 --- a/utils/mods/legacy_combat.lua +++ b/utils/mods/legacy_combat.lua @@ -1,7 +1,7 @@ SoftcapFactor = 1.88; MonkACBonusWeight = 15; NPCACFactor = 2.25; -OldACSoftcapRules = false; +OldACSoftcapRules = true; ClothACSoftcap = 75; LeatherACSoftcap = 100; MonkACSoftcap = 120; @@ -40,6 +40,7 @@ HitBonusPerLevel = 1.2; AgiHitFactor = 0.01; WeaponSkillFalloff = 0.33; ArcheryHitPenalty = 0.25; +UseOldDamageIntervalRules = true; function MeleeMitigation(e) e.IgnoreDefault = true; @@ -575,13 +576,13 @@ end function ClientGetMeleeMitDmg(defender, attacker, damage, min_damage, mitigation_rating, attack_rating) if (not attacker:IsNPC() or UseOldDamageIntervalRules) then - return MobGetMeleeMitDmg(attacker, damage, min_damage, mitigation_rating, attack_rating); + return MobGetMeleeMitDmg(defender, attacker, damage, min_damage, mitigation_rating, attack_rating); end local d = 10; local dmg_interval = (damage - min_damage) / 19.0; local dmg_bonus = min_damage - dmg_interval; - local spellMeleeMit = (defender:GetSpellBonuses():MeleeMitigationEffect() + defender:GetItemBonuses():MeleeMitigationEffect() + defender:GetAABonuses():MeleeMitigationEffect()) / 100.0; + local spellMeleeMit = (defender:GetSpellBonuses():MeleeMitigationEffect() + defender:GetItemBonuses():MeleeMitigationEffect() + defender:GetAABonuses():MeleeMitigationEffect()) / 100.0; if (defender:GetClass() == Class.WARRIOR) then spellMeleeMit = spellMeleeMit + 0.05; end diff --git a/zone/attack.cpp b/zone/attack.cpp index 1f7738119..388a959c2 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -4926,6 +4926,15 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac if (!defender) return; +#ifdef LUA_EQEMU + bool ignoreDefault = false; + LuaParser::Instance()->CommonOutgoingHitSuccess(this, defender, hit, opts, ignoreDefault); + + if (ignoreDefault) { + return; + } +#endif + // BER weren't parsing the halving if (hit.skill == EQEmu::skills::SkillArchery || (hit.skill == EQEmu::skills::SkillThrowing && GetClass() != BERSERKER)) diff --git a/zone/lua_mod.cpp b/zone/lua_mod.cpp index 1a97945a5..ba675c767 100644 --- a/zone/lua_mod.cpp +++ b/zone/lua_mod.cpp @@ -42,6 +42,7 @@ void LuaMod::Init() m_has_get_required_aa_experience = parser_->HasFunction("GetRequiredAAExperience", package_name_); m_has_get_exp_for_level = parser_->HasFunction("GetEXPForLevel", package_name_); m_has_get_experience_for_kill = parser_->HasFunction("GetExperienceForKill", package_name_); + m_has_common_outgoing_hit_success = parser_->HasFunction("CommonOutgoingHitSuccess", package_name_); } void PutDamageHitInfo(lua_State *L, luabind::adl::object &e, DamageHitInfo &hit) { @@ -391,6 +392,58 @@ bool LuaMod::CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &ign return retval; } +void LuaMod::CommonOutgoingHitSuccess(Mob *self, Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault) +{ + int start = lua_gettop(L); + ignoreDefault = false; + + try { + if (!m_has_common_outgoing_hit_success) { + return; + } + + lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str()); + lua_getfield(L, -1, "CommonOutgoingHitSuccess"); + + Lua_Mob l_self(self); + Lua_Mob l_other(other); + luabind::adl::object e = luabind::newtable(L); + e["self"] = l_self; + e["other"] = l_other; + + PutDamageHitInfo(L, e, hit); + PutExtraAttackOptions(L, e, opts); + e.push(L); + + if (lua_pcall(L, 1, 1, 0)) { + std::string error = lua_tostring(L, -1); + parser_->AddError(error); + lua_pop(L, 1); + return; + } + + if (lua_type(L, -1) == LUA_TTABLE) { + luabind::adl::object ret(luabind::from_stack(L, -1)); + auto IgnoreDefaultObj = ret["IgnoreDefault"]; + if (luabind::type(IgnoreDefaultObj) == LUA_TBOOLEAN) { + ignoreDefault = ignoreDefault || luabind::object_cast(IgnoreDefaultObj); + } + + GetDamageHitInfo(ret, hit); + GetExtraAttackOptions(ret, opts); + } + } + 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::TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault) { int start = lua_gettop(L); ignoreDefault = false; diff --git a/zone/lua_mod.h b/zone/lua_mod.h index bef40bbcc..04f991f05 100644 --- a/zone/lua_mod.h +++ b/zone/lua_mod.h @@ -21,6 +21,7 @@ public: void ApplyDamageTable(Mob *self, DamageHitInfo &hit, bool &ignoreDefault); bool AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool &ignoreDefault); bool CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &ignoreDefault); + void CommonOutgoingHitSuccess(Mob *self, Mob* other, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault); void TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault); uint32 GetRequiredAAExperience(Client *self, bool &ignoreDefault); uint32 GetEXPForLevel(Client *self, uint16 level, bool &ignoreDefault); @@ -34,6 +35,7 @@ private: bool m_has_apply_damage_table; bool m_has_avoid_damage; bool m_has_check_hit_chance; + bool m_has_common_outgoing_hit_success; bool m_has_try_critical_hit; bool m_has_get_required_aa_experience; bool m_has_get_exp_for_level; diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 431d7cd29..8f2eda66d 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -1333,6 +1333,13 @@ void LuaParser::TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, Ext } } +void LuaParser::CommonOutgoingHitSuccess(Mob *self, Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault) +{ + for (auto &mod : mods_) { + mod.CommonOutgoingHitSuccess(self, other, hit, opts, ignoreDefault); + } +} + uint32 LuaParser::GetRequiredAAExperience(Client *self, bool &ignoreDefault) { uint32 retval = false; diff --git a/zone/lua_parser.h b/zone/lua_parser.h index f99553ccc..eb57faa96 100644 --- a/zone/lua_parser.h +++ b/zone/lua_parser.h @@ -95,6 +95,7 @@ public: bool AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool &ignoreDefault); bool CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &ignoreDefault); void TryCriticalHit(Mob *self, Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault); + void CommonOutgoingHitSuccess(Mob *self, Mob* other, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault); uint32 GetRequiredAAExperience(Client *self, bool &ignoreDefault); uint32 GetEXPForLevel(Client *self, uint16 level, bool &ignoreDefault); uint32 GetExperienceForKill(Client *self, Mob *against, bool &ignoreDefault);