Basic mod setup only supports combat hooks for now I'll add a few more before i push this

This commit is contained in:
KimLS 2017-04-26 22:56:18 -07:00
parent 78a73cab85
commit 6d59baffaf
11 changed files with 2322 additions and 125 deletions

View File

@ -277,7 +277,7 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
m_encode_passes[1] = owner->m_options.encode_passes[1];
m_hold_time = Clock::now();
m_buffered_packets_length = 0;
m_rolling_ping = 500;
m_rolling_ping = 900;
m_resend_delay = (m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms;
m_combined.reset(new char[512]);
m_combined[0] = 0;
@ -300,7 +300,7 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
m_crc_bytes = 0;
m_hold_time = Clock::now();
m_buffered_packets_length = 0;
m_rolling_ping = 500;
m_rolling_ping = 900;
m_resend_delay = (m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms;
m_combined.reset(new char[512]);
m_combined[0] = 0;
@ -1026,7 +1026,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
InternalBufferedSend(entry.second.packet);
entry.second.last_sent = now;
entry.second.times_resent++;
m_rolling_ping += 100;
m_rolling_ping += 300;
}
}
else {
@ -1040,7 +1040,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
InternalBufferedSend(entry.second.packet);
entry.second.last_sent = now;
entry.second.times_resent++;
m_rolling_ping += 100;
m_rolling_ping += 300;
}
}
}
@ -1061,7 +1061,7 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
m_stats.max_ping = std::max(m_stats.max_ping, round_time);
m_stats.min_ping = std::min(m_stats.min_ping, round_time);
m_stats.last_ping = round_time;
m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
m_rolling_ping = (m_rolling_ping * 3 + round_time) / 4;
iter = s->sent_packets.erase(iter);
}

View File

@ -205,10 +205,10 @@ namespace EQ
DaybreakConnectionManagerOptions() {
max_connection_count = 0;
keepalive_delay_ms = 9000;
resend_delay_ms = 150;
resend_delay_ms = 300;
resend_delay_factor = 1.5;
resend_delay_min = 150;
resend_delay_max = 1000;
resend_delay_min = 300;
resend_delay_max = 6000;
connect_delay_ms = 500;
stale_connection_ms = 90000;
connect_stale_ms = 5000;
@ -282,4 +282,4 @@ namespace EQ
friend class DaybreakConnection;
};
}
}
}

View File

