TrinityCore
cs_tele.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* ScriptData
19Name: tele_commandscript
20%Complete: 100
21Comment: All tele related commands
22Category: commandscripts
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "Chat.h"
27#include "ChatCommand.h"
28#include "DatabaseEnv.h"
29#include "DB2Stores.h"
30#include "Group.h"
31#include "Language.h"
32#include "MapManager.h"
33#include "ObjectMgr.h"
34#include "PhasingHandler.h"
35#include "Player.h"
36#include "RBAC.h"
37#include "TerrainMgr.h"
38#include "WorldSession.h"
39
40using namespace Trinity::ChatCommands;
41
43{
44public:
45 tele_commandscript() : CommandScript("tele_commandscript") { }
46
48 {
49 static ChatCommandTable teleNameNpcCommandTable =
50 {
54 };
55 static ChatCommandTable teleNameCommandTable =
56 {
57 { "npc", teleNameNpcCommandTable },
59 };
60 static ChatCommandTable teleCommandTable =
61 {
64 { "name", teleNameCommandTable },
67 };
68 static ChatCommandTable commandTable =
69 {
70 { "tele", teleCommandTable },
71 };
72 return commandTable;
73 }
74
75 static bool HandleTeleAddCommand(ChatHandler* handler, std::string const& name)
76 {
77 Player* player = handler->GetSession()->GetPlayer();
78 if (!player)
79 return false;
80
81 if (sObjectMgr->GetGameTeleExactName(name))
82 {
84 handler->SetSentErrorMessage(true);
85 return false;
86 }
87
88 GameTele tele;
89 tele.position_x = player->GetPositionX();
90 tele.position_y = player->GetPositionY();
91 tele.position_z = player->GetPositionZ();
92 tele.orientation = player->GetOrientation();
93 tele.mapId = player->GetMapId();
94 tele.name = name;
95
96 if (sObjectMgr->AddGameTele(tele))
97 {
99 }
100 else
101 {
103 handler->SetSentErrorMessage(true);
104 return false;
105 }
106
107 return true;
108 }
109
110 static bool HandleTeleDelCommand(ChatHandler* handler, GameTele const* tele)
111 {
112 if (!tele)
113 {
115 handler->SetSentErrorMessage(true);
116 return false;
117 }
118 std::string name = tele->name;
119 sObjectMgr->DeleteGameTele(name);
121 return true;
122 }
123
124 static bool DoNameTeleport(ChatHandler* handler, PlayerIdentifier player, uint32 mapId, Position const& pos, std::string const& locationName)
125 {
126 if (!MapManager::IsValidMapCoord(mapId, pos) || sObjectMgr->IsTransportMap(mapId))
127 {
129 handler->SetSentErrorMessage(true);
130 return false;
131 }
132
133 if (Player* target = player.GetConnectedPlayer())
134 {
135 // check online security
136 if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
137 return false;
138
139 std::string chrNameLink = handler->playerLink(target->GetName());
140
141 if (target->IsBeingTeleported() == true)
142 {
143 handler->PSendSysMessage(LANG_IS_TELEPORTED, chrNameLink.c_str());
144 handler->SetSentErrorMessage(true);
145 return false;
146 }
147
148 handler->PSendSysMessage(LANG_TELEPORTING_TO, chrNameLink.c_str(), "", locationName.c_str());
149 if (handler->needReportToTarget(target))
150 ChatHandler(target->GetSession()).PSendSysMessage(LANG_TELEPORTED_TO_BY, handler->GetNameLink().c_str());
151
152 // stop flight if need
153 if (target->IsInFlight())
154 target->FinishTaxiFlight();
155 else
156 target->SaveRecallPosition(); // save only in non-flight case
157
158 target->TeleportTo({ mapId, pos });
159 }
160 else
161 {
162 // check offline security
163 if (handler->HasLowerSecurity(nullptr, player.GetGUID()))
164 return false;
165
166 std::string nameLink = handler->playerLink(player.GetName());
167
168 handler->PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE), locationName.c_str());
169
170 Player::SavePositionInDB({ mapId, pos }, sTerrainMgr.GetZoneId(PhasingHandler::GetEmptyPhaseShift(), { mapId, pos }), player.GetGUID(), nullptr);
171 }
172
173 return true;
174 }
175
176 // teleport player to given game_tele.entry
177 static bool HandleTeleNameCommand(ChatHandler* handler, Optional<PlayerIdentifier> player, Variant<GameTele const*, EXACT_SEQUENCE("$home")> where)
178 {
179 if (!player)
180 player = PlayerIdentifier::FromTargetOrSelf(handler);
181 if (!player)
182 return false;
183
184 if (where.index() == 1) // References target's homebind
185 {
186 if (Player* target = player->GetConnectedPlayer())
187 target->TeleportTo(target->m_homebind);
188 else
189 {
191 stmt->setUInt64(0, player->GetGUID().GetCounter());
192 PreparedQueryResult resultDB = CharacterDatabase.Query(stmt);
193
194 if (resultDB)
195 {
196 Field* fieldsDB = resultDB->Fetch();
197 WorldLocation loc(fieldsDB[0].GetUInt16(), fieldsDB[2].GetFloat(), fieldsDB[3].GetFloat(), fieldsDB[4].GetFloat(), 0.0f);
198 uint32 zoneId = fieldsDB[1].GetUInt16();
199
200 Player::SavePositionInDB(loc, zoneId, player->GetGUID(), nullptr);
201 }
202 }
203
204 return true;
205 }
206
207 // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
208 GameTele const* tele = where.get<GameTele const*>();
209 return DoNameTeleport(handler, *player, tele->mapId, { tele->position_x, tele->position_y, tele->position_z, tele->orientation }, tele->name);
210 }
211
212 //Teleport group to given game_tele.entry
213 static bool HandleTeleGroupCommand(ChatHandler* handler, GameTele const* tele)
214 {
215 if (!tele)
216 {
218 handler->SetSentErrorMessage(true);
219 return false;
220 }
221
222 Player* target = handler->getSelectedPlayer();
223 if (!target)
224 {
226 handler->SetSentErrorMessage(true);
227 return false;
228 }
229
230 // check online security
231 if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
232 return false;
233
234 MapEntry const* map = sMapStore.LookupEntry(tele->mapId);
235 if (!map || map->IsBattlegroundOrArena())
236 {
238 handler->SetSentErrorMessage(true);
239 return false;
240 }
241
242 std::string nameLink = handler->GetNameLink(target);
243
244 Group* grp = target->GetGroup();
245 if (!grp)
246 {
247 handler->PSendSysMessage(LANG_NOT_IN_GROUP, nameLink.c_str());
248 handler->SetSentErrorMessage(true);
249 return false;
250 }
251
252 for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
253 {
254 Player* player = itr->GetSource();
255
256 if (!player || !player->GetSession())
257 continue;
258
259 // check online security
260 if (handler->HasLowerSecurity(player, ObjectGuid::Empty))
261 return false;
262
263 std::string plNameLink = handler->GetNameLink(player);
264
265 if (player->IsBeingTeleported())
266 {
267 handler->PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str());
268 continue;
269 }
270
271 handler->PSendSysMessage(LANG_TELEPORTING_TO, plNameLink.c_str(), "", tele->name.c_str());
272 if (handler->needReportToTarget(player))
273 ChatHandler(player->GetSession()).PSendSysMessage(LANG_TELEPORTED_TO_BY, nameLink.c_str());
274
275 // stop flight if need
276 if (player->IsInFlight())
277 player->FinishTaxiFlight();
278 else
279 player->SaveRecallPosition(); // save only in non-flight case
280
281 player->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation);
282 }
283
284 return true;
285 }
286
287 static bool HandleTeleCommand(ChatHandler* handler, GameTele const* tele)
288 {
289 if (!tele)
290 {
292 handler->SetSentErrorMessage(true);
293 return false;
294 }
295
296 Player* player = handler->GetSession()->GetPlayer();
298 {
300 handler->SetSentErrorMessage(true);
301 return false;
302 }
303
304 MapEntry const* map = sMapStore.LookupEntry(tele->mapId);
305 if (!map || (map->IsBattlegroundOrArena() && (player->GetMapId() != tele->mapId || !player->IsGameMaster())))
306 {
308 handler->SetSentErrorMessage(true);
309 return false;
310 }
311
312 // stop flight if need
313 if (player->IsInFlight())
314 player->FinishTaxiFlight();
315 else
316 player->SaveRecallPosition(); // save only in non-flight case
317
318 player->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation);
319 return true;
320 }
321
323 {
324 CreatureData const* spawnpoint = nullptr;
325 for (auto const& pair : sObjectMgr->GetAllCreatureData())
326 {
327 if (pair.second.id != *creatureId)
328 continue;
329
330 if (!spawnpoint)
331 spawnpoint = &pair.second;
332 else
333 {
335 break;
336 }
337 }
338
339 if (!spawnpoint)
340 {
342 handler->SetSentErrorMessage(true);
343 return false;
344 }
345
346 CreatureTemplate const* creatureTemplate = ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(*creatureId));
347
348 return DoNameTeleport(handler, player, spawnpoint->mapId, spawnpoint->spawnPoint, creatureTemplate->Name);
349 }
350
352 {
353 CreatureData const* spawnpoint = sObjectMgr->GetCreatureData(spawnId);
354 if (!spawnpoint)
355 {
357 handler->SetSentErrorMessage(true);
358 return false;
359 }
360
361 CreatureTemplate const* creatureTemplate = ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(spawnpoint->id));
362
363 return DoNameTeleport(handler, player, spawnpoint->mapId, spawnpoint->spawnPoint, creatureTemplate->Name);
364 }
365
367 {
368 std::string normalizedName(name);
369 WorldDatabase.EscapeString(normalizedName);
370
371 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 '{}'", normalizedName);
372 if (!result)
373 {
375 handler->SetSentErrorMessage(true);
376 return false;
377 }
378
379 if (result->GetRowCount() > 1)
381
382 Field* fields = result->Fetch();
383 return DoNameTeleport(handler, player, fields[4].GetUInt16(), { fields[0].GetFloat(), fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat() }, fields[5].GetString());
384 }
385};
386
388{
389 new tele_commandscript();
390}
@ CHAR_SEL_CHAR_HOMEBIND
#define EXACT_SEQUENCE(str)
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
std::shared_ptr< ResultSet > QueryResult
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
uint32_t uint32
Definition: Define.h:142
#define ASSERT_NOTNULL(pointer)
Definition: Errors.h:84
@ LANG_COMMAND_TP_ALREADYEXIST
Definition: Language.h:522
@ LANG_OFFLINE
Definition: Language.h:69
@ LANG_COMMAND_TP_ADDEDERR
Definition: Language.h:524
@ LANG_NOT_IN_GROUP
Definition: Language.h:151
@ LANG_IS_TELEPORTED
Definition: Language.h:136
@ LANG_COMMAND_GOCREATNOTFOUND
Definition: Language.h:320
@ LANG_YOU_IN_COMBAT
Definition: Language.h:55
@ LANG_COMMAND_TP_DELETED
Definition: Language.h:525
@ LANG_NO_CHAR_SELECTED
Definition: Language.h:150
@ LANG_INVALID_TARGET_COORD
Definition: Language.h:315
@ LANG_COMMAND_GOCREATMULTIPLE
Definition: Language.h:321
@ LANG_COMMAND_TP_ADDED
Definition: Language.h:523
@ LANG_TELEPORTED_TO_BY
Definition: Language.h:145
@ LANG_COMMAND_TELE_NOTFOUND
Definition: Language.h:205
@ LANG_TELEPORTING_TO
Definition: Language.h:144
@ LANG_CANNOT_TELE_TO_BG
Definition: Language.h:723
#define sObjectMgr
Definition: ObjectMgr.h:1946
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
Role Based Access Control related classes definition.
#define sTerrainMgr
Definition: TerrainMgr.h:165
std::string playerLink(std::string const &name) const
Definition: Chat.cpp:602
Player * getSelectedPlayer()
Definition: Chat.cpp:200
WorldSession * GetSession()
Definition: Chat.h:42
virtual std::string GetNameLink() const
Definition: Chat.cpp:58
void PSendSysMessage(const char *fmt, Args &&... args)
Definition: Chat.h:57
bool HasLowerSecurity(Player *target, ObjectGuid guid, bool strong=false)
Definition: Chat.cpp:63
void SetSentErrorMessage(bool val)
Definition: Chat.h:114
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition: Chat.cpp:113
virtual bool needReportToTarget(Player *chr) const
Definition: Chat.cpp:586
virtual char const * GetTrinityString(uint32 entry) const
Definition: Chat.cpp:48
Class used to access individual fields of database query result.
Definition: Field.h:90
std::string GetString() const
Definition: Field.cpp:118
uint16 GetUInt16() const
Definition: Field.cpp:46
float GetFloat() const
Definition: Field.cpp:94
GroupReference * next()
Definition: Group.h:197
GroupReference * GetFirstMember()
Definition: Group.h:325
static bool IsValidMapCoord(uint32 mapid, float x, float y)
Definition: MapManager.h:82
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
uint64 LowType
Definition: ObjectGuid.h:278
static PhaseShift const & GetEmptyPhaseShift()
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, TeleportToOptions options=TELE_TO_NONE, Optional< uint32 > instanceId={})
Definition: Player.cpp:1250
static void SavePositionInDB(WorldLocation const &loc, uint16 zoneId, ObjectGuid guid, CharacterDatabaseTransaction trans)
Definition: Player.cpp:21279
WorldSession * GetSession() const
Definition: Player.h:2101
void SaveRecallPosition()
Definition: Player.h:2491
void FinishTaxiFlight()
Definition: Player.cpp:22706
bool IsGameMaster() const
Definition: Player.h:1178
Group * GetGroup(Optional< uint8 > partyIndex)
Definition: Player.h:2606
bool IsBeingTeleported() const
Definition: Player.h:2219
void setUInt64(const uint8 index, const uint64 value)
bool IsInFlight() const
Definition: Unit.h:1012
bool IsInCombat() const
Definition: Unit.h:1043
constexpr uint32 GetMapId() const
Definition: Position.h:201
Player * GetPlayer() const
bool HasPermission(uint32 permissionId)
ChatCommandTable GetCommands() const override
Definition: cs_tele.cpp:47
static bool HandleTeleNameNpcNameCommand(ChatHandler *handler, PlayerIdentifier player, Tail name)
Definition: cs_tele.cpp:366
static bool HandleTeleNameNpcIdCommand(ChatHandler *handler, PlayerIdentifier player, Variant< Hyperlink< creature_entry >, uint32 > creatureId)
Definition: cs_tele.cpp:322
static bool HandleTeleNameCommand(ChatHandler *handler, Optional< PlayerIdentifier > player, Variant< GameTele const *, EXACT_SEQUENCE("$home")> where)
Definition: cs_tele.cpp:177
static bool HandleTeleNameNpcSpawnIdCommand(ChatHandler *handler, PlayerIdentifier player, Variant< Hyperlink< creature >, ObjectGuid::LowType > spawnId)
Definition: cs_tele.cpp:351
static bool HandleTeleAddCommand(ChatHandler *handler, std::string const &name)
Definition: cs_tele.cpp:75
static bool HandleTeleCommand(ChatHandler *handler, GameTele const *tele)
Definition: cs_tele.cpp:287
static bool HandleTeleDelCommand(ChatHandler *handler, GameTele const *tele)
Definition: cs_tele.cpp:110
static bool DoNameTeleport(ChatHandler *handler, PlayerIdentifier player, uint32 mapId, Position const &pos, std::string const &locationName)
Definition: cs_tele.cpp:124
static bool HandleTeleGroupCommand(ChatHandler *handler, GameTele const *tele)
Definition: cs_tele.cpp:213
void AddSC_tele_commandscript()
Definition: cs_tele.cpp:387
std::vector< ChatCommandBuilder > ChatCommandTable
Definition: ChatCommand.h:49
@ RBAC_PERM_COMMAND_TELE_GROUP
Definition: RBAC.h:613
@ RBAC_PERM_COMMAND_TELE_ADD
Definition: RBAC.h:610
@ RBAC_PERM_COMMAND_TELE_NAME
Definition: RBAC.h:612
@ RBAC_PERM_COMMAND_TELE
Definition: RBAC.h:609
@ RBAC_PERM_COMMAND_TELE_DEL
Definition: RBAC.h:611
std::string Name
Definition: CreatureData.h:483
float position_y
Definition: ObjectMgr.h:164
float orientation
Definition: ObjectMgr.h:166
float position_x
Definition: ObjectMgr.h:163
uint32 mapId
Definition: ObjectMgr.h:167
std::string name
Definition: ObjectMgr.h:168
float position_z
Definition: ObjectMgr.h:165
bool IsBattlegroundOrArena() const
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr float GetOrientation() const
Definition: Position.h:79
constexpr float GetPositionZ() const
Definition: Position.h:78
uint32 id
Definition: SpawnData.h:104
Position spawnPoint
Definition: SpawnData.h:105
uint32 mapId
Definition: SpawnData.h:94
std::string const & GetName() const