diff --git a/common/rdtsc.cpp b/common/rdtsc.cpp index 15786397e..1d66c0254 100644 --- a/common/rdtsc.cpp +++ b/common/rdtsc.cpp @@ -58,7 +58,7 @@ RDTSC_Timer::RDTSC_Timer(bool start_it) { } int64 RDTSC_Timer::rdtsc() { - int64 res; + int64 res = 0; #ifdef USE_RDTSC #ifndef WIN64 #ifdef WIN32 diff --git a/common/ruletypes.h b/common/ruletypes.h index 9548d99e1..b08260634 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -385,7 +385,6 @@ RULE_BOOL ( NPC, SmartLastFightingDelayMoving, true) RULE_BOOL ( NPC, ReturnNonQuestNoDropItems, false) // Returns NO DROP items on NPCs that don't have an EVENT_TRADE sub in their script RULE_INT ( NPC, StartEnrageValue, 9) // % HP that an NPC will begin to enrage RULE_BOOL ( NPC, LiveLikeEnrage, false) // If set to true then only player controlled pets will enrage -RULE_BOOL (NPC, UseMultiQuest, false) // If true, NPC will remember items handed to them for classic multiquest support. RULE_CATEGORY_END() RULE_CATEGORY ( Aggro ) diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index 40d3b88ac..cc51fb5a8 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -33,7 +33,9 @@ SET(zone_sources loottables.cpp lua_client.cpp lua_entity.cpp + lua_hate_entry.cpp lua_item.cpp + lua_iteminst.cpp lua_mob.cpp lua_npc.cpp lua_parser.cpp @@ -133,6 +135,7 @@ SET(zone_headers lua_client.h lua_entity.h lua_item.h + lua_iteminst.h lua_mob.h lua_npc.h lua_parser.h diff --git a/zone/QuestParserCollection.cpp b/zone/QuestParserCollection.cpp index 995b066fc..5ee36749d 100644 --- a/zone/QuestParserCollection.cpp +++ b/zone/QuestParserCollection.cpp @@ -432,7 +432,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string iter++; } - //third look for /quests/templates/npcid.ext (precedence) + //third look for /quests/global/npcid.ext (precedence) filename = "quests/"; filename += QUEST_GLOBAL_DIRECTORY; filename += "/"; @@ -453,7 +453,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string iter++; } - //fourth look for /quests/templates/npcname.ext (precedence) + //fourth look for /quests/global/npcname.ext (precedence) filename = "quests/"; filename += QUEST_GLOBAL_DIRECTORY; filename += "/"; @@ -495,7 +495,7 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string iter++; } - //last look for /quests/templates/default.ext (precedence) + //last look for /quests/global/default.ext (precedence) filename = "quests/"; filename += QUEST_GLOBAL_DIRECTORY; filename += "/"; @@ -571,7 +571,7 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename) iter++; } - //third look for /quests/templates/player.ext (precedence) + //third look for /quests/global/player.ext (precedence) filename = "quests/"; filename += QUEST_GLOBAL_DIRECTORY; filename += "/"; @@ -596,7 +596,7 @@ QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename) } QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filename) { - // simply look for templates/global_npc.pl + // simply look for quests/global/global_npc.pl filename = "quests/"; filename += QUEST_GLOBAL_DIRECTORY; filename += "/"; @@ -624,7 +624,7 @@ QuestInterface *QuestParserCollection::GetQIByGlobalNPCQuest(std::string &filena } QuestInterface *QuestParserCollection::GetQIByGlobalPlayerQuest(std::string &filename) { - //first look for /quests/templates/player.ext (precedence) + //first look for /quests/global/player.ext (precedence) filename = "quests/"; filename += QUEST_GLOBAL_DIRECTORY; filename += "/"; @@ -652,38 +652,14 @@ QuestInterface *QuestParserCollection::GetQIByGlobalPlayerQuest(std::string &fil } QuestInterface *QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::string &filename) { - //first look for /quests/spells/spell_id.ext (precedence) - filename = "quests/spells/"; + //first look for /quests/zone/spells/spell_id.ext (precedence) + filename = "quests/"; + filename += zone->GetShortName(); + filename += "/spells/"; filename += itoa(spell_id); std::string tmp; FILE *f = nullptr; - std::list::iterator iter = _load_precedence.begin(); - while(iter != _load_precedence.end()) { - tmp = filename; - std::map::iterator ext = _extensions.find((*iter)->GetIdentifier()); - tmp += "."; - tmp += ext->second; - f = fopen(tmp.c_str(), "r"); - if(f) { - fclose(f); - filename = tmp; - return (*iter); - } - - iter++; - } - - return nullptr; -} - -QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script, std::string &filename) { - //first look for /quests/items/item_script.ext (precedence) - filename = "quests/items/"; - filename += item_script; - std::string tmp; - FILE *f = nullptr; - std::list::iterator iter = _load_precedence.begin(); while(iter != _load_precedence.end()) { tmp = filename; @@ -700,5 +676,73 @@ QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script, iter++; } + //second look for /quests/spells/spell_id.ext (precedence) + filename = "quests/spells/"; + filename += itoa(spell_id); + + iter = _load_precedence.begin(); + while(iter != _load_precedence.end()) { + tmp = filename; + std::map::iterator ext = _extensions.find((*iter)->GetIdentifier()); + tmp += "."; + tmp += ext->second; + f = fopen(tmp.c_str(), "r"); + if(f) { + fclose(f); + filename = tmp; + return (*iter); + } + + iter++; + } + + return nullptr; +} + +QuestInterface *QuestParserCollection::GetQIByItemQuest(std::string item_script, std::string &filename) { + //first look for /quests/zone/items/item_script.ext (precedence) + filename = "quests/"; + filename += zone->GetShortName(); + filename += "/items/"; + filename += item_script; + std::string tmp; + FILE *f = nullptr; + + std::list::iterator iter = _load_precedence.begin(); + while(iter != _load_precedence.end()) { + tmp = filename; + std::map::iterator ext = _extensions.find((*iter)->GetIdentifier()); + tmp += "."; + tmp += ext->second; + f = fopen(tmp.c_str(), "r"); + if(f) { + fclose(f); + filename = tmp; + return (*iter); + } + + iter++; + } + + //second look for /quests/items/item_script.ext (precedence) + filename = "quests/items/"; + filename += item_script; + + iter = _load_precedence.begin(); + while(iter != _load_precedence.end()) { + tmp = filename; + std::map::iterator ext = _extensions.find((*iter)->GetIdentifier()); + tmp += "."; + tmp += ext->second; + f = fopen(tmp.c_str(), "r"); + if(f) { + fclose(f); + filename = tmp; + return (*iter); + } + + iter++; + } + return nullptr; } diff --git a/zone/client.h b/zone/client.h index 99a7e68ee..d915d78fc 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1097,7 +1097,6 @@ public: const char* GetClassPlural(Client* client); void SendWebLink(const char* website); - bool StoreTurnInItems(Mob* with); void DuplicateLoreMessage(uint32 ItemID); void GarbleMessage(char *, uint8); diff --git a/zone/command.cpp b/zone/command.cpp index 63cd457ae..5530b518c 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -444,8 +444,6 @@ int command_init(void) { command_add("picklock", "Analog for ldon pick lock for the newer clients since we still don't have it working.", 0, command_picklock) || command_add("mysql", "Mysql CLI, see 'help' for options.", 250, command_mysql) || command_add("xtargets", "Show your targets Extended Targets and optionally set how many xtargets they can have.", 250, command_xtargets) || - command_add("printquestitems","Returns available quest items for multiquesting currently on the target npc.",200,command_printquestitems) || - command_add("clearquestitems","Clears quest items for multiquesting currently on the target npc.",200,command_clearquestitems) || command_add("zopp", "Troubleshooting command - Sends a fake item packet to you. No server reference is created.", 250, command_zopp) || command_add("augmentitem", "Force augments an item. Must have the augment item window open.", 250, command_augmentitem) ) @@ -11374,35 +11372,6 @@ void command_xtargets(Client *c, const Seperator *sep) t->ShowXTargets(c); } -void command_printquestitems(Client *c, const Seperator *sep) -{ - if (c->GetTarget() != 0) - { - if ( c->GetTarget()->IsNPC() ) - c->GetTarget()->CastToNPC()->PrintOutQuestItems(c); - else - c->Message(13,"Pick a NPC target."); - } - else - c->Message(13,"Pick a NPC target."); -} - -void command_clearquestitems(Client *c, const Seperator *sep) -{ - if (c->GetTarget() != 0) - { - if ( c->GetTarget()->IsNPC() ) - { - c->GetTarget()->CastToNPC()->ClearQuestLists(); - c->Message(5,"Quest item list cleared."); - } - else - c->Message(13,"Pick a NPC target."); - } - else - c->Message(13,"Pick a NPC target."); -} - void command_zopp(Client *c, const Seperator *sep) { // - Owner only command..non-targetable to eliminate malicious or mischievious activities. if (!c) diff --git a/zone/command.h b/zone/command.h index dd61b9638..99adc0d71 100644 --- a/zone/command.h +++ b/zone/command.h @@ -317,8 +317,6 @@ void command_picklock(Client *c, const Seperator *sep); void command_qtest(Client *c, const Seperator *sep); void command_mysql(Client *c, const Seperator *sep); void command_xtargets(Client *c, const Seperator *sep); -void command_printquestitems(Client *c, const Seperator *sep); -void command_clearquestitems(Client *c, const Seperator *sep); void command_zopp(Client *c, const Seperator *sep); void command_augmentitem(Client *c, const Seperator *sep); diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index eb91675f6..5afc3721e 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -3253,58 +3253,6 @@ XS(XS__GetTimeSeconds) XSRETURN_UV(seconds); } -XS(XS__handleturnin); // prototype to pass -Wmissing-prototypes -XS(XS__handleturnin) { - dXSARGS; - - if (items != 2) - Perl_croak(aTHX_ "Usage: handleturnin(itemid, itemcharges)"); - int itemid = (int)SvIV(ST(0)); - int charges = (int)SvIV(ST(1)); - - bool returnVal = quest_manager.TurnInItem(itemid,charges); - - ST(0) = boolSV(returnVal); - sv_2mortal(ST(0)); - XSRETURN(1); -} - -XS(XS__completehandin); // prototype to pass -Wmissing-prototypes -XS(XS__completehandin) { - dXSARGS; - - if (items != 0) - Perl_croak(aTHX_ "Usage: completehandin()"); - - quest_manager.CompleteHandIn(); - - XSRETURN_EMPTY; -} - -XS(XS__resethandin); // prototype to pass -Wmissing-prototypes -XS(XS__resethandin) { - dXSARGS; - - if (items != 0) - Perl_croak(aTHX_ "Usage: resethandin()"); - - quest_manager.ResetHandIn(); - - XSRETURN_EMPTY; -} - -XS(XS__clearhandin); // prototype to pass -Wmissing-prototypes -XS(XS__clearhandin) { - dXSARGS; - - if (items != 0) - Perl_croak(aTHX_ "Usage: clearhandin()"); - - quest_manager.ClearHandIn(); - - XSRETURN_EMPTY; -} - XS(XS__crosszonesignalclientbycharid); XS(XS__crosszonesignalclientbycharid) { @@ -3579,10 +3527,6 @@ EXTERN_C XS(boot_quest) newXS(strcpy(buf, "GetZoneID"), XS__GetZoneID, file); newXS(strcpy(buf, "GetZoneLongName"), XS__GetZoneLongName, file); newXS(strcpy(buf, "GetTimeSeconds"), XS__GetTimeSeconds, file); - newXS(strcpy(buf, "handleturnin"), XS__handleturnin, file); - newXS(strcpy(buf, "completehandin"), XS__completehandin, file); - newXS(strcpy(buf, "resethandin"), XS__resethandin, file); - newXS(strcpy(buf, "clearhandin"), XS__clearhandin, file); newXS(strcpy(buf, "crosszonesignalclientbycharid"), XS__crosszonesignalclientbycharid, file); newXS(strcpy(buf, "crosszonesignalclientbyname"), XS__crosszonesignalclientbyname, file); newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file); diff --git a/zone/hate_list.h b/zone/hate_list.h index 2bcde40f8..b61670310 100644 --- a/zone/hate_list.h +++ b/zone/hate_list.h @@ -19,9 +19,8 @@ #ifndef HATELIST_H #define HATELIST_H -class tHateEntry +struct tHateEntry { -public: Mob *ent; int32 damage, hate; bool bFrenzy; diff --git a/zone/lua_entity.h b/zone/lua_entity.h index f1105b347..9f877be9d 100644 --- a/zone/lua_entity.h +++ b/zone/lua_entity.h @@ -28,7 +28,7 @@ struct Lua_HateList; #define Lua_Safe_Call_Client() if(!d_) { return Lua_Client(); } NativeType *self = reinterpret_cast(d_) #define Lua_Safe_Call_HateList() if(!d_) { return Lua_HateList(); } NativeType *self = reinterpret_cast(d_) -class Lua_Entity : public Lua_Ptr +class Lua_Entity : public Lua_Ptr { typedef Entity NativeType; public: diff --git a/zone/lua_hate_entry.cpp b/zone/lua_hate_entry.cpp new file mode 100644 index 000000000..940701d42 --- /dev/null +++ b/zone/lua_hate_entry.cpp @@ -0,0 +1,48 @@ +#ifdef LUA_EQEMU + +#include "masterentity.h" +#include "hate_list.h" +#include "lua_mob.h" +#include "lua_hate_entry.h" + +Lua_Mob Lua_HateEntry::GetEnt() { + Lua_Safe_Call_Mob(); + return Lua_Mob(self->ent); +} + +void Lua_HateEntry::SetEnt(Lua_Mob e) { + Lua_Safe_Call_Void(); + self->ent = e; +} + +int Lua_HateEntry::GetDamage() { + Lua_Safe_Call_Int(); + return self->damage; +} + +void Lua_HateEntry::SetDamage(int value) { + Lua_Safe_Call_Void(); + self->damage = value; +} + +int Lua_HateEntry::GetHate() { + Lua_Safe_Call_Int(); + return self->hate; +} + +void Lua_HateEntry::SetHate(int value) { + Lua_Safe_Call_Void(); + self->hate = value; +} + +int Lua_HateEntry::GetFrenzy() { + Lua_Safe_Call_Int(); + return self->bFrenzy; +} + +void Lua_HateEntry::SetFrenzy(bool value) { + Lua_Safe_Call_Void(); + self->bFrenzy = value; +} + +#endif diff --git a/zone/lua_hate_entry.h b/zone/lua_hate_entry.h index 6b6337bad..c79cca7ea 100644 --- a/zone/lua_hate_entry.h +++ b/zone/lua_hate_entry.h @@ -2,17 +2,27 @@ #define EQEMU_LUA_HATE_ENTRY_H #ifdef LUA_EQEMU -class Lua_Mob; +#include "lua_ptr.h" -struct Lua_HateEntry +class Lua_Mob; +struct tHateEntry; + +class Lua_HateEntry : public Lua_Ptr { + typedef tHateEntry NativeType; +public: Lua_HateEntry() { } + Lua_HateEntry(tHateEntry *d) : Lua_Ptr(d) { } virtual ~Lua_HateEntry() { } - Lua_Mob ent; - int damage; - int hate; - bool frenzy; + Lua_Mob GetEnt(); + void SetEnt(Lua_Mob e); + int GetDamage(); + void SetDamage(int value); + int GetHate(); + void SetHate(int value); + int GetFrenzy(); + void SetFrenzy(bool value); }; #endif diff --git a/zone/lua_item.h b/zone/lua_item.h index d56bf4a04..d3f09e2a7 100644 --- a/zone/lua_item.h +++ b/zone/lua_item.h @@ -4,20 +4,20 @@ #include "lua_ptr.h" -class ItemInst; +struct Item_Struct; -class Lua_Item : public Lua_Ptr +class Lua_Item : public Lua_Ptr { - typedef ItemInst NativeType; + typedef Item_Struct NativeType; public: Lua_Item() { } - Lua_Item(ItemInst *d) : Lua_Ptr(d) { } + Lua_Item(const Item_Struct *d) : Lua_Ptr(d) { } virtual ~Lua_Item() { } - operator ItemInst*() { - void *d = GetLuaPtrData(); + operator const Item_Struct*() { + const void *d = GetLuaPtrData(); if(d) { - return reinterpret_cast(d); + return reinterpret_cast(d); } return nullptr; diff --git a/zone/lua_iteminst.cpp b/zone/lua_iteminst.cpp new file mode 100644 index 000000000..125a5e728 --- /dev/null +++ b/zone/lua_iteminst.cpp @@ -0,0 +1,6 @@ +#ifdef LUA_EQEMU + +#include "masterentity.h" +#include "lua_iteminst.h" + +#endif diff --git a/zone/lua_iteminst.h b/zone/lua_iteminst.h new file mode 100644 index 000000000..c622af826 --- /dev/null +++ b/zone/lua_iteminst.h @@ -0,0 +1,28 @@ +#ifndef EQEMU_LUA_ITEMINST_H +#define EQEMU_LUA_ITEMINST_H +#ifdef LUA_EQEMU + +#include "lua_ptr.h" + +class ItemInst; + +class Lua_ItemInst : public Lua_Ptr +{ + typedef ItemInst NativeType; +public: + Lua_ItemInst() { } + Lua_ItemInst(ItemInst *d) : Lua_Ptr(d) { } + virtual ~Lua_ItemInst() { } + + operator ItemInst*() { + void *d = GetLuaPtrData(); + if(d) { + return reinterpret_cast(d); + } + + return nullptr; + } +}; + +#endif +#endif diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 88fa6b89b..7537479d9 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -760,12 +760,7 @@ Lua_HateList Lua_Mob::GetHateList() { auto h_list = self->GetHateList(); auto iter = h_list.begin(); while(iter != h_list.end()) { - tHateEntry *ent = (*iter); - Lua_HateEntry e; - e.ent = Lua_Mob(ent->ent); - e.damage = ent->damage; - e.hate = ent->hate; - e.frenzy = ent->bFrenzy; + Lua_HateEntry e(*iter); ret.entries.push_back(e); ++iter; } diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index b75473fed..496339e88 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -19,6 +19,7 @@ #include "lua_client.h" #include "lua_npc.h" #include "lua_item.h" +#include "lua_iteminst.h" #include "lua_spell.h" #include "zone.h" @@ -258,96 +259,7 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client * auto arg_function = PlayerArgumentDispatch[evt]; arg_function(this, L, client, data, extra_data); - - /*switch(evt) { - case EVENT_DEATH: { - Seperator sep(data.c_str()); - lua_pushinteger(L, std::stoi(sep.arg[0])); - lua_pushinteger(L, std::stoi(sep.arg[1])); - lua_pushinteger(L, std::stoi(sep.arg[2])); - lua_pushinteger(L, std::stoi(sep.arg[3])); - arg_count += 4; - break; - } - - case EVENT_SAY: { - lua_pushstring(L, data.c_str()); - lua_pushinteger(L, extra_data); - - arg_count += 2; - break; - } - - case EVENT_DISCOVER_ITEM: - case EVENT_FISH_SUCCESS: - case EVENT_FORAGE_SUCCESS: { - lua_pushinteger(L, extra_data); - - arg_count += 1; - break; - } - - case EVENT_CLICK_OBJECT: - case EVENT_CLICK_DOOR: - case EVENT_SIGNAL: - case EVENT_POPUP_RESPONSE: - case EVENT_PLAYER_PICKUP: - case EVENT_CAST: - case EVENT_TASK_FAIL: - case EVENT_ZONE: { - lua_pushinteger(L, std::stoi(data)); - - arg_count += 1; - break; - } - - case EVENT_TIMER: { - lua_pushstring(L, data.c_str()); - - arg_count += 1; - break; - } - - case EVENT_DUEL_WIN: - case EVENT_DUEL_LOSE: { - lua_pushstring(L, data.c_str()); - lua_pushinteger(L, extra_data); - arg_count += 2; - break; - } - - case EVENT_LOOT: { - Seperator sep(data.c_str()); - lua_pushinteger(L, std::stoi(sep.arg[0])); - lua_pushinteger(L, std::stoi(sep.arg[1])); - lua_pushstring(L, sep.arg[2]); - - arg_count += 3; - break; - } - - case EVENT_TASK_STAGE_COMPLETE: { - Seperator sep(data.c_str()); - lua_pushinteger(L, std::stoi(sep.arg[0])); - lua_pushinteger(L, std::stoi(sep.arg[1])); - - arg_count += 2; - break; - } - - case EVENT_TASK_COMPLETE: { - Seperator sep(data.c_str()); - lua_pushinteger(L, std::stoi(sep.arg[0])); - lua_pushinteger(L, std::stoi(sep.arg[1])); - lua_pushinteger(L, std::stoi(sep.arg[2])); - - arg_count += 3; - break; - } - - }*/ - if(lua_pcall(L, 1, 1, 0)) { printf("Error: %s\n", lua_tostring(L, -1)); return 0; @@ -422,10 +334,10 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl lua_createtable(L, 0, 0); //always push self - Lua_Item l_item(item); + Lua_ItemInst l_item(item); luabind::object l_item_o = luabind::object(L, l_item); l_item_o.push(L); - lua_setfield(L, -2, "item"); + lua_setfield(L, -2, "self"); auto arg_function = ItemArgumentDispatch[evt]; arg_function(this, L, client, item, objid, extra_data); @@ -481,6 +393,12 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, lua_getfield(L, -1, sub_name); lua_createtable(L, 0, 0); + + //always push self + 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, "self"); auto arg_function = SpellArgumentDispatch[evt]; arg_function(this, L, npc, client, spell_id, extra_data); @@ -631,11 +549,11 @@ void LuaParser::ReloadQuests() { lua_pop(L, 1); //load init - FILE *f = fopen("quests/templates/script_init.lua", "r"); + FILE *f = fopen("quests/global/script_init.lua", "r"); if(f) { fclose(f); - if(luaL_dofile(L, "quests/templates/script_init.lua")) { + if(luaL_dofile(L, "quests/global/script_init.lua")) { printf("Lua Error in Global Init: %s\n", lua_tostring(L, -1)); lua_close(L); return; @@ -673,6 +591,10 @@ void LuaParser::LoadScript(std::string filename, std::string package_name) { return; } + //This makes an env table named: package_name + //And makes it so we can see the global table _G from it + //Then sets it so this script is called from that table as an env + lua_createtable(L, 0, 0); // anon table lua_getglobal(L, "_G"); // get _G lua_setfield(L, -2, "__index"); //anon table.__index = _G @@ -893,8 +815,7 @@ void LuaParser::MapFunctions(lua_State *L) { .def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob,int,int,uint32,int))&Lua_Mob::SpellFinished) .def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob,int,int,uint32,int,bool))&Lua_Mob::SpellFinished) .def("SpellEffect", &Lua_Mob::SpellEffect) - .def("GetHateList", &Lua_Mob::GetHateList) - , + .def("GetHateList", &Lua_Mob::GetHateList), luabind::class_("Client") .def(luabind::constructor<>()), @@ -902,16 +823,28 @@ void LuaParser::MapFunctions(lua_State *L) { luabind::class_("NPC") .def(luabind::constructor<>()), + luabind::class_("ItemInst") + .def(luabind::constructor<>()) + .property("null", &Lua_ItemInst::Null) + .property("valid", &Lua_ItemInst::Valid), + luabind::class_("Item") .def(luabind::constructor<>()) - .property("null", &Lua_Entity::Null) - .property("valid", &Lua_Entity::Valid), + .property("null", &Lua_Item::Null) + .property("valid", &Lua_Item::Valid), + + luabind::class_("Spell") + .def(luabind::constructor<>()) + .property("null", &Lua_Spell::Null) + .property("valid", &Lua_Spell::Valid), luabind::class_("HateEntry") - .def_readwrite("ent", &Lua_HateEntry::ent) - .def_readwrite("damage", &Lua_HateEntry::damage) - .def_readwrite("hate", &Lua_HateEntry::hate) - .def_readwrite("frenzy", &Lua_HateEntry::frenzy), + .property("null", &Lua_HateEntry::Null) + .property("valid", &Lua_HateEntry::Valid) + .property("ent", &Lua_HateEntry::GetEnt, &Lua_HateEntry::SetEnt) + .property("damage", &Lua_HateEntry::GetDamage, &Lua_HateEntry::SetDamage) + .property("hate", &Lua_HateEntry::GetHate, &Lua_HateEntry::SetHate) + .property("frenzy", &Lua_HateEntry::GetFrenzy, &Lua_HateEntry::SetFrenzy), luabind::class_("HateList") .def_readwrite("entries", &Lua_HateList::entries, luabind::return_stl_iterator) diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 379e487a9..13ec568f8 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -14,6 +14,8 @@ #include "lua_client.h" #include "lua_npc.h" #include "lua_item.h" +#include "lua_iteminst.h" +#include "lua_spell.h" #include "zone.h" #include "lua_parser_events.h" @@ -179,8 +181,18 @@ void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, lua_pushinteger(L, std::stoi(sep.arg[0])); lua_setfield(L, -2, "damage"); - lua_pushinteger(L, std::stoi(sep.arg[1])); - lua_setfield(L, -2, "spell_id"); + int spell_id = std::stoi(sep.arg[1]); + 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"); + } lua_pushinteger(L, std::stoi(sep.arg[2])); lua_setfield(L, -2, "skill_id"); @@ -189,7 +201,127 @@ void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data) { } +/*switch(evt) { +case EVENT_FISH_SUCCESS: +case EVENT_FORAGE_SUCCESS: { + lua_pushinteger(L, extra_data); + + arg_count += 1; + break; +} + +case EVENT_CLICK_OBJECT: +case EVENT_CLICK_DOOR: +case EVENT_SIGNAL: +case EVENT_POPUP_RESPONSE: +case EVENT_PLAYER_PICKUP: +case EVENT_CAST: +case EVENT_TASK_FAIL: +case EVENT_ZONE: { + lua_pushinteger(L, std::stoi(data)); + + arg_count += 1; + break; +} + +case EVENT_DUEL_WIN: +case EVENT_DUEL_LOSE: { + lua_pushstring(L, data.c_str()); + lua_pushinteger(L, extra_data); + arg_count += 2; + break; +} + +case EVENT_LOOT: { + Seperator sep(data.c_str()); + lua_pushinteger(L, std::stoi(sep.arg[0])); + lua_pushinteger(L, std::stoi(sep.arg[1])); + lua_pushstring(L, sep.arg[2]); + + arg_count += 3; + break; +} + +case EVENT_TASK_STAGE_COMPLETE: { + Seperator sep(data.c_str()); + lua_pushinteger(L, std::stoi(sep.arg[0])); + lua_pushinteger(L, std::stoi(sep.arg[1])); + + arg_count += 2; + break; +} + +case EVENT_TASK_COMPLETE: { + Seperator sep(data.c_str()); + lua_pushinteger(L, std::stoi(sep.arg[0])); + lua_pushinteger(L, std::stoi(sep.arg[1])); + lua_pushinteger(L, std::stoi(sep.arg[2])); + + arg_count += 3; + break; +} + +}*/ + //Player +void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) { + lua_pushstring(L, data.c_str()); + lua_setfield(L, -2, "message"); + + lua_pushinteger(L, extra_data); + lua_setfield(L, -2, "language"); +} + + +void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) { + Seperator sep(data.c_str()); + + Mob *o = entity_list.GetMobID(std::stoi(sep.arg[0])); + Lua_Mob l_mob(o); + luabind::object l_mob_o = luabind::object(L, l_mob); + l_mob_o.push(L); + lua_setfield(L, -2, "other"); + + lua_pushinteger(L, std::stoi(sep.arg[1])); + lua_setfield(L, -2, "damage"); + + int spell_id = std::stoi(sep.arg[2]); + 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"); + } + + lua_pushinteger(L, std::stoi(sep.arg[3])); + lua_setfield(L, -2, "skill_id"); +} + +void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) { + lua_pushstring(L, data.c_str()); + lua_setfield(L, -2, "timer"); +} + +void handle_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) { + const Item_Struct *item = database.GetItem(extra_data); + if(item) { + Lua_Item l_item(item); + luabind::object l_item_o = luabind::object(L, l_item); + l_item_o.push(L); + lua_setfield(L, -2, "item"); + } else { + Lua_Item l_item(nullptr); + luabind::object l_item_o = luabind::object(L, l_item); + l_item_o.push(L); + lua_setfield(L, -2, "item"); + } +} + void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data) { } diff --git a/zone/lua_ptr.h b/zone/lua_ptr.h index 7b8fc261d..0a6df3d95 100644 --- a/zone/lua_ptr.h +++ b/zone/lua_ptr.h @@ -2,23 +2,24 @@ #define EQEMU_LUA_PTR_H #ifdef LUA_EQEMU +template class Lua_Ptr { public: Lua_Ptr() { } - Lua_Ptr(void *d) : d_(d) { + Lua_Ptr(T *d) : d_(d) { } ~Lua_Ptr() { } - void *GetLuaPtrData() { + T *GetLuaPtrData() { return d_; } - void SetLuaPtrData(void *d) { + void SetLuaPtrData(T *d) { d_ = d; } @@ -31,7 +32,7 @@ public: } protected: - void *d_; + T *d_; }; #endif diff --git a/zone/lua_spell.h b/zone/lua_spell.h index 131b6f21f..bed0eb2d7 100644 --- a/zone/lua_spell.h +++ b/zone/lua_spell.h @@ -1,23 +1,23 @@ -#ifndef EQEMU_LUA_ITEM_H -#define EQEMU_LUA_ITEM_H +#ifndef EQEMU_LUA_SPELL_H +#define EQEMU_LUA_SPELL_H #ifdef LUA_EQEMU #include "lua_ptr.h" struct SPDat_Spell_Struct; -class Lua_Spell : public Lua_Ptr +class Lua_Spell : public Lua_Ptr { - typedef SPDat_Spell_Struct NativeType; + typedef const SPDat_Spell_Struct NativeType; public: Lua_Spell() { } - Lua_Spell(SPDat_Spell_Struct *d) : Lua_Ptr(d) { } + Lua_Spell(const SPDat_Spell_Struct *d) : Lua_Ptr(d) { } virtual ~Lua_Spell() { } - operator SPDat_Spell_Struct*() { - void *d = GetLuaPtrData(); + operator const SPDat_Spell_Struct*() { + const void *d = GetLuaPtrData(); if(d) { - return reinterpret_cast(d); + return reinterpret_cast(d); } return nullptr; diff --git a/zone/net.cpp b/zone/net.cpp index 50286753e..258fb6325 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -284,17 +284,16 @@ int main(int argc, char** argv) { } parse = new QuestParserCollection(); -#ifdef EMBPERL - //PerlXSParser *pxs = new PerlXSParser(); - PerlembParser *perl_parser = new PerlembParser(); - parse->RegisterQuestInterface(perl_parser, "pl"); -#endif - #ifdef LUA_EQEMU LuaParser *lua_parser = new LuaParser(); parse->RegisterQuestInterface(lua_parser, "lua"); #endif +#ifdef EMBPERL + PerlembParser *perl_parser = new PerlembParser(); + parse->RegisterQuestInterface(perl_parser, "pl"); +#endif + //now we have our parser, load the quests _log(ZONE__INIT, "Loading quests"); parse->ReloadQuests(); diff --git a/zone/npc.cpp b/zone/npc.cpp index bf1ac517c..cae899378 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -357,7 +357,6 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float NPC::~NPC() { - ClearQuestLists(); entity_list.RemoveNPC(GetID()); AI_Stop(); @@ -2342,21 +2341,6 @@ bool NPC::CanTalk() return false; } -void NPC::PrintOutQuestItems(Client* c){ - c->Message(4,"Quest Items currently awaiting completion on %s",GetName()); - - LinkedListIterator iterator(questItems); - iterator.Reset(); - - while(iterator.MoreElements()) - { - c->Message(5,"ItemName: %s (%d) | Charges: %i",iterator.GetData()->GetItem()->Name,iterator.GetData()->GetItem()->ID,iterator.GetData()->GetCharges()); - iterator.Advance(); - } - - c->Message(4,"End of quest items list."); -} - //this is called with 'this' as the mob being looked at, and //iOther the mob who is doing the looking. It should figure out //what iOther thinks about 'this' diff --git a/zone/npc.h b/zone/npc.h index 87d6cccc9..80e6e694c 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -349,111 +349,6 @@ public: inline void SetHealScale(float amt) { healscale = amt; } inline float GetHealScale() { return healscale; } - void AddQuestItem(ItemInst* inst) { questItems.Insert(inst); } - - void ClearQuestLists() - { - ClearQuestItems(true); - ClearQuestDeleteItems(true); - } - - void ResetQuestDeleteList() - { - ClearQuestDeleteItems(true); - } - - - void ClearQuestItems(bool delete_=false) - { - LinkedListIterator iterator(questItems); - iterator.Reset(); - while(iterator.MoreElements()) - { - iterator.RemoveCurrent(delete_); - } - - questItems.Clear(); - } - - void ClearQuestDeleteItems(bool delete_=false) - { - LinkedListIterator iterator(questDeletionItems); - iterator.Reset(); - while(iterator.MoreElements()) - { - iterator.RemoveCurrent(delete_); - } - - questDeletionItems.Clear(); - } - - ItemInst* FindQuestItemByID(uint32 itmID, int charges, bool flagItemForDeletion=false) - { - LinkedListIterator iterator(questItems); - iterator.Reset(); - int totalCharges = 0; - while(iterator.MoreElements()) - { - if ( iterator.GetData()->GetItem()->ID == itmID ) - { - totalCharges += 1; - - if ( flagItemForDeletion ) - questDeletionItems.Insert(iterator.GetData()->Clone()); - if ( charges > totalCharges ) - { - iterator.Advance(); - continue; - } - - return iterator.GetData(); - } - iterator.Advance(); - } - return nullptr; - } - - bool DoesQuestItemExist(uint32 itmID, int charges, bool flagItemForDeletion=false) { - ItemInst* inst = FindQuestItemByID(itmID,charges,flagItemForDeletion); - if ( inst != nullptr ) - { - return true; - } - else - return false; - } - - void ClearQuestItem(ItemInst* inst, bool delete_=true) - { - LinkedListIterator iterator(questItems); - iterator.Reset(); - - while(iterator.MoreElements()) - { - if ( iterator.GetData ()->GetItem()->ID == inst->GetItem()->ID ) - { - iterator.RemoveCurrent(delete_); - break; - } - iterator.Advance(); - } - } - - void RemoveQuestDeleteItems() - { - LinkedListIterator iterator(questDeletionItems); - iterator.Reset(); - while(iterator.MoreElements()) - { - ClearQuestItem(iterator.GetData(),true); - iterator.RemoveCurrent(true); - } - - questDeletionItems.Clear(); - } - - void PrintOutQuestItems(Client* c); - uint32 GetSpawnKillCount(); int GetScore(); void mod_prespawn(Spawn2 *sp); @@ -552,9 +447,6 @@ protected: QGlobalCache *qGlobals; uint32 adventure_template_id; - LinkedList questItems; - LinkedList questDeletionItems; - //mercenary stuff std::list mercTypeList; std::list mercDataList; diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 775ff464d..c3244f156 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2730,41 +2730,6 @@ const char* QuestManager::GetZoneLongName(const char *zone) { return ln.c_str(); } -bool QuestManager::TurnInItem(uint32 itm, int charges) -{ - if ( owner && owner->IsNPC() ) - { - if ( owner->CastToNPC()->DoesQuestItemExist(itm, charges, true) ) - return true; - } - - return false; -} - -void QuestManager::CompleteHandIn() -{ - if ( owner && owner->IsNPC() ) - { - owner->CastToNPC()->RemoveQuestDeleteItems(); - } -} - -void QuestManager::ResetHandIn() -{ - if ( owner && owner->IsNPC() ) - { - owner->CastToNPC()->ResetQuestDeleteList(); - } -} - -void QuestManager::ClearHandIn() -{ - if ( owner && owner->IsNPC() ) - { - owner->CastToNPC()->ClearQuestLists(); - } -} - void QuestManager::CrossZoneSignalPlayerByCharID(int charid, uint32 data){ ServerPacket* pack = new ServerPacket(ServerOP_CZSignalClient, sizeof(CZClientSignal_Struct)); CZClientSignal_Struct* CZSC = (CZClientSignal_Struct*) pack->pBuffer; diff --git a/zone/questmgr.h b/zone/questmgr.h index 5f321aec6..09b40eee1 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -238,10 +238,6 @@ public: inline ItemInst *GetQuestItem() const {return questitem; } inline bool ProximitySayInUse() { return HaveProximitySays; } - bool TurnInItem(uint32 itm, int charges); - void CompleteHandIn(); - void ResetHandIn(); - void ClearHandIn(); void CrossZoneSignalPlayerByCharID(int charid, uint32 data); void CrossZoneSignalPlayerByName(const char *CharName, uint32 data); void CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message); diff --git a/zone/trading.cpp b/zone/trading.cpp index 5fead2d23..f64f5e3d9 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -572,22 +572,25 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) if(parse->HasQuestSub(tradingWith->GetNPCTypeID(), "EVENT_TRADE")) { // This is a quest NPC quest_npc = true; - if(RuleB(NPC, UseMultiQuest)){ - StoreTurnInItems(tradingWith); - } } - uint32 items[4]={0}; - uint8 charges[4]={0}; - bool attuned[4]={0}; + uint32 items[4] = { 0 }; + uint8 charges[4] = { 0 }; + bool attuned[4] = { 0 }; + uint32 augments[4][5] = { 0 }; - for (int16 i=3000; i<=3003; i++) { + for (int i = 3000; i < 3004; i++) { const ItemInst* inst = m_inv[i]; if (inst) { - items[i-3000]=inst->GetItem()->ID; - charges[i-3000]=inst->GetCharges(); - attuned[i-3000]=inst->IsInstNoDrop(); - const Item_Struct* item2 = database.GetItem(items[i-3000]); + items[i - 3000] = inst->GetItem()->ID; + charges[i - 3000] = inst->GetCharges(); + attuned[i - 3000] = inst->IsInstNoDrop(); + + for(int j = 0; j < 5; j++) { + augments[i][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 @@ -630,33 +633,37 @@ 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]; - memset(temp1,0x0,100); - char temp2[100]; - memset(temp2,0x0,100); + 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); + 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); + + for(int y = 0; y < 5; y++) { + snprintf(temp1, 100, "item%d.augment.%d", z + 1, tradingWith->GetNPCTypeID()); + snprintf(temp2, 100, "%d", augments[z][y]); + parse->AddVar(temp1, temp2); + } } - snprintf(temp1, 100, "copper.%d",tradingWith->GetNPCTypeID()); - snprintf(temp2, 100, "%i",trade->cp); - parse->AddVar(temp1,temp2); - snprintf(temp1, 100, "silver.%d",tradingWith->GetNPCTypeID()); - snprintf(temp2, 100, "%i",trade->sp); - parse->AddVar(temp1,temp2); + 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, "%i",trade->gp); + snprintf(temp2, 100, "%u", trade->gp); parse->AddVar(temp1, temp2); snprintf(temp1, 100, "platinum.%d", tradingWith->GetNPCTypeID()); - snprintf(temp2, 100, "%i",trade->pp); - parse->AddVar(temp1,temp2); + snprintf(temp2, 100, "%u", trade->pp); + parse->AddVar(temp1, temp2); if(tradingWith->GetAppearance() != eaDead) { tradingWith->FaceTarget(this); @@ -2720,21 +2727,3 @@ void Client::BuyerItemSearch(const EQApplicationPacket *app) { QueuePacket(outapp); safe_delete(outapp); } - -bool Client::StoreTurnInItems(Mob* tradingWith) { - - if ( !tradingWith || !tradingWith->IsNPC() ) - return false; - - for (int16 i=3000; i<=3003; i++) { - const ItemInst* inst = m_inv[i]; - if (inst) { - database.logevents(AccountName(),AccountID(),admin,GetName(),tradingWith->GetName(),"Quest Turn In Attempt",inst->GetItem()->Name,22); - - tradingWith->CastToNPC()->AddQuestItem(inst->Clone()); - } - } - - return true; -} -