From c21d83b30a5f01551ce346630fbd67a06c922983 Mon Sep 17 00:00:00 2001 From: IntelligentQuantum Date: Sat, 4 Dec 2021 12:28:30 +0330 Subject: [PATCH] feat(Core/Commands): command to teleport character to npc (#8887) --- .../rev_1635830311358655196.sql | 10 +++ src/server/scripts/Commands/cs_tele.cpp | 88 +++++++++++++++++-- 2 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1635830311358655196.sql diff --git a/data/sql/updates/pending_db_world/rev_1635830311358655196.sql b/data/sql/updates/pending_db_world/rev_1635830311358655196.sql new file mode 100644 index 000000000..b9596861f --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1635830311358655196.sql @@ -0,0 +1,10 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1635830311358655196'); + +DELETE FROM `command` WHERE `name` IN ('teleport name npc id','teleport name npc guid','teleport name npc name'); +INSERT INTO `command` (`name`,`security`,`help`) VALUES +('teleport name npc id',2,'Syntax: .teleport name id #playername #creatureId +Teleport the given character to first found creature with id #creatureId. Character can be offline.'), +('teleport name npc guid',2,'Syntax: .teleport name id #playername #creatureSpawnId +Teleport the given character to creature with spawn id #creatureSpawnId. Character can be offline.'), +('teleport name npc name',2,'Syntax: .teleport name id #playername #creatureName +Teleport the given character to first found creature with name (must match exactly) #creatureName. Character can be offline.'); diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index ea552f59d..00c0a3a2e 100644 --- a/src/server/scripts/Commands/cs_tele.cpp +++ b/src/server/scripts/Commands/cs_tele.cpp @@ -23,6 +23,8 @@ Category: commandscripts EndScriptData */ #include "Chat.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" #include "Group.h" #include "Language.h" #include "MapMgr.h" @@ -39,13 +41,24 @@ public: ChatCommandTable GetCommands() const override { + static ChatCommandTable teleNameNpcCommandTable = + { + { "id", HandleTeleNameNpcIdCommand, SEC_GAMEMASTER, Console::Yes }, + { "guid", HandleTeleNameNpcSpawnIdCommand, SEC_GAMEMASTER, Console::Yes }, + { "name", HandleTeleNameNpcNameCommand, SEC_GAMEMASTER, Console::Yes }, + }; + static ChatCommandTable teleNameCommandTable = + { + { "npc", teleNameNpcCommandTable }, + { "", HandleTeleNameCommand, SEC_GAMEMASTER, Console::Yes }, + }; static ChatCommandTable teleCommandTable = { - { "add", HandleTeleAddCommand, SEC_ADMINISTRATOR, Console::No }, - { "del", HandleTeleDelCommand, SEC_ADMINISTRATOR, Console::Yes }, - { "name", HandleTeleNameCommand, SEC_GAMEMASTER, Console::Yes }, - { "group", HandleTeleGroupCommand, SEC_GAMEMASTER, Console::No }, - { "", HandleTeleCommand, SEC_GAMEMASTER, Console::No } + { "add", HandleTeleAddCommand, SEC_ADMINISTRATOR, Console::No }, + { "del", HandleTeleDelCommand, SEC_ADMINISTRATOR, Console::Yes }, + { "name", teleNameCommandTable }, + { "group", HandleTeleGroupCommand, SEC_GAMEMASTER, Console::No }, + { "", HandleTeleCommand, SEC_GAMEMASTER, Console::No } }; static ChatCommandTable commandTable = { @@ -97,7 +110,6 @@ public: handler->SetSentErrorMessage(true); return false; } - std::string name = tele->name; sObjectMgr->DeleteGameTele(name); handler->SendSysMessage(LANG_COMMAND_TP_DELETED); @@ -310,6 +322,70 @@ public: player->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation); return true; } + + static bool HandleTeleNameNpcIdCommand(ChatHandler* handler, PlayerIdentifier player, Variant, uint32> creatureId) + { + CreatureData const* spawnpoint = nullptr; + for (auto const& pair : sObjectMgr->GetAllCreatureData()) + { + if (pair.second.id != *creatureId) + continue; + + if (!spawnpoint) + spawnpoint = &pair.second; + else + { + handler->SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE); + break; + } + } + + if (!spawnpoint) + { + handler->SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + CreatureTemplate const* creatureTemplate = ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(*creatureId)); + + return DoNameTeleport(handler, player, spawnpoint->mapid, { spawnpoint->posX, spawnpoint->posY, spawnpoint->posZ }, creatureTemplate->Name); + } + + static bool HandleTeleNameNpcSpawnIdCommand(ChatHandler* handler, PlayerIdentifier player, Variant, ObjectGuid::LowType> spawnId) + { + CreatureData const* spawnpoint = sObjectMgr->GetCreatureData(spawnId); + if (!spawnpoint) + { + handler->SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + CreatureTemplate const* creatureTemplate = ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(spawnpoint->id)); + + return DoNameTeleport(handler, player, spawnpoint->mapid, { spawnpoint->posX, spawnpoint->posY, spawnpoint->posZ }, creatureTemplate->Name); + } + + static bool HandleTeleNameNpcNameCommand(ChatHandler* handler, PlayerIdentifier player, Tail name) + { + std::string normalizedName(name); + WorldDatabase.EscapeString(normalizedName); + + QueryResult result = WorldDatabase.PQuery("SELECT c.position_x, c.position_y, c.position_z, c.orientation, c.map, ct.name FROM creature c INNER JOIN creature_template ct ON c.id = ct.entry WHERE ct.name LIKE '%s'", normalizedName.c_str()); + if (!result) + { + handler->SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + if (result->GetRowCount() > 1) + handler->SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE); + + Field* fields = result->Fetch(); + return DoNameTeleport(handler, player, fields[4].GetUInt16(), { fields[0].GetFloat(), fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat() }, fields[5].GetString()); + } }; void AddSC_tele_commandscript()