From 7b894a7c61470b9bba024cab6104618338476a1d Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 20 Jun 2013 14:03:22 -0700 Subject: [PATCH] Added direct inventory access, and event_loot for items and event_weapon_proc for items --- world/cliententry.cpp | 3 +- zone/CMakeLists.txt | 2 + zone/attack.cpp | 26 ++--- zone/bot.cpp | 4 +- zone/bot.h | 2 +- zone/client_packet.cpp | 2 +- zone/corpse.cpp | 1 + zone/embparser.cpp | 3 +- zone/event_codes.h | 1 + zone/lua_client.cpp | 19 ++-- zone/lua_client.h | 3 +- zone/lua_general.cpp | 7 +- zone/lua_inventory.cpp | 195 +++++++++++++++++++++++++++++++++++++ zone/lua_inventory.h | 60 ++++++++++++ zone/lua_parser.cpp | 12 ++- zone/lua_parser_events.cpp | 108 ++++++++++++++++++-- zone/lua_parser_events.h | 16 ++- zone/mob.cpp | 64 ++++++------ zone/mob.h | 7 +- zone/spell_effects.cpp | 34 +++++-- zone/spells.cpp | 2 - 21 files changed, 483 insertions(+), 88 deletions(-) create mode 100644 zone/lua_inventory.cpp create mode 100644 zone/lua_inventory.h diff --git a/world/cliententry.cpp b/world/cliententry.cpp index 3d0361d3f..a125b706f 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -250,7 +250,7 @@ void ClientListEntry::Camp(ZoneServer* iZS) { bool ClientListEntry::CheckStale() { stale++; - if (stale >= 3) { + if (stale > 20) { if (pOnline > CLE_Status_Offline) SetOnline(CLE_Status_Offline); else @@ -260,7 +260,6 @@ bool ClientListEntry::CheckStale() { } bool ClientListEntry::CheckAuth(uint32 iLSID, const char* iKey) { -// if (LSID() == iLSID && strncmp(plskey, iKey,10) == 0) { if (strncmp(plskey, iKey,10) == 0) { if (paccountid == 0 && LSID()>0) { int16 tmpStatus = WorldConfig::get()->DefaultStatus; diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index df0428301..f9e2e1c08 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -40,6 +40,7 @@ SET(zone_sources lua_general.cpp lua_group.cpp lua_hate_list.cpp + lua_inventory.cpp lua_item.cpp lua_iteminst.cpp lua_mob.cpp @@ -147,6 +148,7 @@ SET(zone_headers lua_general.h lua_group.h lua_hate_list.h + lua_inventory.h lua_item.h lua_iteminst.h lua_mob.h diff --git a/zone/attack.cpp b/zone/attack.cpp index 291d32664..ca5ee2340 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1953,8 +1953,8 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool if (!GetTarget()) return true; //We killed them - if( !bRiposte && other->GetHP() > 0 ) { - TryWeaponProc(weapon, other, Hand); //no weapon + if(!bRiposte && other->GetHP() > 0 ) { + TryWeaponProc(nullptr, weapon, other, Hand); //no weapon } TriggerDefensiveProcs(nullptr, other, Hand, damage); @@ -3780,7 +3780,7 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand, int dam if (DefensiveProcs[i].spellID != SPELL_UNKNOWN) { int chance = ProcChance * (DefensiveProcs[i].chance); if ((MakeRandomInt(0, 100) < chance)) { - ExecWeaponProc(DefensiveProcs[i].spellID, on); + ExecWeaponProc(nullptr, DefensiveProcs[i].spellID, on); CheckHitsRemaining(0, false, false, 0, DefensiveProcs[i].base_spellID); } } @@ -3812,17 +3812,17 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) { } if(!weapon_g) { - TryWeaponProc((const Item_Struct*) nullptr, on, hand); + TryWeaponProc(nullptr, (const Item_Struct*)nullptr, on, hand); return; } if(!weapon_g->IsType(ItemClassCommon)) { - TryWeaponProc((const Item_Struct*) nullptr, on, hand); + TryWeaponProc(nullptr, (const Item_Struct*) nullptr, on, hand); return; } //do main procs - TryWeaponProc(weapon_g->GetItem(), on, hand); + TryWeaponProc(weapon_g, weapon_g->GetItem(), on, hand); //we have to calculate these again, oh well @@ -3855,14 +3855,14 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) { Message_StringID(13,PROC_TOOLOW); } } else { - ExecWeaponProc(aug->Proc.Effect, on); + ExecWeaponProc(aug_i, aug->Proc.Effect, on); } } } } } -void Mob::TryWeaponProc(const Item_Struct* weapon, Mob *on, uint16 hand) { +void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct* weapon, Mob *on, uint16 hand) { _ZP(Mob_TryWeaponProcB); uint16 skillinuse = 28; int ourlevel = GetLevel(); @@ -3891,7 +3891,7 @@ void Mob::TryWeaponProc(const Item_Struct* weapon, Mob *on, uint16 hand) { } } else { mlog(COMBAT__PROCS, "Attacking weapon (%s) successfully procing spell %d (%.2f percent chance)", weapon->Name, weapon->Proc.Effect, ProcChance*100); - ExecWeaponProc(weapon->Proc.Effect, on); + ExecWeaponProc(inst, weapon->Proc.Effect, on); } } else { mlog(COMBAT__PROCS, "Attacking weapon (%s) did no proc (%.2f percent chance).", weapon->Name, ProcChance*100); @@ -3928,7 +3928,7 @@ void Mob::TryWeaponProc(const Item_Struct* weapon, Mob *on, uint16 hand) { if (PermaProcs[i].spellID != SPELL_UNKNOWN) { if(MakeRandomInt(0, 100) < PermaProcs[i].chance) { mlog(COMBAT__PROCS, "Permanent proc %d procing spell %d (%d percent chance)", i, PermaProcs[i].spellID, PermaProcs[i].chance); - ExecWeaponProc(PermaProcs[i].spellID, on); + ExecWeaponProc(nullptr, PermaProcs[i].spellID, on); } else { mlog(COMBAT__PROCS, "Permanent proc %d failed to proc %d (%d percent chance)", i, PermaProcs[i].spellID, PermaProcs[i].chance); } @@ -3945,7 +3945,7 @@ void Mob::TryWeaponProc(const Item_Struct* weapon, Mob *on, uint16 hand) { int chance = ProcChance * (SpellProcs[i].chance); if(MakeRandomInt(0, 100) < chance) { mlog(COMBAT__PROCS, "Spell proc %d procing spell %d (%d percent chance)", i, SpellProcs[i].spellID, chance); - ExecWeaponProc(SpellProcs[i].spellID, on); + ExecWeaponProc(nullptr, SpellProcs[i].spellID, on); } else { mlog(COMBAT__PROCS, "Spell proc %d failed to proc %d (%d percent chance)", i, SpellProcs[i].spellID, chance); } @@ -3955,7 +3955,7 @@ void Mob::TryWeaponProc(const Item_Struct* weapon, Mob *on, uint16 hand) { int chance = ProcChance * RangedProcs[i].chance; if(MakeRandomInt(0, 100) < chance) { mlog(COMBAT__PROCS, "Ranged proc %d procing spell %d", i, RangedProcs[i].spellID, RangedProcs[i].chance); - ExecWeaponProc(RangedProcs[i].spellID, on); + ExecWeaponProc(nullptr, RangedProcs[i].spellID, on); CheckHitsRemaining(0, false, false, 0, RangedProcs[i].base_spellID); } else { mlog(COMBAT__PROCS, "Ranged proc %d failed to proc %d", i, RangedProcs[i].spellID, RangedProcs[i].chance); @@ -4295,7 +4295,7 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, float chance) if (PassLimitToSkill(SkillProcs[i].base_spellID,skill)){ int ProcChance = chance * (float)SkillProcs[i].chance; if ((MakeRandomInt(0, 100) < ProcChance)) { - ExecWeaponProc(SkillProcs[i].spellID, on); + ExecWeaponProc(nullptr, SkillProcs[i].spellID, on); CheckHitsRemaining(0, false, false, 0, SkillProcs[i].base_spellID); } } diff --git a/zone/bot.cpp b/zone/bot.cpp index 39911c3aa..39c48c09a 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -9896,8 +9896,8 @@ bool Bot::SpellEffect(Mob* caster, uint16 spell_id, float partial) { return Result; } -void Bot::DoBuffTic(uint16 spell_id, uint32 ticsremaining, uint8 caster_level, Mob* caster) { - Mob::DoBuffTic(spell_id, ticsremaining, caster_level, caster); +void Bot::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caster_level, Mob* caster) { + Mob::DoBuffTic(spell_id, slot, ticsremaining, caster_level, caster); } bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, int16 *resist_adjust) { diff --git a/zone/bot.h b/zone/bot.h index 1e6240373..f037bf107 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -312,7 +312,7 @@ public: virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration); virtual float GetAOERange(uint16 spell_id); virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100); - virtual void DoBuffTic(uint16 spell_id, uint32 ticsremaining, uint8 caster_level, Mob* caster = 0); + virtual void DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caster_level, Mob* caster = 0); virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = 10, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr); virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar); virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 7aa8ddb65..420ea4b2b 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1218,7 +1218,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) if(proximity_timer.Check()) { entity_list.ProcessMove(this, ppu->x_pos, ppu->y_pos, ppu->z_pos); - if(RuleB(TaskSystem, EnableTaskSystem) && RuleB(TaskSystem,EnableTaskProximity)) + if(RuleB(TaskSystem, EnableTaskSystem) && RuleB(TaskSystem,EnableTaskProximity)) ProcessTaskProximities(ppu->x_pos, ppu->y_pos, ppu->z_pos); proximity_x = ppu->x_pos; proximity_y = ppu->y_pos; diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 6485f3800..b3ccfe48f 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -1171,6 +1171,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) args.push_back(inst); args.push_back(this); parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args); + parse->EventItem(EVENT_LOOT, client, inst, this, buf, 0); if ((RuleB(Character, EnableDiscoveredItems))) { diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 10a488c23..d6aab2211 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -100,7 +100,8 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_SAY", "EVENT_DROP_ITEM", "EVENT_DESTROY_ITEM", - "EVENT_FEIGN_DEATH" + "EVENT_FEIGN_DEATH", + "EVENT_WEAPON_PROC" }; PerlembParser::PerlembParser() : perl(nullptr), event_queue_in_use_(false) { diff --git a/zone/event_codes.h b/zone/event_codes.h index 2b3315ef1..94bd94a4c 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -69,6 +69,7 @@ typedef enum { EVENT_DROP_ITEM, EVENT_DESTROY_ITEM, EVENT_FEIGN_DEATH, + EVENT_WEAPON_PROC, _LargestEventID } QuestEventID; diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index fcff6e01d..b8be88c64 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -8,6 +8,7 @@ #include "lua_npc.h" #include "lua_item.h" #include "lua_iteminst.h" +#include "lua_inventory.h" #include "lua_group.h" #include "lua_raid.h" @@ -880,11 +881,6 @@ int Lua_Client::GetLDoNLossesTheme(int theme) { return self->GetLDoNLossesTheme(theme); } -Lua_ItemInst Lua_Client::GetItemAt(int slot) { - Lua_Safe_Call_Class(Lua_ItemInst); - return Lua_ItemInst(self->GetInv().GetItem(slot)); -} - int Lua_Client::GetStartZone() { Lua_Safe_Call_Int(); return self->GetStartZone(); @@ -1152,12 +1148,12 @@ std::string Lua_Client::GetAccountFlag(std::string flag) { Lua_Group Lua_Client::GetGroup() { Lua_Safe_Call_Class(Lua_Group); - return Lua_Group(self->GetGroup()); + return self->GetGroup(); } Lua_Raid Lua_Client::GetRaid() { Lua_Safe_Call_Class(Lua_Raid); - return Lua_Raid(self->GetRaid()); + return self->GetRaid(); } bool Lua_Client::PutItemInInventory(int slot_id, Lua_ItemInst inst) { @@ -1172,6 +1168,11 @@ bool Lua_Client::PushItemOnCursor(Lua_ItemInst inst) { return self->PushItemOnCursor(*rinst, true); } +Lua_Inventory Lua_Client::GetInventory() { + Lua_Safe_Call_Class(Lua_Inventory); + return &self->GetInv(); +} + luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()) @@ -1348,7 +1349,6 @@ luabind::scope lua_register_client() { .def("GetLDoNLosses", (int(Lua_Client::*)(void))&Lua_Client::GetLDoNLosses) .def("GetLDoNWinsTheme", (int(Lua_Client::*)(int))&Lua_Client::GetLDoNWinsTheme) .def("GetLDoNLossesTheme", (int(Lua_Client::*)(int))&Lua_Client::GetLDoNLossesTheme) - .def("GetItemAt", (Lua_ItemInst(Lua_Client::*)(int))&Lua_Client::GetItemAt) .def("GetStartZone", (int(Lua_Client::*)(void))&Lua_Client::GetStartZone) .def("SetStartZone", (void(Lua_Client::*)(int))&Lua_Client::SetStartZone) .def("SetStartZone", (void(Lua_Client::*)(int,float))&Lua_Client::SetStartZone) @@ -1405,7 +1405,8 @@ luabind::scope lua_register_client() { .def("GetGroup", (Lua_Group(Lua_Client::*)(void))&Lua_Client::GetGroup) .def("GetRaid", (Lua_Raid(Lua_Client::*)(void))&Lua_Client::GetRaid) .def("PutItemInInventory", (bool(Lua_Client::*)(int,Lua_ItemInst))&Lua_Client::PutItemInInventory) - .def("PushItemOnCursor", (bool(Lua_Client::*)(Lua_ItemInst))&Lua_Client::PushItemOnCursor); + .def("PushItemOnCursor", (bool(Lua_Client::*)(Lua_ItemInst))&Lua_Client::PushItemOnCursor) + .def("GetInventory", (Lua_Inventory(Lua_Client::*)(void))&Lua_Client::GetInventory); } luabind::scope lua_register_inventory_where() { diff --git a/zone/lua_client.h b/zone/lua_client.h index 7b89bf20c..068c38c19 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -7,6 +7,7 @@ class Client; class Lua_Group; class Lua_Raid; +class Lua_Inventory; namespace luabind { struct scope; @@ -202,7 +203,6 @@ public: int GetLDoNLosses(); int GetLDoNWinsTheme(int theme); int GetLDoNLossesTheme(int theme); - Lua_ItemInst GetItemAt(int slot); int GetStartZone(); void SetStartZone(int zone_id); void SetStartZone(int zone_id, float x); @@ -260,6 +260,7 @@ public: Lua_Raid GetRaid(); bool PutItemInInventory(int slot_id, Lua_ItemInst inst); bool PushItemOnCursor(Lua_ItemInst inst); + Lua_Inventory GetInventory(); }; #endif diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 4e47bac30..0562545ba 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -965,6 +965,7 @@ luabind::scope lua_register_events() { luabind::value("popup_response", static_cast(EVENT_POPUP_RESPONSE)), luabind::value("proximity_say", static_cast(EVENT_PROXIMITY_SAY)), luabind::value("cast", static_cast(EVENT_CAST)), + luabind::value("cast_begin", static_cast(EVENT_CAST_BEGIN)), luabind::value("scale_calc", static_cast(EVENT_SCALE_CALC)), luabind::value("item_enter_zone", static_cast(EVENT_ITEM_ENTER_ZONE)), luabind::value("target_change", static_cast(EVENT_TARGET_CHANGE)), @@ -992,7 +993,11 @@ luabind::scope lua_register_events() { luabind::value("duel_lose", static_cast(EVENT_DUEL_LOSE)), luabind::value("encounter_load", static_cast(EVENT_ENCOUNTER_LOAD)), luabind::value("encounter_unload", static_cast(EVENT_ENCOUNTER_UNLOAD)), - luabind::value("command", static_cast(EVENT_COMMAND)) + luabind::value("command", static_cast(EVENT_COMMAND)), + luabind::value("drop_item", static_cast(EVENT_DROP_ITEM)), + luabind::value("destroy_item", static_cast(EVENT_DESTROY_ITEM)), + luabind::value("feign_death", static_cast(EVENT_FEIGN_DEATH)), + luabind::value("weapon_proc", static_cast(EVENT_WEAPON_PROC)) ]; } diff --git a/zone/lua_inventory.cpp b/zone/lua_inventory.cpp new file mode 100644 index 000000000..d69c873d5 --- /dev/null +++ b/zone/lua_inventory.cpp @@ -0,0 +1,195 @@ +#ifdef LUA_EQEMU + +#include "lua.hpp" +#include + +#include "masterentity.h" +#include "lua_inventory.h" +#include "lua_iteminst.h" +#include "lua_item.h" + +Lua_ItemInst Lua_Inventory::GetItem(int slot_id) { + Lua_Safe_Call_Class(Lua_ItemInst); + return self->GetItem(slot_id); +} + +Lua_ItemInst Lua_Inventory::GetItem(int slot_id, int bag_slot) { + Lua_Safe_Call_Class(Lua_ItemInst); + return self->GetItem(slot_id, bag_slot); +} + +int Lua_Inventory::PutItem(int slot_id, Lua_ItemInst item) { + Lua_Safe_Call_Int(); + ItemInst *inst = item; + if(!inst) { + return 0; + } + + return self->PutItem(slot_id, *inst); +} + +int Lua_Inventory::PushCursor(Lua_ItemInst item) { + Lua_Safe_Call_Int(); + ItemInst *inst = item; + if(!inst) { + return 0; + } + + return self->PushCursor(*inst); +} + +bool Lua_Inventory::SwapItem(int slot_a, int slot_b) { + Lua_Safe_Call_Bool(); + return self->SwapItem(slot_a, slot_b); +} + +bool Lua_Inventory::DeleteItem(int slot_id) { + Lua_Safe_Call_Bool(); + return self->DeleteItem(slot_id); +} + +bool Lua_Inventory::DeleteItem(int slot_id, int quantity) { + Lua_Safe_Call_Bool(); + return self->DeleteItem(slot_id, quantity); +} + +bool Lua_Inventory::CheckNoDrop(int slot_id) { + Lua_Safe_Call_Bool(); + return self->CheckNoDrop(slot_id); +} + +Lua_ItemInst Lua_Inventory::PopItem(int slot_id) { + Lua_Safe_Call_Class(Lua_ItemInst); + return Lua_ItemInst(self->PopItem(slot_id), true); +} + +int Lua_Inventory::HasItem(int item_id) { + Lua_Safe_Call_Int(); + return self->HasItem(item_id); +} + +int Lua_Inventory::HasItem(int item_id, int quantity) { + Lua_Safe_Call_Int(); + return self->HasItem(item_id, quantity); +} + +int Lua_Inventory::HasItem(int item_id, int quantity, int where) { + Lua_Safe_Call_Int(); + return self->HasItem(item_id, quantity, where); +} + +bool Lua_Inventory::HasSpaceForItem(Lua_Item item, int quantity) { + Lua_Safe_Call_Bool(); + return self->HasSpaceForItem(item, quantity); +} + +int Lua_Inventory::HasItemByUse(int use) { + Lua_Safe_Call_Int(); + return self->HasItemByUse(use); +} + +int Lua_Inventory::HasItemByUse(int use, uint8 quantity) { + Lua_Safe_Call_Int(); + return self->HasItemByUse(use, quantity); +} + +int Lua_Inventory::HasItemByUse(int use, uint8 quantity, uint8 where) { + Lua_Safe_Call_Int(); + return self->HasItemByUse(use, quantity, where); +} + +int Lua_Inventory::HasItemByLoreGroup(uint32 loregroup) { + Lua_Safe_Call_Int(); + return self->HasItemByLoreGroup(loregroup); +} + +int Lua_Inventory::HasItemByLoreGroup(uint32 loregroup, int where) { + Lua_Safe_Call_Int(); + return self->HasItemByLoreGroup(loregroup, where); +} + +int Lua_Inventory::FindFreeSlot(bool for_bag, bool try_cursor) { + Lua_Safe_Call_Int(); + return self->FindFreeSlot(for_bag, try_cursor); +} + +int Lua_Inventory::FindFreeSlot(bool for_bag, bool try_cursor, int min_size) { + Lua_Safe_Call_Int(); + return self->FindFreeSlot(for_bag, try_cursor, min_size); +} + +int Lua_Inventory::FindFreeSlot(bool for_bag, bool try_cursor, int min_size, bool is_arrow) { + Lua_Safe_Call_Int(); + return self->FindFreeSlot(for_bag, try_cursor, min_size, is_arrow); +} + +int Lua_Inventory::CalcSlotId(int slot_id) { + Lua_Safe_Call_Int(); + return self->CalcSlotId(slot_id); +} + +int Lua_Inventory::CalcSlotId(int slot_id, int bag_slot) { + Lua_Safe_Call_Int(); + return self->CalcSlotId(slot_id, bag_slot); +} + +int Lua_Inventory::CalcBagIdx(int slot_id) { + Lua_Safe_Call_Int(); + return self->CalcBagIdx(slot_id); +} + +int Lua_Inventory::CalcSlotFromMaterial(int material) { + Lua_Safe_Call_Int(); + return self->CalcSlotFromMaterial(material); +} + +int Lua_Inventory::CalcMaterialFromSlot(int equipslot) { + Lua_Safe_Call_Int(); + return self->CalcMaterialFromSlot(equipslot); +} + +bool Lua_Inventory::CanItemFitInContainer(Lua_Item item, Lua_Item container) { + Lua_Safe_Call_Bool(); + return self->CanItemFitInContainer(item, container); +} + +bool Lua_Inventory::SupportsContainers(int slot_id) { + Lua_Safe_Call_Bool(); + return self->SupportsContainers(slot_id); +} + + +luabind::scope lua_register_inventory() { + return luabind::class_("Inventory") + .def(luabind::constructor<>()) + .def("GetItem", (Lua_ItemInst(Lua_Inventory::*)(int))&Lua_Inventory::GetItem) + .def("GetItem", (Lua_ItemInst(Lua_Inventory::*)(int,int))&Lua_Inventory::GetItem) + .def("PutItem", (int(Lua_Inventory::*)(int,Lua_ItemInst))&Lua_Inventory::PutItem) + .def("PushCursor", (int(Lua_Inventory::*)(Lua_ItemInst))&Lua_Inventory::PushCursor) + .def("SwapItem", (bool(Lua_Inventory::*)(int,int))&Lua_Inventory::SwapItem) + .def("DeleteItem", (bool(Lua_Inventory::*)(int))&Lua_Inventory::DeleteItem) + .def("DeleteItem", (bool(Lua_Inventory::*)(int,int))&Lua_Inventory::DeleteItem) + .def("CheckNoDrop", (bool(Lua_Inventory::*)(int))&Lua_Inventory::CheckNoDrop) + .def("PopItem", (Lua_ItemInst(Lua_Inventory::*)(int))&Lua_Inventory::PopItem) + .def("HasItem", (int(Lua_Inventory::*)(int))&Lua_Inventory::HasItem) + .def("HasItem", (int(Lua_Inventory::*)(int,int))&Lua_Inventory::HasItem) + .def("HasItem", (int(Lua_Inventory::*)(int,int,int))&Lua_Inventory::HasItem) + .def("HasSpaceForItem", (bool(Lua_Inventory::*)(Lua_Item,int))&Lua_Inventory::HasSpaceForItem) + .def("HasItemByUse", (int(Lua_Inventory::*)(int))&Lua_Inventory::HasItemByUse) + .def("HasItemByUse", (int(Lua_Inventory::*)(int,uint8))&Lua_Inventory::HasItemByUse) + .def("HasItemByUse", (int(Lua_Inventory::*)(int,uint8,uint8))&Lua_Inventory::HasItemByUse) + .def("HasItemByLoreGroup", (int(Lua_Inventory::*)(uint32))&Lua_Inventory::HasItemByLoreGroup) + .def("HasItemByLoreGroup", (int(Lua_Inventory::*)(uint32,int))&Lua_Inventory::HasItemByLoreGroup) + .def("FindFreeSlot", (int(Lua_Inventory::*)(bool,bool))&Lua_Inventory::FindFreeSlot) + .def("FindFreeSlot", (int(Lua_Inventory::*)(bool,bool,int))&Lua_Inventory::FindFreeSlot) + .def("FindFreeSlot", (int(Lua_Inventory::*)(bool,bool,int,bool))&Lua_Inventory::FindFreeSlot) + .def("CalcSlotId", (int(Lua_Inventory::*)(int))&Lua_Inventory::CalcSlotId) + .def("CalcSlotId", (int(Lua_Inventory::*)(int,int))&Lua_Inventory::CalcSlotId) + .def("CalcBagIdx", (int(Lua_Inventory::*)(int))&Lua_Inventory::CalcBagIdx) + .def("CalcSlotFromMaterial", (int(Lua_Inventory::*)(int))&Lua_Inventory::CalcSlotFromMaterial) + .def("CalcMaterialFromSlot", (int(Lua_Inventory::*)(int))&Lua_Inventory::CalcMaterialFromSlot) + .def("CanItemFitInContainer", (bool(Lua_Inventory::*)(Lua_Item,Lua_Item))&Lua_Inventory::CanItemFitInContainer) + .def("SupportsContainers", (bool(Lua_Inventory::*)(int))&Lua_Inventory::SupportsContainers); +} + +#endif diff --git a/zone/lua_inventory.h b/zone/lua_inventory.h new file mode 100644 index 000000000..6b8ccb2e1 --- /dev/null +++ b/zone/lua_inventory.h @@ -0,0 +1,60 @@ +#ifndef EQEMU_LUA_INVENTORY_H +#define EQEMU_LUA_INVENTORY_H +#ifdef LUA_EQEMU + +#include "lua_ptr.h" + +class Inventory; +class Lua_ItemInst; +class Lua_Item; + +namespace luabind { + struct scope; +} + +luabind::scope lua_register_inventory(); + +class Lua_Inventory : public Lua_Ptr +{ + typedef Inventory NativeType; +public: + Lua_Inventory() : Lua_Ptr(nullptr) { } + Lua_Inventory(Inventory *d) : Lua_Ptr(d) { } + virtual ~Lua_Inventory() { } + + operator Inventory*() { + return reinterpret_cast(GetLuaPtrData()); + } + + Lua_ItemInst GetItem(int slot_id); + Lua_ItemInst GetItem(int slot_id, int bag_slot); + int PutItem(int slot_id, Lua_ItemInst item); + int PushCursor(Lua_ItemInst item); + bool SwapItem(int slot_a, int slot_b); + bool DeleteItem(int slot_id); + bool DeleteItem(int slot_id, int quantity); + bool CheckNoDrop(int slot_id); + Lua_ItemInst PopItem(int slot_id); + int HasItem(int item_id); + int HasItem(int item_id, int quantity); + int HasItem(int item_id, int quantity, int where); + bool HasSpaceForItem(Lua_Item item, int quantity); + int HasItemByUse(int use); + int HasItemByUse(int use, uint8 quantity); + int HasItemByUse(int use, uint8 quantity, uint8 where); + int HasItemByLoreGroup(uint32 loregroup); + int HasItemByLoreGroup(uint32 loregroup, int where); + int FindFreeSlot(bool for_bag, bool try_cursor); + int FindFreeSlot(bool for_bag, bool try_cursor, int min_size); + int FindFreeSlot(bool for_bag, bool try_cursor, int min_size, bool is_arrow); + int CalcSlotId(int slot_id); + int CalcSlotId(int slot_id, int bag_slot); + int CalcBagIdx(int slot_id); + int CalcSlotFromMaterial(int material); + int CalcMaterialFromSlot(int equipslot); + bool CanItemFitInContainer(Lua_Item item, Lua_Item container); + bool SupportsContainers(int slot_id); +}; + +#endif +#endif diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 88c511d40..929dfedca 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -18,6 +18,7 @@ #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" @@ -98,7 +99,8 @@ const char *LuaEvents[_LargestEventID] = { "event_command", "event_drop_item", "event_destroy_item", - "event_feign_death" + "event_feign_death", + "event_weapon_proc" }; extern Zone *zone; @@ -172,10 +174,13 @@ LuaParser::LuaParser() { ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click; ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click; ItemArgumentDispatch[EVENT_TIMER] = handle_item_timer; + ItemArgumentDispatch[EVENT_WEAPON_PROC] = handle_item_proc; + ItemArgumentDispatch[EVENT_LOOT] = handle_item_loot; SpellArgumentDispatch[EVENT_SPELL_EFFECT_CLIENT] = handle_spell_effect; - SpellArgumentDispatch[EVENT_SPELL_BUFF_TIC_CLIENT] = handle_spell_effect; + SpellArgumentDispatch[EVENT_SPELL_BUFF_TIC_CLIENT] = handle_spell_tic; SpellArgumentDispatch[EVENT_SPELL_FADE] = handle_spell_fade; + SpellArgumentDispatch[EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE] = handle_translocate_finish; L = nullptr; } @@ -424,7 +429,7 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl //redo this arg function auto arg_function = ItemArgumentDispatch[evt]; - arg_function(this, L, client, item, data, extra_data, extra_pointers); + arg_function(this, L, client, item, mob, data, extra_data, extra_pointers); quest_manager.StartQuest(client, client, item); if(lua_pcall(L, 1, 1, 0)) { @@ -867,6 +872,7 @@ void LuaParser::MapFunctions(lua_State *L) { lua_register_mob(), lua_register_npc(), lua_register_client(), + lua_register_inventory(), lua_register_inventory_where(), lua_register_iteminst(), lua_register_item(), diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 557a15b19..7e157e10b 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -445,19 +445,55 @@ void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std } //Item -void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, std::string data, uint32 extra_data, +void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, std::vector *extra_pointers) { lua_pushinteger(L, extra_data); lua_setfield(L, -2, "slot_id"); } -void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, std::string data, uint32 extra_data, +void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, std::vector *extra_pointers) { lua_pushstring(L, data.c_str()); lua_setfield(L, -2, "timer"); } -void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, std::string data, uint32 extra_data, +void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, + std::vector *extra_pointers) { + + Lua_Mob l_mob(mob); + luabind::object l_mob_o = luabind::object(L, l_mob); + l_mob_o.push(L); + lua_setfield(L, -2, "target"); + + if(IsValidSpell(extra_data)) { + Lua_Spell l_spell(&spells[extra_data]); + luabind::object l_spell_o = luabind::object(L, l_spell); + l_spell_o.push(L); + lua_setfield(L, -2, "spell"); + } else { + Lua_Spell l_spell(nullptr); + luabind::object l_spell_o = luabind::object(L, l_spell); + l_spell_o.push(L); + lua_setfield(L, -2, "spell"); + } +} + +void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, + std::vector *extra_pointers) { + if(mob && mob->IsCorpse()) { + Lua_Corpse l_corpse(mob->CastToCorpse()); + luabind::object l_corpse_o = luabind::object(L, l_corpse); + l_corpse_o.push(L); + lua_setfield(L, -2, "corpse"); + } else { + Lua_Corpse l_corpse(nullptr); + luabind::object l_corpse_o = luabind::object(L, l_corpse); + l_corpse_o.push(L); + lua_setfield(L, -2, "corpse"); + } +} + +void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, std::vector *extra_pointers) { } @@ -465,11 +501,11 @@ void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemI void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, std::vector *extra_pointers) { if(npc) { - Lua_NPC l_npc(npc); + Lua_Mob l_npc(npc); luabind::object l_npc_o = luabind::object(L, l_npc); l_npc_o.push(L); } else if(client) { - Lua_Client l_client(client); + Lua_Mob l_client(client); luabind::object l_client_o = luabind::object(L, l_client); l_client_o.push(L); } else { @@ -477,8 +513,43 @@ void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* luabind::object l_mob_o = luabind::object(L, l_mob); l_mob_o.push(L); } + lua_setfield(L, -2, "target"); + lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + lua_setfield(L, -2, "buff_slot"); + + lua_pushinteger(L, extra_data); + lua_setfield(L, -2, "caster_id"); +} + +void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, + std::vector *extra_pointers) { + if(npc) { + Lua_Mob l_npc(npc); + luabind::object l_npc_o = luabind::object(L, l_npc); + l_npc_o.push(L); + } else if(client) { + Lua_Mob l_client(client); + luabind::object l_client_o = luabind::object(L, l_client); + l_client_o.push(L); + } else { + Lua_Mob l_mob(nullptr); + luabind::object l_mob_o = luabind::object(L, l_mob); + l_mob_o.push(L); + } + + lua_setfield(L, -2, "target"); + + lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + lua_setfield(L, -2, "tics_remaining"); + + lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(1))); + lua_setfield(L, -2, "caster_level"); + + lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(2))); + lua_setfield(L, -2, "buff_slot"); + lua_pushinteger(L, extra_data); lua_setfield(L, -2, "caster_id"); } @@ -486,11 +557,11 @@ void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, std::vector *extra_pointers) { if(npc) { - Lua_NPC l_npc(npc); + Lua_Mob l_npc(npc); luabind::object l_npc_o = luabind::object(L, l_npc); l_npc_o.push(L); } else if(client) { - Lua_Client l_client(client); + Lua_Mob l_client(client); luabind::object l_client_o = luabind::object(L, l_client); l_client_o.push(L); } else { @@ -498,10 +569,33 @@ void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* cl luabind::object l_mob_o = luabind::object(L, l_mob); l_mob_o.push(L); } + lua_setfield(L, -2, "target"); lua_pushinteger(L, extra_data); lua_setfield(L, -2, "buff_slot"); + + lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + lua_setfield(L, -2, "caster_id"); +} + +void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, + std::vector *extra_pointers) { + if(npc) { + Lua_Mob l_npc(npc); + luabind::object l_npc_o = luabind::object(L, l_npc); + l_npc_o.push(L); + } else if(client) { + Lua_Mob l_client(client); + luabind::object l_client_o = luabind::object(L, l_client); + l_client_o.push(L); + } else { + Lua_Mob l_mob(nullptr); + luabind::object l_mob_o = luabind::object(L, l_mob); + l_mob_o.push(L); + } + + lua_setfield(L, -2, "target"); } void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index 159a8af25..ba6a6113d 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -4,7 +4,7 @@ typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::string, uint32, std::vector*); typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector*); -typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, std::string, uint32, std::vector*); +typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, Mob*, std::string, uint32, std::vector*); typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, uint32, std::vector*); //NPC @@ -86,18 +86,26 @@ void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std std::vector *extra_pointers); //Item -void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, std::string data, uint32 extra_data, +void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, std::vector *extra_pointers); -void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, std::string data, uint32 extra_data, +void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, std::vector *extra_pointers); -void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, std::string data, uint32 extra_data, +void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, + std::vector *extra_pointers); +void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, + std::vector *extra_pointers); +void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, std::vector *extra_pointers); //Spell void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, std::vector *extra_pointers); +void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, + std::vector *extra_pointers); void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, std::vector *extra_pointers); +void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, + std::vector *extra_pointers); void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, std::vector *extra_pointers); diff --git a/zone/mob.cpp b/zone/mob.cpp index 4d11d3922..9fde24219 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2816,48 +2816,54 @@ int32 Mob::GetActSpellCasttime(uint16 spell_id, int32 casttime) { return(casttime); } -void Mob::ExecWeaponProc(uint16 spell_id, Mob *on) { +void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on) { // Changed proc targets to look up based on the spells goodEffect flag. // This should work for the majority of weapons. - if(spell_id == SPELL_UNKNOWN || on->SpecAttacks[NO_HARM_FROM_CLIENT]){ //This is so 65535 doesn't get passed to the client message and to logs because it is not relavant information for debugging. - return; + if(spell_id == SPELL_UNKNOWN || on->SpecAttacks[NO_HARM_FROM_CLIENT]) { + //This is so 65535 doesn't get passed to the client message and to logs because it is not relavant information for debugging. + return; } if (IsNoCast()) return; - if(!IsValidSpell(spell_id)){ // Check for a valid spell otherwise it will crash through the function - if(this->IsClient()){ - this->Message(0, "Invalid spell proc %u", spell_id); + if(!IsValidSpell(spell_id)) { // Check for a valid spell otherwise it will crash through the function + if(IsClient()){ + Message(0, "Invalid spell proc %u", spell_id); mlog(CLIENT__SPELLS, "Player %s, Weapon Procced invalid spell %u", this->GetName(), spell_id); } return; } - /* - int twinproc_chance = itembonuses.TwinProc + spellbonuses.TwinProc; - if(IsClient()) - twinproc_chance += aabonuses.TwinProc; - */ - bool twinproc = false; - int32 twinproc_chance = 0; - - if(IsClient()) - twinproc_chance = CastToClient()->GetFocusEffect(focusTwincast, spell_id); - - if(twinproc_chance && (MakeRandomInt(0,99) < twinproc_chance)) - twinproc = true; - - if (IsBeneficialSpell(spell_id)) { - SpellFinished(spell_id, this, 10, 0, -1, spells[spell_id].ResistDiff, true); - if(twinproc) - SpellOnTarget(spell_id, this, false, false, 0, true); - } - else if(!(on->IsClient() && on->CastToClient()->dead)) { //dont proc on dead clients - SpellFinished(spell_id, on, 10, 0, -1, spells[spell_id].ResistDiff, true); - if(twinproc) - SpellOnTarget(spell_id, on, false, false, 0, true); + if(inst && IsClient()) { + //const cast is dirty but it would require redoing a ton of interfaces at this point + //It should be safe as we don't have any truly const ItemInst floating around anywhere. + //So we'll live with it for now + int i = parse->EventItem(EVENT_WEAPON_PROC, CastToClient(), const_cast(inst), on, "", spell_id); + if(i != 0) { + return; } + } + + bool twinproc = false; + int32 twinproc_chance = 0; + + if(IsClient()) + twinproc_chance = CastToClient()->GetFocusEffect(focusTwincast, spell_id); + + if(twinproc_chance && (MakeRandomInt(0,99) < twinproc_chance)) + twinproc = true; + + if (IsBeneficialSpell(spell_id)) { + SpellFinished(spell_id, this, 10, 0, -1, spells[spell_id].ResistDiff, true); + if(twinproc) + SpellOnTarget(spell_id, this, false, false, 0, true); + } + else if(!(on->IsClient() && on->CastToClient()->dead)) { //dont proc on dead clients + SpellFinished(spell_id, on, 10, 0, -1, spells[spell_id].ResistDiff, true); + if(twinproc) + SpellOnTarget(spell_id, on, false, false, 0, true); + } return; } diff --git a/zone/mob.h b/zone/mob.h index 6c9bc63d8..a69199aea 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -192,7 +192,7 @@ public: //Buff void BuffProcess(); - virtual void DoBuffTic(uint16 spell_id, uint32 ticsremaining, uint8 caster_level, Mob* caster = 0); + virtual void DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caster_level, Mob* caster = 0); void BuffFadeBySpellID(uint16 spell_id); void BuffFadeByEffect(int effectid, int skipslot = -1); void BuffFadeAll(); @@ -878,7 +878,6 @@ protected: uint32 scalerate; Buffs_Struct *buffs; uint32 current_buff_count; - Timer *buff_tic_timer; StatBonuses itembonuses; StatBonuses spellbonuses; StatBonuses aabonuses; @@ -917,9 +916,9 @@ protected: bool PassLimitToSkill(uint16 spell_id, uint16 skill); bool PassLimitClass(uint32 Classes_, uint16 Class_); void TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand = 13, int damage=0); - void TryWeaponProc(const Item_Struct* weapon, Mob *on, uint16 hand = 13); + void TryWeaponProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = 13); void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = 13); - void ExecWeaponProc(uint16 spell_id, Mob *on); + void ExecWeaponProc(const ItemInst* weapon, uint16 spell_id, Mob *on); virtual float GetProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_speed = 30, uint16 hand = 13); virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_speed = 30, uint16 hand = 13); int GetWeaponDamage(Mob *against, const Item_Struct *weapon_item); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 6c27bec92..fb1255cfe 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -141,7 +141,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) if(IsNPC()) { - int i = parse->EventSpell(EVENT_SPELL_EFFECT_NPC, CastToNPC(), nullptr, spell_id, caster ? caster->GetID() : 0); + std::vector args; + args.push_back(&buffslot); + int i = parse->EventSpell(EVENT_SPELL_EFFECT_NPC, CastToNPC(), nullptr, spell_id, caster ? caster->GetID() : 0, &args); if(i != 0){ CalcBonuses(); return true; @@ -149,7 +151,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) } else if(IsClient()) { - int i = parse->EventSpell(EVENT_SPELL_EFFECT_CLIENT, nullptr, CastToClient(), spell_id, caster ? caster->GetID() : 0); + std::vector args; + args.push_back(&buffslot); + int i = parse->EventSpell(EVENT_SPELL_EFFECT_CLIENT, nullptr, CastToClient(), spell_id, caster ? caster->GetID() : 0, &args); if(i != 0){ CalcBonuses(); return true; @@ -3001,7 +3005,7 @@ void Mob::BuffProcess() { if (buffs[buffs_i].spellid != SPELL_UNKNOWN) { - DoBuffTic(buffs[buffs_i].spellid, buffs[buffs_i].ticsremaining, buffs[buffs_i].casterlevel, entity_list.GetMob(buffs[buffs_i].casterid)); + DoBuffTic(buffs[buffs_i].spellid, buffs_i, buffs[buffs_i].ticsremaining, buffs[buffs_i].casterlevel, entity_list.GetMob(buffs[buffs_i].casterid)); // If the Mob died during DoBuffTic, then the buff we are currently processing will have been removed if(buffs[buffs_i].spellid == SPELL_UNKNOWN) continue; @@ -3051,7 +3055,7 @@ void Mob::BuffProcess() } } -void Mob::DoBuffTic(uint16 spell_id, uint32 ticsremaining, uint8 caster_level, Mob* caster) { +void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caster_level, Mob* caster) { _ZP(Mob_DoBuffTic); int effect, effect_value; @@ -3066,14 +3070,22 @@ void Mob::DoBuffTic(uint16 spell_id, uint32 ticsremaining, uint8 caster_level, M if(IsNPC()) { - int i = parse->EventSpell(EVENT_SPELL_BUFF_TIC_NPC, CastToNPC(), nullptr, spell_id, caster ? caster->GetID() : 0); + std::vector args; + args.push_back(&ticsremaining); + args.push_back(&caster_level); + args.push_back(&slot); + int i = parse->EventSpell(EVENT_SPELL_BUFF_TIC_NPC, CastToNPC(), nullptr, spell_id, caster ? caster->GetID() : 0, &args); if(i != 0) { return; } } else { - int i = parse->EventSpell(EVENT_SPELL_BUFF_TIC_CLIENT, nullptr, CastToClient(), spell_id, caster ? caster->GetID() : 0); + std::vector args; + args.push_back(&ticsremaining); + args.push_back(&caster_level); + args.push_back(&slot); + int i = parse->EventSpell(EVENT_SPELL_BUFF_TIC_CLIENT, nullptr, CastToClient(), spell_id, caster ? caster->GetID() : 0, &args); if(i != 0) { return; } @@ -3334,9 +3346,15 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses) } if(IsClient()) { - parse->EventSpell(EVENT_SPELL_FADE, nullptr, CastToClient(), buffs[slot].spellid, slot); + std::vector args; + args.push_back(&buffs[slot].casterid); + + parse->EventSpell(EVENT_SPELL_FADE, nullptr, CastToClient(), buffs[slot].spellid, slot, &args); } else if(IsNPC()) { - parse->EventSpell(EVENT_SPELL_FADE, CastToNPC(), nullptr, buffs[slot].spellid, slot); + std::vector args; + args.push_back(&buffs[slot].casterid); + + parse->EventSpell(EVENT_SPELL_FADE, CastToNPC(), nullptr, buffs[slot].spellid, slot, &args); } for (int i=0; i < EFFECT_COUNT; i++) diff --git a/zone/spells.cpp b/zone/spells.cpp index d6f65a59d..28fca659d 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -5099,7 +5099,6 @@ void Client::InitializeBuffSlots() buffs[x].spellid = SPELL_UNKNOWN; } current_buff_count = 0; - buff_tic_timer = nullptr; } void Client::UninitializeBuffSlots() @@ -5116,7 +5115,6 @@ void NPC::InitializeBuffSlots() buffs[x].spellid = SPELL_UNKNOWN; } current_buff_count = 0; - buff_tic_timer = nullptr; } void NPC::UninitializeBuffSlots()