aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts/Commands
diff options
context:
space:
mode:
authorMatan Shukry <matanshukry@gmail.com>2021-01-28 21:32:36 +0100
committerShauren <shauren.trinity@gmail.com>2022-03-06 16:37:42 +0100
commite93ef06b05c27c7c79b234e331a0d26aa956ba65 (patch)
treed9373e3e61753bae38cff4436fdc1413de65993d /src/server/scripts/Commands
parentd1cae5c6a9aaace44f1c21c88fcf2dde2b6e2971 (diff)
Core/Commands: Implemented command to teleport character to npc
Closes #25870 (cherry picked from commit d2be584f99a63a165cfd1d047f460a8ebfb87ac3)
Diffstat (limited to 'src/server/scripts/Commands')
-rw-r--r--src/server/scripts/Commands/cs_tele.cpp162
1 files changed, 124 insertions, 38 deletions
diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp
index 06f277b0370..6469a31249d 100644
--- a/src/server/scripts/Commands/cs_tele.cpp
+++ b/src/server/scripts/Commands/cs_tele.cpp
@@ -45,11 +45,22 @@ public:
ChatCommandTable GetCommands() const override
{
+ static ChatCommandTable teleNameNpcCommandTable =
+ {
+ { "id", HandleTeleNameNpcIdCommand, rbac::RBAC_PERM_COMMAND_TELE_NAME, Console::Yes },
+ { "guid", HandleTeleNameNpcSpawnIdCommand, rbac::RBAC_PERM_COMMAND_TELE_NAME, Console::Yes },
+ { "name", HandleTeleNameNpcNameCommand, rbac::RBAC_PERM_COMMAND_TELE_NAME, Console::Yes },
+ };
+ static ChatCommandTable teleNameCommandTable =
+ {
+ { "npc", teleNameNpcCommandTable },
+ { "", HandleTeleNameCommand, rbac::RBAC_PERM_COMMAND_TELE_NAME, Console::Yes },
+ };
static ChatCommandTable teleCommandTable =
{
{ "add", HandleTeleAddCommand, rbac::RBAC_PERM_COMMAND_TELE_ADD, Console::No },
{ "del", HandleTeleDelCommand, rbac::RBAC_PERM_COMMAND_TELE_DEL, Console::Yes },
- { "name", HandleTeleNameCommand, rbac::RBAC_PERM_COMMAND_TELE_NAME, Console::Yes },
+ { "name", teleNameCommandTable },
{ "group", HandleTeleGroupCommand, rbac::RBAC_PERM_COMMAND_TELE_GROUP, Console::No },
{ "", HandleTeleCommand, rbac::RBAC_PERM_COMMAND_TELE, Console::No },
};
@@ -109,40 +120,16 @@ public:
return true;
}
- // teleport player to given game_tele.entry
- static bool HandleTeleNameCommand(ChatHandler* handler, Optional<PlayerIdentifier> player, Variant<GameTele const*, EXACT_SEQUENCE("$home")> where)
+ static bool DoNameTeleport(ChatHandler* handler, PlayerIdentifier player, uint32 mapId, Position const& pos, std::string const& locationName)
{
- if (!player)
- player = PlayerIdentifier::FromTargetOrSelf(handler);
- if (!player)
- return false;
-
- if (where.index() == 1) // References target's homebind
+ if (!MapManager::IsValidMapCoord(mapId, pos) || sObjectMgr->IsTransportMap(mapId))
{
- if (Player* target = player->GetConnectedPlayer())
- target->TeleportTo(target->m_homebind);
- else
- {
- CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_HOMEBIND);
- stmt->setUInt64(0, player->GetGUID().GetCounter());
- PreparedQueryResult resultDB = CharacterDatabase.Query(stmt);
-
- if (resultDB)
- {
- Field* fieldsDB = resultDB->Fetch();
- WorldLocation loc(fieldsDB[0].GetUInt16(), fieldsDB[2].GetFloat(), fieldsDB[3].GetFloat(), fieldsDB[4].GetFloat(), 0.0f);
- uint32 zoneId = fieldsDB[1].GetUInt16();
-
- Player::SavePositionInDB(loc, zoneId, player->GetGUID(), nullptr);
- }
- }
-
- return true;
+ handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, pos.GetPositionX(), pos.GetPositionY(), mapId);
+ handler->SetSentErrorMessage(true);
+ return false;
}
- // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
- GameTele const* tele = where.get<GameTele const*>();
- if (Player* target = player->GetConnectedPlayer())
+ if (Player* target = player.GetConnectedPlayer())
{
// check online security
if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
@@ -157,7 +144,7 @@ public:
return false;
}
- handler->PSendSysMessage(LANG_TELEPORTING_TO, chrNameLink.c_str(), "", tele->name.c_str());
+ handler->PSendSysMessage(LANG_TELEPORTING_TO, chrNameLink.c_str(), "", locationName.c_str());
if (handler->needReportToTarget(target))
ChatHandler(target->GetSession()).PSendSysMessage(LANG_TELEPORTED_TO_BY, handler->GetNameLink().c_str());
@@ -167,25 +154,60 @@ public:
else
target->SaveRecallPosition(); // save only in non-flight case
- target->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation);
+ target->TeleportTo({ mapId, pos });
}
else
{
// check offline security
- if (handler->HasLowerSecurity(nullptr, player->GetGUID()))
+ if (handler->HasLowerSecurity(nullptr, player.GetGUID()))
return false;
- std::string nameLink = handler->playerLink(player->GetName());
+ std::string nameLink = handler->playerLink(player.GetName());
- handler->PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE), tele->name.c_str());
+ handler->PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE), locationName.c_str());
- Player::SavePositionInDB(WorldLocation(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation),
- sMapMgr->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), tele->mapId, tele->position_x, tele->position_y, tele->position_z), player->GetGUID(), nullptr);
+ Player::SavePositionInDB({ mapId, pos }, sMapMgr->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), { mapId, pos }), player.GetGUID(), nullptr);
}
return true;
}
+ // teleport player to given game_tele.entry
+ static bool HandleTeleNameCommand(ChatHandler* handler, Optional<PlayerIdentifier> player, Variant<GameTele const*, EXACT_SEQUENCE("$home")> where)
+ {
+ if (!player)
+ player = PlayerIdentifier::FromTargetOrSelf(handler);
+ if (!player)
+ return false;
+
+ if (where.index() == 1) // References target's homebind
+ {
+ if (Player* target = player->GetConnectedPlayer())
+ target->TeleportTo(target->m_homebind);
+ else
+ {
+ CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_HOMEBIND);
+ stmt->setUInt64(0, player->GetGUID().GetCounter());
+ PreparedQueryResult resultDB = CharacterDatabase.Query(stmt);
+
+ if (resultDB)
+ {
+ Field* fieldsDB = resultDB->Fetch();
+ WorldLocation loc(fieldsDB[0].GetUInt16(), fieldsDB[2].GetFloat(), fieldsDB[3].GetFloat(), fieldsDB[4].GetFloat(), 0.0f);
+ uint32 zoneId = fieldsDB[1].GetUInt16();
+
+ Player::SavePositionInDB(loc, zoneId, player->GetGUID(), nullptr);
+ }
+ }
+
+ return true;
+ }
+
+ // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
+ GameTele const* tele = where.get<GameTele const*>();
+ return DoNameTeleport(handler, *player, tele->mapId, { tele->position_x, tele->position_y, tele->position_z, tele->orientation }, tele->name);
+ }
+
//Teleport group to given game_tele.entry
static bool HandleTeleGroupCommand(ChatHandler* handler, GameTele const* tele)
{
@@ -295,6 +317,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<Hyperlink<creature_entry>, 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->spawnPoint, creatureTemplate->Name);
+ }
+
+ static bool HandleTeleNameNpcSpawnIdCommand(ChatHandler* handler, PlayerIdentifier player, Variant<Hyperlink<creature>, 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->spawnPoint, 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()