@ -59,6 +59,7 @@ SET(zone_sources
lua_raid.cpp
lua_spawn.cpp
lua_spell.cpp
lua_stat_bonuses.cpp
embperl.cpp
embxs.cpp
entity.cpp
@ -182,6 +183,7 @@ SET(zone_headers
lua_raid.h
lua_spawn.h
lua_spell.h
lua_stat_bonuses.h
map.h
masterentity.h
maxskill.h

View File

@ -272,6 +272,16 @@ int Mob::GetTotalDefense()
// and does other mitigation checks. 'this' is the mob being attacked.
bool Mob::CheckHitChance(Mob* other, DamageHitInfo &hit)
{
#ifdef LUA_EQEMU
bool lua_ret = false;
bool ignoreDefault = false;
lua_ret = LuaParser::Instance()->CheckHitChance(this, other, hit, ignoreDefault);
if(ignoreDefault) {
return lua_ret;
}
#endif
Mob *attacker = other;
Mob *defender = this;
Log(Logs::Detail, Logs::Attack, "CheckHitChance(%s) attacked by %s", defender->GetName(), attacker->GetName());
@ -302,6 +312,16 @@ bool Mob::CheckHitChance(Mob* other, DamageHitInfo &hit)
bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
{
#ifdef LUA_EQEMU
bool lua_ret = false;
bool ignoreDefault = false;
lua_ret = LuaParser::Instance()->AvoidDamage(this, other, hit, ignoreDefault);
if (ignoreDefault) {
return lua_ret;
}
#endif
/* called when a mob is attacked, does the checks to see if it's a hit
* and does other mitigation checks. 'this' is the mob being attacked.
*
@ -872,6 +892,15 @@ double Mob::RollD20(int offense, int mitigation)
void Mob::MeleeMitigation(Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts)
{
#ifdef LUA_EQEMU
bool ignoreDefault = false;
LuaParser::Instance()->MeleeMitigation(this, attacker, hit, opts, ignoreDefault);
if (ignoreDefault) {
return;
}
#endif
if (hit.damage_done < 0 || hit.base_damage == 0)
return;
@ -1239,14 +1268,6 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts)
Log(Logs::Detail, Logs::Combat, "%s::DoAttack vs %s base %d min %d offense %d tohit %d skill %d", GetName(),
other->GetName(), hit.base_damage, hit.min_damage, hit.offense, hit.tohit, hit.skill);
#ifdef LUA_EQEMU
try {
LuaParser::Instance()->DoAttack(this, other, hit, opts);
} catch(IgnoreDefaultException) {
return;
}
#endif
// check to see if we hit..
if (other->AvoidDamage(this, hit)) {
int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
@ -4537,6 +4558,15 @@ const DamageTable &Mob::GetDamageTable() const
void Mob::ApplyDamageTable(DamageHitInfo &hit)
{
#ifdef LUA_EQEMU
bool ignoreDefault = false;
LuaParser::Instance()->ApplyDamageTable(this, hit, ignoreDefault);
if (ignoreDefault) {
return;
}
#endif
// someone may want to add this to custom servers, can remove this if that's the case
if (!IsClient()
#ifdef BOTS

View File

@ -10,6 +10,7 @@
#include "lua_mob.h"
#include "lua_hate_list.h"
#include "lua_client.h"
#include "lua_stat_bonuses.h"
struct SpecialAbilities { };
@ -1985,6 +1986,41 @@ int32 Lua_Mob::GetMeleeMitigation() {
return self->GetMeleeMitigation();
}
int Lua_Mob::GetWeaponDamageBonus(Lua_Item weapon, bool offhand) {
Lua_Safe_Call_Int();
return self->GetWeaponDamageBonus(weapon, offhand);
}
Lua_StatBonuses Lua_Mob::GetItemBonuses()
{
Lua_Safe_Call_Class(Lua_StatBonuses);
return self->GetItemBonusesPtr();
}
Lua_StatBonuses Lua_Mob::GetSpellBonuses()
{
Lua_Safe_Call_Class(Lua_StatBonuses);
return self->GetSpellBonusesPtr();
}
Lua_StatBonuses Lua_Mob::GetAABonuses()
{
Lua_Safe_Call_Class(Lua_StatBonuses);
return self->GetAABonusesPtr();
}
int16 Lua_Mob::GetMeleeDamageMod_SE(uint16 skill)
{
Lua_Safe_Call_Int();
return self->GetMeleeDamageMod_SE(skill);
}
int16 Lua_Mob::GetMeleeMinDamageMod_SE(uint16 skill)
{
Lua_Safe_Call_Int();
return self->GetMeleeMinDamageMod_SE(skill);
}
luabind::scope lua_register_mob() {
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
.def(luabind::constructor<>())
@ -2330,7 +2366,13 @@ luabind::scope lua_register_mob() {
.def("HasPet", (bool(Lua_Mob::*)(void))&Lua_Mob::HasPet)
.def("IsSilenced", (bool(Lua_Mob::*)(void))&Lua_Mob::IsSilenced)
.def("IsAmnesiad", (bool(Lua_Mob::*)(void))&Lua_Mob::IsAmnesiad)
.def("GetMeleeMitigation", (int32(Lua_Mob::*)(void))&Lua_Mob::GetMeleeMitigation);
.def("GetMeleeMitigation", (int32(Lua_Mob::*)(void))&Lua_Mob::GetMeleeMitigation)
.def("GetWeaponDamageBonus", &Lua_Mob::GetWeaponDamageBonus)
.def("GetItemBonuses", &Lua_Mob::GetItemBonuses)
.def("GetSpellBonuses", &Lua_Mob::GetSpellBonuses)
.def("GetAABonuses", &Lua_Mob::GetAABonuses)
.def("GetMeleeDamageMod_SE", &Lua_Mob::GetMeleeDamageMod_SE)
.def("GetMeleeMinDamageMod_SE", &Lua_Mob::GetMeleeMinDamageMod_SE);
}
luabind::scope lua_register_special_abilities() {

View File

@ -8,6 +8,7 @@ class Mob;
struct Lua_HateList;
class Lua_Item;
class Lua_ItemInst;
class Lua_StatBonuses;
namespace luabind {
struct scope;
@ -381,6 +382,12 @@ public:
bool IsSilenced();
bool IsAmnesiad();
int32 GetMeleeMitigation();
int GetWeaponDamageBonus(Lua_Item weapon, bool offhand);
Lua_StatBonuses GetItemBonuses();
Lua_StatBonuses GetSpellBonuses();
Lua_StatBonuses GetAABonuses();
int16 GetMeleeDamageMod_SE(uint16 skill);
int16 GetMeleeMinDamageMod_SE(uint16 skill);
};
#endif

View File

@ -11,7 +11,6 @@
#include <algorithm>
#include "../common/spdat.h"
#include "../common/util/directory.h"
#include "masterentity.h"
#include "questmgr.h"
#include "zone.h"
@ -38,6 +37,7 @@
#include "lua_packet.h"
#include "lua_general.h"
#include "lua_encounter.h"
#include "lua_stat_bonuses.h"
const char *LuaEvents[_LargestEventID] = {
"event_say",
@ -137,77 +137,6 @@ std::map<std::string, std::list<lua_registered_event>> lua_encounter_events_regi
std::map<std::string, bool> lua_encounters_loaded;
std::map<std::string, Encounter *> lua_encounters;
void LuaParser::DoAttack(Mob *self, Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts)
{
int start = lua_gettop(L);
bool ignoreDefault = false;
for (auto &mod : mods_) {
try {
lua_getfield(L, LUA_REGISTRYINDEX, mod.c_str());
lua_getfield(L, -1, "DoAttack");
Lua_Mob l_self(self);
Lua_Mob l_other(other);
luabind::adl::object e = luabind::newtable(L);
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["self"] = luabind::adl::object(L, l_self);
e["other"] = luabind::adl::object(L, l_other);
e["hit"] = lua_hit;
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;
}
else {
e["opts"] = luabind::nil;
}
e.push(L);
if (lua_pcall(L, 1, 1, 0)) {
std::string error = lua_tostring(L, -1);
AddError(error);
}
}
catch (std::exception &ex) {
std::string error = "Lua Exception: ";
error += std::string(ex.what());
AddError(error);
}
int end = lua_gettop(L);
int n = end - start;
if (n > 0) {
lua_pop(L, n);
}
}
if (ignoreDefault) {
throw IgnoreDefaultException();
}
}
LuaParser::LuaParser() {
for(int i = 0; i < _LargestEventID; ++i) {
NPCArgumentDispatch[i] = handle_npc_null;
@ -877,6 +806,7 @@ void LuaParser::ReloadQuests() {
for (auto encounter : lua_encounters) {
encounter.second->Depop();
}
lua_encounters.clear();
// so the Depop function above depends on the Process being called again so ...
// And there is situations where it wouldn't be :P
@ -889,6 +819,8 @@ void LuaParser::ReloadQuests() {
L = luaL_newstate();
luaL_openlibs(L);
auto top = lua_gettop(L);
if(luaopen_bit(L) != 1) {
std::string error = lua_tostring(L, -1);
AddError(error);
@ -1005,35 +937,41 @@ void LuaParser::ReloadQuests() {
std::string error = lua_tostring(L, -1);
AddError(error);
}
return;
}
else {
zone_script = Config->QuestDir;
zone_script += "/";
zone_script += zone->GetShortName();
zone_script += "/script_init.lua";
f = fopen(zone_script.c_str(), "r");
if (f) {
fclose(f);
zone_script = Config->QuestDir;
zone_script += "/";
zone_script += zone->GetShortName();
zone_script += "/script_init.lua";
f = fopen(zone_script.c_str(), "r");
if(f) {
fclose(f);
if(luaL_dofile(L, zone_script.c_str())) {
std::string error = lua_tostring(L, -1);
AddError(error);
if (luaL_dofile(L, zone_script.c_str())) {
std::string error = lua_tostring(L, -1);
AddError(error);
}
}
}
}
EQ::Directory dir("mods");
std::vector<std::string> mods;
dir.GetFiles(mods);
for (auto &mod : mods) {
if (mod.find_first_of(".lua") != std::string::npos) {
LoadScript("mods/" + mod, mod);
mods_.push_back(mod);
FILE *load_order = fopen("mods/load_order.txt", "r");
if (load_order) {
char file_name[256] = { 0 };
while (fgets(file_name, 256, load_order) != nullptr) {
LoadScript("mods/" + std::string(file_name), file_name);
mods_.push_back(file_name);
}
fclose(load_order);
}
auto end = lua_gettop(L);
int n = end - top;
if (n > 0) {
lua_pop(L, n);
}
}
void LuaParser::LoadScript(std::string filename, std::string package_name) {
@ -1042,6 +980,7 @@ void LuaParser::LoadScript(std::string filename, std::string package_name) {
return;
}
auto top = lua_gettop(L);
if(luaL_loadfile(L, filename.c_str())) {
std::string error = lua_tostring(L, -1);
AddError(error);
@ -1069,14 +1008,20 @@ void LuaParser::LoadScript(std::string filename, std::string package_name) {
std::string error = lua_tostring(L, -1);
AddError(error);
lua_pop(L, 1);
return;
}
else {
loaded_[package_name] = true;
}
loaded_[package_name] = true;
auto end = lua_gettop(L);
int n = end - top;
if (n > 0) {
lua_pop(L, n);
}
}
bool LuaParser::HasFunction(std::string subname, std::string package_name) {
std::transform(subname.begin(), subname.end(), subname.begin(), ::tolower);
//std::transform(subname.begin(), subname.end(), subname.begin(), ::tolower);
auto iter = loaded_.find(package_name);
if(iter == loaded_.end()) {
@ -1137,7 +1082,8 @@ void LuaParser::MapFunctions(lua_State *L) {
lua_register_door(),
lua_register_object(),
lua_register_packet(),
lua_register_packet_opcodes()
lua_register_packet_opcodes(),
lua_register_stat_bonuses()
];
} catch(std::exception &ex) {
@ -1310,6 +1256,355 @@ int LuaParser::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, ui
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) {
switch(evt) {
case EVENT_SLAY:

View File

@ -31,15 +31,6 @@ namespace luabind {
}
}
class IgnoreDefaultException : std::exception {
public:
IgnoreDefaultException() { };
IgnoreDefaultException(const exception&) { };
IgnoreDefaultException& operator= (const exception&) { return *this; }
virtual ~IgnoreDefaultException() { }
virtual const char* what() const { return "Ignore Default Action"; }
};
class LuaParser : public QuestInterface {
public:
~LuaParser();
@ -96,7 +87,10 @@ public:
}
//Mod Extensions
void DoAttack(Mob *self, Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts);
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);
private:
LuaParser();

1539
zone/lua_stat_bonuses.cpp Normal file

File diff suppressed because it is too large Load Diff

285
zone/lua_stat_bonuses.h Normal file
View File

@ -0,0 +1,285 @@
#pragma once
#ifdef LUA_EQEMU
#include "lua_ptr.h"
#include "common.h"
struct StatBonuses;
namespace luabind {
struct scope;
}
luabind::scope lua_register_stat_bonuses();
class Lua_StatBonuses : public Lua_Ptr<StatBonuses>
{
typedef StatBonuses NativeType;
public:
Lua_StatBonuses() : Lua_Ptr(nullptr) { }
Lua_StatBonuses(StatBonuses *d) : Lua_Ptr(d) { }
virtual ~Lua_StatBonuses() { }
operator StatBonuses*() {
return reinterpret_cast<StatBonuses*>(GetLuaPtrData());
}
int32 GetAC() const;
int32 GetHP() const;
int32 GetHPRegen() const;
int32 GetMaxHP() const;
int32 GetManaRegen() const;
int32 GetEnduranceRegen() const;
int32 GetMana() const;
int32 GetEndurance() const;
int32 GetATK() const;
int32 GetSTR() const;
int32 GetSTRCapMod() const;
int32 GetHeroicSTR() const;
int32 GetSTA() const;
int32 GetSTACapMod() const;
int32 GetHeroicSTA() const;
int32 GetDEX() const;
int32 GetDEXCapMod() const;
int32 GetHeroicDEX() const;
int32 GetAGI() const;
int32 GetAGICapMod() const;
int32 GetHeroicAGI() const;
int32 GetINT() const;
int32 GetINTCapMod() const;
int32 GetHeroicINT() const;
int32 GetWIS() const;
int32 GetWISCapMod() const;
int32 GetHeroicWIS() const;
int32 GetCHA() const;
int32 GetCHACapMod() const;
int32 GetHeroicCHA() const;
int32 GetMR() const;
int32 GetMRCapMod() const;
int32 GetHeroicMR() const;
int32 GetFR() const;
int32 GetFRCapMod() const;
int32 GetHeroicFR() const;
int32 GetCR() const;
int32 GetCRCapMod() const;
int32 GetHeroicCR() const;
int32 GetPR() const;
int32 GetPRCapMod() const;
int32 GetHeroicPR() const;
int32 GetDR() const;
int32 GetDRCapMod() const;
int32 GetHeroicDR() const;
int32 GetCorrup() const;
int32 GetCorrupCapMod() const;
int32 GetHeroicCorrup() const;
uint16 GetDamageShieldSpellID() const;
int GetDamageShield() const;
int GetDamageShieldType() const;
int GetSpellDamageShield() const;
int GetSpellShield() const;
int GetReverseDamageShield() const;
uint16 GetReverseDamageShieldSpellID() const;
int GetReverseDamageShieldType() const;
int Getmovementspeed() const;
int32 Gethaste() const;
int32 Gethastetype2() const;
int32 Gethastetype3() const;
int32 Getinhibitmelee() const;
float GetAggroRange() const;
float GetAssistRange() const;
int32 Getskillmod(int idx) const;
int32 Getskillmodmax(int idx) const;
int Geteffective_casting_level() const;
int Getreflect_chance() const;
uint32 GetsingingMod() const;
uint32 GetAmplification() const;
uint32 GetbrassMod() const;
uint32 GetpercussionMod() const;
uint32 GetwindMod() const;
uint32 GetstringedMod() const;
uint32 GetsongModCap() const;
int8 Gethatemod() const;
int32 GetEnduranceReduction() const;
int32 GetStrikeThrough() const;
int32 GetMeleeMitigation() const;
int32 GetMeleeMitigationEffect() const;
int32 GetCriticalHitChance(int idx) const;
int32 GetCriticalSpellChance() const;
int32 GetSpellCritDmgIncrease() const;
int32 GetSpellCritDmgIncNoStack() const;
int32 GetDotCritDmgIncrease() const;
int32 GetCriticalHealChance() const;
int32 GetCriticalHealOverTime() const;
int32 GetCriticalDoTChance() const;
int32 GetCrippBlowChance() const;
int32 GetAvoidMeleeChance() const;
int32 GetAvoidMeleeChanceEffect() const;
int32 GetRiposteChance() const;
int32 GetDodgeChance() const;
int32 GetParryChance() const;
int32 GetDualWieldChance() const;
int32 GetDoubleAttackChance() const;
int32 GetTripleAttackChance() const;
int32 GetDoubleRangedAttack() const;
int32 GetResistSpellChance() const;
int32 GetResistFearChance() const;
bool GetFearless() const;
bool GetIsFeared() const;
bool GetIsBlind() const;
int32 GetStunResist() const;
int32 GetMeleeSkillCheck() const;
uint8 GetMeleeSkillCheckSkill() const;
int32 GetHitChance() const;
int32 GetHitChanceEffect(int idx) const;
int32 GetDamageModifier(int idx) const;
int32 GetDamageModifier2(int idx) const;
int32 GetMinDamageModifier(int idx) const;
int32 GetProcChance() const;
int32 GetProcChanceSPA() const;
int32 GetExtraAttackChance() const;
int32 GetDoTShielding() const;
int32 GetFlurryChance() const;
int32 GetHundredHands() const;
int32 GetMeleeLifetap() const;
int32 GetVampirism() const;
int32 GetHealRate() const;
int32 GetMaxHPChange() const;
int32 GetHealAmt() const;
int32 GetSpellDmg() const;
int32 GetClairvoyance() const;
int32 GetDSMitigation() const;
int32 GetDSMitigationOffHand() const;
int32 GetTwoHandBluntBlock() const;
uint32 GetItemManaRegenCap() const;
int32 GetGravityEffect() const;
bool GetAntiGate() const;
bool GetMagicWeapon() const;
int32 GetIncreaseBlockChance() const;
uint32 GetPersistantCasting() const;
int GetXPRateMod() const;
bool GetBlockNextSpell() const;
bool GetImmuneToFlee() const;
uint32 GetVoiceGraft() const;
int32 GetSpellProcChance() const;
int32 GetCharmBreakChance() const;
int32 GetSongRange() const;
uint32 GetHPToManaConvert() const;
bool GetNegateEffects() const;
bool GetTriggerMeleeThreshold() const;
bool GetTriggerSpellThreshold() const;
int32 GetShieldBlock() const;
int32 GetBlockBehind() const;
bool GetCriticalRegenDecay() const;
bool GetCriticalHealDecay() const;
bool GetCriticalDotDecay() const;
bool GetDivineAura() const;
bool GetDistanceRemoval() const;
int32 GetFrenziedDevastation() const;
bool GetNegateIfCombat() const;
int8 GetScreech() const;
int32 GetAlterNPCLevel() const;
bool GetBerserkSPA() const;
int32 GetMetabolism() const;
bool GetSanctuary() const;
int32 GetFactionModPct() const;
uint32 GetPC_Pet_Flurry() const;
int8 GetPackrat() const;
uint8 GetBuffSlotIncrease() const;
uint32 GetDelayDeath() const;
int8 GetBaseMovementSpeed() const;
uint8 GetIncreaseRunSpeedCap() const;
int32 GetDoubleSpecialAttack() const;
uint8 GetFrontalStunResist() const;
int32 GetBindWound() const;
int32 GetMaxBindWound() const;
int32 GetChannelChanceSpells() const;
int32 GetChannelChanceItems() const;
uint8 GetSeeInvis() const;
uint8 GetTripleBackstab() const;
bool GetFrontalBackstabMinDmg() const;
uint8 GetFrontalBackstabChance() const;
uint8 GetConsumeProjectile() const;
uint8 GetForageAdditionalItems() const;
uint8 GetSalvageChance() const;
uint32 GetArcheryDamageModifier() const;
bool GetSecondaryDmgInc() const;
uint32 GetGiveDoubleAttack() const;
int32 GetPetCriticalHit() const;
int32 GetPetAvoidance() const;
int32 GetCombatStability() const;
int32 GetDoubleRiposte() const;
int32 GetAmbidexterity() const;
int32 GetPetMaxHP() const;
int32 GetPetFlurry() const;
uint8 GetMasteryofPast() const;
bool GetGivePetGroupTarget() const;
int32 GetRootBreakChance() const;
int32 GetUnfailingDivinity() const;
int32 GetItemHPRegenCap() const;
int32 GetOffhandRiposteFail() const;
int32 GetItemATKCap() const;
int32 GetShieldEquipDmgMod() const;
bool GetTriggerOnValueAmount() const;
int8 GetStunBashChance() const;
int8 GetIncreaseChanceMemwipe() const;
int8 GetCriticalMend() const;
int32 GetImprovedReclaimEnergy() const;
int32 GetPetMeleeMitigation() const;
bool GetIllusionPersistence() const;
uint16 Getextra_xtargets() const;
bool GetShroudofStealth() const;
uint16 GetReduceFallDamage() const;
uint8 GetTradeSkillMastery() const;
int16 GetNoBreakAESneak() const;
int16 GetFeignedCastOnChance() const;
int32 GetDivineSaveChance(int idx) const;
uint32 GetDeathSave(int idx) const;
int32 GetAccuracy(int idx) const;
int16 GetSkillDmgTaken(int idx) const;
uint32 GetSpellTriggers(int idx) const;
uint32 GetSpellOnKill(int idx) const;
uint32 GetSpellOnDeath(int idx) const;
int32 GetCritDmgMob(int idx) const;
int32 GetSkillReuseTime(int idx) const;
int32 GetSkillDamageAmount(int idx) const;
int GetHPPercCap(int idx) const;
int GetManaPercCap(int idx) const;
int GetEndPercCap(int idx) const;
uint8 GetFocusEffects(int idx) const;
int16 GetFocusEffectsWorn(int idx) const;
int32 GetSkillDamageAmount2(int idx) const;
uint32 GetNegateAttacks(int idx) const;
uint32 GetMitigateMeleeRune(int idx) const;
uint32 GetMeleeThresholdGuard(int idx) const;
uint32 GetSpellThresholdGuard(int idx) const;
uint32 GetMitigateSpellRune(int idx) const;
uint32 GetMitigateDotRune(int idx) const;
uint32 GetManaAbsorbPercentDamage(int idx) const;
int32 GetImprovedTaunt(int idx) const;
int8 GetRoot(int idx) const;
uint32 GetAbsorbMagicAtt(int idx) const;
uint32 GetMeleeRune(int idx) const;
int32 GetAStacker(int idx) const;
int32 GetBStacker(int idx) const;
int32 GetCStacker(int idx) const;
int32 GetDStacker(int idx) const;
bool GetLimitToSkill(int idx) const;
uint32 GetSkillProc(int idx) const;
uint32 GetSkillProcSuccess(int idx) const;
uint32 GetPC_Pet_Rampage(int idx) const;
int32 GetSkillAttackProc(int idx) const;
int32 GetSlayUndead(int idx) const;
int32 GetGiveDoubleRiposte(int idx) const;
uint32 GetRaiseSkillCap(int idx) const;
int32 GetSEResist(int idx) const;
int32 GetFinishingBlow(int idx) const;
uint32 GetFinishingBlowLvl(int idx) const;
uint32 GetHeadShot(int idx) const;
uint8 GetHSLevel(int idx) const;
uint32 GetAssassinate(int idx) const;
uint8 GetAssassinateLevel(int idx) const;
int32 GetReduceTradeskillFail(int idx) const;
};
#endif

View File

@ -446,6 +446,9 @@ public:
inline StatBonuses GetItemBonuses() const { return itembonuses; }
inline StatBonuses GetSpellBonuses() const { return spellbonuses; }
inline StatBonuses GetAABonuses() const { return aabonuses; }
inline StatBonuses* GetItemBonusesPtr() { return &itembonuses; }
inline StatBonuses* GetSpellBonusesPtr() { return &spellbonuses; }
inline StatBonuses* GetAABonusesPtr() { return &aabonuses; }
inline virtual int32 GetMaxSTR() const { return GetSTR(); }
inline virtual int32 GetMaxSTA() const { return GetSTA(); }
inline virtual int32 GetMaxDEX() const { return GetDEX(); }