/
white.sheikh
/
mangoszero-server
Обзор
Документация
Войти
/
white.sheikh
/
mangoszero-server
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/game/ChatCommands/WaypointCommands.cpp
944 строки
34 KB
Antz
Happy New Year 2023 from everyone at getMangos.eu :tada:
01 янв 2023, 00:29
Не верифицирован
01 янв 2023, 00:29
ce8b12f
Код
Авторство
О чём код?
/** * MaNGOS is a full featured server for World of Warcraft, supporting * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 * * Copyright (C) 2005-2023 MaNGOS <https://getmangos.eu> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * World of Warcraft, and all World of Warcraft or Warcraft art, images, * and lore are copyrighted by Blizzard Entertainment, Inc. */ #include "Chat.h" #include "Language.h" #include "PointMovementGenerator.h" #include "WaypointMovementGenerator.h" #include "TemporarySummon.h" #include "MoveMap.h" #include "PathFinder.h" // for mmap manager #include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "CellImpl.h" #include "movement/MoveSplineInit.h" #include <fstream> #include <map> #include <typeinfo> /// Helper function inline Creature* Helper_CreateWaypointFor(Creature* wpOwner, WaypointPathOrigin wpOrigin, int32 pathId, uint32 wpId, WaypointNode const* wpNode, CreatureInfo const* waypointInfo) { TemporarySummonWaypoint* wpCreature = new TemporarySummonWaypoint(wpOwner->GetObjectGuid(), wpId, pathId, (uint32)wpOrigin); CreatureCreatePos pos(wpOwner->GetMap(), wpNode->x, wpNode->y, wpNode->z, wpNode->orientation); if (!wpCreature->Create(wpOwner->GetMap()->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, waypointInfo)) { delete wpCreature; return NULL; } wpCreature->SetVisibility(VISIBILITY_OFF); wpCreature->SetRespawnCoord(pos); wpCreature->SetActiveObjectState(true); wpCreature->Summon(TEMPSPAWN_TIMED_DESPAWN, 5 * MINUTE * IN_MILLISECONDS); // Also initializes the AI and MMGen return wpCreature; } inline void UnsummonVisualWaypoints(Player const* player, ObjectGuid ownerGuid) { std::list<Creature*> waypoints; MaNGOS::AllCreaturesOfEntryInRangeCheck checkerForWaypoint(player, VISUAL_WAYPOINT, SIZE_OF_GRIDS); MaNGOS::CreatureListSearcher<MaNGOS::AllCreaturesOfEntryInRangeCheck> searcher(waypoints, checkerForWaypoint); Cell::VisitGridObjects(player, searcher, SIZE_OF_GRIDS); for (std::list<Creature*>::iterator itr = waypoints.begin(); itr != waypoints.end(); ++itr) { if ((*itr)->GetSubtype() != CREATURE_SUBTYPE_TEMPORARY_SUMMON) { continue; } TemporarySummonWaypoint* wpTarget = dynamic_cast<TemporarySummonWaypoint*>(*itr); if (!wpTarget) { continue; } if (wpTarget->GetSummonerGuid() == ownerGuid) { wpTarget->UnSummon(); } } } /** Add a waypoint to a creature * .wp add [dbGuid] [pathId] [source] * * The user can either select an npc or provide its dbGuid. * Also the user can specify pathId and source if wanted. * * The user can even select a visual waypoint - then the new waypoint * is placed *after* the selected one - this makes insertion of new * waypoints possible. * * .wp add [pathId] [source] * -> adds a waypoint to the currently selected creature, to path pathId in source-storage * * .wp add guid [pathId] [source] * -> if no npc is selected, expect the creature provided with guid argument * * @return true - command did succeed, false - something went wrong */ bool ChatHandler::HandleWpAddCommand(char* args) { DEBUG_LOG("DEBUG: HandleWpAddCommand"); CreatureInfo const* waypointInfo = ObjectMgr::GetCreatureTemplate(VISUAL_WAYPOINT); if (!waypointInfo || waypointInfo->GetHighGuid() != HIGHGUID_UNIT) { return false; // must exist as normal creature in mangos.sql 'creature_template' } Creature* targetCreature = getSelectedCreature(); WaypointPathOrigin wpDestination = PATH_NO_PATH; ///< into which storage int32 wpPathId = 0; ///< along which path uint32 wpPointId = 0; ///< pointId if a waypoint was selected, in this case insert after Creature* wpOwner; if (targetCreature) { // Check if the user did specify a visual waypoint if (targetCreature->GetEntry() == VISUAL_WAYPOINT && targetCreature->GetSubtype() == CREATURE_SUBTYPE_TEMPORARY_SUMMON) { TemporarySummonWaypoint* wpTarget = dynamic_cast<TemporarySummonWaypoint*>(targetCreature); if (!wpTarget) { PSendSysMessage(LANG_WAYPOINT_VP_SELECT); SetSentErrorMessage(true); return false; } // Who moves along this waypoint? wpOwner = targetCreature->GetMap()->GetAnyTypeCreature(wpTarget->GetSummonerGuid()); if (!wpOwner) { PSendSysMessage(LANG_WAYPOINT_NOTFOUND_NPC, wpTarget->GetSummonerGuid().GetString().c_str()); SetSentErrorMessage(true); return false; } wpDestination = (WaypointPathOrigin)wpTarget->GetPathOrigin(); wpPathId = wpTarget->GetPathId(); wpPointId = wpTarget->GetWaypointId() + 1; // Insert as next waypoint } else // normal creature selected { wpOwner = targetCreature; } } else //!targetCreature - first argument must be dbGuid { uint32 dbGuid; if (!ExtractUInt32(&args, dbGuid)) { PSendSysMessage(LANG_WAYPOINT_NOGUID); SetSentErrorMessage(true); return false; } CreatureData const* data = sObjectMgr.GetCreatureData(dbGuid); if (!data) { PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, dbGuid); SetSentErrorMessage(true); return false; } if (m_session->GetPlayer()->GetMapId() != data->mapid) { PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, dbGuid); SetSentErrorMessage(true); return false; } wpOwner = m_session->GetPlayer()->GetMap()->GetAnyTypeCreature(data->GetObjectGuid(dbGuid)); if (!wpOwner) { PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, dbGuid); SetSentErrorMessage(true); return false; } } if (wpDestination == PATH_NO_PATH) // No Waypoint selected, parse additional params { if (ExtractOptInt32(&args, wpPathId, 0)) // Fill path-id and source { uint32 src = (uint32)PATH_NO_PATH; if (ExtractOptUInt32(&args, src, src)) { wpDestination = (WaypointPathOrigin)src; } else // pathId provided but no destination { if (wpPathId != 0) { wpDestination = PATH_FROM_ENTRY; // Multiple Paths must only be assigned by entry } } } if (wpDestination == PATH_NO_PATH) // No overwrite params. Do best estimate { if (wpOwner->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) { if (WaypointMovementGenerator<Creature> const* wpMMGen = dynamic_cast<WaypointMovementGenerator<Creature> const*>(wpOwner->GetMotionMaster()->GetCurrent())) { wpMMGen->GetPathInformation(wpPathId, wpDestination); } } // Get information about default path if no current path. If no default path, prepare data dependendy on uniqueness if (wpDestination == PATH_NO_PATH && !sWaypointMgr.GetDefaultPath(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), &wpDestination)) { wpDestination = PATH_FROM_ENTRY; // Default place to store paths if (wpOwner->HasStaticDBSpawnData()) { QueryResult* result = WorldDatabase.PQuery("SELECT COUNT(`id`) FROM `creature` WHERE `id` = %u", wpOwner->GetEntry()); if (result && result->Fetch()[0].GetUInt32() != 1) { wpDestination = PATH_FROM_GUID; } delete result; } } } } // All arguments parsed // wpOwner will get a new waypoint inserted into wpPath = GetPathFromOrigin(wpOwner, wpDestination, wpPathId) at wpPointId float x, y, z; m_session->GetPlayer()->GetPosition(x, y, z); if (!sWaypointMgr.AddNode(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpPointId, wpDestination, x, y, z)) { PSendSysMessage(LANG_WAYPOINT_NOTCREATED, wpPointId, wpOwner->GetGuidStr().c_str(), wpPathId, WaypointManager::GetOriginString(wpDestination).c_str()); SetSentErrorMessage(true); return false; } // Unsummon old visuals, summon new ones UnsummonVisualWaypoints(m_session->GetPlayer(), wpOwner->GetObjectGuid()); WaypointPath const* wpPath = sWaypointMgr.GetPathFromOrigin(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpPathId, wpDestination); for (WaypointPath::const_iterator itr = wpPath->begin(); itr != wpPath->end(); ++itr) { if (!Helper_CreateWaypointFor(wpOwner, wpDestination, wpPathId, itr->first, &itr->second, waypointInfo)) { PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); SetSentErrorMessage(true); return false; } } PSendSysMessage(LANG_WAYPOINT_ADDED, wpPointId, wpOwner->GetGuidStr().c_str(), wpPathId, WaypointManager::GetOriginString(wpDestination).c_str()); return true; } // HandleWpAddCommand /** * .wp modify waittime | scriptid | orientation | del | move [dbGuid, id] [value] * * waittime <Delay> * User has selected a visual waypoint before. * Delay <Delay> is added to this waypoint. Everytime the * NPC comes to this waypoint, it will wait Delay millieseconds. * * waittime <DBGuid> <WPNUM> <Delay> * User has not selected visual waypoint before. * For the waypoint <WPNUM> for the NPC with <DBGuid> * an delay Delay is added to this waypoint * Everytime the NPC comes to this waypoint, it will wait Delay millieseconds. * * scriptid <scriptId> * User has selected a visual waypoint before. * <scriptId> is added to this waypoint. Everytime the * NPC comes to this waypoint, the DBScript scriptId is executed. * * scriptid <DBGuid> <WPNUM> <scriptId> * User has not selected visual waypoint before. * For the waypoint <WPNUM> for the NPC with <DBGuid> * an emote <scriptId> is added. * Everytime the NPC comes to this waypoint, the DBScript scriptId is executed. * * orientation [DBGuid, WpNum] <Orientation> * Set the orientation of the selected waypoint or waypoint given with DbGuid/ WpId * to the value of <Orientation>. * * del [DBGuid, WpId] * Remove the selected waypoint or waypoint given with DbGuid/ WpId. * * move [DBGuid, WpId] * Move the selected waypoint or waypoint given with DbGuid/ WpId to player's current positiion. */ bool ChatHandler::HandleWpModifyCommand(char* args) { DEBUG_LOG("DEBUG: HandleWpModifyCommand"); if (!*args) { return false; } CreatureInfo const* waypointInfo = ObjectMgr::GetCreatureTemplate(VISUAL_WAYPOINT); if (!waypointInfo || waypointInfo->GetHighGuid() != HIGHGUID_UNIT) { return false; // must exist as normal creature in mangos.sql 'creature_template' } // first arg: add del text emote spell waittime move char* subCmd_str = ExtractLiteralArg(&args); if (!subCmd_str) { return false; } std::string subCmd = subCmd_str; // Check // Remember: "show" must also be the name of a column! if ((subCmd != "waittime") && (subCmd != "scriptid") && (subCmd != "orientation") && (subCmd != "del") && (subCmd != "move")) { return false; } // Next arg is: <GUID> <WPNUM> <ARGUMENT> // Did user provide a GUID or did the user select a creature? Creature* targetCreature = getSelectedCreature(); // Expect a visual waypoint to be selected Creature* wpOwner; // Who moves along the waypoint uint32 wpId = 0; WaypointPathOrigin wpSource = PATH_NO_PATH; int32 wpPathId = 0; if (targetCreature) { DEBUG_LOG("DEBUG: HandleWpModifyCommand - User did select an NPC"); // Check if the user did specify a visual waypoint if (targetCreature->GetEntry() != VISUAL_WAYPOINT || targetCreature->GetSubtype() != CREATURE_SUBTYPE_TEMPORARY_SUMMON) { PSendSysMessage(LANG_WAYPOINT_VP_SELECT); SetSentErrorMessage(true); return false; } TemporarySummonWaypoint* wpTarget = dynamic_cast<TemporarySummonWaypoint*>(targetCreature); if (!wpTarget) { PSendSysMessage(LANG_WAYPOINT_VP_SELECT); SetSentErrorMessage(true); return false; } // Who moves along this waypoint? wpOwner = targetCreature->GetMap()->GetAnyTypeCreature(wpTarget->GetSummonerGuid()); if (!wpOwner) { PSendSysMessage(LANG_WAYPOINT_NOTFOUND_NPC, wpTarget->GetSummonerGuid().GetString().c_str()); SetSentErrorMessage(true); return false; } wpId = wpTarget->GetWaypointId(); wpPathId = wpTarget->GetPathId(); wpSource = (WaypointPathOrigin)wpTarget->GetPathOrigin(); } else { uint32 dbGuid = 0; // User did provide <GUID> <WPNUM> if (!ExtractUInt32(&args, dbGuid)) { SendSysMessage(LANG_WAYPOINT_NOGUID); SetSentErrorMessage(true); return false; } if (!ExtractUInt32(&args, wpId)) { SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN); SetSentErrorMessage(true); return false; } CreatureData const* data = sObjectMgr.GetCreatureData(dbGuid); if (!data) { PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, dbGuid); SetSentErrorMessage(true); return false; } wpOwner = m_session->GetPlayer()->GetMap()->GetAnyTypeCreature(data->GetObjectGuid(dbGuid)); if (!wpOwner) { PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, dbGuid); SetSentErrorMessage(true); return false; } } if (wpSource == PATH_NO_PATH) // No waypoint selected { if (wpOwner->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) { if (WaypointMovementGenerator<Creature> const* wpMMGen = dynamic_cast<WaypointMovementGenerator<Creature> const*>(wpOwner->GetMotionMaster()->GetCurrent())) { wpMMGen->GetPathInformation(wpPathId, wpSource); } } if (wpSource == PATH_NO_PATH) { sWaypointMgr.GetDefaultPath(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), &wpSource); } } WaypointPath const* wpPath = sWaypointMgr.GetPathFromOrigin(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpPathId, wpSource); if (!wpPath) { PSendSysMessage(LANG_WAYPOINT_NOTFOUNDPATH, wpOwner->GetGuidStr().c_str(), wpPathId, WaypointManager::GetOriginString(wpSource).c_str()); SetSentErrorMessage(true); return false; } WaypointPath::const_iterator point = wpPath->find(wpId); if (point == wpPath->end()) { PSendSysMessage(LANG_WAYPOINT_NOTFOUND, wpId, wpOwner->GetGuidStr().c_str(), wpPathId, WaypointManager::GetOriginString(wpSource).c_str()); SetSentErrorMessage(true); return false; } // If no visual WP was selected, but we are not going to remove it if (!targetCreature && subCmd != "del") { targetCreature = Helper_CreateWaypointFor(wpOwner, wpSource, wpPathId, wpId, &(point->second), waypointInfo); if (!targetCreature) { PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); SetSentErrorMessage(true); return false; } } if (subCmd == "del") // Remove WP, no additional command required { sWaypointMgr.DeleteNode(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpId, wpPathId, wpSource); if (TemporarySummonWaypoint* wpCreature = dynamic_cast<TemporarySummonWaypoint*>(targetCreature)) { wpCreature->UnSummon(); } if (wpPath->empty()) { wpOwner->SetDefaultMovementType(RANDOM_MOTION_TYPE); wpOwner->GetMotionMaster()->Initialize(); if (wpOwner->IsAlive()) // Dead creature will reset movement generator at respawn { wpOwner->SetDeathState(JUST_DIED); wpOwner->Respawn(); } wpOwner->SaveToDB(); } PSendSysMessage(LANG_WAYPOINT_REMOVED); return true; } else if (subCmd == "move") // Move to player position, no additional command required { float x, y, z; m_session->GetPlayer()->GetPosition(x, y, z); // Move visual waypoint targetCreature->NearTeleportTo(x, y, z, targetCreature->GetOrientation()); sWaypointMgr.SetNodePosition(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpId, wpPathId, wpSource, x, y, z); PSendSysMessage(LANG_WAYPOINT_CHANGED); return true; } else if (subCmd == "waittime") { uint32 waittime; if (!ExtractUInt32(&args, waittime)) { return false; } sWaypointMgr.SetNodeWaittime(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpId, wpPathId, wpSource, waittime); } else if (subCmd == "scriptid") { uint32 scriptId; if (!ExtractUInt32(&args, scriptId)) { return false; } if (!sWaypointMgr.SetNodeScriptId(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpId, wpPathId, wpSource, scriptId)) { PSendSysMessage(LANG_WAYPOINT_INFO_UNK_SCRIPTID, scriptId); } } else if (subCmd == "orientation") { float ori; if (!ExtractFloat(&args, ori)) { return false; } sWaypointMgr.SetNodeOrientation(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpId, wpPathId, wpSource, ori); } PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, subCmd_str); return true; } /** * .wp show info | on | off | first | last [dbGuid] [pathId [wpOrigin] ] * * info -> User has selected a visual waypoint before * * on -> User has selected an NPC; all visual waypoints for this * NPC are added to the world * * on <dbGuid> -> User did not select an NPC - instead the dbGuid of the * NPC is provided. All visual waypoints for this NPC * are added from the world. * * off -> User has selected an NPC; all visual waypoints for this * NPC are removed from the world. */ bool ChatHandler::HandleWpShowCommand(char* args) { DEBUG_LOG("DEBUG: HandleWpShowCommand"); if (!*args) { return false; } CreatureInfo const* waypointInfo = ObjectMgr::GetCreatureTemplate(VISUAL_WAYPOINT); if (!waypointInfo || waypointInfo->GetHighGuid() != HIGHGUID_UNIT) { return false; // must exist as normal creature in mangos.sql 'creature_template' } // first arg: info, on, off, first, last char* subCmd_str = ExtractLiteralArg(&args); if (!subCmd_str) { return false; } std::string subCmd = subCmd_str; ///< info, on, off, first, last uint32 dbGuid = 0; int32 wpPathId = 0; WaypointPathOrigin wpOrigin = PATH_NO_PATH; // User selected an npc? Creature* targetCreature = getSelectedCreature(); if (targetCreature) { if (ExtractOptInt32(&args, wpPathId, 0)) // Fill path-id and source { uint32 src; if (ExtractOptUInt32(&args, src, (uint32)PATH_NO_PATH)) { wpOrigin = (WaypointPathOrigin)src; } } } else // Guid must be provided { if (!ExtractUInt32(&args, dbGuid)) // No creature selected and no dbGuid provided { return false; } if (ExtractOptInt32(&args, wpPathId, 0)) // Fill path-id and source { uint32 src = (uint32)PATH_NO_PATH; if (ExtractOptUInt32(&args, src, src)) { wpOrigin = (WaypointPathOrigin)src; } } // Params now parsed, check them CreatureData const* data = sObjectMgr.GetCreatureData(dbGuid); if (!data) { PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, dbGuid); SetSentErrorMessage(true); return false; } targetCreature = m_session->GetPlayer()->GetMap()->GetCreature(data->GetObjectGuid(dbGuid)); if (!targetCreature) { PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, dbGuid); SetSentErrorMessage(true); return false; } } Creature* wpOwner; ///< Npc that is moving TemporarySummonWaypoint* wpTarget = NULL; // Define here for wp-info command // Show info for the selected waypoint (Step one: get moving npc) if (subCmd == "info") { // Check if the user did specify a visual waypoint if (targetCreature->GetEntry() != VISUAL_WAYPOINT || targetCreature->GetSubtype() != CREATURE_SUBTYPE_TEMPORARY_SUMMON) { PSendSysMessage(LANG_WAYPOINT_VP_SELECT); SetSentErrorMessage(true); return false; } wpTarget = dynamic_cast<TemporarySummonWaypoint*>(targetCreature); if (!wpTarget) { PSendSysMessage(LANG_WAYPOINT_VP_SELECT); SetSentErrorMessage(true); return false; } // Who moves along this waypoint? wpOwner = targetCreature->GetMap()->GetAnyTypeCreature(wpTarget->GetSummonerGuid()); if (!wpOwner) { PSendSysMessage(LANG_WAYPOINT_NOTFOUND_NPC, wpTarget->GetSummonerGuid().GetString().c_str()); SetSentErrorMessage(true); return false; } // Ignore params, use information of selected waypoint! wpOrigin = (WaypointPathOrigin)wpTarget->GetPathOrigin(); wpPathId = wpTarget->GetPathId(); } else { wpOwner = targetCreature; } // Get the path WaypointPath* wpPath = NULL; if (wpOrigin != PATH_NO_PATH) // Might have been provided by param { wpPath = sWaypointMgr.GetPathFromOrigin(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpPathId, wpOrigin); } else { if (wpOwner->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) { if (WaypointMovementGenerator<Creature> const* wpMMGen = dynamic_cast<WaypointMovementGenerator<Creature> const*>(wpOwner->GetMotionMaster()->GetCurrent())) { wpMMGen->GetPathInformation(wpPathId, wpOrigin); wpPath = sWaypointMgr.GetPathFromOrigin(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpPathId, wpOrigin); } } if (wpOrigin == PATH_NO_PATH) { wpPath = sWaypointMgr.GetDefaultPath(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), &wpOrigin); } } if (!wpPath || wpPath->empty()) { PSendSysMessage(LANG_WAYPOINT_NOTFOUNDPATH, wpOwner->GetGuidStr().c_str(), wpPathId, WaypointManager::GetOriginString(wpOrigin).c_str()); SetSentErrorMessage(true); return false; } // Show info for the selected waypoint (Step two: Show actual info) if (subCmd == "info") { // Find the waypoint WaypointPath::const_iterator point = wpPath->find(wpTarget->GetWaypointId()); if (point == wpPath->end()) { PSendSysMessage(LANG_WAYPOINT_NOTFOUND, wpTarget->GetWaypointId(), wpOwner->GetGuidStr().c_str(), wpPathId, WaypointManager::GetOriginString(wpOrigin).c_str()); SetSentErrorMessage(true); return false; } PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, wpTarget->GetWaypointId(), wpOwner->GetGuidStr().c_str(), wpPathId, WaypointManager::GetOriginString(wpOrigin).c_str()); PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, point->second.delay); PSendSysMessage(LANG_WAYPOINT_INFO_ORI, point->second.orientation); PSendSysMessage(LANG_WAYPOINT_INFO_SCRIPTID, point->second.script_id); if (wpOrigin == PATH_FROM_EXTERNAL) { PSendSysMessage(LANG_WAYPOINT_INFO_AISCRIPT, wpOwner->GetScriptName().c_str()); } if (WaypointBehavior* behaviour = point->second.behavior) { PSendSysMessage(" ModelId1: %u", behaviour->model1); PSendSysMessage(" ModelId2: %u", behaviour->model2); PSendSysMessage(" Emote: %u", behaviour->emote); PSendSysMessage(" Spell: %u", behaviour->spell); for (int i = 0; i < MAX_WAYPOINT_TEXT; ++i) { PSendSysMessage(" TextId%i: %i \'%s\'", i + 1, behaviour->textid[i], (behaviour->textid[i] ? GetMangosString(behaviour->textid[i]) : "")); } } return true; } if (subCmd == "on") { UnsummonVisualWaypoints(m_session->GetPlayer(), wpOwner->GetObjectGuid()); for (WaypointPath::const_iterator pItr = wpPath->begin(); pItr != wpPath->end(); ++pItr) { if (!Helper_CreateWaypointFor(wpOwner, wpOrigin, wpPathId, pItr->first, &(pItr->second), waypointInfo)) { PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); SetSentErrorMessage(true); return false; } } return true; } if (subCmd == "first") { if (!Helper_CreateWaypointFor(wpOwner, wpOrigin, wpPathId, wpPath->begin()->first, &(wpPath->begin()->second), waypointInfo)) { PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); SetSentErrorMessage(true); return false; } // player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint"); return true; } if (subCmd == "last") { if (!Helper_CreateWaypointFor(wpOwner, wpOrigin, wpPathId, wpPath->rbegin()->first, &(wpPath->rbegin()->second), waypointInfo)) { PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); SetSentErrorMessage(true); return false; } // player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint"); return true; } if (subCmd == "off") { UnsummonVisualWaypoints(m_session->GetPlayer(), wpOwner->GetObjectGuid()); PSendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED); return true; } return false; } // HandleWpShowCommand /// [Guid if no selected unit] <filename> [pathId [wpOrigin] ] bool ChatHandler::HandleWpExportCommand(char* args) { if (!*args) { return false; } Creature* wpOwner; WaypointPathOrigin wpOrigin = PATH_NO_PATH; int32 wpPathId = 0; if (Creature* targetCreature = getSelectedCreature()) { // Check if the user did specify a visual waypoint if (targetCreature->GetEntry() == VISUAL_WAYPOINT && targetCreature->GetSubtype() == CREATURE_SUBTYPE_TEMPORARY_SUMMON) { TemporarySummonWaypoint* wpTarget = dynamic_cast<TemporarySummonWaypoint*>(targetCreature); if (!wpTarget) { PSendSysMessage(LANG_WAYPOINT_VP_SELECT); SetSentErrorMessage(true); return false; } // Who moves along this waypoint? wpOwner = targetCreature->GetMap()->GetAnyTypeCreature(wpTarget->GetSummonerGuid()); if (!wpOwner) { PSendSysMessage(LANG_WAYPOINT_NOTFOUND_NPC, wpTarget->GetSummonerGuid().GetString().c_str()); SetSentErrorMessage(true); return false; } wpOrigin = (WaypointPathOrigin)wpTarget->GetPathOrigin(); wpPathId = wpTarget->GetPathId(); } else // normal creature selected { wpOwner = targetCreature; } } else { uint32 dbGuid; if (!ExtractUInt32(&args, dbGuid)) { PSendSysMessage(LANG_WAYPOINT_NOGUID); SetSentErrorMessage(true); return false; } CreatureData const* data = sObjectMgr.GetCreatureData(dbGuid); if (!data) { PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, dbGuid); SetSentErrorMessage(true); return false; } if (m_session->GetPlayer()->GetMapId() != data->mapid) { PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, dbGuid); SetSentErrorMessage(true); return false; } wpOwner = m_session->GetPlayer()->GetMap()->GetAnyTypeCreature(data->GetObjectGuid(dbGuid)); if (!wpOwner) { PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, dbGuid); SetSentErrorMessage(true); return false; } } // wpOwner is now known, in case of export by visual waypoint also the to be exported path char* export_str = ExtractLiteralArg(&args); if (!export_str) { PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export"); SetSentErrorMessage(true); return false; } if (wpOrigin == PATH_NO_PATH) // No WP selected, Extract optional arguments { if (ExtractOptInt32(&args, wpPathId, 0)) // Fill path-id and source { uint32 src = (uint32)PATH_NO_PATH; if (ExtractOptUInt32(&args, src, src)) { wpOrigin = (WaypointPathOrigin)src; } else // pathId provided but no destination { if (wpPathId != 0) { wpOrigin = PATH_FROM_ENTRY; // Multiple Paths must only be assigned by entry } } } if (wpOrigin == PATH_NO_PATH) { if (wpOwner->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) if (WaypointMovementGenerator<Creature> const* wpMMGen = dynamic_cast<WaypointMovementGenerator<Creature> const*>(wpOwner->GetMotionMaster()->GetCurrent())) { wpMMGen->GetPathInformation(wpPathId, wpOrigin); } if (wpOrigin == PATH_NO_PATH) { sWaypointMgr.GetDefaultPath(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), &wpOrigin); } } } WaypointPath const* wpPath = sWaypointMgr.GetPathFromOrigin(wpOwner->GetEntry(), wpOwner->GetGUIDLow(), wpPathId, wpOrigin); if (!wpPath || wpPath->empty()) { PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT); SetSentErrorMessage(true); return false; } std::ofstream outfile; outfile.open(export_str); std::string table; char const* key_field; uint32 key; switch (wpOrigin) { case PATH_FROM_ENTRY: key = wpOwner->GetEntry(); key_field = "entry"; table = "creature_movement_template"; break; case PATH_FROM_GUID: key = wpOwner->GetGUIDLow(); key_field = "id"; table = "creature_movement"; break; case PATH_FROM_EXTERNAL: key = wpOwner->GetEntry(); key_field = "entry"; table = sWaypointMgr.GetExternalWPTable(); break; case PATH_NO_PATH: return false; } outfile << "DELETE FROM `" << table << "` WHERE `" << key_field << "`=" << key << ";\n"; if (wpOrigin != PATH_FROM_EXTERNAL) { outfile << "INSERT INTO `" << table << "` (`" << key_field << "`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `waittime`, `script_id`) VALUES\n"; } else { outfile << "INSERT INTO `" << table << "` (`" << key_field << "`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `waittime`) VALUES\n"; } WaypointPath::const_iterator itr = wpPath->begin(); uint32 countDown = wpPath->size(); for (; itr != wpPath->end(); ++itr, --countDown) { outfile << "(" << key << ","; outfile << itr->first << ","; outfile << itr->second.x << ","; outfile << itr->second.y << ","; outfile << itr->second.z << ","; outfile << itr->second.orientation << ","; outfile << itr->second.delay << ","; if (wpOrigin != PATH_FROM_EXTERNAL) // Only for normal waypoints { outfile << itr->second.script_id << ")"; } if (countDown > 1) { outfile << ",\n"; } else { outfile << ";\n"; } } PSendSysMessage(LANG_WAYPOINT_EXPORTED); outfile.close(); return true; }