diff options
| author | Treeston <treeston.mmoc@gmail.com> | 2020-09-04 00:58:23 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-04 00:58:23 +0200 |
| commit | 88d446dadf65bf47c72d3042834281233b1174ac (patch) | |
| tree | 3e111e59e2241712bc82c627fdcb3e8ed9a9cf51 /src/server/scripts/Commands | |
| parent | 35b3ba90b03143f2dc700cc4baeb88a58089c102 (diff) | |
Scripts/Commands: Convert argument parsing of .npc commands
(And I snuck some chat command cleanup in there, more de-cluttering!)
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 | 634 |
2 files changed, 200 insertions, 442 deletions
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 8b796cd6f49..3910d5213d6 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -43,13 +43,15 @@ EndScriptData */ #include <boost/core/demangle.hpp> #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 45e98088460..fd1f6e71585 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -39,93 +39,21 @@ EndScriptData */ #include "Pet.h" #include "Player.h" #include "RBAC.h" +#include "SmartEnum.h" #include "Transport.h" #include "World.h" #include "WorldSession.h" #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: @@ -195,16 +123,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; @@ -255,37 +175,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) { - if (!*args) - return false; - - char* pitem = handler->extractKeyFromLink((char*)args, "Hitem"); - if (!pitem) + if (!item) { handler->SendSysMessage(LANG_COMMAND_NEEDITEMSEND); handler->SetSentErrorMessage(true); return false; } - int32 item_int = atol(pitem); - if (item_int <= 0) - return false; - - uint32 itemId = item_int; - - 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; Creature* vendor = handler->getSelectedCreature(); if (!vendor) { @@ -294,6 +192,10 @@ public: return false; } + uint32 itemId = item->ItemId; + uint32 maxcount = mc.value_or(0); + uint32 incrtime = it.value_or(0); + uint32 extendedcost = ec.value_or(0); uint32 vendor_entry = vendor->GetEntry(); if (!sObjectMgr->IsVendorItemValid(vendor_entry, itemId, maxcount, incrtime, extendedcost, handler->GetSession()->GetPlayer())) @@ -311,16 +213,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 = atoul(guidStr); - // attempt check creature existence by DB data CreatureData const* data = sObjectMgr->GetCreatureData(lowGuid); if (!data) @@ -330,11 +224,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); @@ -348,7 +237,7 @@ public: return true; } - static bool HandleNpcSetAllowMovementCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleNpcSetAllowMovementCommand(ChatHandler* handler) { if (sWorld->getAllowMovement()) { @@ -363,12 +252,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; @@ -388,12 +273,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); @@ -417,7 +298,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) @@ -454,11 +335,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()) { @@ -467,15 +345,14 @@ 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); + uint32 itemId = item->ItemId; if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), itemId)) { handler->PSendSysMessage(LANG_ITEM_NOT_IN_LIST, itemId); @@ -490,13 +367,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); @@ -559,23 +431,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) @@ -592,7 +449,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(); @@ -611,7 +468,7 @@ public: return true; } - static bool HandleNpcInfoCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleNpcInfoCommand(ChatHandler* handler) { Creature* target = handler->getSelectedCreature(); @@ -683,9 +540,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(); @@ -730,26 +587,17 @@ public: } //move selected creature - static bool HandleNpcMoveCommand(ChatHandler* handler, char const* args) + static bool HandleNpcMoveCommand(ChatHandler* handler, Optional<CreatureSpawnId> spawnid) { - ObjectGuid::LowType lowguid = 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 = atoul(cId); - } + ObjectGuid::LowType lowguid = spawnid ? *spawnid : creature->GetSpawnId(); // Attempting creature load from DB data CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); if (!data) @@ -782,23 +630,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) { @@ -813,13 +653,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()) @@ -831,7 +666,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; } @@ -856,11 +691,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) @@ -868,50 +700,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 = 0; Creature* creature = nullptr; - if (dontdel_str) - { - //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 + if (!lowGuid) // case .setmovetype $move_type (with selected creature) { - // 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; @@ -919,7 +715,7 @@ public: } else // case .setmovetype #creature_guid $move_type (with selected creature) { - lowguid = atoul(guid_str); + lowguid = *lowGuid; if (lowguid) creature = handler->GetCreatureFromPlayerMapByDbGuid(lowguid); @@ -945,17 +741,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) @@ -978,11 +777,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; @@ -990,12 +789,8 @@ public: //npc phasemask handling //change phasemask of creature or pet - static bool HandleNpcSetPhaseCommand(ChatHandler* handler, char const* args) + static bool HandleNpcSetPhaseCommand(ChatHandler* handler, uint32 phasemask) { - if (!*args) - return false; - - uint32 phasemask = atoul(args); if (phasemask == 0) { handler->SendSysMessage(LANG_BAD_VALUE); @@ -1020,12 +815,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); @@ -1033,7 +824,7 @@ public: } MovementGeneratorType mtype = IDLE_MOTION_TYPE; - if (option >0.0f) + if (option > 0.0f) mtype = RANDOM_MOTION_TYPE; Creature* creature = handler->getSelectedCreature(); @@ -1066,49 +857,26 @@ 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; - - int spawnTime = atoi(stime); - - if (spawnTime < 0) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - Creature* creature = handler->getSelectedCreature(); - ObjectGuid::LowType guidLow = 0; - - if (creature) - guidLow = creature->GetSpawnId(); - else + if (!creature) return false; WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_SPAWN_TIME_SECS); - - stmt->setUInt32(0, uint32(spawnTime)); - stmt->setUInt32(1, guidLow); - + stmt->setUInt32(0, spawnTime); + stmt->setUInt32(1, creature->GetSpawnId()); WorldDatabase.Execute(stmt); - creature->SetRespawnDelay((uint32)spawnTime); + creature->SetRespawnDelay(spawnTime); handler->PSendSysMessage(LANG_COMMAND_SPAWNTIME, spawnTime); 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(); @@ -1119,24 +887,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(); @@ -1148,13 +915,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(); @@ -1189,24 +956,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) @@ -1216,10 +969,8 @@ public: return false; } - ObjectGuid receiver_guid(HighGuid::Player, uint32(atoul(receiver_str))); - // check online security - Player* receiver = ObjectAccessor::FindPlayer(receiver_guid); + Player* receiver = ObjectAccessor::FindPlayerByName(recv); if (handler->HasLowerSecurity(receiver, ObjectGuid::Empty)) return false; @@ -1227,14 +978,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) @@ -1244,7 +991,7 @@ public: return false; } - creature->Yell(args, LANG_UNIVERSAL); + creature->Yell(text, LANG_UNIVERSAL); // make an emote creature->HandleEmoteCommand(EMOTE_ONESHOT_SHOUT); @@ -1253,40 +1000,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()) @@ -1352,7 +1089,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()) @@ -1369,30 +1106,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; } @@ -1429,7 +1145,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()) @@ -1450,7 +1166,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) @@ -1491,12 +1207,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 = atoul(args); Creature* creature = handler->getSelectedCreature(); if (!creature || !creature->GetSpawnId()) @@ -1538,13 +1250,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 = atoul(args); - Creature* creature = handler->getSelectedCreature(); if (!creature) @@ -1573,16 +1280,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); @@ -1590,53 +1299,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; } @@ -1646,3 +1330,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; +} |
