diff options
author | Treeston <treeston.mmoc@gmail.com> | 2020-09-04 00:58:23 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-02-05 00:43:55 +0100 |
commit | 4d62cc70d6a7726d6619ba5c722fcb74d1123396 (patch) | |
tree | 723da75a1eac12b687b570fffbfaa7fa093b7b47 /src/server/scripts/Commands | |
parent | 6fded37e86bc77cd54be63139fb434708223da98 (diff) |
Scripts/Commands: Convert argument parsing of .npc commands
(And I snuck some chat command cleanup in there, more de-cluttering!)
(cherry picked from commit 88d446dadf65bf47c72d3042834281233b1174ac)
Diffstat (limited to 'src/server/scripts/Commands')
-rw-r--r-- | src/server/scripts/Commands/cs_gobject.cpp | 8 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_npc.cpp | 630 |
2 files changed, 201 insertions, 437 deletions
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 93dfac2992e..f2556ba8804 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -45,13 +45,15 @@ EndScriptData */ #include <sstream> #include <typeinfo> -// definitions are over in cs_npc.cpp -bool HandleNpcSpawnGroup(ChatHandler* handler, char const* args); -bool HandleNpcDespawnGroup(ChatHandler* handler, char const* args); using namespace Trinity::ChatCommands; using GameObjectSpawnId = Variant<Hyperlink<gameobject>, ObjectGuid::LowType>; using GameObjectEntry = Variant<Hyperlink<gameobject_entry>, uint32>; + +// definitions are over in cs_npc.cpp +bool HandleNpcSpawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'f','o','r','c','e'>, ExactSequence<'i','g','n','o','r','e','r','e','s','p','a','w','n'>>> const& opts); +bool HandleNpcDespawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'r','e','m','o','v','e','r','e','s','p','a','w','n','t','i','m','e'>>> const& opts); + class gobject_commandscript : public CommandScript { public: diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 8107ef086d6..b4bd7f6fc51 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -48,87 +48,14 @@ EndScriptData */ #include <boost/core/demangle.hpp> #include <typeinfo> -bool HandleNpcSpawnGroup(ChatHandler* handler, char const* args) -{ - if (!*args) - return false; - - bool ignoreRespawn = false; - bool force = false; - uint32 groupId = 0; - - // Decode arguments - char* arg = strtok((char*)args, " "); - while (arg) - { - std::string thisArg = arg; - std::transform(thisArg.begin(), thisArg.end(), thisArg.begin(), ::tolower); - if (thisArg == "ignorerespawn") - ignoreRespawn = true; - else if (thisArg == "force") - force = true; - else if (thisArg.empty() || !(std::count_if(thisArg.begin(), thisArg.end(), ::isdigit) == (int)thisArg.size())) - return false; - else - groupId = atoi(thisArg.c_str()); - - arg = strtok(nullptr, " "); - } - - Player* player = handler->GetSession()->GetPlayer(); - - std::vector <WorldObject*> creatureList; - if (!player->GetMap()->SpawnGroupSpawn(groupId, ignoreRespawn, force, &creatureList)) - { - handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId); - handler->SetSentErrorMessage(true); - return false; - } - - handler->PSendSysMessage(LANG_SPAWNGROUP_SPAWNCOUNT, creatureList.size()); - - return true; -} - -bool HandleNpcDespawnGroup(ChatHandler* handler, char const* args) -{ - if (!*args) - return false; - - bool deleteRespawnTimes = false; - uint32 groupId = 0; - - // Decode arguments - char* arg = strtok((char*)args, " "); - while (arg) - { - std::string thisArg = arg; - std::transform(thisArg.begin(), thisArg.end(), thisArg.begin(), ::tolower); - if (thisArg == "removerespawntime") - deleteRespawnTimes = true; - else if (thisArg.empty() || !(std::count_if(thisArg.begin(), thisArg.end(), ::isdigit) == (int)thisArg.size())) - return false; - else - groupId = atoi(thisArg.c_str()); - - arg = strtok(nullptr, " "); - } - - Player* player = handler->GetSession()->GetPlayer(); - - size_t n = 0; - if (!player->GetMap()->SpawnGroupDespawn(groupId, deleteRespawnTimes, &n)) - { - handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId); - handler->SetSentErrorMessage(true); - return false; - } - handler->PSendSysMessage("Despawned a total of %zu objects.", n); +using namespace Trinity::ChatCommands; +using CreatureSpawnId = Variant<Hyperlink<creature>, ObjectGuid::LowType>; +using CreatureEntry = Variant<Hyperlink<creature_entry>, uint32>; - return true; -} +// shared with cs_gobject.cpp, definitions are at the bottom of this file +bool HandleNpcSpawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'f','o','r','c','e'>, ExactSequence<'i','g','n','o','r','e','r','e','s','p','a','w','n'>>> const& opts); +bool HandleNpcDespawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'r','e','m','o','v','e','r','e','s','p','a','w','n','t','i','m','e'>>> const& opts); -using namespace Trinity::ChatCommands; class npc_commandscript : public CommandScript { public: @@ -199,16 +126,8 @@ public: } //add spawn of creature - static bool HandleNpcAddCommand(ChatHandler* handler, char const* args) + static bool HandleNpcAddCommand(ChatHandler* handler, CreatureEntry id) { - if (!*args) - return false; - - char* charID = handler->extractKeyFromLink((char*)args, "Hcreature_entry"); - if (!charID) - return false; - - uint32 id = atoul(charID); if (!sObjectMgr->GetCreatureTemplate(id)) return false; @@ -254,38 +173,15 @@ public: } //add item in vendorlist - static bool HandleNpcAddVendorItemCommand(ChatHandler* handler, char const* args) + static bool HandleNpcAddVendorItemCommand(ChatHandler* handler, ItemTemplate const* item, Optional<uint32> mc, Optional<uint32> it, Optional<uint32> ec, Optional<std::string_view> bonusListIDs) { - if (!*args) - return false; - - const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument - - char* pitem = handler->extractKeyFromLink((char*)args, "Hitem"); - if (!pitem) + if (!item) { handler->SendSysMessage(LANG_COMMAND_NEEDITEMSEND); handler->SetSentErrorMessage(true); return false; } - uint32 itemId = atoull(pitem); - if (!itemId) - return false; - - char* fmaxcount = strtok(nullptr, " "); //add maxcount, default: 0 - uint32 maxcount = 0; - if (fmaxcount) - maxcount = atoul(fmaxcount); - - char* fincrtime = strtok(nullptr, " "); //add incrtime, default: 0 - uint32 incrtime = 0; - if (fincrtime) - incrtime = atoul(fincrtime); - - char* fextendedcost = strtok(nullptr, " "); //add ExtendedCost, default: 0 - uint32 extendedcost = fextendedcost ? atoul(fextendedcost) : 0; - char const* fbonuslist = strtok(nullptr, " "); Creature* vendor = handler->getSelectedCreature(); if (!vendor) { @@ -294,6 +190,10 @@ public: return false; } + uint32 itemId = item->GetId(); + uint32 maxcount = mc.value_or(0); + uint32 incrtime = it.value_or(0); + uint32 extendedcost = ec.value_or(0); uint32 vendor_entry = vendor->GetEntry(); VendorItem vItem; @@ -301,10 +201,10 @@ public: vItem.maxcount = maxcount; vItem.incrtime = incrtime; vItem.ExtendedCost = extendedcost; - vItem.Type = type; + vItem.Type = ITEM_VENDOR_TYPE_ITEM; - if (fbonuslist) - for (std::string_view token : Trinity::Tokenize(fbonuslist, ';', false)) + if (bonusListIDs) + for (std::string_view token : Trinity::Tokenize(*bonusListIDs, ';', false)) if (Optional<int32> bonusListID = Trinity::StringTo<int32>(token)) vItem.BonusListIDs.push_back(*bonusListID); @@ -323,16 +223,8 @@ public: } //add move for creature - static bool HandleNpcAddMoveCommand(ChatHandler* handler, char const* args) + static bool HandleNpcAddMoveCommand(ChatHandler* handler, CreatureSpawnId lowGuid) { - if (!*args) - return false; - - char* guidStr = strtok((char*)args, " "); - char* waitStr = strtok((char*)nullptr, " "); - - ObjectGuid::LowType lowGuid = atoull(guidStr); - // attempt check creature existence by DB data CreatureData const* data = sObjectMgr->GetCreatureData(lowGuid); if (!data) @@ -342,11 +234,6 @@ public: return false; } - int wait = waitStr ? atoi(waitStr) : 0; - - if (wait < 0) - wait = 0; - // Update movement type WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE); @@ -360,7 +247,7 @@ public: return true; } - static bool HandleNpcSetAllowMovementCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleNpcSetAllowMovementCommand(ChatHandler* handler) { if (sWorld->getAllowMovement()) { @@ -375,12 +262,8 @@ public: return true; } - static bool HandleNpcSetEntryCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSetEntryCommand(ChatHandler* handler, CreatureEntry newEntryNum) { - if (!*args) - return false; - - uint32 newEntryNum = atoul(args); if (!newEntryNum) return false; @@ -400,12 +283,8 @@ public: } //change level of creature or pet - static bool HandleNpcSetLevelCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSetLevelCommand(ChatHandler* handler, uint8 lvl) { - if (!*args) - return false; - - uint8 lvl = (uint8) atoi(args); if (lvl < 1 || lvl > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + 3) { handler->SendSysMessage(LANG_BAD_VALUE); @@ -429,7 +308,7 @@ public: return true; } - static bool HandleNpcDeleteCommand(ChatHandler* handler, Optional<Variant<Hyperlink<creature>, ObjectGuid::LowType>> spawnIdArg) + static bool HandleNpcDeleteCommand(ChatHandler* handler, Optional<CreatureSpawnId> spawnIdArg) { ObjectGuid::LowType spawnId; if (spawnIdArg) @@ -466,11 +345,8 @@ public: } //del item from vendor list - static bool HandleNpcDeleteVendorItemCommand(ChatHandler* handler, char const* args) + static bool HandleNpcDeleteVendorItemCommand(ChatHandler* handler, ItemTemplate const* item) { - if (!*args) - return false; - Creature* vendor = handler->getSelectedCreature(); if (!vendor || !vendor->IsVendor()) { @@ -479,18 +355,15 @@ public: return false; } - char* pitem = handler->extractKeyFromLink((char*)args, "Hitem"); - if (!pitem) + if (!item) { handler->SendSysMessage(LANG_COMMAND_NEEDITEMSEND); handler->SetSentErrorMessage(true); return false; } - uint32 itemId = atoul(pitem); - - const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument - if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), itemId, type)) + uint32 itemId = item->GetId(); + if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), ITEM_VENDOR_TYPE_ITEM, itemId)) { handler->PSendSysMessage(LANG_ITEM_NOT_IN_LIST, itemId); handler->SetSentErrorMessage(true); @@ -504,13 +377,8 @@ public: } //set faction of creature - static bool HandleNpcSetFactionIdCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSetFactionIdCommand(ChatHandler* handler, uint32 factionId) { - if (!*args) - return false; - - uint32 factionId = atoul(args); - if (!sFactionTemplateStore.LookupEntry(factionId)) { handler->PSendSysMessage(LANG_WRONG_FACTION, factionId); @@ -574,23 +442,8 @@ public: } //set data of creature for testing scripting - static bool HandleNpcSetDataCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSetDataCommand(ChatHandler* handler, uint32 data_1, uint32 data_2) { - if (!*args) - return false; - - char* arg1 = strtok((char*)args, " "); - char* arg2 = strtok((char*)nullptr, ""); - - if (!arg1 || !arg2) - return false; - - uint32 data_1 = (uint32)atoi(arg1); - uint32 data_2 = (uint32)atoi(arg2); - - if (!data_1 || !data_2) - return false; - Creature* creature = handler->getSelectedCreature(); if (!creature) @@ -607,7 +460,7 @@ public: } //npc follow handling - static bool HandleNpcFollowCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleNpcFollowCommand(ChatHandler* handler) { Player* player = handler->GetSession()->GetPlayer(); Creature* creature = handler->getSelectedCreature(); @@ -626,7 +479,7 @@ public: return true; } - static bool HandleNpcInfoCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleNpcInfoCommand(ChatHandler* handler) { Creature* target = handler->getSelectedCreature(); @@ -720,9 +573,9 @@ public: return true; } - static bool HandleNpcNearCommand(ChatHandler* handler, char const* args) + static bool HandleNpcNearCommand(ChatHandler* handler, Optional<float> dist) { - float distance = (!*args) ? 10.0f : float((atof(args))); + float distance = dist.value_or(10.0f); uint32 count = 0; Player* player = handler->GetSession()->GetPlayer(); @@ -767,26 +620,17 @@ public: } //move selected creature - static bool HandleNpcMoveCommand(ChatHandler* handler, char const* args) + static bool HandleNpcMoveCommand(ChatHandler* handler, Optional<CreatureSpawnId> spawnid) { - ObjectGuid::LowType lowguid = UI64LIT(0); - Creature* creature = handler->getSelectedCreature(); Player const* player = handler->GetSession()->GetPlayer(); if (!player) return false; - if (creature) - lowguid = creature->GetSpawnId(); - else - { - // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r - char* cId = handler->extractKeyFromLink((char*)args, "Hcreature"); - if (!cId) - return false; + if (!spawnid && !creature) + return false; - lowguid = atoull(cId); - } + ObjectGuid::LowType lowguid = spawnid ? *spawnid : creature->GetSpawnId(); // Attempting creature load from DB data CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); if (!data) @@ -819,23 +663,15 @@ public: // respawn selected creature at the new location if (creature) - { - if (creature->IsAlive()) - creature->setDeathState(JUST_DIED); - creature->Respawn(true); - if (!creature->GetRespawnCompatibilityMode()) - creature->AddObjectToRemoveList(); - } + creature->DespawnOrUnsummon(0s, 1s); handler->PSendSysMessage(LANG_COMMAND_CREATUREMOVED); return true; } //play npc emote - static bool HandleNpcPlayEmoteCommand(ChatHandler* handler, char const* args) + static bool HandleNpcPlayEmoteCommand(ChatHandler* handler, uint32 emote) { - uint32 emote = atoi((char*)args); - Creature* target = handler->getSelectedCreature(); if (!target) { @@ -850,13 +686,8 @@ public: } //set model of creature - static bool HandleNpcSetModelCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSetModelCommand(ChatHandler* handler, uint32 displayId) { - if (!*args) - return false; - - uint32 displayId = atoul(args); - Creature* creature = handler->getSelectedCreature(); if (!creature || creature->IsPet()) @@ -868,7 +699,7 @@ public: if (!sCreatureDisplayInfoStore.LookupEntry(displayId)) { - handler->PSendSysMessage(LANG_COMMAND_INVALID_PARAM, args); + handler->PSendSysMessage(LANG_COMMAND_INVALID_PARAM, Trinity::ToString(displayId).c_str()); handler->SetSentErrorMessage(true); return false; } @@ -893,11 +724,8 @@ public: * additional parameter: NODEL - so no waypoints are deleted, if you * change the movement type */ - static bool HandleNpcSetMoveTypeCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSetMoveTypeCommand(ChatHandler* handler, Optional<CreatureSpawnId> lowGuid, Variant<ExactSequence<'s','t','a','y'>, ExactSequence<'r','a','n','d','o','m'>, ExactSequence<'w','a','y'>> type, Optional<ExactSequence<'n','o','d','e','l'>> nodel) { - if (!*args) - return false; - // 3 arguments: // GUID (optional - you can also select the creature) // stay|random|way (determines the kind of movement) @@ -905,50 +733,14 @@ public: // this is very handy if you want to do waypoints, that are // later switched on/off according to special events (like escort // quests, etc) - char* guid_str = strtok((char*)args, " "); - char* type_str = strtok((char*)nullptr, " "); - char* dontdel_str = strtok((char*)nullptr, " "); - - bool doNotDelete = false; - if (!guid_str) - return false; + bool doNotDelete = nodel.has_value(); ObjectGuid::LowType lowguid = UI64LIT(0); Creature* creature = nullptr; - if (dontdel_str) + if (!lowGuid) // case .setmovetype $move_type (with selected creature) { - //TC_LOG_ERROR("misc", "DEBUG: All 3 params are set"); - - // All 3 params are set - // GUID - // type - // doNotDEL - if (stricmp(dontdel_str, "NODEL") == 0) - { - //TC_LOG_ERROR("misc", "DEBUG: doNotDelete = true;"); - doNotDelete = true; - } - } - else - { - // Only 2 params - but maybe NODEL is set - if (type_str) - { - TC_LOG_ERROR("misc", "DEBUG: Only 2 params "); - if (stricmp(type_str, "NODEL") == 0) - { - //TC_LOG_ERROR("misc", "DEBUG: type_str, NODEL "); - doNotDelete = true; - type_str = nullptr; - } - } - } - - if (!type_str) // case .setmovetype $move_type (with selected creature) - { - type_str = guid_str; creature = handler->getSelectedCreature(); if (!creature || creature->IsPet()) return false; @@ -956,7 +748,7 @@ public: } else // case .setmovetype #creature_guid $move_type (with selected creature) { - lowguid = atoull(guid_str); + lowguid = *lowGuid; if (lowguid) creature = handler->GetCreatureFromPlayerMapByDbGuid(lowguid); @@ -982,17 +774,20 @@ public: // and creature point (maybe) to this creature or nullptr MovementGeneratorType move_type; - - std::string type = type_str; - - if (type == "stay") - move_type = IDLE_MOTION_TYPE; - else if (type == "random") - move_type = RANDOM_MOTION_TYPE; - else if (type == "way") - move_type = WAYPOINT_MOTION_TYPE; - else - return false; + switch (type.index()) + { + case 0: + move_type = IDLE_MOTION_TYPE; + break; + case 1: + move_type = RANDOM_MOTION_TYPE; + break; + case 2: + move_type = WAYPOINT_MOTION_TYPE; + break; + default: + return false; + } // update movement type //if (doNotDelete == false) @@ -1015,11 +810,11 @@ public: } if (doNotDelete == false) { - handler->PSendSysMessage(LANG_MOVE_TYPE_SET, type_str); + handler->PSendSysMessage(LANG_MOVE_TYPE_SET, EnumUtils::ToTitle(move_type)); } else { - handler->PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL, type_str); + handler->PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL, EnumUtils::ToTitle(move_type)); } return true; @@ -1053,13 +848,9 @@ public: //npc phase handling //change phase of creature - static bool HandleNpcSetPhaseCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSetPhaseCommand(ChatHandler* handler, uint32 phaseID) { - if (!*args) - return false; - - uint32 phaseID = atoul(args); - if (!sPhaseStore.LookupEntry(phaseID)) + if (phaseID == 0) { handler->SendSysMessage(LANG_PHASE_NOTFOUND); handler->SetSentErrorMessage(true); @@ -1084,12 +875,8 @@ public: } //set spawn dist of creature - static bool HandleNpcSetWanderDistanceCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSetWanderDistanceCommand(ChatHandler* handler, float option) { - if (!*args) - return false; - - float option = (float)(atof((char*)args)); if (option < 0.0f) { handler->SendSysMessage(LANG_BAD_VALUE); @@ -1097,7 +884,7 @@ public: } MovementGeneratorType mtype = IDLE_MOTION_TYPE; - if (option >0.0f) + if (option > 0.0f) mtype = RANDOM_MOTION_TYPE; Creature* creature = handler->getSelectedCreature(); @@ -1130,28 +917,15 @@ public: } //spawn time handling - static bool HandleNpcSetSpawnTimeCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSetSpawnTimeCommand(ChatHandler* handler, uint32 spawnTime) { - if (!*args) - return false; - - char* stime = strtok((char*)args, " "); - - if (!stime) - return false; - - uint32 spawnTime = atoul(stime); - Creature* creature = handler->getSelectedCreature(); if (!creature) return false; - ObjectGuid::LowType guidLow = creature->GetSpawnId(); - WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_SPAWN_TIME_SECS); stmt->setUInt32(0, spawnTime); - stmt->setUInt64(1, guidLow); - + stmt->setUInt64(1, creature->GetSpawnId()); WorldDatabase.Execute(stmt); creature->SetRespawnDelay(spawnTime); @@ -1160,9 +934,9 @@ public: return true; } - static bool HandleNpcSayCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSayCommand(ChatHandler* handler, Tail text) { - if (!*args) + if (text.empty()) return false; Creature* creature = handler->getSelectedCreature(); @@ -1173,24 +947,23 @@ public: return false; } - creature->Say(args, LANG_UNIVERSAL); + creature->Say(text, LANG_UNIVERSAL); // make some emotes - char lastchar = args[strlen(args) - 1]; - switch (lastchar) + switch (text.back()) { - case '?': creature->HandleEmoteCommand(EMOTE_ONESHOT_QUESTION); break; - case '!': creature->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); break; - default: creature->HandleEmoteCommand(EMOTE_ONESHOT_TALK); break; + case '?': creature->HandleEmoteCommand(EMOTE_ONESHOT_QUESTION); break; + case '!': creature->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); break; + default: creature->HandleEmoteCommand(EMOTE_ONESHOT_TALK); break; } return true; } //show text emote by creature in chat - static bool HandleNpcTextEmoteCommand(ChatHandler* handler, char const* args) + static bool HandleNpcTextEmoteCommand(ChatHandler* handler, Tail text) { - if (!*args) + if (text.empty()) return false; Creature* creature = handler->getSelectedCreature(); @@ -1202,13 +975,13 @@ public: return false; } - creature->TextEmote(args); + creature->TextEmote(text); return true; } // npc unfollow handling - static bool HandleNpcUnFollowCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleNpcUnFollowCommand(ChatHandler* handler) { Player* player = handler->GetSession()->GetPlayer(); Creature* creature = handler->getSelectedCreature(); @@ -1243,24 +1016,10 @@ public: } // make npc whisper to player - static bool HandleNpcWhisperCommand(ChatHandler* handler, char const* args) + static bool HandleNpcWhisperCommand(ChatHandler* handler, Variant<Hyperlink<player>, std::string_view> recv, Tail text) { - if (!*args) - { - handler->SendSysMessage(LANG_CMD_SYNTAX); - handler->SetSentErrorMessage(true); + if (text.empty()) return false; - } - - char* receiver_str = strtok((char*)args, " "); - char* text = strtok(nullptr, ""); - - if (!receiver_str || !text) - { - handler->SendSysMessage(LANG_CMD_SYNTAX); - handler->SetSentErrorMessage(true); - return false; - } Creature* creature = handler->getSelectedCreature(); if (!creature) @@ -1270,10 +1029,8 @@ public: return false; } - ObjectGuid receiver_guid = ObjectGuid::Create<HighGuid::Player>(strtoull(receiver_str, nullptr, 10)); - // check online security - Player* receiver = ObjectAccessor::FindPlayer(receiver_guid); + Player* receiver = ObjectAccessor::FindPlayerByName(recv); if (handler->HasLowerSecurity(receiver, ObjectGuid::Empty)) return false; @@ -1281,14 +1038,10 @@ public: return true; } - static bool HandleNpcYellCommand(ChatHandler* handler, char const* args) + static bool HandleNpcYellCommand(ChatHandler* handler, Tail text) { - if (!*args) - { - handler->SendSysMessage(LANG_CMD_SYNTAX); - handler->SetSentErrorMessage(true); + if (text.empty()) return false; - } Creature* creature = handler->getSelectedCreature(); if (!creature) @@ -1298,7 +1051,7 @@ public: return false; } - creature->Yell(args, LANG_UNIVERSAL); + creature->Yell(text, LANG_UNIVERSAL); // make an emote creature->HandleEmoteCommand(EMOTE_ONESHOT_SHOUT); @@ -1307,40 +1060,30 @@ public: } // add creature, temp only - static bool HandleNpcAddTempSpawnCommand(ChatHandler* handler, char const* args) + static bool HandleNpcAddTempSpawnCommand(ChatHandler* handler, Optional<std::string_view> lootStr, CreatureEntry id) { - if (!*args) - return false; - bool loot = false; - char const* spawntype_str = strtok((char*)args, " "); - char const* entry_str = strtok(nullptr, ""); - if (stricmp(spawntype_str, "LOOT") == 0) - loot = true; - else if (stricmp(spawntype_str, "NOLOOT") == 0) - loot = false; - else - entry_str = args; - char* charID = handler->extractKeyFromLink((char*)entry_str, "Hcreature_entry"); - if (!charID) - return false; + if (lootStr) + { + if (StringEqualI(*lootStr, "loot")) + loot = true; + else if (StringEqualI(*lootStr, "noloot")) + loot = false; + else + return false; + } Player* chr = handler->GetSession()->GetPlayer(); - - uint32 id = atoul(charID); - if (!id) - return false; - if (!sObjectMgr->GetCreatureTemplate(id)) return false; - chr->SummonCreature(id, *chr, loot ? TEMPSUMMON_CORPSE_TIMED_DESPAWN : TEMPSUMMON_CORPSE_DESPAWN, 30s); + chr->SummonCreature(id, chr->GetPosition(), loot ? TEMPSUMMON_CORPSE_TIMED_DESPAWN : TEMPSUMMON_CORPSE_DESPAWN, 30s); return true; } //npc tame handling - static bool HandleNpcTameCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleNpcTameCommand(ChatHandler* handler) { Creature* creatureTarget = handler->getSelectedCreature(); if (!creatureTarget || creatureTarget->IsPet()) @@ -1406,7 +1149,7 @@ public: return true; } - static bool HandleNpcEvadeCommand(ChatHandler* handler, char const* args) + static bool HandleNpcEvadeCommand(ChatHandler* handler, Optional<CreatureAI::EvadeReason> why, Optional<ExactSequence<'f','o','r','c','e'>> force) { Creature* creatureTarget = handler->getSelectedCreature(); if (!creatureTarget || creatureTarget->IsPet()) @@ -1423,30 +1166,9 @@ public: return false; } - char* type_str = args ? strtok((char*)args, " ") : nullptr; - char* force_str = args ? strtok(nullptr, " ") : nullptr; - - CreatureAI::EvadeReason why = CreatureAI::EVADE_REASON_OTHER; - bool force = false; - if (type_str) - { - if (stricmp(type_str, "NO_HOSTILES") == 0 || stricmp(type_str, "EVADE_REASON_NO_HOSTILES") == 0) - why = CreatureAI::EVADE_REASON_NO_HOSTILES; - else if (stricmp(type_str, "BOUNDARY") == 0 || stricmp(type_str, "EVADE_REASON_BOUNDARY") == 0) - why = CreatureAI::EVADE_REASON_BOUNDARY; - else if (stricmp(type_str, "SEQUENCE_BREAK") == 0 || stricmp(type_str, "EVADE_REASON_SEQUENCE_BREAK") == 0) - why = CreatureAI::EVADE_REASON_SEQUENCE_BREAK; - else if (stricmp(type_str, "FORCE") == 0) - force = true; - - if (!force && force_str) - if (stricmp(force_str, "FORCE") == 0) - force = true; - } - if (force) creatureTarget->ClearUnitState(UNIT_STATE_EVADE); - creatureTarget->AI()->EnterEvadeMode(why); + creatureTarget->AI()->EnterEvadeMode(why.value_or(CreatureAI::EVADE_REASON_OTHER)); return true; } @@ -1480,7 +1202,7 @@ public: } } } - static bool HandleNpcShowLootCommand(ChatHandler* handler, char const* args) + static bool HandleNpcShowLootCommand(ChatHandler* handler, Optional<ExactSequence<'a','l','l'>> all) { Creature* creatureTarget = handler->getSelectedCreature(); if (!creatureTarget || creatureTarget->IsPet()) @@ -1501,7 +1223,7 @@ public: handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_HEADER, creatureTarget->GetName(), creatureTarget->GetEntry()); handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_MONEY, loot.gold / GOLD, (loot.gold%GOLD) / SILVER, loot.gold%SILVER); - if (strcmp(args, "all")) // nonzero from strcmp <-> not equal + if (!all) { handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_LABEL, "Standard items", loot.items.size()); for (LootItem const& item : loot.items) @@ -1542,12 +1264,8 @@ public: return true; } - static bool HandleNpcAddFormationCommand(ChatHandler* handler, char const* args) + static bool HandleNpcAddFormationCommand(ChatHandler* handler, ObjectGuid::LowType leaderGUID) { - if (!*args) - return false; - - ObjectGuid::LowType leaderGUID = atoull(args); Creature* creature = handler->getSelectedCreature(); if (!creature || !creature->GetSpawnId()) @@ -1589,13 +1307,8 @@ public: return true; } - static bool HandleNpcSetLinkCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSetLinkCommand(ChatHandler* handler, ObjectGuid::LowType linkguid) { - if (!*args) - return false; - - ObjectGuid::LowType linkguid = atoull(args); - Creature* creature = handler->getSelectedCreature(); if (!creature) @@ -1624,16 +1337,18 @@ public: } /// @todo NpcCommands that need to be fixed : - static bool HandleNpcAddWeaponCommand(ChatHandler* /*handler*/, char const* /*args*/) + static bool HandleNpcAddWeaponCommand([[maybe_unused]] ChatHandler* handler, [[maybe_unused]] uint32 SlotID, [[maybe_unused]] ItemTemplate const* tmpItem) { - /*if (!*args) - return false; + /* + if (!tmpItem) + return; uint64 guid = handler->GetSession()->GetPlayer()->GetSelection(); if (guid == 0) { handler->SendSysMessage(LANG_NO_SELECTION); - return true; + handler->SetSentErrorMessage(true); + return false; } Creature* creature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(), guid); @@ -1641,53 +1356,28 @@ public: if (!creature) { handler->SendSysMessage(LANG_SELECT_CREATURE); - return true; - } - - char* pSlotID = strtok((char*)args, " "); - if (!pSlotID) - return false; - - char* pItemID = strtok(nullptr, " "); - if (!pItemID) + handler->SetSentErrorMessage(true); return false; - - uint32 ItemID = atoi(pItemID); - uint32 SlotID = atoi(pSlotID); - - ItemTemplate* tmpItem = sObjectMgr->GetItemTemplate(ItemID); - - bool added = false; - if (tmpItem) - { - switch (SlotID) - { - case 1: - creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID); - added = true; - break; - case 2: - creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID); - added = true; - break; - case 3: - creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID); - added = true; - break; - default: - handler->PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST, SlotID); - added = false; - break; - } - - if (added) - handler->PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT, ItemID, tmpItem->Name1, SlotID); } - else + + switch (SlotID) { - handler->PSendSysMessage(LANG_ITEM_NOT_FOUND, ItemID); - return true; + case 1: + creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, tmpItem->ItemId); + break; + case 2: + creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, tmpItem->ItemId); + break; + case 3: + creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, tmpItem->ItemId); + break; + default: + handler->PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST, SlotID); + handler->SetSentErrorMessage(true); + return false; } + + handler->PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT, tmpItem->ItemID, tmpItem->Name1, SlotID); */ return true; } @@ -1697,3 +1387,75 @@ void AddSC_npc_commandscript() { new npc_commandscript(); } + +bool HandleNpcSpawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'f','o','r','c','e'>, ExactSequence<'i','g','n','o','r','e','r','e','s','p','a','w','n'>>> const& opts) +{ + if (opts.empty()) + return false; + + bool ignoreRespawn = false; + bool force = false; + uint32 groupId = 0; + + // Decode arguments + for (auto const& variant : opts) + { + switch (variant.index()) + { + case 0: + groupId = variant.get<uint32>(); + break; + case 1: + force = true; + break; + case 2: + ignoreRespawn = true; + break; + } + } + + Player* player = handler->GetSession()->GetPlayer(); + + std::vector <WorldObject*> creatureList; + if (!player->GetMap()->SpawnGroupSpawn(groupId, ignoreRespawn, force, &creatureList)) + { + handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_SPAWNGROUP_SPAWNCOUNT, creatureList.size()); + + return true; +} + +bool HandleNpcDespawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'r','e','m','o','v','e','r','e','s','p','a','w','n','t','i','m','e'>>> const& opts) +{ + if (opts.empty()) + return false; + + bool deleteRespawnTimes = false; + uint32 groupId = 0; + + // Decode arguments + for (auto const& variant : opts) + { + if (variant.holds_alternative<uint32>()) + groupId = variant.get<uint32>(); + else + deleteRespawnTimes = true; + } + + Player* player = handler->GetSession()->GetPlayer(); + + size_t n = 0; + if (!player->GetMap()->SpawnGroupDespawn(groupId, deleteRespawnTimes, &n)) + { + handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId); + handler->SetSentErrorMessage(true); + return false; + } + handler->PSendSysMessage("Despawned a total of %zu objects.", n); + + return true; +} |