/* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Affero General Public License as published by the * Free Software Foundation; either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ /* ScriptData Name: go_commandscript %Complete: 100 Comment: All go related commands Category: commandscripts EndScriptData */ #include "Chat.h" #include "GameGraveyard.h" #include "Language.h" #include "MapMgr.h" #include "ObjectMgr.h" #include "Player.h" #include "ScriptMgr.h" #include "TicketMgr.h" using namespace Acore::ChatCommands; class go_commandscript : public CommandScript { public: go_commandscript() : CommandScript("go_commandscript") { } ChatCommandTable GetCommands() const override { static ChatCommandTable goCommandTable = { { "creature", HandleGoCreatureSpawnIdCommand, SEC_MODERATOR, Console::No }, { "creature id", HandleGoCreatureCIdCommand, SEC_MODERATOR, Console::No }, { "gameobject", HandleGoGameObjectSpawnIdCommand, SEC_MODERATOR, Console::No }, { "gameobject id", HandleGoGameObjectGOIdCommand, SEC_MODERATOR, Console::No }, { "graveyard", HandleGoGraveyardCommand, SEC_MODERATOR, Console::No }, { "grid", HandleGoGridCommand, SEC_MODERATOR, Console::No }, { "taxinode", HandleGoTaxinodeCommand, SEC_MODERATOR, Console::No }, { "trigger", HandleGoTriggerCommand, SEC_MODERATOR, Console::No }, { "zonexy", HandleGoZoneXYCommand, SEC_MODERATOR, Console::No }, { "xyz", HandleGoXYZCommand, SEC_MODERATOR, Console::No }, { "ticket", HandleGoTicketCommand, SEC_GAMEMASTER, Console::No } }; static ChatCommandTable commandTable = { { "go", goCommandTable } }; return commandTable; } static bool DoTeleport(ChatHandler* handler, Position pos, uint32 mapId = MAPID_INVALID) { Player* player = handler->GetSession()->GetPlayer(); if (mapId == MAPID_INVALID) mapId = player->GetMapId(); if (!MapMgr::IsValidMapCoord(mapId, pos) || sObjectMgr->IsTransportMap(mapId)) { handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, pos.GetPositionX(), pos.GetPositionY(), mapId); handler->SetSentErrorMessage(true); return false; } // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); player->TeleportTo({ mapId, pos }); return true; } static bool HandleGoCreatureCIdCommand(ChatHandler* handler, Variant, uint32> cId) { CreatureData const* spawnpoint = nullptr; for (auto const& pair : sObjectMgr->GetAllCreatureData()) { if (pair.second.id != *cId) 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; } return DoTeleport(handler, { spawnpoint->posX, spawnpoint->posY, spawnpoint->posZ }, spawnpoint->mapid); } static bool HandleGoCreatureSpawnIdCommand(ChatHandler* handler, Variant, ObjectGuid::LowType> spawnId) { CreatureData const* spawnpoint = sObjectMgr->GetCreatureData(spawnId); if (!spawnpoint) { handler->SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND); handler->SetSentErrorMessage(true); return false; } return DoTeleport(handler, { spawnpoint->posX, spawnpoint->posY, spawnpoint->posZ }, spawnpoint->mapid); } static bool HandleGoGameObjectSpawnIdCommand(ChatHandler* handler, uint32 spawnId) { GameObjectData const* spawnpoint = sObjectMgr->GetGOData(spawnId); if (!spawnpoint) { handler->SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND); handler->SetSentErrorMessage(true); return false; } return DoTeleport(handler, { spawnpoint->posX, spawnpoint->posY, spawnpoint->posZ }, spawnpoint->mapid); } static bool HandleGoGameObjectGOIdCommand(ChatHandler* handler, uint32 goId) { GameObjectData const* spawnpoint = nullptr; for (auto const& pair : sObjectMgr->GetAllGOData()) { if (pair.second.id != goId) continue; if (!spawnpoint) spawnpoint = &pair.second; else { handler->SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE); break; } } if (!spawnpoint) { handler->SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND); handler->SetSentErrorMessage(true); return false; } return DoTeleport(handler, { spawnpoint->posX, spawnpoint->posY, spawnpoint->posZ }, spawnpoint->mapid); } static bool HandleGoGraveyardCommand(ChatHandler* handler, uint32 gyId) { GraveyardStruct const* gy = sGraveyard->GetGraveyard(gyId); if (!gy) { handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, gyId); handler->SetSentErrorMessage(true); return false; } if (!MapMgr::IsValidMapCoord(gy->Map, gy->x, gy->y, gy->z)) { handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, gy->x, gy->y, gy->Map); handler->SetSentErrorMessage(true); return false; } Player* player = handler->GetSession()->GetPlayer(); // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); player->TeleportTo(gy->Map, gy->x, gy->y, gy->z, player->GetOrientation()); return true; } //teleport to grid static bool HandleGoGridCommand(ChatHandler* handler, float gridX, float gridY, Optional oMapId) { Player* player = handler->GetSession()->GetPlayer(); uint32 mapId = oMapId.value_or(player->GetMapId()); // center of grid float x = (gridX - CENTER_GRID_ID + 0.5f) * SIZE_OF_GRIDS; float y = (gridY - CENTER_GRID_ID + 0.5f) * SIZE_OF_GRIDS; if (!MapMgr::IsValidMapCoord(mapId, x, y)) { handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, mapId); handler->SetSentErrorMessage(true); return false; } // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); Map const* map = sMapMgr->CreateBaseMap(mapId); float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); player->TeleportTo(mapId, x, y, z, player->GetOrientation()); return true; } static bool HandleGoTaxinodeCommand(ChatHandler* handler, Variant, uint32> nodeId) { TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(nodeId); if (!node) { handler->PSendSysMessage(LANG_COMMAND_GOTAXINODENOTFOUND, uint32(nodeId)); handler->SetSentErrorMessage(true); return false; } return DoTeleport(handler, { node->x, node->y, node->z }, node->map_id); } static bool HandleGoTriggerCommand(ChatHandler* handler, Variant, uint32> areaTriggerId) { AreaTrigger const* at = sObjectMgr->GetAreaTrigger(areaTriggerId); if (!at) { handler->PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND, uint32(areaTriggerId)); handler->SetSentErrorMessage(true); return false; } return DoTeleport(handler, { at->x, at->y, at->z }, at->map); } //teleport at coordinates static bool HandleGoZoneXYCommand(ChatHandler* handler, float x, float y, Optional, uint32>> areaIdArg) { Player* player = handler->GetSession()->GetPlayer(); uint32 areaId = areaIdArg ? *areaIdArg : player->GetZoneId(); AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId); if (x < 0 || x > 100 || y < 0 || y > 100 || !areaEntry) { handler->PSendSysMessage(LANG_INVALID_ZONE_COORD, x, y, areaId); handler->SetSentErrorMessage(true); return false; } // update to parent zone if exist (client map show only zones without parents) AreaTableEntry const* zoneEntry = areaEntry->zone ? sAreaTableStore.LookupEntry(areaEntry->zone) : areaEntry; ASSERT(zoneEntry); Map const* map = sMapMgr->CreateBaseMap(zoneEntry->mapid); if (map->Instanceable()) { handler->PSendSysMessage(LANG_INVALID_ZONE_MAP, areaEntry->ID, areaEntry->area_name[handler->GetSessionDbcLocale()], map->GetId(), map->GetMapName()); handler->SetSentErrorMessage(true); return false; } Zone2MapCoordinates(x, y, zoneEntry->ID); if (!MapMgr::IsValidMapCoord(zoneEntry->mapid, x, y)) { handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, zoneEntry->mapid); handler->SetSentErrorMessage(true); return false; } // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); player->TeleportTo(zoneEntry->mapid, x, y, z, player->GetOrientation()); return true; } //teleport at coordinates, including Z and orientation static bool HandleGoXYZCommand(ChatHandler* handler, float x, float y, Optional z, Optional id, Optional o) { Player* player = handler->GetSession()->GetPlayer(); uint32 mapId = id.value_or(player->GetMapId()); if (z) { if (!MapMgr::IsValidMapCoord(mapId, x, y, *z)) { handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, mapId); handler->SetSentErrorMessage(true); return false; } } else { if (!MapMgr::IsValidMapCoord(mapId, x, y)) { handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, mapId); handler->SetSentErrorMessage(true); return false; } Map const* map = sMapMgr->CreateBaseMap(mapId); z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); } return DoTeleport(handler, { x, y, *z, o.value_or(0.0f) }, mapId); } static bool HandleGoTicketCommand(ChatHandler* handler, uint32 ticketId) { GmTicket* ticket = sTicketMgr->GetTicket(ticketId); if (!ticket) { handler->SendSysMessage(LANG_COMMAND_TICKETNOTEXIST); return true; } Player* player = handler->GetSession()->GetPlayer(); // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); ticket->TeleportTo(player); return true; } }; void AddSC_go_commandscript() { new go_commandscript(); }