From 8866b3170e23e4573a0d8e39798fa45fbec00ec3 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Tue, 1 Apr 2014 21:03:49 -0400 Subject: [PATCH] Implement ability for NPC Merchants to open and close shop --- changelog.txt | 6 ++++++ zone/client_packet.cpp | 6 ++++++ zone/command.cpp | 29 ++++++++++++++++++++++++++++- zone/command.h | 2 ++ zone/lua_npc.cpp | 14 +++++++++++++- zone/lua_npc.h | 4 +++- zone/npc.cpp | 1 + zone/npc.h | 4 ++++ 8 files changed, 63 insertions(+), 3 deletions(-) diff --git a/changelog.txt b/changelog.txt index 94ed3789f..4afe9c941 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,11 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 04/01/2014 == +demonstar55: Implemented ability for a merchant to open and close shop. + Lua quest functions: e.self:MerchantOpenShop() and e.self:MerchantCloseShop() + GM Commands: #merchant_open_shop (short: #open_shop) and #merchant_close_shop (short: #close_shop) + default to status 100, just in case you need to force the merchants status + == 03/31/2014 == Uleat: Fix for unconscious skillups. Uleat: Fix for crash issue with nullptr reference in recent Client::SummonItem() work. diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 441681fd0..cde2b143f 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -5421,6 +5421,12 @@ void Client::Handle_OP_ShopRequest(const EQApplicationPacket *app) action = 0; } + // 1199 I don't have time for that now. etc + if (!tmp->CastToNPC()->IsMerchantOpen()) { + tmp->Say_StringID(MakeRandomInt(1199, 1202)); + action = 0; + } + EQApplicationPacket* outapp = new EQApplicationPacket(OP_ShopRequest, sizeof(Merchant_Click_Struct)); Merchant_Click_Struct* mco=(Merchant_Click_Struct*)outapp->pBuffer; diff --git a/zone/command.cpp b/zone/command.cpp index c55fa4542..8c2192c87 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -449,7 +449,11 @@ int command_init(void) { command_add("questerrors", "Shows quest errors.", 100, command_questerrors) || command_add("enablerecipe", "[recipe_id] - Enables a recipe using the recipe id.", 80, command_enablerecipe) || command_add("disablerecipe", "[recipe_id] - Disables a recipe using the recipe id.", 80, command_disablerecipe) || - command_add("npctype_cache", "[id] or all - Clears the npc type cache for either the id or all npcs.", 250, command_npctype_cache) + command_add("npctype_cache", "[id] or all - Clears the npc type cache for either the id or all npcs.", 250, command_npctype_cache) || + command_add("merchant_open_shop", "Opens a merchants shop", 100, command_merchantopenshop) || + command_add("open_shop", nullptr, 100, command_merchantopenshop) || + command_add("merchant_close_shop", "Closes a merchant shop", 100, command_merchantcloseshop) || + command_add("close_shop", nullptr, 100, command_merchantcloseshop) ) { command_deinit(); @@ -11497,3 +11501,26 @@ void command_npctype_cache(Client *c, const Seperator *sep) c->Message(0, "#npctype_cache all"); } } + +void command_merchantopenshop(Client *c, const Seperator *sep) +{ + Mob *merchant = c->GetTarget(); + if (!merchant || merchant->GetClass() != MERCHANT) { + c->Message(0, "You must target a merchant to open their shop."); + return; + } + + merchant->CastToNPC()->MerchantOpenShop(); +} + +void command_merchantcloseshop(Client *c, const Seperator *sep) +{ + Mob *merchant = c->GetTarget(); + if (!merchant || merchant->GetClass() != MERCHANT) { + c->Message(0, "You must target a merchant to close their shop."); + return; + } + + merchant->CastToNPC()->MerchantCloseShop(); +} + diff --git a/zone/command.h b/zone/command.h index 48ca51b58..a36009309 100644 --- a/zone/command.h +++ b/zone/command.h @@ -324,6 +324,8 @@ void command_enablerecipe(Client *c, const Seperator *sep); void command_disablerecipe(Client *c, const Seperator *sep); void command_showspellslist(Client *c, const Seperator *sep); void command_npctype_cache(Client *c, const Seperator *sep); +void command_merchantopenshop(Client *c, const Seperator *sep); +void command_merchantcloseshop(Client *c, const Seperator *sep); #ifdef EQPROFILE void command_profiledump(Client *c, const Seperator *sep); diff --git a/zone/lua_npc.cpp b/zone/lua_npc.cpp index e9d1ae0ec..1dd61cc91 100644 --- a/zone/lua_npc.cpp +++ b/zone/lua_npc.cpp @@ -432,6 +432,16 @@ int Lua_NPC::GetScore() { return self->GetScore(); } +void Lua_NPC::MerchantOpenShop() { + Lua_Safe_Call_Void(); + self->MerchantOpenShop(); +} + +void Lua_NPC::MerchantCloseShop() { + Lua_Safe_Call_Void(); + self->MerchantCloseShop(); +} + luabind::scope lua_register_npc() { return luabind::class_("NPC") @@ -520,7 +530,9 @@ luabind::scope lua_register_npc() { .def("GetAttackSpeed", (float(Lua_NPC::*)(void))&Lua_NPC::GetAttackSpeed) .def("GetAccuracyRating", (int(Lua_NPC::*)(void))&Lua_NPC::GetAccuracyRating) .def("GetSpawnKillCount", (int(Lua_NPC::*)(void))&Lua_NPC::GetSpawnKillCount) - .def("GetScore", (int(Lua_NPC::*)(void))&Lua_NPC::GetScore); + .def("GetScore", (int(Lua_NPC::*)(void))&Lua_NPC::GetScore) + .def("MerchantOpenShop", (void(Lua_NPC::*)(void))&Lua_NPC::MerchantOpenShop) + .def("MerchantCloseShop", (void(Lua_NPC::*)(void))&Lua_NPC::MerchantCloseShop); } #endif diff --git a/zone/lua_npc.h b/zone/lua_npc.h index 1dbd33253..8c34ed17d 100644 --- a/zone/lua_npc.h +++ b/zone/lua_npc.h @@ -112,7 +112,9 @@ public: int GetAccuracyRating(); int GetSpawnKillCount(); int GetScore(); + void MerchantOpenShop(); + void MerchantCloseShop(); }; #endif -#endif \ No newline at end of file +#endif diff --git a/zone/npc.cpp b/zone/npc.cpp index 2c21c94a7..861a4359e 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -199,6 +199,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float SetMana(GetMaxMana()); MerchantType = d->merchanttype; + merchant_open = GetClass() == MERCHANT; adventure_template_id = d->adventure_template; org_x = x; org_y = y; diff --git a/zone/npc.h b/zone/npc.h index f374c8fe6..e8877172b 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -209,6 +209,10 @@ public: void SetSecSkill(uint8 skill_type) { sec_melee_type = skill_type; } uint32 MerchantType; + bool merchant_open; + inline void MerchantOpenShop() { merchant_open = true; } + inline void MerchantCloseShop() { merchant_open = false; } + inline bool IsMerchantOpen() { return merchant_open; } void Depop(bool StartSpawnTimer = false); void Stun(int duration); void UnStun();