aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/3.3.5/2021_01_28_00_world.sql11
-rw-r--r--src/server/scripts/Commands/cs_tele.cpp162
2 files changed, 135 insertions, 38 deletions
diff --git a/sql/updates/world/3.3.5/2021_01_28_00_world.sql b/sql/updates/world/3.3.5/2021_01_28_00_world.sql
new file mode 100644
index 00000000000..60ed2b34c59
--- /dev/null
+++ b/sql/updates/world/3.3.5/2021_01_28_00_world.sql
@@ -0,0 +1,11 @@
+DELETE FROM `command` WHERE `name` IN ('tele name npc id','tele name npc guid','tele name npc name');
+INSERT INTO `command` (`name`,`help`) VALUES
+('tele name npc id','Syntax: .tele name id #playername #creatureId
+
+Teleport the given character to first found creature with id #creatureId. Character can be offline.'),
+('tele name npc guid','Syntax: .tele name id #playername #creatureSpawnId
+
+Teleport the given character to creature with spawn id #creatureSpawnId. Character can be offline.'),
+('tele name npc name','Syntax: .tele 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 38cba116284..db98dbd630f 100644
--- a/src/server/scripts/Commands/cs_tele.cpp
+++ b/src/server/scripts/Commands/cs_tele.cpp
@@ -43,11 +43,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 },
};
@@ -107,40 +118,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_homebindMapId, target->m_homebindX, target->m_homebindY, target->m_homebindZ, target->GetOrientation());
- else
- {
- CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_HOMEBIND);
- stmt->setUInt32(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))
@@ -155,7 +142,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());
@@ -165,25 +152,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(PHASEMASK_NORMAL, tele->mapId, tele->position_x, tele->position_y, tele->position_z), player->GetGUID(), nullptr);
+ Player::SavePositionInDB({ mapId, pos }, sMapMgr->GetZoneId(PHASEMASK_NORMAL, { 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_homebindMapId, target->m_homebindX, target->m_homebindY, target->m_homebindZ, target->GetOrientation());
+ else
+ {
+ CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_HOMEBIND);
+ stmt->setUInt32(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)
{
@@ -293,6 +315,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()