From 56b41c882bc3bf133e7b3cf1f6ae4344d388ed11 Mon Sep 17 00:00:00 2001 From: KimLS Date: Fri, 7 Jun 2013 02:26:17 -0700 Subject: [PATCH] Redoing event item api --- common/CMakeLists.txt | 2 + common/Item.cpp | 14 +++++ common/Item.h | 4 ++ common/callback_manager.cpp | 17 ++++++ common/callback_manager.h | 12 +++++ zone/QuestInterface.h | 6 +-- zone/QuestParserCollection.cpp | 57 ++++++++++---------- zone/QuestParserCollection.h | 6 +-- zone/bonuses.cpp | 8 +-- zone/client.cpp | 4 +- zone/client_packet.cpp | 10 ++-- zone/embparser.cpp | 58 ++++++--------------- zone/embparser.h | 6 +-- zone/inventory.cpp | 4 +- zone/lua_general.cpp | 49 +++--------------- zone/lua_parser.cpp | 95 ++++++++-------------------------- zone/lua_parser.h | 10 ++-- zone/net.cpp | 7 ++- zone/questmgr.cpp | 52 +++++++++++-------- zone/questmgr.h | 6 ++- 20 files changed, 192 insertions(+), 235 deletions(-) create mode 100644 common/callback_manager.cpp create mode 100644 common/callback_manager.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 1f613a885..4bb7df4dc 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -2,6 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(common_sources BasePacket.cpp + callback_manager.cpp classes.cpp Condition.cpp crash.cpp @@ -93,6 +94,7 @@ SET(common_headers BasePacket.h bodytypes.h breakdowns.h + callback_manager.h classes.h common_profile.h Condition.h diff --git a/common/Item.cpp b/common/Item.cpp index 3e798363e..5c302d77e 100644 --- a/common/Item.cpp +++ b/common/Item.cpp @@ -65,6 +65,7 @@ ItemInst::ItemInst(const Item_Struct* item, int16 charges) { m_color = 0; m_merchantcount = 1; m_SerialNumber = GetNextItemInstSerialNumber(); + m_on_destroy = GetEQCallback("OnItemInstDestroy"); } ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) { @@ -80,6 +81,7 @@ ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) { m_color = 0; m_merchantcount = 1; m_SerialNumber = GetNextItemInstSerialNumber(); + m_on_destroy = GetEQCallback("OnItemInstDestroy"); } ItemInstQueue::~ItemInstQueue() { @@ -170,11 +172,16 @@ ItemInst::ItemInst(const ItemInst& copy) } m_SerialNumber = copy.m_SerialNumber; m_custom_data = copy.m_custom_data; + m_on_destroy = copy.m_on_destroy; } // Clean up container contents ItemInst::~ItemInst() { + if(m_on_destroy) { + m_on_destroy(this); + } + Clear(); } @@ -1677,6 +1684,8 @@ EvoItemInst::EvoItemInst(const EvoItemInst ©) { m_scaledItem = new Item_Struct(*copy.m_scaledItem); else m_scaledItem = nullptr; + + m_on_destroy = GetEQCallback("OnItemInstDestroy"); } EvoItemInst::EvoItemInst(const ItemInst &basecopy) { @@ -1716,6 +1725,7 @@ EvoItemInst::EvoItemInst(const ItemInst &basecopy) { m_activated = false; m_evolveInfo = nullptr; m_scaledItem = nullptr; + m_on_destroy = copy->m_on_destroy; } EvoItemInst::EvoItemInst(const Item_Struct* item, int16 charges) { @@ -1736,9 +1746,13 @@ EvoItemInst::EvoItemInst(const Item_Struct* item, int16 charges) { m_activated = false; m_evolveInfo = nullptr; m_scaledItem = nullptr; + m_on_destroy = GetEQCallback("OnItemInstDestroy"); } EvoItemInst::~EvoItemInst() { + if(m_on_destroy) { + m_on_destroy(this); + } safe_delete(m_scaledItem); } diff --git a/common/Item.h b/common/Item.h index 6ddf32a73..16b53deab 100644 --- a/common/Item.h +++ b/common/Item.h @@ -37,6 +37,7 @@ class EvolveInfo; // Stores information about an evolving item family #include "../common/eq_packet_structs.h" #include "../common/eq_constants.h" #include "../common/item_struct.h" +#include "callback_manager.h" // Helper typedefs typedef std::list::const_iterator iter_queue; @@ -265,6 +266,8 @@ public: m_instnodrop = false; m_merchantslot = 0; m_color = 0; + + m_on_destroy = GetEQCallback("OnItemInstDestroy"); } ItemInst(const ItemInst& copy); @@ -404,6 +407,7 @@ protected: // Items inside of this item (augs or contents); std::map m_contents; // Zero-based index: min=0, max=9 std::map m_custom_data; + eqemu_callback m_on_destroy; }; class EvoItemInst: public ItemInst { diff --git a/common/callback_manager.cpp b/common/callback_manager.cpp new file mode 100644 index 000000000..f20c88578 --- /dev/null +++ b/common/callback_manager.cpp @@ -0,0 +1,17 @@ +#include +#include "callback_manager.h" + +std::map callback_functions; + +void RegisterEQCallback(std::string name, eqemu_callback func) { + callback_functions[name] = func; +} + +eqemu_callback GetEQCallback(std::string name) { + auto iter = callback_functions.find(name); + if(iter == callback_functions.end()) { + return nullptr; + } + + return iter->second; +} diff --git a/common/callback_manager.h b/common/callback_manager.h new file mode 100644 index 000000000..78ba7b301 --- /dev/null +++ b/common/callback_manager.h @@ -0,0 +1,12 @@ +#ifndef EQEMU_CALLBACK_MANAGER_H +#define EQEMU_CALLBACK_MANAGER_H + +#include +#include + +typedef std::function eqemu_callback; + +void RegisterEQCallback(std::string name, eqemu_callback func); +eqemu_callback GetEQCallback(std::string name); + +#endif diff --git a/zone/QuestInterface.h b/zone/QuestInterface.h index 037a65afe..46baa2f1a 100644 --- a/zone/QuestInterface.h +++ b/zone/QuestInterface.h @@ -34,7 +34,7 @@ public: std::vector *items) { return 0; } virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data) { return 0; } virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data) { return 0; } - virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data) { return 0; } + virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data) { return 0; } virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data) { return 0; } virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data) { return 0; } @@ -49,14 +49,14 @@ public: virtual void LoadGlobalNPCScript(std::string filename) { } virtual void LoadPlayerScript(std::string filename) { } virtual void LoadGlobalPlayerScript(std::string filename) { } - virtual void LoadItemScript(std::string filename, std::string item_script) { } + virtual void LoadItemScript(std::string filename, ItemInst *item) { } virtual void LoadSpellScript(std::string filename, uint32 spell_id) { } virtual void LoadEncounterScript(std::string filename, std::string encounter_name) { } virtual void DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *items) { } virtual void DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data) { } - virtual void DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data) { } + virtual void DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data) { } virtual void DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data) { } virtual void AddVar(std::string name, std::string val) { } diff --git a/zone/QuestParserCollection.cpp b/zone/QuestParserCollection.cpp index efdcafcaf..c2899031b 100644 --- a/zone/QuestParserCollection.cpp +++ b/zone/QuestParserCollection.cpp @@ -194,16 +194,17 @@ bool QuestParserCollection::SpellHasQuestSub(uint32 spell_id, const char *subnam bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, const char *subname) { std::string item_script; - if(strcmp("EVENT_SCALE_CALC", subname) == 0 || strcmp("EVENT_ITEM_ENTER_ZONE", subname) == 0) { - item_script = itm->GetItem()->CharmFile; - } else if(strcmp("EVENT_ITEM_CLICK", subname) == 0 || strcmp("EVENT_ITEM_CLICK_CAST", subname) == 0) { + if(itm->GetItem()->ScriptFileID != 0) { item_script = "script_"; - item_script += itoa(itm->GetItem()->ScriptFileID); + item_script += std::to_string(itm->GetItem()->ScriptFileID); + } else if(strlen(itm->GetItem()->CharmFile) > 0) { + item_script = itm->GetItem()->CharmFile; } else { - item_script += itoa(itm->GetItem()->ID); + item_script = std::to_string(itm->GetID()); } - std::map::iterator iter = _item_quest_status.find(item_script); + uint32 item_id = itm->GetID(); + std::map::iterator iter = _item_quest_status.find(item_id); if(iter != _item_quest_status.end()) { //loaded or failed to load if(iter->second != QuestFailedToLoad) { @@ -214,11 +215,11 @@ bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, const char *subname) std::string filename; QuestInterface *qi = GetQIByItemQuest(item_script, filename); if(qi) { - _item_quest_status[item_script] = qi->GetIdentifier(); - qi->LoadItemScript(filename, item_script); + _item_quest_status[item_id] = qi->GetIdentifier(); + qi->LoadItemScript(filename, itm); return qi->ItemHasQuestSub(itm, subname); } else { - _item_quest_status[item_script] = QuestFailedToLoad; + _item_quest_status[item_id] = QuestFailedToLoad; } } return false; @@ -333,39 +334,40 @@ int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, s return 0; } -int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data) { +int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data) { std::string item_script; - if(evt == EVENT_SCALE_CALC || evt == EVENT_ITEM_ENTER_ZONE) { - item_script = item->GetItem()->CharmFile; - } else if(evt == EVENT_ITEM_CLICK || evt == EVENT_ITEM_CLICK_CAST) { + if(item->GetItem()->ScriptFileID != 0) { item_script = "script_"; - item_script += itoa(item->GetItem()->ScriptFileID); + item_script += std::to_string(item->GetItem()->ScriptFileID); + } else if(strlen(item->GetItem()->CharmFile) > 0) { + item_script = item->GetItem()->CharmFile; } else { - item_script += itoa(item->GetItem()->ID); + item_script = std::to_string(item->GetID()); } - std::map::iterator iter = _item_quest_status.find(item_script); + uint32 item_id = item->GetID(); + std::map::iterator iter = _item_quest_status.find(item_id); if(iter != _item_quest_status.end()) { //loaded or failed to load if(iter->second != QuestFailedToLoad) { std::map::iterator qiter = _interfaces.find(iter->second); - auto ret = qiter->second->EventItem(evt, client, item, objid, extra_data); - DispatchEventItem(evt, client, item, objid, extra_data); + auto ret = qiter->second->EventItem(evt, client, item, mob, data, extra_data); + DispatchEventItem(evt, client, item, mob, data, extra_data); return ret; } - DispatchEventItem(evt, client, item, objid, extra_data); + DispatchEventItem(evt, client, item, mob, data, extra_data); } else { std::string filename; QuestInterface *qi = GetQIByItemQuest(item_script, filename); if(qi) { - _item_quest_status[item_script] = qi->GetIdentifier(); - qi->LoadItemScript(filename, item_script); - auto ret = qi->EventItem(evt, client, item, objid, extra_data); - DispatchEventItem(evt, client, item, objid, extra_data); + _item_quest_status[item_id] = qi->GetIdentifier(); + qi->LoadItemScript(filename, item); + auto ret = qi->EventItem(evt, client, item, mob, data, extra_data); + DispatchEventItem(evt, client, item, mob, data, extra_data); return ret; } else { - _item_quest_status[item_script] = QuestFailedToLoad; - DispatchEventItem(evt, client, item, objid, extra_data); + _item_quest_status[item_id] = QuestFailedToLoad; + DispatchEventItem(evt, client, item, mob, data, extra_data); } } return 0; @@ -869,10 +871,11 @@ void QuestParserCollection::DispatchEventPlayer(QuestEventID evt, Client *client } } -void QuestParserCollection::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data) { +void QuestParserCollection::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, + uint32 extra_data) { auto iter = _load_precedence.begin(); while(iter != _load_precedence.end()) { - (*iter)->DispatchEventItem(evt, client, item, objid, extra_data); + (*iter)->DispatchEventItem(evt, client, item, mob, data, extra_data); ++iter; } } diff --git a/zone/QuestParserCollection.h b/zone/QuestParserCollection.h index 1f3c4973d..11a1ed581 100644 --- a/zone/QuestParserCollection.h +++ b/zone/QuestParserCollection.h @@ -52,7 +52,7 @@ public: int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *items = nullptr); int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data); - int EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data); + int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data); int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data); int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data); @@ -79,7 +79,7 @@ private: void DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *items); void DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data); - void DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data); + void DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data); void DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data); std::map _interfaces; @@ -93,7 +93,7 @@ private: uint32 _player_quest_status; uint32 _global_player_quest_status; std::map _spell_quest_status; - std::map _item_quest_status; + std::map _item_quest_status; std::map _encounter_quest_status; }; diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 00af3ce65..29c99ab22 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -2443,9 +2443,9 @@ bool Client::CalcItemScale(uint32 slot_x, uint32 slot_y, bool login) uint16 oldexp = e_inst->GetExp(); if(login) { - parse->EventItem(EVENT_ITEM_ENTER_ZONE, this, e_inst, e_inst->GetID(), 0); + parse->EventItem(EVENT_ITEM_ENTER_ZONE, this, e_inst, nullptr, "", 0); } - parse->EventItem(EVENT_SCALE_CALC, this, e_inst, e_inst->GetID(), 0); + parse->EventItem(EVENT_SCALE_CALC, this, e_inst, nullptr, "", 0); if (e_inst->GetExp() != oldexp) { // if the scaling factor changed, rescale the item and update the client e_inst->ScaleItem(); @@ -2467,9 +2467,9 @@ bool Client::CalcItemScale(uint32 slot_x, uint32 slot_y, bool login) uint16 oldexp = e_inst->GetExp(); if(login) { - parse->EventItem(EVENT_ITEM_ENTER_ZONE, this, e_inst, e_inst->GetID(), 0); + parse->EventItem(EVENT_ITEM_ENTER_ZONE, this, e_inst, nullptr, "", 0); } - parse->EventItem(EVENT_SCALE_CALC, this, e_inst, e_inst->GetID(), 0); + parse->EventItem(EVENT_SCALE_CALC, this, e_inst, nullptr, "", 0); if (e_inst->GetExp() != oldexp) { diff --git a/zone/client.cpp b/zone/client.cpp index 5f0dceb5f..030bf77b4 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7697,7 +7697,7 @@ void Client::TryItemTick(int slot) if( GetLevel() >= zone->tick_items[iid].level && MakeRandomInt(0, 100) >= (100 - zone->tick_items[iid].chance) && (zone->tick_items[iid].bagslot || slot < 22) ) { ItemInst* e_inst = (ItemInst*)inst; - parse->EventItem(EVENT_ITEM_TICK, this, e_inst, e_inst->GetID(), slot); + parse->EventItem(EVENT_ITEM_TICK, this, e_inst, nullptr, "", slot); } } @@ -7716,7 +7716,7 @@ void Client::TryItemTick(int slot) if( GetLevel() >= zone->tick_items[iid].level && MakeRandomInt(0, 100) >= (100 - zone->tick_items[iid].chance) ) { ItemInst* e_inst = (ItemInst*)a_inst; - parse->EventItem(EVENT_ITEM_TICK, this, e_inst, e_inst->GetID(), slot); + parse->EventItem(EVENT_ITEM_TICK, this, e_inst, nullptr, "", slot); } } } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 08dbbc808..af7cda6d5 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -2059,7 +2059,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) { ItemInst* p_inst = (ItemInst*)inst; - int i = parse->EventItem(EVENT_ITEM_CLICK, this, p_inst, p_inst->GetID(), slot_id); + int i = parse->EventItem(EVENT_ITEM_CLICK, this, p_inst, nullptr, "", slot_id); inst = m_inv[slot_id]; if(!inst) { @@ -2114,7 +2114,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) } if(GetLevel() >= item->Click.Level2) { - int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, p_inst->GetID(), slot_id); + int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", slot_id); inst = m_inv[slot_id]; if(!inst) { @@ -2141,7 +2141,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) } if(GetLevel() >= augitem->Click.Level2) { - int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, clickaug, clickaug->GetID(), slot_id); + int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, clickaug, nullptr, "", slot_id); inst = m_inv[slot_id]; if(!inst) { @@ -4595,7 +4595,7 @@ LogFile->write(EQEMuLog::Debug, "OP CastSpell: slot=%d, spell=%d, target=%d, inv if(GetLevel() >= item->Click.Level2) { ItemInst* p_inst = (ItemInst*)inst; - int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, p_inst->GetID(), castspell->inventoryslot); + int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", castspell->inventoryslot); if(i != 0) { CastSpell(item->Click.Effect, castspell->target_id, castspell->slot, item->CastTime, 0, 0, castspell->inventoryslot); @@ -4614,7 +4614,7 @@ LogFile->write(EQEMuLog::Debug, "OP CastSpell: slot=%d, spell=%d, target=%d, inv else { ItemInst* p_inst = (ItemInst*)inst; - int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, p_inst->GetID(), castspell->inventoryslot); + int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", castspell->inventoryslot); if(i != 0) { CastSpell(item->Click.Effect, castspell->target_id, castspell->slot, item->CastTime, 0, 0, castspell->inventoryslot); diff --git a/zone/embparser.cpp b/zone/embparser.cpp index c50c90872..07fbb587b 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -225,8 +225,8 @@ int PerlembParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::stri return 0; } -int PerlembParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data) { - EventCommon(evt, objid, nullptr, nullptr, item, client, extra_data, false, nullptr); +int PerlembParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data) { + EventCommon(evt, item->GetID(), nullptr, nullptr, item, client, extra_data, false, nullptr); return 0; } @@ -300,30 +300,12 @@ bool PerlembParser::SpellHasQuestSub(uint32 spell_id, const char *subname) { bool PerlembParser::ItemHasQuestSub(ItemInst *itm, const char *subname) { std::stringstream package_name; - package_name << "qst_item_"; - - std::string item_name; - const Item_Struct* item = itm->GetItem(); - if(strcmp("EVENT_SCALE_CALC", subname) == 0 || strcmp("EVENT_ITEM_ENTER_ZONE", subname) == 0) - { - item_name = item->CharmFile; - } - else if(strcmp("EVENT_ITEM_CLICK", subname) == 0 || strcmp("EVENT_ITEM_CLICK_CAST", subname) == 0 ) - { - item_name = "script_"; - item_name += itoa(item->ScriptFileID); - } - else - { - item_name += itoa(item->ID); - } - - package_name << item_name; + package_name << "qst_item_" << itm->GetID(); if(!perl) return false; - auto iter = item_quest_status_.find(item_name); + auto iter = item_quest_status_.find(itm->GetID()); if(iter == item_quest_status_.end() || iter->second == QuestFailedToLoad) { return false; } @@ -439,34 +421,34 @@ void PerlembParser::LoadGlobalPlayerScript(std::string filename) { global_player_quest_status_ = questLoaded; } -void PerlembParser::LoadItemScript(std::string filename, std::string item_script) { +void PerlembParser::LoadItemScript(std::string filename, ItemInst *item) { std::stringstream package_name; - package_name << "qst_item_" << item_script; - + package_name << "qst_item_" << item->GetID(); + if(!perl) return; - + if(perl->InUse()) { return; } - - auto iter = item_quest_status_.find(item_script); + + auto iter = item_quest_status_.find(item->GetID()); if(iter != item_quest_status_.end()) { return; } - + try { perl->eval_file(package_name.str().c_str(), filename.c_str()); } catch(const char *err) { LogFile->write(EQEMuLog::Quest, "WARNING: error compiling quest file %s: %s", filename.c_str(), err); - item_quest_status_[item_script] = questFailedToLoad; + item_quest_status_[item->GetID()] = questFailedToLoad; return; } - - item_quest_status_[item_script] = questLoaded; + + item_quest_status_[item->GetID()] = questLoaded; } void PerlembParser::LoadSpellScript(std::string filename, uint32 spell_id) { @@ -810,17 +792,7 @@ void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlaye else if(isItemQuest) { const Item_Struct* item = iteminst->GetItem(); package_name = "qst_item_"; - - if (event == EVENT_SCALE_CALC || event == EVENT_ITEM_ENTER_ZONE) { - package_name += item->CharmFile; - } - else if (event == EVENT_ITEM_CLICK || event == EVENT_ITEM_CLICK_CAST) { - package_name += "script_"; - package_name += itoa(item->ScriptFileID); - } - else { - package_name += itoa(objid); - } + package_name += itoa(item->ID); } else if(isPlayerQuest) { package_name = "qst_player"; diff --git a/zone/embparser.h b/zone/embparser.h index 2eb00eb02..cd52fe9c0 100644 --- a/zone/embparser.h +++ b/zone/embparser.h @@ -62,7 +62,7 @@ public: std::vector *items); virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data); virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data); - virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data); + virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data); virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data); virtual bool HasQuestSub(uint32 npcid, const char *subname); @@ -76,7 +76,7 @@ public: virtual void LoadGlobalNPCScript(std::string filename); virtual void LoadPlayerScript(std::string filename); virtual void LoadGlobalPlayerScript(std::string filename); - virtual void LoadItemScript(std::string filename, std::string item_script); + virtual void LoadItemScript(std::string filename, ItemInst *item); virtual void LoadSpellScript(std::string filename, uint32 spell_id); virtual void AddVar(std::string name, std::string val); @@ -121,7 +121,7 @@ private: PerlQuestStatus global_npc_quest_status_; PerlQuestStatus player_quest_status_; PerlQuestStatus global_player_quest_status_; - std::map item_quest_status_; + std::map item_quest_status_; std::map spell_quest_status_; bool event_queue_in_use_; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 63b60149e..2a7cd11db 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -330,7 +330,7 @@ void Client::DropItem(int16 slot_id) // Take control of item in client inventory ItemInst *inst = m_inv.PopItem(slot_id); if(inst) { - int i = parse->EventItem(EVENT_DROP_ITEM, this, inst, 0, 0); + int i = parse->EventItem(EVENT_DROP_ITEM, this, inst, nullptr, "", 0); if(i != 0) { safe_delete(inst); return; @@ -1014,7 +1014,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { ItemInst *inst = m_inv.GetItem(SLOT_CURSOR); if(inst) { - parse->EventItem(EVENT_DESTROY_ITEM, this, inst, 0, 0); + parse->EventItem(EVENT_DESTROY_ITEM, this, inst, nullptr, "", 0); } DeleteItemInInventory(move_in->from_slot); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 091a777e4..58babfa69 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -112,29 +112,11 @@ void register_item_event(std::string name, int evt, Lua_Item item, luabind::obje return; } - std::stringstream package_name; - package_name << "item_"; + std::string package_name = "item_"; + package_name += std::to_string(itm->ID); - std::stringstream item_name; - if(EVENT_SCALE_CALC == evt || EVENT_ITEM_ENTER_ZONE == evt) - { - item_name << itm->CharmFile; - } - else if(EVENT_ITEM_CLICK == evt || EVENT_ITEM_CLICK_CAST == evt) - { - item_name << "script_"; - item_name << itm->ScriptFileID; - } - else - { - item_name << "item_"; - item_name << itm->ID; - } - - package_name << item_name; - if(luabind::type(func) == LUA_TFUNCTION) { - register_event(package_name.str(), name, evt, func); + register_event(package_name, name, evt, func); } } @@ -144,27 +126,10 @@ void unregister_item_event(std::string name, int evt, Lua_Item item) { return; } - std::stringstream package_name; - package_name << "item_"; - - std::stringstream item_name; - if(EVENT_SCALE_CALC == evt || EVENT_ITEM_ENTER_ZONE == evt) - { - item_name << itm->CharmFile; - } - else if(EVENT_ITEM_CLICK == evt || EVENT_ITEM_CLICK_CAST == evt) - { - item_name << "script_"; - item_name << itm->ScriptFileID; - } - else - { - item_name << "item_"; - item_name << itm->ID; - } - - package_name << item_name; - unregister_event(package_name.str(), name, evt); + std::string package_name = "item_"; + package_name += std::to_string(itm->ID); + + unregister_event(package_name, name, evt); } void register_spell_event(std::string name, int evt, int spell_id, luabind::object func) { diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 09b8d2147..f2611a08b 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -366,43 +366,26 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client * return 0; } -int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data) { +int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data) { if(evt >= _LargestEventID) { return 0; } - + if(!item) { return 0; } - + if(!ItemHasQuestSub(item, LuaEvents[evt])) { return 0; } - + std::string package_name = "item_"; - - std::stringstream item_name; - const Item_Struct* itm = item->GetItem(); - if(evt == EVENT_SCALE_CALC || evt == EVENT_ITEM_ENTER_ZONE) - { - item_name << itm->CharmFile; - } - else if(evt == EVENT_ITEM_CLICK || evt == EVENT_ITEM_CLICK_CAST) - { - item_name << "script_"; - item_name << itm->ScriptFileID; - } - else - { - item_name << itm->ID; - } - package_name += item_name.str(); - - return _EventItem(package_name, evt, client, item, objid, extra_data); + package_name += std::to_string(item->GetID()); + return _EventItem(package_name, evt, client, item, mob, data, extra_data); } -int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data, - luabind::object *l_func) { +int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, Mob *mob, + std::string data, uint32 extra_data, luabind::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -428,8 +411,9 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl l_client_o.push(L); lua_setfield(L, -2, "owner"); + //redo this arg function auto arg_function = ItemArgumentDispatch[evt]; - arg_function(this, L, client, item, objid, extra_data); + arg_function(this, L, client, item, 0, extra_data); quest_manager.StartQuest(nullptr, client, item); if(lua_pcall(L, 1, 1, 0)) { @@ -630,24 +614,8 @@ bool LuaParser::SpellHasQuestSub(uint32 spell_id, const char *subname) { bool LuaParser::ItemHasQuestSub(ItemInst *itm, const char *subname) { std::string package_name = "item_"; + package_name += std::to_string(itm->GetID()); - std::stringstream item_name; - const Item_Struct* item = itm->GetItem(); - if(strcmp("EVENT_SCALE_CALC", subname) == 0 || strcmp("EVENT_ITEM_ENTER_ZONE", subname) == 0) - { - item_name << item->CharmFile; - } - else if(strcmp("EVENT_ITEM_CLICK", subname) == 0 || strcmp("EVENT_ITEM_CLICK_CAST", subname) == 0 ) - { - item_name << "script_"; - item_name << item->ScriptFileID; - } - else - { - item_name << item->ID; - } - - package_name += item_name.str(); return HasFunction(subname, package_name); } @@ -676,11 +644,11 @@ void LuaParser::LoadGlobalPlayerScript(std::string filename) { LoadScript(filename, "global_player"); } -void LuaParser::LoadItemScript(std::string filename, std::string item_script) { - std::stringstream package_name; - package_name << "item_" << item_script; +void LuaParser::LoadItemScript(std::string filename, ItemInst *item) { + std::string package_name = "item_"; + package_name += std::to_string(item->GetID()); - LoadScript(filename, package_name.str()); + LoadScript(filename, package_name); } void LuaParser::LoadSpellScript(std::string filename, uint32 spell_id) { @@ -914,40 +882,23 @@ void LuaParser::DispatchEventPlayer(QuestEventID evt, Client *client, std::strin } } -void LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data) { +void LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data) { if(!item) return; - - std::stringstream package_name; - package_name << "item_"; - - std::stringstream item_name; - const Item_Struct* itm = item->GetItem(); - if(evt == EVENT_SCALE_CALC || evt == EVENT_ITEM_ENTER_ZONE) - { - item_name << itm->CharmFile; - } - else if(evt == EVENT_ITEM_CLICK || evt == EVENT_ITEM_CLICK_CAST) - { - item_name << "script_"; - item_name << itm->ScriptFileID; - } - else - { - item_name << itm->ID; - } - package_name << item_name; - - auto iter = lua_encounter_events_registered.find(package_name.str()); + + std::string package_name = "item_"; + package_name += std::to_string(item->GetID()); + + auto iter = lua_encounter_events_registered.find(package_name); if(iter == lua_encounter_events_registered.end()) { return; } - + auto riter = iter->second.begin(); while(riter != iter->second.end()) { if(riter->event_id == evt) { std::string package_name = "encounter_" + riter->encounter_name; - _EventItem(package_name, evt, client, item, objid, extra_data, &riter->lua_reference); + _EventItem(package_name, evt, client, item, mob, data, extra_data, &riter->lua_reference); } ++riter; } diff --git a/zone/lua_parser.h b/zone/lua_parser.h index e734802bd..3f22a5aea 100644 --- a/zone/lua_parser.h +++ b/zone/lua_parser.h @@ -31,7 +31,7 @@ public: std::vector *items); virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data); virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data); - virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data); + virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data); virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data); virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data); @@ -47,7 +47,7 @@ public: virtual void LoadGlobalNPCScript(std::string filename); virtual void LoadPlayerScript(std::string filename); virtual void LoadGlobalPlayerScript(std::string filename); - virtual void LoadItemScript(std::string filename, std::string item_script); + virtual void LoadItemScript(std::string filename, ItemInst *item); virtual void LoadSpellScript(std::string filename, uint32 spell_id); virtual void LoadEncounterScript(std::string filename, std::string encounter_name); @@ -60,7 +60,7 @@ public: virtual void DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *items); virtual void DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data); - virtual void DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data); + virtual void DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data); virtual void DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data); private: @@ -68,8 +68,8 @@ private: std::vector *items, luabind::object *l_func = nullptr); int _EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data, luabind::object *l_func = nullptr); - int _EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, uint32 objid, uint32 extra_data, - luabind::object *l_func = nullptr); + int _EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, + uint32 extra_data, luabind::object *l_func = nullptr); int _EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, luabind::object *l_func = nullptr); int _EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data); diff --git a/zone/net.cpp b/zone/net.cpp index 60d529b50..56e44383c 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -42,6 +42,7 @@ #include "../common/memory_mapped_file.h" #include "../common/eqemu_exception.h" #include "../common/spdat.h" +#include "../common/callback_manager.h" #include "ZoneConfig.h" #include "masterentity.h" @@ -85,8 +86,6 @@ volatile bool RunLoops = true; extern volatile bool ZoneLoaded; - - TimeoutManager timeout_manager; NetConnection net; EntityList entity_list; @@ -290,6 +289,10 @@ int main(int argc, char** argv) { parse->RegisterQuestInterface(perl_parser, "pl"); #endif + RegisterEQCallback("OnItemInstDestroy", [](void* item) { + quest_manager.stop_item_timers(reinterpret_cast(item)); + }); + //now we have our parser, load the quests _log(ZONE__INIT, "Loading quests"); parse->ReloadQuests(); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index a472a3209..5a3caf40b 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -107,6 +107,7 @@ QuestManager quest_manager; QuestManager::QuestManager() { HaveProximitySays = false; + item_timers = 0; } QuestManager::~QuestManager() { @@ -118,8 +119,13 @@ void QuestManager::Process() { end = QTimerList.end(); while (cur != end) { if (cur->Timer_.Enabled() && cur->Timer_.Check()) { - //make sure the mob is still in zone. - if(entity_list.IsMobInZone(cur->mob)){ + + if(cur->item) { + parse->EventItem(EVENT_TIMER, cur->mob->CastToClient(), cur->item, nullptr, cur->name, 0); + + cur = QTimerList.begin(); + end = QTimerList.end(); + } else if(entity_list.IsMobInZone(cur->mob)) { if(cur->mob->IsNPC()) { parse->EventNPC(EVENT_TIMER, cur->mob->CastToNPC(), nullptr, cur->name, 0); } @@ -188,17 +194,7 @@ void QuestManager::EndQuest() { } void QuestManager::ClearAllTimers() { - - std::list::iterator cur = QTimerList.begin(), end, tmp; - - end = QTimerList.end(); - while (cur != end) - { - tmp = cur; - tmp++; - QTimerList.erase(cur); - cur = tmp; - } + QTimerList.clear(); } //quest perl functions @@ -461,17 +457,16 @@ void QuestManager::settimer(const char *timer_name, int seconds) { end = QTimerList.end(); while (cur != end) { - if (cur->mob == owner && cur->name == timer_name) { + if (cur->mob == owner && cur->item == questitem && cur->name == timer_name) { cur->mob = owner; cur->Timer_.Enable(); cur->Timer_.Start(seconds * 1000, false); - printf("Resetting: %s for %d seconds\n", cur->name.c_str(), seconds); return; } cur++; } - QTimerList.push_back(QuestTimer(seconds * 1000, owner, timer_name)); + QTimerList.push_back(QuestTimer(seconds * 1000, owner, questitem, timer_name)); } void QuestManager::settimerMS(const char *timer_name, int milliseconds) { @@ -481,17 +476,16 @@ void QuestManager::settimerMS(const char *timer_name, int milliseconds) { end = QTimerList.end(); while (cur != end) { - if (cur->mob == owner && cur->name == timer_name) { + if (cur->mob == owner && cur->item == questitem && cur->name == timer_name) { cur->mob = owner; cur->Timer_.Enable(); cur->Timer_.Start(milliseconds, false); - printf("Resetting: %s for %d seconds\n", cur->name.c_str(), milliseconds); return; } cur++; } - QTimerList.push_back(QuestTimer(milliseconds, owner, timer_name)); + QTimerList.push_back(QuestTimer(milliseconds, owner, questitem, timer_name)); } void QuestManager::stoptimer(const char *timer_name) { @@ -502,7 +496,7 @@ void QuestManager::stoptimer(const char *timer_name) { end = QTimerList.end(); while (cur != end) { - if(cur->mob == owner && cur->name == timer_name) + if(cur->mob == owner && cur->item == questitem && cur->name == timer_name) { QTimerList.erase(cur); return; @@ -519,7 +513,7 @@ void QuestManager::stopalltimers() { end = QTimerList.end(); while (cur != end) { - if(cur->mob == owner) + if(cur->mob == owner && cur->item == questitem) { tmp = cur; tmp++; @@ -2905,3 +2899,19 @@ ItemInst *QuestManager::GetQuestItem() const { return nullptr; } + +void QuestManager::stop_item_timers(ItemInst *item) { + if(item_timers == 0) + return; + + auto iter = QTimerList.begin(); + while(iter != QTimerList.end()) { + if(iter->item == item) { + iter = QTimerList.erase(iter); + --item_timers; + continue; + } + + ++iter; + } +} diff --git a/zone/questmgr.h b/zone/questmgr.h index 801aa97d0..c5a426b23 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -237,6 +237,7 @@ public: Mob *GetOwner() const; ItemInst *GetQuestItem() const; inline bool ProximitySayInUse() { return HaveProximitySays; } + void stop_item_timers(ItemInst *item); #ifdef BOTS int createbotcount(); @@ -257,8 +258,10 @@ private: class QuestTimer { public: - inline QuestTimer(int duration, Mob *_mob, std::string _name) : mob(_mob), name(_name), Timer_(duration) { Timer_.Start(duration, false); } + inline QuestTimer(int duration, Mob *_mob, ItemInst *_item, std::string _name) + : mob(_mob), item(_item), name(_name), Timer_(duration) { Timer_.Start(duration, false); } Mob* mob; + ItemInst *item; std::string name; Timer Timer_; }; @@ -271,6 +274,7 @@ private: }; std::list QTimerList; std::list STimerList; + size_t item_timers; };