mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 18:51:29 +00:00
Mods get their own file so i can take the big chunks of code out of lua parser
This commit is contained in:
parent
8d391a7e3f
commit
0fd6815f81
@ -51,6 +51,7 @@ SET(zone_sources
|
|||||||
lua_item.cpp
|
lua_item.cpp
|
||||||
lua_iteminst.cpp
|
lua_iteminst.cpp
|
||||||
lua_mob.cpp
|
lua_mob.cpp
|
||||||
|
lua_mod.cpp
|
||||||
lua_npc.cpp
|
lua_npc.cpp
|
||||||
lua_object.cpp
|
lua_object.cpp
|
||||||
lua_packet.cpp
|
lua_packet.cpp
|
||||||
@ -174,6 +175,7 @@ SET(zone_headers
|
|||||||
lua_item.h
|
lua_item.h
|
||||||
lua_iteminst.h
|
lua_iteminst.h
|
||||||
lua_mob.h
|
lua_mob.h
|
||||||
|
lua_mod.h
|
||||||
lua_npc.h
|
lua_npc.h
|
||||||
lua_object.h
|
lua_object.h
|
||||||
lua_packet.h
|
lua_packet.h
|
||||||
|
|||||||
@ -1306,6 +1306,16 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts)
|
|||||||
// IsFromSpell added to allow spell effects to use Attack. (Mainly for the Rampage AA right now.)
|
// IsFromSpell added to allow spell effects to use Attack. (Mainly for the Rampage AA right now.)
|
||||||
bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts)
|
bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts)
|
||||||
{
|
{
|
||||||
|
#ifdef LUA_EQEMU
|
||||||
|
bool lua_ret = false;
|
||||||
|
bool ignoreDefault = false;
|
||||||
|
lua_ret = LuaParser::Instance()->ClientAttack(this, other, Hand, bRiposte, IsStrikethrough, IsFromSpell, opts, ignoreDefault);
|
||||||
|
|
||||||
|
if (ignoreDefault) {
|
||||||
|
return lua_ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!other) {
|
if (!other) {
|
||||||
SetTarget(nullptr);
|
SetTarget(nullptr);
|
||||||
Log(Logs::General, Logs::Error, "A null Mob object was passed to Client::Attack() for evaluation!");
|
Log(Logs::General, Logs::Error, "A null Mob object was passed to Client::Attack() for evaluation!");
|
||||||
@ -1829,6 +1839,16 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, EQEmu::skills::Sk
|
|||||||
|
|
||||||
bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts)
|
bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts)
|
||||||
{
|
{
|
||||||
|
#ifdef LUA_EQEMU
|
||||||
|
bool lua_ret = false;
|
||||||
|
bool ignoreDefault = false;
|
||||||
|
lua_ret = LuaParser::Instance()->NPCAttack(this, other, Hand, bRiposte, IsStrikethrough, IsFromSpell, opts, ignoreDefault);
|
||||||
|
|
||||||
|
if (ignoreDefault) {
|
||||||
|
return lua_ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!other) {
|
if (!other) {
|
||||||
SetTarget(nullptr);
|
SetTarget(nullptr);
|
||||||
Log(Logs::General, Logs::Error, "A null Mob object was passed to NPC::Attack() for evaluation!");
|
Log(Logs::General, Logs::Error, "A null Mob object was passed to NPC::Attack() for evaluation!");
|
||||||
@ -2827,6 +2847,8 @@ uint8 Mob::GetWeaponDamageBonus(const EQEmu::ItemData *weapon, bool offhand)
|
|||||||
}
|
}
|
||||||
return damage_bonus;
|
return damage_bonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Mob::GetHandToHandDamage(void)
|
int Mob::GetHandToHandDamage(void)
|
||||||
|
|||||||
11
zone/bot.cpp
11
zone/bot.cpp
@ -22,6 +22,7 @@
|
|||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "doors.h"
|
#include "doors.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "lua_parser.h"
|
||||||
#include "../common/string_util.h"
|
#include "../common/string_util.h"
|
||||||
#include "../common/say_link.h"
|
#include "../common/say_link.h"
|
||||||
|
|
||||||
@ -3857,6 +3858,16 @@ void Bot::AddToHateList(Mob* other, uint32 hate, int32 damage, bool iYellForHelp
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts) {
|
bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts) {
|
||||||
|
#ifdef LUA_EQEMU
|
||||||
|
bool lua_ret = false;
|
||||||
|
bool ignoreDefault = false;
|
||||||
|
lua_ret = LuaParser::Instance()->BotAttack(this, other, Hand, bRiposte, IsStrikethrough, IsFromSpell, opts, ignoreDefault);
|
||||||
|
|
||||||
|
if (ignoreDefault) {
|
||||||
|
return lua_ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!other) {
|
if (!other) {
|
||||||
SetTarget(nullptr);
|
SetTarget(nullptr);
|
||||||
Log(Logs::General, Logs::Error, "A null Mob object was passed to Bot::Attack for evaluation!");
|
Log(Logs::General, Logs::Error, "A null Mob object was passed to Bot::Attack for evaluation!");
|
||||||
|
|||||||
778
zone/lua_mod.cpp
Normal file
778
zone/lua_mod.cpp
Normal file
@ -0,0 +1,778 @@
|
|||||||
|
#include "lua.hpp"
|
||||||
|
#include <luabind/luabind.hpp>
|
||||||
|
#include <luabind/object.hpp>
|
||||||
|
|
||||||
|
#include "../common/spdat.h"
|
||||||
|
#include "masterentity.h"
|
||||||
|
#include "questmgr.h"
|
||||||
|
#include "zone.h"
|
||||||
|
#include "zone_config.h"
|
||||||
|
|
||||||
|
#include "lua_parser.h"
|
||||||
|
#include "lua_mod.h"
|
||||||
|
#include "lua_bit.h"
|
||||||
|
#include "lua_entity.h"
|
||||||
|
#include "lua_item.h"
|
||||||
|
#include "lua_iteminst.h"
|
||||||
|
#include "lua_mob.h"
|
||||||
|
#include "lua_hate_list.h"
|
||||||
|
#include "lua_client.h"
|
||||||
|
#include "lua_inventory.h"
|
||||||
|
#include "lua_npc.h"
|
||||||
|
#include "lua_spell.h"
|
||||||
|
#include "lua_entity_list.h"
|
||||||
|
#include "lua_group.h"
|
||||||
|
#include "lua_raid.h"
|
||||||
|
#include "lua_corpse.h"
|
||||||
|
#include "lua_object.h"
|
||||||
|
#include "lua_door.h"
|
||||||
|
#include "lua_spawn.h"
|
||||||
|
#include "lua_packet.h"
|
||||||
|
#include "lua_general.h"
|
||||||
|
#include "lua_encounter.h"
|
||||||
|
#include "lua_stat_bonuses.h"
|
||||||
|
|
||||||
|
void LuaMod::Init()
|
||||||
|
{
|
||||||
|
m_has_client_attack = parser_->HasFunction("ClientAttack", package_name_);
|
||||||
|
m_has_npc_attack = parser_->HasFunction("NPCAttack", package_name_);
|
||||||
|
m_has_bot_attack = parser_->HasFunction("BotAttack", package_name_);
|
||||||
|
m_has_melee_mitigation = parser_->HasFunction("MeleeMitigation", package_name_);
|
||||||
|
m_has_apply_damage_table = parser_->HasFunction("ApplyDamageTable", package_name_);
|
||||||
|
m_has_avoid_damage = parser_->HasFunction("AvoidDamage", package_name_);
|
||||||
|
m_has_check_hit_chance = parser_->HasFunction("CheckHitChance", package_name_);
|
||||||
|
m_has_do_special_attack_damage = parser_->HasFunction("DoSpecialAttackDamage", package_name_);
|
||||||
|
m_has_do_ranged_attack_dmg = parser_->HasFunction("DoRangedAttackDmg", package_name_);
|
||||||
|
m_has_do_archery_attack_dmg = parser_->HasFunction("DoArcheryAttackDmg", package_name_);
|
||||||
|
m_has_do_throwing_attack_dmg = parser_->HasFunction("DoThrowingAttackDmg", package_name_);
|
||||||
|
m_has_do_melee_skill_attack_dmg = parser_->HasFunction("DoMeleeSkillAttackDmg", package_name_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PutDamageHitInfo(lua_State *L, luabind::adl::object &e, DamageHitInfo &hit) {
|
||||||
|
luabind::adl::object lua_hit = luabind::newtable(L);
|
||||||
|
lua_hit["base_damage"] = hit.base_damage;
|
||||||
|
lua_hit["damage_done"] = hit.damage_done;
|
||||||
|
lua_hit["offense"] = hit.offense;
|
||||||
|
lua_hit["tohit"] = hit.tohit;
|
||||||
|
lua_hit["hand"] = hit.hand;
|
||||||
|
lua_hit["skill"] = (int)hit.skill;
|
||||||
|
e["hit"] = lua_hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetDamageHitInfo(luabind::adl::object &ret, DamageHitInfo &hit) {
|
||||||
|
auto luaHitTable = ret["hit"];
|
||||||
|
if (luabind::type(luaHitTable) == LUA_TTABLE) {
|
||||||
|
auto base_damage = luaHitTable["base_damage"];
|
||||||
|
auto damage_done = luaHitTable["damage_done"];
|
||||||
|
auto offense = luaHitTable["offense"];
|
||||||
|
auto tohit = luaHitTable["tohit"];
|
||||||
|
auto hand = luaHitTable["hand"];
|
||||||
|
auto skill = luaHitTable["skill"];
|
||||||
|
|
||||||
|
if (luabind::type(base_damage) == LUA_TNUMBER) {
|
||||||
|
hit.base_damage = luabind::object_cast<int>(base_damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(damage_done) == LUA_TNUMBER) {
|
||||||
|
hit.damage_done = luabind::object_cast<int>(damage_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(offense) == LUA_TNUMBER) {
|
||||||
|
hit.offense = luabind::object_cast<int>(offense);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(tohit) == LUA_TNUMBER) {
|
||||||
|
hit.tohit = luabind::object_cast<int>(tohit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(hand) == LUA_TNUMBER) {
|
||||||
|
hit.hand = luabind::object_cast<int>(hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(skill) == LUA_TNUMBER) {
|
||||||
|
hit.skill = (EQEmu::skills::SkillType)luabind::object_cast<int>(skill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PutExtraAttackOptions(lua_State *L, luabind::adl::object &e, ExtraAttackOptions *opts) {
|
||||||
|
if (opts) {
|
||||||
|
luabind::adl::object lua_opts = luabind::newtable(L);
|
||||||
|
lua_opts["damage_percent"] = opts->damage_percent;
|
||||||
|
lua_opts["damage_flat"] = opts->damage_flat;
|
||||||
|
lua_opts["armor_pen_percent"] = opts->armor_pen_percent;
|
||||||
|
lua_opts["armor_pen_flat"] = opts->armor_pen_flat;
|
||||||
|
lua_opts["crit_percent"] = opts->crit_percent;
|
||||||
|
lua_opts["crit_flat"] = opts->crit_flat;
|
||||||
|
lua_opts["hate_percent"] = opts->hate_percent;
|
||||||
|
lua_opts["hate_flat"] = opts->hate_flat;
|
||||||
|
lua_opts["hit_chance"] = opts->hit_chance;
|
||||||
|
lua_opts["melee_damage_bonus_flat"] = opts->melee_damage_bonus_flat;
|
||||||
|
lua_opts["skilldmgtaken_bonus_flat"] = opts->skilldmgtaken_bonus_flat;
|
||||||
|
e["opts"] = lua_opts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetExtraAttackOptions(luabind::adl::object &ret, ExtraAttackOptions *opts) {
|
||||||
|
if (opts) {
|
||||||
|
auto luaOptsTable = ret["opts"];
|
||||||
|
if (luabind::type(luaOptsTable) == LUA_TTABLE) {
|
||||||
|
auto damage_percent = luaOptsTable["damage_percent"];
|
||||||
|
auto damage_flat = luaOptsTable["damage_flat"];
|
||||||
|
auto armor_pen_percent = luaOptsTable["armor_pen_percent"];
|
||||||
|
auto armor_pen_flat = luaOptsTable["armor_pen_flat"];
|
||||||
|
auto crit_percent = luaOptsTable["crit_percent"];
|
||||||
|
auto crit_flat = luaOptsTable["crit_flat"];
|
||||||
|
auto hate_percent = luaOptsTable["hate_percent"];
|
||||||
|
auto hate_flat = luaOptsTable["hate_flat"];
|
||||||
|
auto hit_chance = luaOptsTable["hit_chance"];
|
||||||
|
auto melee_damage_bonus_flat = luaOptsTable["melee_damage_bonus_flat"];
|
||||||
|
auto skilldmgtaken_bonus_flat = luaOptsTable["skilldmgtaken_bonus_flat"];
|
||||||
|
|
||||||
|
if (luabind::type(damage_percent) == LUA_TNUMBER) {
|
||||||
|
opts->damage_percent = luabind::object_cast<float>(damage_percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(damage_flat) == LUA_TNUMBER) {
|
||||||
|
opts->damage_flat = luabind::object_cast<int>(damage_flat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(armor_pen_percent) == LUA_TNUMBER) {
|
||||||
|
opts->armor_pen_percent = luabind::object_cast<float>(armor_pen_percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(armor_pen_flat) == LUA_TNUMBER) {
|
||||||
|
opts->armor_pen_flat = luabind::object_cast<int>(armor_pen_flat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(crit_percent) == LUA_TNUMBER) {
|
||||||
|
opts->crit_percent = luabind::object_cast<float>(crit_percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(crit_flat) == LUA_TNUMBER) {
|
||||||
|
opts->crit_flat = luabind::object_cast<float>(crit_flat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(hate_percent) == LUA_TNUMBER) {
|
||||||
|
opts->hate_percent = luabind::object_cast<float>(hate_percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(hate_flat) == LUA_TNUMBER) {
|
||||||
|
opts->hate_flat = luabind::object_cast<int>(hate_flat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(hit_chance) == LUA_TNUMBER) {
|
||||||
|
opts->hit_chance = luabind::object_cast<int>(hit_chance);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(melee_damage_bonus_flat) == LUA_TNUMBER) {
|
||||||
|
opts->melee_damage_bonus_flat = luabind::object_cast<int>(melee_damage_bonus_flat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luabind::type(skilldmgtaken_bonus_flat) == LUA_TNUMBER) {
|
||||||
|
opts->skilldmgtaken_bonus_flat = luabind::object_cast<int>(skilldmgtaken_bonus_flat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaMod::ClientAttack(Mob *self, Mob *other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
if (!m_has_client_attack) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = CommonAttack("ClientAttack", self, other, Hand, bRiposte, IsStrikethrough, IsFromSpell, opts, ignoreDefault);
|
||||||
|
|
||||||
|
int end = lua_gettop(L);
|
||||||
|
int n = end - start;
|
||||||
|
if (n > 0) {
|
||||||
|
lua_pop(L, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaMod::NPCAttack(Mob *self, Mob *other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
if (!m_has_npc_attack) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = CommonAttack("NPCAttack", self, other, Hand, bRiposte, IsStrikethrough, IsFromSpell, opts, ignoreDefault);
|
||||||
|
|
||||||
|
int end = lua_gettop(L);
|
||||||
|
int n = end - start;
|
||||||
|
if (n > 0) {
|
||||||
|
lua_pop(L, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaMod::BotAttack(Mob *self, Mob *other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
if (!m_has_bot_attack) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = CommonAttack("BotAttack", self, other, Hand, bRiposte, IsStrikethrough, IsFromSpell, opts, ignoreDefault);
|
||||||
|
|
||||||
|
int end = lua_gettop(L);
|
||||||
|
int n = end - start;
|
||||||
|
if (n > 0) {
|
||||||
|
lua_pop(L, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaMod::CommonAttack(const std::string &fn, Mob *self, Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault) {
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||||
|
lua_getfield(L, -1, fn.c_str());
|
||||||
|
|
||||||
|
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;
|
||||||
|
e["Hand"] = Hand;
|
||||||
|
e["bRiposte"] = bRiposte;
|
||||||
|
e["IsStrikethrough"] = IsStrikethrough;
|
||||||
|
e["IsFromSpell"] = IsFromSpell;
|
||||||
|
|
||||||
|
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 retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<bool>(IgnoreDefaultObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto returnValueObj = ret["ReturnValue"];
|
||||||
|
if (luabind::type(returnValueObj) == LUA_TBOOLEAN) {
|
||||||
|
retval = luabind::object_cast<bool>(returnValueObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetExtraAttackOptions(ret, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaMod::MeleeMitigation(Mob *self, Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault) {
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!m_has_melee_mitigation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||||
|
lua_getfield(L, -1, "MeleeMitigation");
|
||||||
|
|
||||||
|
Lua_Mob l_self(self);
|
||||||
|
Lua_Mob l_other(attacker);
|
||||||
|
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<bool>(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::ApplyDamageTable(Mob *self, DamageHitInfo &hit, bool &ignoreDefault) {
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!m_has_apply_damage_table) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||||
|
lua_getfield(L, -1, "ApplyDamageTable");
|
||||||
|
|
||||||
|
Lua_Mob l_self(self);
|
||||||
|
luabind::adl::object e = luabind::newtable(L);
|
||||||
|
e["self"] = l_self;
|
||||||
|
|
||||||
|
PutDamageHitInfo(L, e, hit);
|
||||||
|
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<bool>(IgnoreDefaultObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetDamageHitInfo(ret, hit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception &ex) {
|
||||||
|
parser_->AddError(ex.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
int end = lua_gettop(L);
|
||||||
|
int n = end - start;
|
||||||
|
if (n > 0) {
|
||||||
|
lua_pop(L, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaMod::AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool &ignoreDefault) {
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!m_has_avoid_damage) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||||
|
lua_getfield(L, -1, "AvoidDamage");
|
||||||
|
|
||||||
|
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);
|
||||||
|
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 retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<bool>(IgnoreDefaultObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto returnValueObj = ret["ReturnValue"];
|
||||||
|
if (luabind::type(returnValueObj) == LUA_TBOOLEAN) {
|
||||||
|
retval = luabind::object_cast<bool>(returnValueObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetDamageHitInfo(ret, hit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception &ex) {
|
||||||
|
parser_->AddError(ex.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
int end = lua_gettop(L);
|
||||||
|
int n = end - start;
|
||||||
|
if (n > 0) {
|
||||||
|
lua_pop(L, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaMod::CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &ignoreDefault) {
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!m_has_check_hit_chance) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||||
|
lua_getfield(L, -1, "CheckHitChance");
|
||||||
|
|
||||||
|
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);
|
||||||
|
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 retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<bool>(IgnoreDefaultObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto returnValueObj = ret["ReturnValue"];
|
||||||
|
if (luabind::type(returnValueObj) == LUA_TBOOLEAN) {
|
||||||
|
retval = luabind::object_cast<bool>(returnValueObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetDamageHitInfo(ret, hit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception &ex) {
|
||||||
|
parser_->AddError(ex.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
int end = lua_gettop(L);
|
||||||
|
int n = end - start;
|
||||||
|
if (n > 0) {
|
||||||
|
lua_pop(L, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaMod::DoSpecialAttackDamage(Mob *self, Mob *who, EQEmu::skills::SkillType skill, int32 base_damage, int32 min_damage, int32 hate_override, int ReuseTime, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!m_has_do_special_attack_damage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||||
|
lua_getfield(L, -1, "DoSpecialAttackDamage");
|
||||||
|
|
||||||
|
Lua_Mob l_self(self);
|
||||||
|
Lua_Mob l_other(who);
|
||||||
|
luabind::adl::object e = luabind::newtable(L);
|
||||||
|
e["self"] = l_self;
|
||||||
|
e["other"] = l_other;
|
||||||
|
e["skill"] = (int)skill;
|
||||||
|
e["base_damage"] = base_damage;
|
||||||
|
e["min_damage"] = min_damage;
|
||||||
|
e["hate_override"] = hate_override;
|
||||||
|
e["ReuseTime"] = ReuseTime;
|
||||||
|
|
||||||
|
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<bool>(IgnoreDefaultObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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::DoRangedAttackDmg(Mob *self, Mob *other, bool Launch, int16 damage_mod, int16 chance_mod, EQEmu::skills::SkillType skill, float speed, const char *IDFile, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!m_has_do_ranged_attack_dmg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||||
|
lua_getfield(L, -1, "DoRangedAttackDmg");
|
||||||
|
|
||||||
|
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;
|
||||||
|
e["Launch"] = Launch;
|
||||||
|
e["damage_mod"] = damage_mod;
|
||||||
|
e["chance_mod"] = chance_mod;
|
||||||
|
e["skill"] = (int)skill;
|
||||||
|
e["speed"] = speed;
|
||||||
|
e["IDFile"] = IDFile ? IDFile : "";
|
||||||
|
|
||||||
|
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<bool>(IgnoreDefaultObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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::DoArcheryAttackDmg(Mob *self, Mob *other, const EQEmu::ItemInstance *RangeWeapon, const EQEmu::ItemInstance *Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus,
|
||||||
|
int ReuseTime, uint32 range_id, uint32 ammo_id, const EQEmu::ItemData *AmmoItem, int AmmoSlot, float speed, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!m_has_do_archery_attack_dmg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||||
|
lua_getfield(L, -1, "DoArcheryAttackDmg");
|
||||||
|
|
||||||
|
Lua_Mob l_self(self);
|
||||||
|
Lua_Mob l_other(other);
|
||||||
|
Lua_ItemInst l_RangeWeapon(const_cast<EQEmu::ItemInstance*>(RangeWeapon));
|
||||||
|
Lua_ItemInst l_Ammo(const_cast<EQEmu::ItemInstance*>(Ammo));
|
||||||
|
Lua_Item l_AmmoItem(const_cast<EQEmu::ItemData*>(AmmoItem));
|
||||||
|
luabind::adl::object e = luabind::newtable(L);
|
||||||
|
e["self"] = l_self;
|
||||||
|
e["other"] = l_other;
|
||||||
|
e["RangeWeapon"] = l_RangeWeapon;
|
||||||
|
e["Ammo"] = l_Ammo;
|
||||||
|
e["weapon_damage"] = weapon_damage;
|
||||||
|
e["chance_mod"] = chance_mod;
|
||||||
|
e["focus"] = focus;
|
||||||
|
e["ReuseTime"] = ReuseTime;
|
||||||
|
e["range_id"] = range_id;
|
||||||
|
e["ammo_id"] = ammo_id;
|
||||||
|
e["AmmoItem"] = l_AmmoItem;
|
||||||
|
e["AmmoSlot"] = AmmoSlot;
|
||||||
|
e["speed"] = speed;
|
||||||
|
|
||||||
|
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<bool>(IgnoreDefaultObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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::DoThrowingAttackDmg(Mob *self, Mob *other, const EQEmu::ItemInstance *RangeWeapon, const EQEmu::ItemData *AmmoItem, uint16 weapon_damage, int16 chance_mod, int16 focus,
|
||||||
|
int ReuseTime, uint32 range_id, int AmmoSlot, float speed, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!m_has_do_throwing_attack_dmg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||||
|
lua_getfield(L, -1, "DoThrowingAttackDmg");
|
||||||
|
|
||||||
|
Lua_Mob l_self(self);
|
||||||
|
Lua_Mob l_other(other);
|
||||||
|
Lua_ItemInst l_RangeWeapon(const_cast<EQEmu::ItemInstance*>(RangeWeapon));
|
||||||
|
Lua_Item l_AmmoItem(const_cast<EQEmu::ItemData*>(AmmoItem));
|
||||||
|
luabind::adl::object e = luabind::newtable(L);
|
||||||
|
e["self"] = l_self;
|
||||||
|
e["other"] = l_other;
|
||||||
|
e["RangeWeapon"] = l_RangeWeapon;
|
||||||
|
e["weapon_damage"] = weapon_damage;
|
||||||
|
e["chance_mod"] = chance_mod;
|
||||||
|
e["focus"] = focus;
|
||||||
|
e["ReuseTime"] = ReuseTime;
|
||||||
|
e["range_id"] = range_id;
|
||||||
|
e["AmmoItem"] = l_AmmoItem;
|
||||||
|
e["AmmoSlot"] = AmmoSlot;
|
||||||
|
e["speed"] = speed;
|
||||||
|
|
||||||
|
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<bool>(IgnoreDefaultObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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::DoMeleeSkillAttackDmg(Mob *self, Mob *other, uint16 weapon_damage, EQEmu::skills::SkillType skillinuse, int16 chance_mod, int16 focus, bool CanRiposte, int ReuseTime,
|
||||||
|
bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
ignoreDefault = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!m_has_do_melee_skill_attack_dmg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, package_name_.c_str());
|
||||||
|
lua_getfield(L, -1, "DoMeleeSkillAttackDmg");
|
||||||
|
|
||||||
|
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;
|
||||||
|
e["weapon_damage"] = weapon_damage;
|
||||||
|
e["skillinuse"] = (int)skillinuse;
|
||||||
|
e["chance_mod"] = chance_mod;
|
||||||
|
e["focus"] = focus;
|
||||||
|
e["CanRiposte"] = CanRiposte;
|
||||||
|
e["ReuseTime"] = ReuseTime;
|
||||||
|
|
||||||
|
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<bool>(IgnoreDefaultObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception &ex) {
|
||||||
|
parser_->AddError(ex.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
int end = lua_gettop(L);
|
||||||
|
int n = end - start;
|
||||||
|
if (n > 0) {
|
||||||
|
lua_pop(L, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
53
zone/lua_mod.h
Normal file
53
zone/lua_mod.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct lua_State;
|
||||||
|
|
||||||
|
class LuaParser;
|
||||||
|
class LuaMod
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LuaMod(lua_State *ls, LuaParser *lp, const std::string &package_name) {
|
||||||
|
L = ls;
|
||||||
|
parser_ = lp;
|
||||||
|
package_name_ = package_name;
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
~LuaMod() { }
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
bool ClientAttack(Mob *self, Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||||
|
bool NPCAttack(Mob *self, Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||||
|
bool BotAttack(Mob *self, Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||||
|
bool CommonAttack(const std::string &fn, Mob *self, Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||||
|
void MeleeMitigation(Mob *self, Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||||
|
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 DoSpecialAttackDamage(Mob *self, Mob *who, EQEmu::skills::SkillType skill, int32 base_damage, int32 min_damage, int32 hate_override, int ReuseTime, bool &ignoreDefault);
|
||||||
|
void DoRangedAttackDmg(Mob *self, Mob* other, bool Launch, int16 damage_mod, int16 chance_mod, EQEmu::skills::SkillType skill, float speed, const char *IDFile, bool &ignoreDefault);
|
||||||
|
void DoArcheryAttackDmg(Mob *self, Mob *other, const EQEmu::ItemInstance *RangeWeapon, const EQEmu::ItemInstance *Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus,
|
||||||
|
int ReuseTime, uint32 range_id, uint32 ammo_id, const EQEmu::ItemData *AmmoItem, int AmmoSlot, float speed, bool &ignoreDefault);
|
||||||
|
void DoThrowingAttackDmg(Mob *self, Mob *other, const EQEmu::ItemInstance *RangeWeapon, const EQEmu::ItemData *AmmoItem, uint16 weapon_damage, int16 chance_mod, int16 focus,
|
||||||
|
int ReuseTime, uint32 range_id, int AmmoSlot, float speed, bool &ignoreDefault);
|
||||||
|
void DoMeleeSkillAttackDmg(Mob *self, Mob *other, uint16 weapon_damage, EQEmu::skills::SkillType skillinuse, int16 chance_mod, int16 focus, bool CanRiposte, int ReuseTime,
|
||||||
|
bool &ignoreDefault);
|
||||||
|
private:
|
||||||
|
LuaParser *parser_;
|
||||||
|
lua_State *L;
|
||||||
|
std::string package_name_;
|
||||||
|
|
||||||
|
bool m_has_client_attack;
|
||||||
|
bool m_has_npc_attack;
|
||||||
|
bool m_has_bot_attack;
|
||||||
|
bool m_has_melee_mitigation;
|
||||||
|
bool m_has_apply_damage_table;
|
||||||
|
bool m_has_avoid_damage;
|
||||||
|
bool m_has_check_hit_chance;
|
||||||
|
bool m_has_do_special_attack_damage;
|
||||||
|
bool m_has_do_ranged_attack_dmg;
|
||||||
|
bool m_has_do_archery_attack_dmg;
|
||||||
|
bool m_has_do_throwing_attack_dmg;
|
||||||
|
bool m_has_do_melee_skill_attack_dmg;
|
||||||
|
};
|
||||||
@ -960,7 +960,7 @@ void LuaParser::ReloadQuests() {
|
|||||||
char file_name[256] = { 0 };
|
char file_name[256] = { 0 };
|
||||||
while (fgets(file_name, 256, load_order) != nullptr) {
|
while (fgets(file_name, 256, load_order) != nullptr) {
|
||||||
LoadScript("mods/" + std::string(file_name), file_name);
|
LoadScript("mods/" + std::string(file_name), file_name);
|
||||||
mods_.push_back(file_name);
|
mods_.push_back(LuaMod(L, this, file_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(load_order);
|
fclose(load_order);
|
||||||
@ -971,7 +971,6 @@ void LuaParser::ReloadQuests() {
|
|||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
lua_pop(L, n);
|
lua_pop(L, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaParser::LoadScript(std::string filename, std::string package_name) {
|
void LuaParser::LoadScript(std::string filename, std::string package_name) {
|
||||||
@ -1256,355 +1255,6 @@ int LuaParser::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, ui
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PutDamageHitInfo(lua_State *L, luabind::adl::object &e, DamageHitInfo &hit) {
|
|
||||||
luabind::adl::object lua_hit = luabind::newtable(L);
|
|
||||||
lua_hit["base_damage"] = hit.base_damage;
|
|
||||||
lua_hit["damage_done"] = hit.damage_done;
|
|
||||||
lua_hit["offense"] = hit.offense;
|
|
||||||
lua_hit["tohit"] = hit.tohit;
|
|
||||||
lua_hit["hand"] = hit.hand;
|
|
||||||
lua_hit["skill"] = (int)hit.skill;
|
|
||||||
e["hit"] = lua_hit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetDamageHitInfo(luabind::adl::object &ret, DamageHitInfo &hit) {
|
|
||||||
auto luaHitTable = ret["hit"];
|
|
||||||
if (luabind::type(luaHitTable) == LUA_TTABLE) {
|
|
||||||
auto base_damage = luaHitTable["base_damage"];
|
|
||||||
auto damage_done = luaHitTable["damage_done"];
|
|
||||||
auto offense = luaHitTable["offense"];
|
|
||||||
auto tohit = luaHitTable["tohit"];
|
|
||||||
auto hand = luaHitTable["hand"];
|
|
||||||
auto skill = luaHitTable["skill"];
|
|
||||||
|
|
||||||
if (luabind::type(base_damage) == LUA_TNUMBER) {
|
|
||||||
hit.base_damage = luabind::object_cast<int>(base_damage);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(damage_done) == LUA_TNUMBER) {
|
|
||||||
hit.damage_done = luabind::object_cast<int>(damage_done);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(offense) == LUA_TNUMBER) {
|
|
||||||
hit.offense = luabind::object_cast<int>(offense);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(tohit) == LUA_TNUMBER) {
|
|
||||||
hit.tohit = luabind::object_cast<int>(tohit);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(hand) == LUA_TNUMBER) {
|
|
||||||
hit.hand = luabind::object_cast<int>(hand);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(skill) == LUA_TNUMBER) {
|
|
||||||
hit.skill = (EQEmu::skills::SkillType)luabind::object_cast<int>(skill);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PutExtraAttackOptions(lua_State *L, luabind::adl::object &e, ExtraAttackOptions *opts) {
|
|
||||||
if (opts) {
|
|
||||||
luabind::adl::object lua_opts = luabind::newtable(L);
|
|
||||||
lua_opts["damage_percent"] = opts->damage_percent;
|
|
||||||
lua_opts["damage_flat"] = opts->damage_flat;
|
|
||||||
lua_opts["armor_pen_percent"] = opts->armor_pen_percent;
|
|
||||||
lua_opts["armor_pen_flat"] = opts->armor_pen_flat;
|
|
||||||
lua_opts["crit_percent"] = opts->crit_percent;
|
|
||||||
lua_opts["crit_flat"] = opts->crit_flat;
|
|
||||||
lua_opts["hate_percent"] = opts->hate_percent;
|
|
||||||
lua_opts["hate_flat"] = opts->hate_flat;
|
|
||||||
lua_opts["hit_chance"] = opts->hit_chance;
|
|
||||||
lua_opts["melee_damage_bonus_flat"] = opts->melee_damage_bonus_flat;
|
|
||||||
lua_opts["skilldmgtaken_bonus_flat"] = opts->skilldmgtaken_bonus_flat;
|
|
||||||
e["opts"] = lua_opts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetExtraAttackOptions(luabind::adl::object &ret, ExtraAttackOptions *opts) {
|
|
||||||
if (opts) {
|
|
||||||
auto luaOptsTable = ret["opts"];
|
|
||||||
if (luabind::type(luaOptsTable) == LUA_TTABLE) {
|
|
||||||
auto damage_percent = luaOptsTable["damage_percent"];
|
|
||||||
auto damage_flat = luaOptsTable["damage_flat"];
|
|
||||||
auto armor_pen_percent = luaOptsTable["armor_pen_percent"];
|
|
||||||
auto armor_pen_flat = luaOptsTable["armor_pen_flat"];
|
|
||||||
auto crit_percent = luaOptsTable["crit_percent"];
|
|
||||||
auto crit_flat = luaOptsTable["crit_flat"];
|
|
||||||
auto hate_percent = luaOptsTable["hate_percent"];
|
|
||||||
auto hate_flat = luaOptsTable["hate_flat"];
|
|
||||||
auto hit_chance = luaOptsTable["hit_chance"];
|
|
||||||
auto melee_damage_bonus_flat = luaOptsTable["melee_damage_bonus_flat"];
|
|
||||||
auto skilldmgtaken_bonus_flat = luaOptsTable["skilldmgtaken_bonus_flat"];
|
|
||||||
|
|
||||||
if (luabind::type(damage_percent) == LUA_TNUMBER) {
|
|
||||||
opts->damage_percent = luabind::object_cast<float>(damage_percent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(damage_flat) == LUA_TNUMBER) {
|
|
||||||
opts->damage_flat = luabind::object_cast<int>(damage_flat);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(armor_pen_percent) == LUA_TNUMBER) {
|
|
||||||
opts->armor_pen_percent = luabind::object_cast<float>(armor_pen_percent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(armor_pen_flat) == LUA_TNUMBER) {
|
|
||||||
opts->armor_pen_flat = luabind::object_cast<int>(armor_pen_flat);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(crit_percent) == LUA_TNUMBER) {
|
|
||||||
opts->crit_percent = luabind::object_cast<float>(crit_percent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(crit_flat) == LUA_TNUMBER) {
|
|
||||||
opts->crit_flat = luabind::object_cast<float>(crit_flat);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(hate_percent) == LUA_TNUMBER) {
|
|
||||||
opts->hate_percent = luabind::object_cast<float>(hate_percent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(hate_flat) == LUA_TNUMBER) {
|
|
||||||
opts->hate_flat = luabind::object_cast<int>(hate_flat);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(hit_chance) == LUA_TNUMBER) {
|
|
||||||
opts->hit_chance = luabind::object_cast<int>(hit_chance);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(melee_damage_bonus_flat) == LUA_TNUMBER) {
|
|
||||||
opts->melee_damage_bonus_flat = luabind::object_cast<int>(melee_damage_bonus_flat);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (luabind::type(skilldmgtaken_bonus_flat) == LUA_TNUMBER) {
|
|
||||||
opts->skilldmgtaken_bonus_flat = luabind::object_cast<int>(skilldmgtaken_bonus_flat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LuaParser::MeleeMitigation(Mob *self, Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault) {
|
|
||||||
int start = lua_gettop(L);
|
|
||||||
ignoreDefault = false;
|
|
||||||
|
|
||||||
for (auto &mod : mods_) {
|
|
||||||
try {
|
|
||||||
if (!HasFunction("MeleeMitigation", mod)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, mod.c_str());
|
|
||||||
lua_getfield(L, -1, "MeleeMitigation");
|
|
||||||
|
|
||||||
Lua_Mob l_self(self);
|
|
||||||
Lua_Mob l_other(attacker);
|
|
||||||
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);
|
|
||||||
AddError(error);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
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<bool>(IgnoreDefaultObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
GetDamageHitInfo(ret, hit);
|
|
||||||
GetExtraAttackOptions(ret, opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception &ex) {
|
|
||||||
AddError(ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int end = lua_gettop(L);
|
|
||||||
int n = end - start;
|
|
||||||
if (n > 0) {
|
|
||||||
lua_pop(L, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LuaParser::ApplyDamageTable(Mob *self, DamageHitInfo &hit, bool &ignoreDefault) {
|
|
||||||
int start = lua_gettop(L);
|
|
||||||
ignoreDefault = false;
|
|
||||||
|
|
||||||
for (auto &mod : mods_) {
|
|
||||||
try {
|
|
||||||
if (!HasFunction("ApplyDamageTable", mod)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, mod.c_str());
|
|
||||||
lua_getfield(L, -1, "ApplyDamageTable");
|
|
||||||
|
|
||||||
Lua_Mob l_self(self);
|
|
||||||
luabind::adl::object e = luabind::newtable(L);
|
|
||||||
e["self"] = l_self;
|
|
||||||
|
|
||||||
PutDamageHitInfo(L, e, hit);
|
|
||||||
e.push(L);
|
|
||||||
|
|
||||||
if (lua_pcall(L, 1, 1, 0)) {
|
|
||||||
std::string error = lua_tostring(L, -1);
|
|
||||||
AddError(error);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
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<bool>(IgnoreDefaultObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
GetDamageHitInfo(ret, hit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception &ex) {
|
|
||||||
AddError(ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int end = lua_gettop(L);
|
|
||||||
int n = end - start;
|
|
||||||
if (n > 0) {
|
|
||||||
lua_pop(L, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LuaParser::AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool &ignoreDefault) {
|
|
||||||
int start = lua_gettop(L);
|
|
||||||
ignoreDefault = false;
|
|
||||||
bool retval = false;
|
|
||||||
|
|
||||||
for (auto &mod : mods_) {
|
|
||||||
try {
|
|
||||||
if (!HasFunction("AvoidDamage", mod)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, mod.c_str());
|
|
||||||
lua_getfield(L, -1, "AvoidDamage");
|
|
||||||
|
|
||||||
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);
|
|
||||||
e.push(L);
|
|
||||||
|
|
||||||
if (lua_pcall(L, 1, 1, 0)) {
|
|
||||||
std::string error = lua_tostring(L, -1);
|
|
||||||
AddError(error);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
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<bool>(IgnoreDefaultObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto returnValueObj = ret["ReturnValue"];
|
|
||||||
if (luabind::type(returnValueObj) == LUA_TBOOLEAN) {
|
|
||||||
retval = luabind::object_cast<bool>(returnValueObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
GetDamageHitInfo(ret, hit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception &ex) {
|
|
||||||
AddError(ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int end = lua_gettop(L);
|
|
||||||
int n = end - start;
|
|
||||||
if (n > 0) {
|
|
||||||
lua_pop(L, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LuaParser::CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &ignoreDefault) {
|
|
||||||
int start = lua_gettop(L);
|
|
||||||
ignoreDefault = false;
|
|
||||||
bool retval = false;
|
|
||||||
|
|
||||||
for (auto &mod : mods_) {
|
|
||||||
try {
|
|
||||||
if (!HasFunction("CheckHitChance", mod)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, mod.c_str());
|
|
||||||
lua_getfield(L, -1, "CheckHitChance");
|
|
||||||
|
|
||||||
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);
|
|
||||||
e.push(L);
|
|
||||||
|
|
||||||
if (lua_pcall(L, 1, 1, 0)) {
|
|
||||||
std::string error = lua_tostring(L, -1);
|
|
||||||
AddError(error);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
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<bool>(IgnoreDefaultObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto returnValueObj = ret["ReturnValue"];
|
|
||||||
if (luabind::type(returnValueObj) == LUA_TBOOLEAN) {
|
|
||||||
retval = luabind::object_cast<bool>(returnValueObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
GetDamageHitInfo(ret, hit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception &ex) {
|
|
||||||
AddError(ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int end = lua_gettop(L);
|
|
||||||
int n = end - start;
|
|
||||||
if (n > 0) {
|
|
||||||
lua_pop(L, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
QuestEventID LuaParser::ConvertLuaEvent(QuestEventID evt) {
|
QuestEventID LuaParser::ConvertLuaEvent(QuestEventID evt) {
|
||||||
switch(evt) {
|
switch(evt) {
|
||||||
case EVENT_SLAY:
|
case EVENT_SLAY:
|
||||||
@ -1629,3 +1279,103 @@ QuestEventID LuaParser::ConvertLuaEvent(QuestEventID evt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool LuaParser::ClientAttack(Mob *self, Mob *other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
bool retval = false;
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
retval = mod.ClientAttack(self, other, Hand, bRiposte, IsStrikethrough, IsFromSpell, opts, ignoreDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaParser::NPCAttack(Mob *self, Mob *other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
bool retval = false;
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
retval = mod.NPCAttack(self, other, Hand, bRiposte, IsStrikethrough, IsFromSpell, opts, ignoreDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaParser::BotAttack(Mob *self, Mob *other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
bool retval = false;
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
retval = mod.BotAttack(self, other, Hand, bRiposte, IsStrikethrough, IsFromSpell, opts, ignoreDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaParser::MeleeMitigation(Mob *self, Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
mod.MeleeMitigation(self, attacker, hit, opts, ignoreDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaParser::ApplyDamageTable(Mob *self, DamageHitInfo &hit, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
mod.ApplyDamageTable(self, hit, ignoreDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaParser::AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool & ignoreDefault)
|
||||||
|
{
|
||||||
|
bool retval = false;
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
retval = mod.AvoidDamage(self, other, hit, ignoreDefault);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaParser::CheckHitChance(Mob *self, Mob *other, DamageHitInfo &hit, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
bool retval = false;
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
retval = mod.CheckHitChance(self, other, hit, ignoreDefault);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaParser::DoSpecialAttackDamage(Mob *self, Mob *who, EQEmu::skills::SkillType skill, int32 base_damage, int32 min_damage, int32 hate_override, int ReuseTime, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
mod.DoSpecialAttackDamage(self, who, skill, base_damage, min_damage, hate_override, ReuseTime, ignoreDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaParser::DoRangedAttackDmg(Mob *self, Mob *other, bool Launch, int16 damage_mod, int16 chance_mod, EQEmu::skills::SkillType skill, float speed, const char *IDFile, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
mod.DoRangedAttackDmg(self, other, Launch, damage_mod, chance_mod, skill, speed, IDFile, ignoreDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaParser::DoArcheryAttackDmg(Mob *self, Mob *other, const EQEmu::ItemInstance *RangeWeapon, const EQEmu::ItemInstance *Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus,
|
||||||
|
int ReuseTime, uint32 range_id, uint32 ammo_id, const EQEmu::ItemData *AmmoItem, int AmmoSlot, float speed, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
mod.DoArcheryAttackDmg(self, other, RangeWeapon, Ammo, weapon_damage, chance_mod, focus, ReuseTime, range_id, ammo_id, AmmoItem, AmmoSlot, speed, ignoreDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaParser::DoThrowingAttackDmg(Mob *self, Mob *other, const EQEmu::ItemInstance *RangeWeapon, const EQEmu::ItemData *AmmoItem, uint16 weapon_damage, int16 chance_mod, int16 focus,
|
||||||
|
int ReuseTime, uint32 range_id, int AmmoSlot, float speed, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
mod.DoThrowingAttackDmg(self, other, RangeWeapon, AmmoItem, weapon_damage, chance_mod, focus, ReuseTime, range_id, AmmoSlot, speed, ignoreDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaParser::DoMeleeSkillAttackDmg(Mob *self, Mob *other, uint16 weapon_damage, EQEmu::skills::SkillType skillinuse, int16 chance_mod, int16 focus, bool CanRiposte,
|
||||||
|
int ReuseTime, bool &ignoreDefault)
|
||||||
|
{
|
||||||
|
for (auto &mod : mods_) {
|
||||||
|
mod.DoMeleeSkillAttackDmg(self, other, weapon_damage, skillinuse, chance_mod, focus, CanRiposte, ReuseTime, ignoreDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
#include "zone_config.h"
|
#include "zone_config.h"
|
||||||
|
#include "lua_mod.h"
|
||||||
|
|
||||||
extern const ZoneConfig *Config;
|
extern const ZoneConfig *Config;
|
||||||
|
|
||||||
@ -86,11 +87,24 @@ public:
|
|||||||
return &inst;
|
return &inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HasFunction(std::string function, std::string package_name);
|
||||||
|
|
||||||
//Mod Extensions
|
//Mod Extensions
|
||||||
|
bool ClientAttack(Mob *self, Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||||
|
bool NPCAttack(Mob *self, Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||||
|
bool BotAttack(Mob *self, Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||||
void MeleeMitigation(Mob *self, Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
void MeleeMitigation(Mob *self, Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts, bool &ignoreDefault);
|
||||||
void ApplyDamageTable(Mob *self, DamageHitInfo &hit, bool &ignoreDefault);
|
void ApplyDamageTable(Mob *self, DamageHitInfo &hit, bool &ignoreDefault);
|
||||||
bool AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool &ignoreDefault);
|
bool AvoidDamage(Mob *self, Mob *other, DamageHitInfo &hit, bool &ignoreDefault);
|
||||||
bool CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &ignoreDefault);
|
bool CheckHitChance(Mob *self, Mob* other, DamageHitInfo &hit, bool &ignoreDefault);
|
||||||
|
void DoSpecialAttackDamage(Mob *self, Mob *who, EQEmu::skills::SkillType skill, int32 base_damage, int32 min_damage, int32 hate_override, int ReuseTime, bool &ignoreDefault);
|
||||||
|
void DoRangedAttackDmg(Mob *self, Mob* other, bool Launch, int16 damage_mod, int16 chance_mod, EQEmu::skills::SkillType skill, float speed, const char *IDFile, bool &ignoreDefault);
|
||||||
|
void DoArcheryAttackDmg(Mob *self, Mob *other, const EQEmu::ItemInstance *RangeWeapon, const EQEmu::ItemInstance *Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus,
|
||||||
|
int ReuseTime, uint32 range_id, uint32 ammo_id, const EQEmu::ItemData *AmmoItem, int AmmoSlot, float speed, bool &ignoreDefault);
|
||||||
|
void DoThrowingAttackDmg(Mob *self, Mob *other, const EQEmu::ItemInstance *RangeWeapon, const EQEmu::ItemData *AmmoItem, uint16 weapon_damage, int16 chance_mod, int16 focus,
|
||||||
|
int ReuseTime, uint32 range_id, int AmmoSlot, float speed, bool &ignoreDefault);
|
||||||
|
void DoMeleeSkillAttackDmg(Mob *self, Mob *other, uint16 weapon_damage, EQEmu::skills::SkillType skillinuse, int16 chance_mod, int16 focus, bool CanRiposte, int ReuseTime,
|
||||||
|
bool &ignoreDefault);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LuaParser();
|
LuaParser();
|
||||||
@ -109,13 +123,12 @@ private:
|
|||||||
std::vector<EQEmu::Any> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
void LoadScript(std::string filename, std::string package_name);
|
void LoadScript(std::string filename, std::string package_name);
|
||||||
bool HasFunction(std::string function, std::string package_name);
|
|
||||||
void MapFunctions(lua_State *L);
|
void MapFunctions(lua_State *L);
|
||||||
QuestEventID ConvertLuaEvent(QuestEventID evt);
|
QuestEventID ConvertLuaEvent(QuestEventID evt);
|
||||||
|
|
||||||
std::map<std::string, std::string> vars_;
|
std::map<std::string, std::string> vars_;
|
||||||
std::map<std::string, bool> loaded_;
|
std::map<std::string, bool> loaded_;
|
||||||
std::vector<std::string> mods_;
|
std::vector<LuaMod> mods_;
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
|
|
||||||
NPCArgumentHandler NPCArgumentDispatch[_LargestEventID];
|
NPCArgumentHandler NPCArgumentDispatch[_LargestEventID];
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
#include "entity.h"
|
#include "entity.h"
|
||||||
#include "mob.h"
|
#include "mob.h"
|
||||||
#include "string_ids.h"
|
#include "string_ids.h"
|
||||||
|
#include "lua_parser.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -137,6 +138,15 @@ int Mob::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target)
|
|||||||
void Mob::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 base_damage, int32 min_damage,
|
void Mob::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 base_damage, int32 min_damage,
|
||||||
int32 hate_override, int ReuseTime)
|
int32 hate_override, int ReuseTime)
|
||||||
{
|
{
|
||||||
|
#ifdef LUA_EQEMU
|
||||||
|
bool ignoreDefault = false;
|
||||||
|
LuaParser::Instance()->DoSpecialAttackDamage(this, who, skill, base_damage, min_damage, hate_override, ReuseTime, ignoreDefault);
|
||||||
|
|
||||||
|
if (ignoreDefault) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// this really should go through the same code as normal melee damage to
|
// this really should go through the same code as normal melee damage to
|
||||||
// pick up all the special behavior there
|
// pick up all the special behavior there
|
||||||
|
|
||||||
@ -758,6 +768,15 @@ void Mob::DoArcheryAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon,
|
|||||||
uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id,
|
uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id,
|
||||||
uint32 ammo_id, const EQEmu::ItemData *AmmoItem, int AmmoSlot, float speed)
|
uint32 ammo_id, const EQEmu::ItemData *AmmoItem, int AmmoSlot, float speed)
|
||||||
{
|
{
|
||||||
|
#ifdef LUA_EQEMU
|
||||||
|
bool ignoreDefault = false;
|
||||||
|
LuaParser::Instance()->DoArcheryAttackDmg(this, other, RangeWeapon, Ammo, weapon_damage, chance_mod, focus, ReuseTime, range_id, ammo_id, AmmoItem, AmmoSlot, speed, ignoreDefault);
|
||||||
|
|
||||||
|
if (ignoreDefault) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if ((other == nullptr ||
|
if ((other == nullptr ||
|
||||||
((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) ||
|
((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) ||
|
||||||
@ -1138,6 +1157,15 @@ void NPC::RangedAttack(Mob* other)
|
|||||||
|
|
||||||
void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 chance_mod, EQEmu::skills::SkillType skill, float speed, const char *IDFile)
|
void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 chance_mod, EQEmu::skills::SkillType skill, float speed, const char *IDFile)
|
||||||
{
|
{
|
||||||
|
#ifdef LUA_EQEMU
|
||||||
|
bool ignoreDefault = false;
|
||||||
|
LuaParser::Instance()->DoRangedAttackDmg(this, other, Launch, damage_mod, chance_mod, skill, speed, IDFile, ignoreDefault);
|
||||||
|
|
||||||
|
if (ignoreDefault) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((other == nullptr ||
|
if ((other == nullptr ||
|
||||||
(other->HasDied())) ||
|
(other->HasDied())) ||
|
||||||
HasDied() ||
|
HasDied() ||
|
||||||
@ -1302,6 +1330,15 @@ void Mob::DoThrowingAttackDmg(Mob *other, const EQEmu::ItemInstance *RangeWeapon
|
|||||||
uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id,
|
uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, uint32 range_id,
|
||||||
int AmmoSlot, float speed)
|
int AmmoSlot, float speed)
|
||||||
{
|
{
|
||||||
|
#ifdef LUA_EQEMU
|
||||||
|
bool ignoreDefault = false;
|
||||||
|
LuaParser::Instance()->DoThrowingAttackDmg(this, other, RangeWeapon, AmmoItem, weapon_damage, chance_mod, focus, ReuseTime, range_id, AmmoSlot, speed, ignoreDefault);
|
||||||
|
|
||||||
|
if (ignoreDefault) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((other == nullptr ||
|
if ((other == nullptr ||
|
||||||
((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) ||
|
((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) ||
|
||||||
HasDied() || (!IsAttackAllowed(other)) || (other->GetInvul() || other->GetSpecialAbility(IMMUNE_MELEE)))) {
|
HasDied() || (!IsAttackAllowed(other)) || (other->GetInvul() || other->GetSpecialAbility(IMMUNE_MELEE)))) {
|
||||||
@ -2086,6 +2123,15 @@ int Mob::TryAssassinate(Mob *defender, EQEmu::skills::SkillType skillInUse)
|
|||||||
void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQEmu::skills::SkillType skillinuse, int16 chance_mod,
|
void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQEmu::skills::SkillType skillinuse, int16 chance_mod,
|
||||||
int16 focus, bool CanRiposte, int ReuseTime)
|
int16 focus, bool CanRiposte, int ReuseTime)
|
||||||
{
|
{
|
||||||
|
#ifdef LUA_EQEMU
|
||||||
|
bool ignoreDefault = false;
|
||||||
|
LuaParser::Instance()->DoMeleeSkillAttackDmg(this, other, weapon_damage, skillinuse, chance_mod, focus, CanRiposte, ReuseTime, ignoreDefault);
|
||||||
|
|
||||||
|
if (ignoreDefault) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!CanDoSpecialAttack(other))
|
if (!CanDoSpecialAttack(other))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user