diff --git a/zone/QuestInterface.h b/zone/QuestInterface.h index a1ccd7b64..037a65afe 100644 --- a/zone/QuestInterface.h +++ b/zone/QuestInterface.h @@ -28,8 +28,10 @@ class NPC; class QuestInterface { public: - virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { return 0; } - virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { return 0; } + virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { return 0; } + virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + 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; } @@ -51,7 +53,8 @@ public: 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) { } + 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 DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data) { } diff --git a/zone/QuestParserCollection.cpp b/zone/QuestParserCollection.cpp index 614d397f6..bee3c735d 100644 --- a/zone/QuestParserCollection.cpp +++ b/zone/QuestParserCollection.cpp @@ -224,10 +224,11 @@ bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, const char *subname) return false; } -int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std::string data, uint32 extra_data) { - int rl = EventNPCLocal(evt, npc, init, data, extra_data); - int rg = EventNPCGlobal(evt, npc, init, data, extra_data); - DispatchEventNPC(evt, npc, init, data, extra_data); +int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { + int rl = EventNPCLocal(evt, npc, init, data, extra_data, items); + int rg = EventNPCGlobal(evt, npc, init, data, extra_data, items); + DispatchEventNPC(evt, npc, init, data, extra_data, items); //Local quests returning non-default values have priority over global quests if(rl != 0) { @@ -239,13 +240,14 @@ int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std:: return 0; } -int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { std::map::iterator iter = _npc_quest_status.find(npc->GetNPCTypeID()); if(iter != _npc_quest_status.end()) { //loaded or failed to load if(iter->second != QuestFailedToLoad) { std::map::iterator qiter = _interfaces.find(iter->second); - return qiter->second->EventNPC(evt, npc, init, data, extra_data); + return qiter->second->EventNPC(evt, npc, init, data, extra_data, items); } } else { std::string filename; @@ -253,7 +255,7 @@ int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, if(qi) { _npc_quest_status[npc->GetNPCTypeID()] = qi->GetIdentifier(); qi->LoadNPCScript(filename, npc->GetNPCTypeID()); - return qi->EventNPC(evt, npc, init, data, extra_data); + return qi->EventNPC(evt, npc, init, data, extra_data, items); } else { _npc_quest_status[npc->GetNPCTypeID()] = QuestFailedToLoad; } @@ -261,17 +263,18 @@ int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, return 0; } -int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { if(_global_npc_quest_status != QuestUnloaded && _global_npc_quest_status != QuestFailedToLoad) { std::map::iterator qiter = _interfaces.find(_global_npc_quest_status); - return qiter->second->EventGlobalNPC(evt, npc, init, data, extra_data); + return qiter->second->EventGlobalNPC(evt, npc, init, data, extra_data, items); } else { std::string filename; QuestInterface *qi = GetQIByGlobalNPCQuest(filename); if(qi) { _global_npc_quest_status = qi->GetIdentifier(); qi->LoadGlobalNPCScript(filename); - return qi->EventGlobalNPC(evt, npc, init, data, extra_data); + return qi->EventGlobalNPC(evt, npc, init, data, extra_data, items); } else { _global_npc_quest_status = QuestFailedToLoad; } @@ -849,10 +852,11 @@ void QuestParserCollection::GetErrors(std::list &err) { } } -void QuestParserCollection::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void QuestParserCollection::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { auto iter = _load_precedence.begin(); while(iter != _load_precedence.end()) { - (*iter)->DispatchEventNPC(evt, npc, init, data, extra_data); + (*iter)->DispatchEventNPC(evt, npc, init, data, extra_data, items); ++iter; } } diff --git a/zone/QuestParserCollection.h b/zone/QuestParserCollection.h index ffafafb3c..1f3c4973d 100644 --- a/zone/QuestParserCollection.h +++ b/zone/QuestParserCollection.h @@ -49,7 +49,8 @@ public: bool SpellHasQuestSub(uint32 spell_id, const char *subname); bool ItemHasQuestSub(ItemInst *itm, const char *subname); - int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data); + 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 EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data); @@ -63,8 +64,8 @@ private: bool PlayerHasQuestSubLocal(const char *subname); bool PlayerHasQuestSubGlobal(const char *subname); - int EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data); - int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data); + int EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *items); + int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *items); int EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data); int EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data); @@ -76,7 +77,7 @@ private: QuestInterface *GetQIByItemQuest(std::string item_script, std::string &filename); QuestInterface *GetQIByEncounterQuest(std::string encounter_name, std::string &filename); - void DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data); + 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 DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data); diff --git a/zone/client.cpp b/zone/client.cpp index 3827cbda7..f0ce91056 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -1029,17 +1029,18 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s case 8: { // /say if(message[0] == COMMAND_CHAR) { if(command_dispatch(this, message) == -2) { - //LUA_TODO: fix this with something like event_command - //if(RuleB(Chat, FlowCommandstoPerl_EVENT_SAY)) { - // if(parse->PlayerHasQuestSub("EVENT_SAY")) { - // parse->EventPlayer(EVENT_SAY, this, message, language); - // } - //} else { - this->Message(13, "Command '%s' not recognized.", message); - //} + if(parse->PlayerHasQuestSub("EVENT_COMMAND")) { + int i = parse->EventPlayer(EVENT_COMMAND, this, message, 0); + if(i != 0) { + Message(13, "Command '%s' not recognized.", message); + } + } else { + Message(13, "Command '%s' not recognized.", message); + } } break; } + Mob* sender = this; if (GetPet() && GetPet()->FindType(SE_VoiceGraft)) sender = GetPet(); diff --git a/zone/command.cpp b/zone/command.cpp index 0dafbff58..93698fca0 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -490,13 +490,7 @@ int command_init(void) { */ void command_deinit(void) { -/* LinkedListIterator cur(cleanup_commandlist); - while(cur.MoreElements()) { - CommandRecord *tmp = cur.GetData(); - safe_delete(tmp); - cur.Advance(); - } -*/ commandlist.clear(); + commandlist.clear(); command_dispatch = command_notavail; commandcount = 0; diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 1c5df639f..dd378b106 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -67,14 +67,14 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_POPUP_RESPONSE", "EVENT_PROXIMITY_SAY", "EVENT_CAST", + "EVENT_CAST_BEGIN", "EVENT_SCALE_CALC", "EVENT_ITEM_ENTER_ZONE", "EVENT_TARGET_CHANGE", "EVENT_HATE_LIST", - "EVENT_SPELL_EFFECT_CLIENT", - "EVENT_SPELL_EFFECT_NPC", - "EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT", - "EVENT_SPELL_EFFECT_BUFF_TIC_NPC", + "EVENT_SPELL_EFFECT", + "EVENT_SPELL_BUFF_TIC", + "EVENT_SPELL_FADE", "EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE", "EVENT_COMBINE_SUCCESS", "EVENT_COMBINE_FAILURE", @@ -94,7 +94,8 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_DUEL_WIN", "EVENT_DUEL_LOSE", "EVENT_ENCOUNTER_LOAD", - "EVENT_ENCOUNTER_UNLOAD" + "EVENT_ENCOUNTER_UNLOAD", + "EVENT_COMMAND" }; PerlembParser::PerlembParser() : perl(nullptr), event_queue_in_use_(false) { @@ -136,7 +137,7 @@ void PerlembParser::ReloadQuests() { } void PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob, - uint32 extradata, bool global) + uint32 extradata, bool global, std::vector *items) { if(!perl) return; @@ -145,7 +146,7 @@ void PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * d return; if(perl->InUse()) { - AddQueueEvent(event, objid, data, npcmob, iteminst, mob, extradata, global); + AddQueueEvent(event, objid, data, npcmob, iteminst, mob, extradata, global, items); return; } @@ -176,7 +177,7 @@ void PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * d package_name, mob, npcmob); ExportZoneVariables(package_name); ExportItemVariables(package_name, mob); - ExportEventVariables(package_name, event, objid, data, npcmob, iteminst, mob, extradata); + ExportEventVariables(package_name, event, objid, data, npcmob, iteminst, mob, extradata, items); if(isPlayerQuest || isGlobalPlayerQuest){ SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr); @@ -199,33 +200,35 @@ void PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * d HandleQueue(); } -int PerlembParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { - EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, false); +int PerlembParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { + EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, false, items); return 0; } -int PerlembParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { - EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, true); +int PerlembParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { + EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, true, nullptr); return 0; } int PerlembParser::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data) { - EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, false); + EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, false, nullptr); return 0; } int PerlembParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data) { - EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, true); + EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, true, nullptr); 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); + EventCommon(evt, objid, nullptr, nullptr, item, client, extra_data, false, nullptr); return 0; } int PerlembParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data) { - EventCommon(evt, 0, itoa(spell_id), npc, nullptr, client, extra_data, false); + EventCommon(evt, 0, itoa(spell_id), npc, nullptr, client, extra_data, false, nullptr); return 0; } @@ -731,14 +734,18 @@ void PerlembParser::HandleQueue() { EventRecord e = event_queue_.front(); event_queue_.pop(); - EventCommon(e.event, e.objid, e.data.c_str(), e.npcmob, e.iteminst, e.mob, e.extradata, e.global); + EventCommon(e.event, e.objid, e.data.c_str(), e.npcmob, e.iteminst, e.mob, e.extradata, e.global, &e.items); + + for(size_t i = 0; i < e.items.size(); ++i) { + delete e.items[i]; + } } event_queue_in_use_ = false; } void PerlembParser::AddQueueEvent(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob, - uint32 extradata, bool global) + uint32 extradata, bool global, std::vector *items) { EventRecord e; e.event = event; @@ -749,16 +756,22 @@ void PerlembParser::AddQueueEvent(QuestEventID event, uint32 objid, const char * e.mob = mob; e.extradata = extradata; e.global = global; + + if(items) { + for(size_t i = 0; i < items->size(); ++i) { + e.items.push_back(items->at(i)->Clone()); + } + } + event_queue_.push(e); } void PerlembParser::GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest, bool &isSpellQuest, QuestEventID event, NPC* npcmob, ItemInst* iteminst, Mob* mob, bool global) { - if(event == EVENT_SPELL_EFFECT_CLIENT || - event == EVENT_SPELL_EFFECT_NPC || - event == EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT || - event == EVENT_SPELL_EFFECT_BUFF_TIC_NPC || + if(event == EVENT_SPELL_EFFECT || + event == EVENT_SPELL_BUFF_TIC || + event == EVENT_SPELL_FADE || event == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE) { isSpellQuest = true; @@ -1063,7 +1076,7 @@ void PerlembParser::ExportItemVariables(std::string &package_name, Mob *mob) { #undef HASITEM_ISNULLITEM void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data, - NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata) + NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector *items) { switch (event) { case EVENT_SAY: { @@ -1078,19 +1091,36 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID } case EVENT_TRADE: { - //this is such a hack... why aren't these just set directly.. - ExportVar(package_name.c_str(), "item1", GetVar("item1." + std::string(itoa(objid))).c_str()); - ExportVar(package_name.c_str(), "item2", GetVar("item2." + std::string(itoa(objid))).c_str()); - ExportVar(package_name.c_str(), "item3", GetVar("item3." + std::string(itoa(objid))).c_str()); - ExportVar(package_name.c_str(), "item4", GetVar("item4." + std::string(itoa(objid))).c_str()); - ExportVar(package_name.c_str(), "item1_charges", GetVar("item1.charges." + std::string(itoa(objid))).c_str()); - ExportVar(package_name.c_str(), "item2_charges", GetVar("item2.charges." + std::string(itoa(objid))).c_str()); - ExportVar(package_name.c_str(), "item3_charges", GetVar("item3.charges." + std::string(itoa(objid))).c_str()); - ExportVar(package_name.c_str(), "item4_charges", GetVar("item4.charges." + std::string(itoa(objid))).c_str()); - ExportVar(package_name.c_str(), "item1_attuned", GetVar("item1.attuned." + std::string(itoa(objid))).c_str()); - ExportVar(package_name.c_str(), "item2_attuned", GetVar("item2.attuned." + std::string(itoa(objid))).c_str()); - ExportVar(package_name.c_str(), "item3_attuned", GetVar("item3.attuned." + std::string(itoa(objid))).c_str()); - ExportVar(package_name.c_str(), "item4_attuned", GetVar("item4.attuned." + std::string(itoa(objid))).c_str()); + if(items) { + for(size_t i = 0; i < items->size(); ++i) { + ItemInst *inst = items->at(i); + std::string var_name = "item"; + var_name += std::to_string(i + 1); + + if(inst) { + ExportVar(package_name.c_str(), var_name.c_str(), inst->GetItem()->ID); + + std::string temp_var_name = var_name; + temp_var_name += "_charges"; + ExportVar(package_name.c_str(), temp_var_name.c_str(), inst->GetCharges()); + + temp_var_name = var_name; + temp_var_name += "_attuned"; + ExportVar(package_name.c_str(), temp_var_name.c_str(), inst->IsInstNoDrop()); + } else { + ExportVar(package_name.c_str(), var_name.c_str(), 0); + + std::string temp_var_name = var_name; + temp_var_name += "_charges"; + ExportVar(package_name.c_str(), temp_var_name.c_str(), 0); + + temp_var_name = var_name; + temp_var_name += "_attuned"; + ExportVar(package_name.c_str(), temp_var_name.c_str(), 0); + } + } + } + ExportVar(package_name.c_str(), "copper", GetVar("copper." + std::string(itoa(objid))).c_str()); ExportVar(package_name.c_str(), "silver", GetVar("silver." + std::string(itoa(objid))).c_str()); ExportVar(package_name.c_str(), "gold", GetVar("gold." + std::string(itoa(objid))).c_str()); @@ -1163,7 +1193,8 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID } case EVENT_CAST_ON: - case EVENT_CAST:{ + case EVENT_CAST: + case EVENT_CAST_BEGIN: { ExportVar(package_name.c_str(), "spell_id", data); break; } @@ -1248,10 +1279,8 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID break; } - case EVENT_SPELL_EFFECT_CLIENT: - case EVENT_SPELL_EFFECT_NPC: - case EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT: - case EVENT_SPELL_EFFECT_BUFF_TIC_NPC: + case EVENT_SPELL_EFFECT: + case EVENT_SPELL_BUFF_TIC: { ExportVar(package_name.c_str(), "caster_id", extradata); break; @@ -1286,6 +1315,11 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID break; } + case EVENT_COMMAND: { + ExportVar(package_name.c_str(), "message", data); + break; + } + default: { break; } diff --git a/zone/embparser.h b/zone/embparser.h index bc38d4076..2eb00eb02 100644 --- a/zone/embparser.h +++ b/zone/embparser.h @@ -49,14 +49,17 @@ class PerlembParser : public QuestInterface { Mob* mob; uint32 extradata; bool global; + std::vector items; } EventRecord; public: PerlembParser(); ~PerlembParser(); - virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data); - virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data); + virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); + virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + 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); @@ -91,13 +94,13 @@ private: void ExportVarComplex(const char *pkgprefix, const char *varname, const char *value) const; void EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob, - uint32 extradata, bool global); + uint32 extradata, bool global, std::vector *items); void SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst* iteminst); void MapFunctions(); void HandleQueue(); void AddQueueEvent(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob, - uint32 extradata, bool global); + uint32 extradata, bool global, std::vector *items); void GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest, bool &isSpellQuest, QuestEventID event, NPC* npcmob, ItemInst* iteminst, Mob* mob, bool global); @@ -112,7 +115,7 @@ private: void ExportZoneVariables(std::string &package_name); void ExportItemVariables(std::string &package_name, Mob *mob); void ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data, - NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata); + NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector *items); std::map npc_quest_status_; PerlQuestStatus global_npc_quest_status_; diff --git a/zone/event_codes.h b/zone/event_codes.h index 6600a79f0..3562d7ad6 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -35,14 +35,14 @@ typedef enum { EVENT_POPUP_RESPONSE, EVENT_PROXIMITY_SAY, EVENT_CAST, + EVENT_CAST_BEGIN, EVENT_SCALE_CALC, EVENT_ITEM_ENTER_ZONE, EVENT_TARGET_CHANGE, //target selected, target changed, or target removed EVENT_HATE_LIST, - EVENT_SPELL_EFFECT_CLIENT, - EVENT_SPELL_EFFECT_NPC, - EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT, - EVENT_SPELL_EFFECT_BUFF_TIC_NPC, + EVENT_SPELL_EFFECT, + EVENT_SPELL_BUFF_TIC, + EVENT_SPELL_FADE, EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE, EVENT_COMBINE_SUCCESS, //PC successfully combined a recipe EVENT_COMBINE_FAILURE, //PC failed to combine a recipe @@ -63,6 +63,7 @@ typedef enum { EVENT_DUEL_LOSE, EVENT_ENCOUNTER_LOAD, EVENT_ENCOUNTER_UNLOAD, + EVENT_COMMAND, _LargestEventID } QuestEventID; diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 1c55c1504..c58b8c90b 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -1160,6 +1160,18 @@ Lua_Raid Lua_Client::GetRaid() { return Lua_Raid(self->GetRaid()); } +bool Lua_Client::PutItemInInventory(int slot_id, Lua_ItemInst inst) { + Lua_Safe_Call_Bool(); + ItemInst *rinst = inst; + return self->PutItemInInventory(slot_id, *rinst, true); +} + +bool Lua_Client::PushItemOnCursor(Lua_ItemInst inst) { + Lua_Safe_Call_Bool(); + ItemInst *rinst = inst; + return self->PushItemOnCursor(*rinst, true); +} + luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()) @@ -1391,7 +1403,9 @@ luabind::scope lua_register_client() { .def("SetAccountFlag", (void(Lua_Client::*)(std::string,std::string))&Lua_Client::SetAccountFlag) .def("GetAccountFlag", (std::string(Lua_Client::*)(std::string))&Lua_Client::GetAccountFlag) .def("GetGroup", (Lua_Group(Lua_Client::*)(void))&Lua_Client::GetGroup) - .def("GetRaid", (Lua_Raid(Lua_Client::*)(void))&Lua_Client::GetRaid); + .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); } luabind::scope lua_register_inventory_where() { diff --git a/zone/lua_client.h b/zone/lua_client.h index d39a58831..7b89bf20c 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -258,6 +258,8 @@ public: std::string GetAccountFlag(std::string flag); Lua_Group GetGroup(); Lua_Raid GetRaid(); + bool PutItemInInventory(int slot_id, Lua_ItemInst inst); + bool PushItemOnCursor(Lua_ItemInst inst); }; #endif diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index f9c1835f9..091a777e4 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -1007,10 +1007,9 @@ luabind::scope lua_register_events() { luabind::value("item_enter_zone", static_cast(EVENT_ITEM_ENTER_ZONE)), luabind::value("target_change", static_cast(EVENT_TARGET_CHANGE)), luabind::value("hate_list", static_cast(EVENT_HATE_LIST)), - luabind::value("spell_effect_client", static_cast(EVENT_SPELL_EFFECT_CLIENT)), - luabind::value("spell_effect_npc", static_cast(EVENT_SPELL_EFFECT_NPC)), - luabind::value("spell_effect_buff_tic_client", static_cast(EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT)), - luabind::value("spell_effect_buff_tic_npc", static_cast(EVENT_SPELL_EFFECT_BUFF_TIC_NPC)), + luabind::value("spell_effect", static_cast(EVENT_SPELL_EFFECT)), + luabind::value("spell_buff_tic", static_cast(EVENT_SPELL_BUFF_TIC)), + luabind::value("spell_fade", static_cast(EVENT_SPELL_FADE)), luabind::value("spell_effect_translocate_complete", static_cast(EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE)), luabind::value("combine_success ", static_cast(EVENT_COMBINE_SUCCESS )), luabind::value("combine_failure ", static_cast(EVENT_COMBINE_FAILURE )), @@ -1030,7 +1029,8 @@ luabind::scope lua_register_events() { luabind::value("duel_win", static_cast(EVENT_DUEL_WIN)), 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("encounter_unload", static_cast(EVENT_ENCOUNTER_UNLOAD)), + luabind::value("command", static_cast(EVENT_COMMAND)) ]; } diff --git a/zone/lua_iteminst.cpp b/zone/lua_iteminst.cpp index 76ca18e16..fc6245a92 100644 --- a/zone/lua_iteminst.cpp +++ b/zone/lua_iteminst.cpp @@ -8,6 +8,16 @@ #include "lua_iteminst.h" #include "lua_item.h" +Lua_ItemInst::Lua_ItemInst(int item_id) { + SetLuaPtrData(database.CreateItem(item_id)); + cloned_ = true; +} + +Lua_ItemInst::Lua_ItemInst(int item_id, int charges) { + SetLuaPtrData(database.CreateItem(item_id, charges)); + cloned_ = true; +} + bool Lua_ItemInst::IsType(int item_class) { Lua_Safe_Call_Bool(); return self->IsType(static_cast(item_class)); @@ -238,9 +248,16 @@ uint32 Lua_ItemInst::GetKillsNeeded(int current_level) { return 0; } +Lua_ItemInst Lua_ItemInst::Clone() { + Lua_Safe_Call_Class(Lua_ItemInst); + return Lua_ItemInst(self->Clone(), true); +} + luabind::scope lua_register_iteminst() { return luabind::class_("ItemInst") .def(luabind::constructor<>()) + .def(luabind::constructor()) + .def(luabind::constructor()) .property("null", &Lua_ItemInst::Null) .property("valid", &Lua_ItemInst::Valid) .def("IsType", (bool(Lua_ItemInst::*)(int))&Lua_ItemInst::IsType) @@ -283,7 +300,8 @@ luabind::scope lua_register_iteminst() { .def("SetExp", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::SetExp) .def("AddExp", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::AddExp) .def("GetMaxEvolveLvl", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetMaxEvolveLvl) - .def("GetKillsNeeded", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetKillsNeeded); + .def("GetKillsNeeded", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetKillsNeeded) + .def("Clone", (Lua_ItemInst(Lua_ItemInst::*)(void))&Lua_ItemInst::Clone); } #endif diff --git a/zone/lua_iteminst.h b/zone/lua_iteminst.h index 5b03278bc..8f1d138a4 100644 --- a/zone/lua_iteminst.h +++ b/zone/lua_iteminst.h @@ -17,9 +17,12 @@ class Lua_ItemInst : public Lua_Ptr { typedef ItemInst NativeType; public: - Lua_ItemInst() : Lua_Ptr(nullptr) { } - Lua_ItemInst(ItemInst *d) : Lua_Ptr(d) { } - virtual ~Lua_ItemInst() { } + Lua_ItemInst(int item_id); + Lua_ItemInst(int item_id, int charges); + Lua_ItemInst() : Lua_Ptr(nullptr), cloned_(false) { } + Lua_ItemInst(ItemInst *d) : Lua_Ptr(d), cloned_(false) { } + Lua_ItemInst(ItemInst *d, bool cloned) : Lua_Ptr(d), cloned_(cloned) { } + virtual ~Lua_ItemInst() { if(cloned_) { void *ptr = GetLuaPtrData(); if(ptr) { delete ptr; } } } operator ItemInst*() { return reinterpret_cast(GetLuaPtrData()); @@ -66,6 +69,10 @@ public: void AddExp(uint32 exp); int GetMaxEvolveLvl(); uint32 GetKillsNeeded(int current_level); + Lua_ItemInst Clone(); + +private: + bool cloned_; }; #endif diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 2857cb160..d7c340088 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -65,14 +65,14 @@ const char *LuaEvents[_LargestEventID] = { "event_popup_response", "event_proximity_say", "event_cast", + "event_cast_begin", "event_scale_calc", "event_item_enter_zone", "event_target_change", "event_hate_list", - "event_spell_effect_client", - "event_spell_effect_npc", - "event_spell_effect_buff_tic_client", - "event_spell_effect_buff_tic_npc", + "event_spell_effect", + "event_spell_buff_tic", + "event_spell_fade", "event_spell_effect_translocate_complete", "event_combine_success", "event_combine_failure", @@ -92,7 +92,8 @@ const char *LuaEvents[_LargestEventID] = { "event_duel_win", "event_duel_lose", "event_encounter_load", - "event_encounter_unload" + "event_encounter_unload", + "event_command" }; extern Zone *zone; @@ -136,6 +137,8 @@ LuaParser::LuaParser() { NPCArgumentDispatch[EVENT_SIGNAL] = handle_npc_signal; NPCArgumentDispatch[EVENT_TIMER] = handle_npc_timer; NPCArgumentDispatch[EVENT_DEATH] = handle_npc_death; + NPCArgumentDispatch[EVENT_CAST] = handle_npc_cast; + NPCArgumentDispatch[EVENT_CAST_BEGIN] = handle_npc_cast; PlayerArgumentDispatch[EVENT_SAY] = handle_player_say; PlayerArgumentDispatch[EVENT_DEATH] = handle_player_death; @@ -149,6 +152,7 @@ LuaParser::LuaParser() { PlayerArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_player_popup_response; PlayerArgumentDispatch[EVENT_PLAYER_PICKUP] = handle_player_pick_up; PlayerArgumentDispatch[EVENT_CAST] = handle_player_cast; + PlayerArgumentDispatch[EVENT_CAST_BEGIN] = handle_player_cast; PlayerArgumentDispatch[EVENT_TASK_FAIL] = handle_player_task_fail; PlayerArgumentDispatch[EVENT_ZONE] = handle_player_zone; PlayerArgumentDispatch[EVENT_DUEL_WIN] = handle_player_duel_win; @@ -156,14 +160,14 @@ LuaParser::LuaParser() { PlayerArgumentDispatch[EVENT_LOOT] = handle_player_loot; PlayerArgumentDispatch[EVENT_TASK_STAGE_COMPLETE] = handle_player_task_stage_complete; PlayerArgumentDispatch[EVENT_TASK_COMPLETE] = handle_player_task_complete; + PlayerArgumentDispatch[EVENT_COMMAND] = handle_player_command; ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click; ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click; - SpellArgumentDispatch[EVENT_SPELL_EFFECT_NPC] = handle_spell_effect; - SpellArgumentDispatch[EVENT_SPELL_EFFECT_CLIENT] = handle_spell_effect; - SpellArgumentDispatch[EVENT_SPELL_EFFECT_BUFF_TIC_NPC] = handle_spell_effect; - SpellArgumentDispatch[EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT] = handle_spell_effect; + SpellArgumentDispatch[EVENT_SPELL_EFFECT] = handle_spell_effect; + SpellArgumentDispatch[EVENT_SPELL_BUFF_TIC] = handle_spell_effect; + SpellArgumentDispatch[EVENT_SPELL_FADE] = handle_spell_fade; L = nullptr; } @@ -174,7 +178,8 @@ LuaParser::~LuaParser() { } } -int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { if(evt >= _LargestEventID) { return 0; } @@ -190,10 +195,11 @@ int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, std::stringstream package_name; package_name << "npc_" << npc->GetNPCTypeID(); - return _EventNPC(package_name.str(), evt, npc, init, data, extra_data); + return _EventNPC(package_name.str(), evt, npc, init, data, extra_data, items); } -int LuaParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +int LuaParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { if(evt >= _LargestEventID) { return 0; } @@ -206,11 +212,11 @@ int LuaParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string return 0; } - return _EventNPC("global_npc", evt, npc, init, data, extra_data); + return _EventNPC("global_npc", evt, npc, init, data, extra_data, items); } int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - luabind::object *l_func) { + std::vector *items, luabind::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -233,7 +239,7 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M lua_setfield(L, -2, "self"); auto arg_function = NPCArgumentDispatch[evt]; - arg_function(this, L, npc, init, data, extra_data); + arg_function(this, L, npc, init, data, extra_data, items); Client *c = (init && init->IsClient()) ? init->CastToClient() : nullptr; quest_manager.StartQuest(npc, c, nullptr); @@ -863,7 +869,8 @@ void LuaParser::MapFunctions(lua_State *L) { } } -void LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { if(!npc) return; @@ -879,7 +886,7 @@ void LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::str while(riter != iter->second.end()) { if(riter->event_id == evt) { std::string package_name = "encounter_" + riter->encounter_name; - _EventNPC(package_name, evt, npc, init, data, extra_data, &riter->lua_reference); + _EventNPC(package_name, evt, npc, init, data, extra_data, items, &riter->lua_reference); } ++riter; } diff --git a/zone/lua_parser.h b/zone/lua_parser.h index 10f0951d9..e734802bd 100644 --- a/zone/lua_parser.h +++ b/zone/lua_parser.h @@ -25,8 +25,10 @@ public: LuaParser(); ~LuaParser(); - virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data); - virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data); + virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); + virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, + 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); @@ -55,14 +57,15 @@ public: virtual void ReloadQuests(); virtual uint32 GetIdentifier() { return 0xb0712acc; } - virtual void DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data); + 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 DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data); private: int _EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - luabind::object *l_func = nullptr); + 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, diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 0b4c99ec2..1d72a09be 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -21,7 +21,8 @@ #include "lua_parser_events.h" //NPC -void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { npc->DoQuestPause(init); Lua_Client l_client(reinterpret_cast(init)); @@ -36,7 +37,8 @@ void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *in lua_setfield(L, -2, "language"); } -void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { Lua_Client l_client(reinterpret_cast(init)); luabind::object l_client_o = luabind::object(L, l_client); l_client_o.push(L); @@ -45,28 +47,18 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob * lua_createtable(L, 0, 0); std::stringstream ident; ident << npc->GetNPCTypeID(); + + if(items) { + for(size_t i = 0; i < items->size(); ++i) { + std::string prefix = "item" + std::to_string(i + 1); + Lua_ItemInst l_inst = items->at(i); + luabind::object l_inst_o = luabind::object(L, l_inst); + l_inst_o.push(L); - for(int i = 1; i <= 4; ++i) { - std::string prefix = "item" + std::to_string(i); - - std::string cur = prefix; - lua_pushinteger(L, std::stoul(parse->GetVar(prefix + "." + ident.str()))); - lua_setfield(L, -2, prefix.c_str()); - - lua_pushinteger(L, std::stoul(parse->GetVar(prefix + ".charges." + ident.str()))); - lua_setfield(L, -2, std::string(prefix + "_charges").c_str()); - - lua_pushboolean(L, std::stoul(parse->GetVar(prefix + ".attuned." + ident.str()))); - lua_setfield(L, -2, std::string(prefix + "_attuned").c_str()); - - for(int j = 1; j <= 5; ++j) { - std::string augment = "augment" + std::to_string(j); - - lua_pushinteger(L, std::stoul(parse->GetVar(prefix + "." + augment + "." + ident.str()))); - lua_setfield(L, -2, std::string(prefix + "_" + augment).c_str()); + lua_setfield(L, -2, prefix.c_str()); } } - + lua_pushinteger(L, std::stoul(parse->GetVar("platinum." + ident.str()))); lua_setfield(L, -2, "platinum"); @@ -81,7 +73,8 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob * lua_setfield(L, -2, "trade"); } -void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { if(extra_data == 1) { lua_pushinteger(L, -1); lua_setfield(L, -2, "hp_event"); @@ -97,28 +90,32 @@ void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *ini } } -void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { Lua_Mob l_mob(init); luabind::object l_mob_o = luabind::object(L, l_mob); l_mob_o.push(L); lua_setfield(L, -2, "other"); } -void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { Lua_Client l_client(reinterpret_cast(init)); luabind::object l_client_o = luabind::object(L, l_client); l_client_o.push(L); lua_setfield(L, -2, "other"); } -void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { Lua_NPC l_npc(reinterpret_cast(init)); luabind::object l_npc_o = luabind::object(L, l_npc); l_npc_o.push(L); lua_setfield(L, -2, "other"); } -void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { Lua_Mob l_mob(init); luabind::object l_mob_o = luabind::object(L, l_mob); l_mob_o.push(L); @@ -128,7 +125,8 @@ void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, lua_setfield(L, -2, "popup_id"); } -void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { Lua_Mob l_mob(init); luabind::object l_mob_o = luabind::object(L, l_mob); l_mob_o.push(L); @@ -138,7 +136,8 @@ void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *ini lua_setfield(L, -2, "wp"); } -void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { Lua_Mob l_mob(init); luabind::object l_mob_o = luabind::object(L, l_mob); l_mob_o.push(L); @@ -149,17 +148,20 @@ void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, s } -void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "signal_id"); } -void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { lua_pushstring(L, data.c_str()); lua_setfield(L, -2, "timer"); } -void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { Lua_Mob l_mob(init); luabind::object l_mob_o = luabind::object(L, l_mob); l_mob_o.push(L); @@ -186,7 +188,24 @@ void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, lua_setfield(L, -2, "skill_id"); } -void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { +void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { + int spell_id = std::stoi(data); + if(IsValidSpell(spell_id)) { + Lua_Spell l_spell(&spells[spell_id]); + 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_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items) { } //Player @@ -351,6 +370,24 @@ void handle_player_task_complete(QuestInterface *parse, lua_State* L, Client* cl lua_setfield(L, -2, "task_id"); } +void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) { + Seperator sep(data.c_str(), ' ', 10, 100, true); + std::string command(sep.arg[0] + 1); + lua_pushstring(L, command.c_str()); + lua_setfield(L, -2, "command"); + + luabind::object args = luabind::newtable(L); + int max_args = sep.GetMaxArgNum(); + for(int i = 1; i < max_args; ++i) { + if(strlen(sep.arg[0]) > 0) { + args[i] = sep.arg[i]; + } + } + + args.push(L); + lua_setfield(L, -2, "args"); +} + void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) { } @@ -365,8 +402,43 @@ void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemI //Spell void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data) { + if(npc) { + Lua_NPC 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); + 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, extra_data); - lua_setfield(L, -2, "caster_id"); + lua_setfield(L, -2, "caster_id"); +} + +void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data) { + if(npc) { + Lua_NPC 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); + 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, extra_data); + lua_setfield(L, -2, "buff_slot"); } 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 4c135dd65..dbabd93fd 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -2,25 +2,40 @@ #define _EQE_LUA_PARSER_EVENTS_H #ifdef LUA_EQEMU -typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::string, uint32); +typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::string, uint32, std::vector*); typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32); typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, uint32, uint32); typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, uint32); //NPC -void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); -void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data); +void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); +void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, + std::vector *items); //Player void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data); @@ -41,6 +56,7 @@ void handle_player_duel_loss(QuestInterface *parse, lua_State* L, Client* client void handle_player_loot(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data); void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data); void handle_player_task_complete(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data); +void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data); void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data); //Item @@ -49,6 +65,7 @@ void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemI //Spell void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data); +void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data); void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data); #endif diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 8300dd8f0..b56f7b93d 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -141,7 +141,7 @@ 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); + int i = parse->EventSpell(EVENT_SPELL_EFFECT, CastToNPC(), nullptr, spell_id, caster ? caster->GetID() : 0); if(i != 0){ CalcBonuses(); return true; @@ -149,7 +149,7 @@ 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); + int i = parse->EventSpell(EVENT_SPELL_EFFECT, nullptr, CastToClient(), spell_id, caster ? caster->GetID() : 0); if(i != 0){ CalcBonuses(); return true; @@ -3066,14 +3066,14 @@ void Mob::DoBuffTic(uint16 spell_id, uint32 ticsremaining, uint8 caster_level, M if(IsNPC()) { - int i = parse->EventSpell(EVENT_SPELL_EFFECT_BUFF_TIC_NPC, CastToNPC(), nullptr, spell_id, caster ? caster->GetID() : 0); + int i = parse->EventSpell(EVENT_SPELL_BUFF_TIC, CastToNPC(), nullptr, spell_id, caster ? caster->GetID() : 0); if(i != 0) { return; } } else { - int i = parse->EventSpell(EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT, nullptr, CastToClient(), spell_id, caster ? caster->GetID() : 0); + int i = parse->EventSpell(EVENT_SPELL_BUFF_TIC, nullptr, CastToClient(), spell_id, caster ? caster->GetID() : 0); if(i != 0) { return; } @@ -3333,6 +3333,12 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses) } } + if(IsClient()) { + parse->EventSpell(EVENT_SPELL_FADE, nullptr, CastToClient(), buffs[slot].spellid, slot); + } else if(IsNPC()) { + parse->EventSpell(EVENT_SPELL_FADE, CastToNPC(), nullptr, buffs[slot].spellid, slot); + } + for (int i=0; i < EFFECT_COUNT; i++) { if(IsBlankSpellEffect(buffs[slot].spellid, i)) diff --git a/zone/spells.cpp b/zone/spells.cpp index 4ac9b1398..ff50ab464 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -297,6 +297,16 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, } } + if(IsClient()) { + char temp[64]; + sprintf(temp, "%d", spell_id); + parse->EventPlayer(EVENT_CAST_BEGIN, CastToClient(), temp, 0); + } else if(IsNPC()) { + char temp[64]; + sprintf(temp, "%d", spell_id); + parse->EventNPC(EVENT_CAST_BEGIN, CastToNPC(), nullptr, temp, 0); + } + if(resist_adjust) { return(DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, timer, timer_duration, type, *resist_adjust)); @@ -1197,13 +1207,14 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, // at this point the spell has successfully been cast // - // if the spell is cast by a client, trigger the EVENT_CAST player quest - if(this->IsClient()) { - if(parse->PlayerHasQuestSub("EVENT_CAST") ) { - char temp[64]; - sprintf(temp, "%d", spell_id); - parse->EventPlayer(EVENT_CAST, CastToClient(), temp, 0); - } + if(IsClient()) { + char temp[64]; + sprintf(temp, "%d", spell_id); + parse->EventPlayer(EVENT_CAST, CastToClient(), temp, 0); + } else if(IsNPC()) { + char temp[64]; + sprintf(temp, "%d", spell_id); + parse->EventNPC(EVENT_CAST, CastToNPC(), nullptr, temp, 0); } if(bard_song_mode) diff --git a/zone/trading.cpp b/zone/trading.cpp index e2619cd56..e81a21d9c 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -574,51 +574,47 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) quest_npc = true; } + std::vector item_list; uint32 items[4] = { 0 }; - uint8 charges[4] = { 0 }; - bool attuned[4] = { 0 }; - uint32 augments[4][5] = { 0 }; - - for (int i = 3000; i < 3004; i++) { - const ItemInst* inst = m_inv[i]; - if (inst) { + for(int i = 3000; i < 3004; ++i) { + ItemInst *inst = m_inv.GetItem(i); + if(inst) { items[i - 3000] = inst->GetItem()->ID; - charges[i - 3000] = inst->GetCharges(); - attuned[i - 3000] = inst->IsInstNoDrop(); + item_list.push_back(inst); + } else { + item_list.push_back(nullptr); + continue; + } - for(int j = 0; j < 5; j++) { - augments[i - 3000][j] = inst->GetAugmentItemID(j); - } - - const Item_Struct* item2 = database.GetItem(items[i - 3000]); - // Handle non-quest NPC trading - if (item2 && quest_npc == false) { - // if it was not a NO DROP or Attuned item (or if a GM is trading), let the NPC have it - if(GetGM() || (item2->NoDrop != 0 && inst->IsInstNoDrop() == false)) { - // pets need to look inside bags and try to equip items found there - if (item2->ItemClass == ItemClassContainer && item2->BagSlots > 0) { - for(int16 bslot=0; bslot < item2->BagSlots; bslot++) { - const ItemInst* baginst = inst->GetItem(bslot); - if (baginst) { - const Item_Struct* bagitem = database.GetItem(baginst->GetItem()->ID); - if (bagitem && (GetGM() || (bagitem->NoDrop != 0 && baginst->IsInstNoDrop() == false))) { - tradingWith->CastToNPC()->AddLootDrop(bagitem, &tradingWith->CastToNPC()->itemlist, baginst->GetCharges(), 1, 127, true, true); - } - else if (RuleB(NPC, ReturnNonQuestNoDropItems)) { - PushItemOnCursor(*baginst, true); - } + const Item_Struct* item = inst->GetItem(); + if(item && quest_npc == false) { + // if it was not a NO DROP or Attuned item (or if a GM is trading), let the NPC have it + if(GetGM() || (item->NoDrop != 0 && inst->IsInstNoDrop() == false)) { + // pets need to look inside bags and try to equip items found there + if(item->ItemClass == ItemClassContainer && item->BagSlots > 0) { + for(int16 bslot=0; bslot < item->BagSlots; bslot++) { + const ItemInst* baginst = inst->GetItem(bslot); + if (baginst) { + const Item_Struct* bagitem = baginst->GetItem(); + if (bagitem && (GetGM() || (bagitem->NoDrop != 0 && baginst->IsInstNoDrop() == false))) { + tradingWith->CastToNPC()->AddLootDrop(bagitem, &tradingWith->CastToNPC()->itemlist, + baginst->GetCharges(), 1, 127, true, true); + } + else if (RuleB(NPC, ReturnNonQuestNoDropItems)) { + PushItemOnCursor(*baginst, true); } } } - - tradingWith->CastToNPC()->AddLootDrop(item2, &tradingWith->CastToNPC()->itemlist, charges[i-3000], 1, 127, true, true); - } - // Return NO DROP and Attuned items being handed into a non-quest NPC if the rule is true - else if (RuleB(NPC, ReturnNonQuestNoDropItems)) { - PushItemOnCursor(*inst, true); } + + tradingWith->CastToNPC()->AddLootDrop(item, &tradingWith->CastToNPC()->itemlist, + inst->GetCharges(), 1, 127, true, true); + } + // Return NO DROP and Attuned items being handed into a non-quest NPC if the rule is true + else if (RuleB(NPC, ReturnNonQuestNoDropItems)) { + PushItemOnCursor(*inst, true); + DeleteItemInInventory(i); } - DeleteItemInInventory(i); } } @@ -630,46 +626,32 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) } } - //dont bother with this crap unless we have a quest... - //pets can have quests! (especially charmed NPCs) - if (quest_npc) { - char temp1[100] = { 0 }; - char temp2[100] = { 0 }; - for(int z = 0; z < 4; z++) { - snprintf(temp1, 100, "item%d.%d", z + 1, tradingWith->GetNPCTypeID()); - snprintf(temp2, 100, "%d", items[z]); - parse->AddVar(temp1, temp2); - snprintf(temp1, 100, "item%d.charges.%d", z + 1, tradingWith->GetNPCTypeID()); - snprintf(temp2, 100, "%d", charges[z]); - parse->AddVar(temp1, temp2); - snprintf(temp1, 100, "item%d.attuned.%d", z + 1, tradingWith->GetNPCTypeID()); - snprintf(temp2, 100, "%d", attuned[z]); - parse->AddVar(temp1, temp2); + char temp1[100] = { 0 }; + char temp2[100] = { 0 }; + snprintf(temp1, 100, "copper.%d", tradingWith->GetNPCTypeID()); + snprintf(temp2, 100, "%u", trade->cp); + parse->AddVar(temp1, temp2); + snprintf(temp1, 100, "silver.%d", tradingWith->GetNPCTypeID()); + snprintf(temp2, 100, "%u", trade->sp); + parse->AddVar(temp1, temp2); + snprintf(temp1, 100, "gold.%d", tradingWith->GetNPCTypeID()); + snprintf(temp2, 100, "%u", trade->gp); + parse->AddVar(temp1, temp2); + snprintf(temp1, 100, "platinum.%d", tradingWith->GetNPCTypeID()); + snprintf(temp2, 100, "%u", trade->pp); + parse->AddVar(temp1, temp2); - for(int y = 0; y < 5; y++) { - snprintf(temp1, 100, "item%d.augment%d.%d", z + 1, y + 1, tradingWith->GetNPCTypeID()); - snprintf(temp2, 100, "%d", augments[z][y]); - parse->AddVar(temp1, temp2); - } + if(tradingWith->GetAppearance() != eaDead) { + tradingWith->FaceTarget(this); + } + + parse->EventNPC(EVENT_TRADE, tradingWith->CastToNPC(), this, "", 0, &item_list); + + for(int i = 3000; i < 3004; ++i) { + ItemInst *inst = m_inv.GetItem(i); + if(inst) { + DeleteItemInInventory(i); } - snprintf(temp1, 100, "copper.%d", tradingWith->GetNPCTypeID()); - snprintf(temp2, 100, "%u", trade->cp); - parse->AddVar(temp1, temp2); - snprintf(temp1, 100, "silver.%d", tradingWith->GetNPCTypeID()); - snprintf(temp2, 100, "%u", trade->sp); - parse->AddVar(temp1, temp2); - snprintf(temp1, 100, "gold.%d", tradingWith->GetNPCTypeID()); - snprintf(temp2, 100, "%u", trade->gp); - parse->AddVar(temp1, temp2); - snprintf(temp1, 100, "platinum.%d", tradingWith->GetNPCTypeID()); - snprintf(temp2, 100, "%u", trade->pp); - parse->AddVar(temp1, temp2); - - if(tradingWith->GetAppearance() != eaDead) { - tradingWith->FaceTarget(this); - } - - parse->EventNPC(EVENT_TRADE, tradingWith->CastToNPC(), this, "", 0); } } }