aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts/Commands
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2020-09-04 00:58:23 +0200
committerGitHub <noreply@github.com>2020-09-04 00:58:23 +0200
commit88d446dadf65bf47c72d3042834281233b1174ac (patch)
tree3e111e59e2241712bc82c627fdcb3e8ed9a9cf51 /src/server/scripts/Commands
parent35b3ba90b03143f2dc700cc4baeb88a58089c102 (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.cpp8
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp634
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;
+}