TrinityCore
Loading...
Searching...
No Matches
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
47 std::span<ChatCommandBuilder const> GetCommands() const override
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 const& itr : grp->GetMembers())
253 {
254 Player* player = itr.GetSource();
255
256 // check online security
257 if (handler->HasLowerSecurity(player, ObjectGuid::Empty))
258 return false;
259
260 std::string plNameLink = handler->GetNameLink(player);
261
262 if (player->IsBeingTeleported())
263 {
264 handler->PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str());
265 continue;
266 }
267
268 handler->PSendSysMessage(LANG_TELEPORTING_TO, plNameLink.c_str(), "", tele->name.c_str());
269 if (handler->needReportToTarget(player))
270 ChatHandler(player->GetSession()).PSendSysMessage(LANG_TELEPORTED_TO_BY, nameLink.c_str());
271
272 // stop flight if need
273 if (player->IsInFlight())
274 player->FinishTaxiFlight();
275 else
276 player->SaveRecallPosition(); // save only in non-flight case
277
278 player->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation);
279 }
280
281 return true;
282 }
283
284 static bool HandleTeleCommand(ChatHandler* handler, GameTele const* tele)
285 {
286 if (!tele)
287 {
289 handler->SetSentErrorMessage(true);
290 return false;
291 }
292
293 Player* player = handler->GetSession()->GetPlayer();
295 {
297 handler->SetSentErrorMessage(true);
298 return false;
299 }
300
301 MapEntry const* map = sMapStore.LookupEntry(tele->mapId);
302 if (!map || (map->IsBattlegroundOrArena() && (player->GetMapId() != tele->mapId || !player->IsGameMaster())))
303 {
305 handler->SetSentErrorMessage(true);
306 return false;
307 }
308
309 // stop flight if need
310 if (player->IsInFlight())
311 player->FinishTaxiFlight();
312 else
313 player->SaveRecallPosition(); // save only in non-flight case
314
315 player->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation);
316 return true;
317 }
318
320 {
321 CreatureData const* spawnpoint = nullptr;
322 for (auto const& pair : sObjectMgr->GetAllCreatureData())
323 {
324 if (pair.second.id != *creatureId)
325 continue;
326
327 if (!spawnpoint)
328 spawnpoint = &pair.second;
329 else
330 {
332 break;
333 }
334 }
335
336 if (!spawnpoint)
337 {
339 handler->SetSentErrorMessage(true);
340 return false;
341 }
342
343 CreatureTemplate const* creatureTemplate = ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(*creatureId));
344
345 return DoNameTeleport(handler, player, spawnpoint->mapId, spawnpoint->spawnPoint, creatureTemplate->Name);
346 }
347
349 {
350 CreatureData const* spawnpoint = sObjectMgr->GetCreatureData(spawnId);
351 if (!spawnpoint)
352 {
354 handler->SetSentErrorMessage(true);
355 return false;
356 }
357
358 CreatureTemplate const* creatureTemplate = ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(spawnpoint->id));
359
360 return DoNameTeleport(handler, player, spawnpoint->mapId, spawnpoint->spawnPoint, creatureTemplate->Name);
361 }
362
364 {
365 std::string normalizedName(name);
366 WorldDatabase.EscapeString(normalizedName);
367
368 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);
369 if (!result)
370 {
372 handler->SetSentErrorMessage(true);
373 return false;
374 }
375
376 if (result->GetRowCount() > 1)
378
379 Field* fields = result->Fetch();
380 return DoNameTeleport(handler, player, fields[4].GetUInt16(), { fields[0].GetFloat(), fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat() }, fields[5].GetString());
381 }
382};
383
@ 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.
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
uint32_t uint32
Definition Define.h:154
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:82
@ LANG_COMMAND_TP_ALREADYEXIST
Definition Language.h:525
@ LANG_OFFLINE
Definition Language.h:69
@ LANG_COMMAND_TP_ADDEDERR
Definition Language.h:527
@ LANG_NOT_IN_GROUP
Definition Language.h:151
@ LANG_IS_TELEPORTED
Definition Language.h:136
@ LANG_COMMAND_GOCREATNOTFOUND
Definition Language.h:319
@ LANG_YOU_IN_COMBAT
Definition Language.h:55
@ LANG_COMMAND_TP_DELETED
Definition Language.h:528
@ LANG_NO_CHAR_SELECTED
Definition Language.h:150
@ LANG_INVALID_TARGET_COORD
Definition Language.h:314
@ LANG_COMMAND_GOCREATMULTIPLE
Definition Language.h:320
@ LANG_COMMAND_TP_ADDED
Definition Language.h:526
@ 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:726
#define sObjectMgr
Definition ObjectMgr.h:1885
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:167
std::string playerLink(std::string const &name) const
Definition Chat.cpp:603
Player * getSelectedPlayer()
Definition Chat.cpp:204
WorldSession * GetSession()
Definition Chat.h:42
virtual std::string GetNameLink() const
Definition Chat.cpp:56
bool HasLowerSecurity(Player *target, ObjectGuid guid, bool strong=false)
Definition Chat.cpp:61
void SetSentErrorMessage(bool val)
Definition Chat.h:127
void PSendSysMessage(char const *fmt, Args &&... args)
Definition Chat.h:62
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:111
virtual bool needReportToTarget(Player *chr) const
Definition Chat.cpp:587
virtual char const * GetTrinityString(uint32 entry) const
Definition Chat.cpp:46
Class used to access individual fields of database query result.
Definition Field.h:94
float GetFloat() const noexcept
Definition Field.cpp:85
uint16 GetUInt16() const noexcept
Definition Field.cpp:43
std::string GetString() const noexcept
Definition Field.cpp:113
Definition Group.h:205
GroupRefManager & GetMembers()
Definition Group.h:332
static bool IsValidMapCoord(uint32 mapid, float x, float y)
Definition MapManager.h:83
static ObjectGuid const Empty
Definition ObjectGuid.h:314
uint64 LowType
Definition ObjectGuid.h:321
static PhaseShift const & GetEmptyPhaseShift()
static void SavePositionInDB(WorldLocation const &loc, uint16 zoneId, ObjectGuid guid, CharacterDatabaseTransaction trans)
Definition Player.cpp:21826
WorldSession * GetSession() const
Definition Player.h:2272
void SaveRecallPosition()
Definition Player.h:2681
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, TeleportToOptions options=TELE_TO_NONE, Optional< uint32 > instanceId={}, uint32 teleportSpellId=0)
Definition Player.cpp:1226
void FinishTaxiFlight()
Definition Player.cpp:23356
bool IsGameMaster() const
Definition Player.h:1309
Group * GetGroup(Optional< uint8 > partyIndex)
Definition Player.h:2796
bool IsBeingTeleported() const
Definition Player.h:2402
void setUInt64(uint8 index, uint64 value)
bool IsInFlight() const
Definition Unit.h:1027
bool IsInCombat() const
Definition Unit.h:1058
constexpr uint32 GetMapId() const
Definition Position.h:216
Player * GetPlayer() const
bool HasPermission(uint32 permissionId)
std::span< ChatCommandBuilder const > GetCommands() const override
Definition cs_tele.cpp:47
static bool HandleTeleNameNpcNameCommand(ChatHandler *handler, PlayerIdentifier player, Tail name)
Definition cs_tele.cpp:363
static bool HandleTeleNameNpcIdCommand(ChatHandler *handler, PlayerIdentifier player, Variant< Hyperlink< creature_entry >, uint32 > creatureId)
Definition cs_tele.cpp:319
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:348
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:284
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:384
ChatCommandBuilder const [] 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
float position_y
Definition ObjectMgr.h:158
float orientation
Definition ObjectMgr.h:160
float position_x
Definition ObjectMgr.h:157
uint32 mapId
Definition ObjectMgr.h:161
std::string name
Definition ObjectMgr.h:162
float position_z
Definition ObjectMgr.h:159
bool IsBattlegroundOrArena() const
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
constexpr float GetOrientation() const
Definition Position.h:90
constexpr float GetPositionZ() const
Definition Position.h:89
uint32 id
Definition SpawnData.h:135
Position spawnPoint
Definition SpawnData.h:136
std::string const & GetName() const
static Optional< PlayerIdentifier > FromTargetOrSelf(ChatHandler *handler)