mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-17 10:55:43 +00:00
Update Vmaps | Mmaps | Recastnav and fixed FleeingMovement
- Fixes getHeight collision (Map height is now calculated properly core-side, extraction of Maps, Vmaps is required) - Fixes invisible walls causing LoS errores and wrong pathing in some zones. - Mmaps update, padding is used, now to ensure proper binary-identical mmtiles - Updated Recastnav to work properly with new updates - Updated Area Storage - Implement Map out of Bound (players will pop on closest graveyard if out of bounds) - FleeingMovementGenerator updated, LoS calc to not go out of bounds or in/under textured when fleeing - Added command .mmap, port from TC (info about mmaps)
This commit is contained in:
@@ -78,7 +78,7 @@ message("")
|
||||
include_directories(
|
||||
${scripts_INCLUDE_DIRS}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/modules/worldengine/deps/recastnavigation/Detour
|
||||
${CMAKE_SOURCE_DIR}/modules/worldengine/deps/recastnavigation/Detour/Include
|
||||
${CMAKE_SOURCE_DIR}/modules/worldengine/deps/recastnavigation/Recast
|
||||
${CMAKE_SOURCE_DIR}/modules/worldengine/deps/g3dlite/include
|
||||
${CMAKE_SOURCE_DIR}/modules/worldengine/deps/SFMT
|
||||
|
||||
@@ -31,6 +31,7 @@ set(scripts_STAT_SRCS
|
||||
Commands/cs_lookup.cpp
|
||||
Commands/cs_message.cpp
|
||||
Commands/cs_misc.cpp
|
||||
Commands/cs_mmaps.cpp
|
||||
Commands/cs_modify.cpp
|
||||
Commands/cs_npc.cpp
|
||||
Commands/cs_quest.cpp
|
||||
|
||||
@@ -417,7 +417,7 @@ public:
|
||||
|
||||
uint32 areaId = id ? (uint32)atoi(id) : player->GetZoneId();
|
||||
|
||||
AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId);
|
||||
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId);
|
||||
|
||||
if (x < 0 || x > 100 || y < 0 || y > 100 || !areaEntry)
|
||||
{
|
||||
@@ -427,7 +427,7 @@ public:
|
||||
}
|
||||
|
||||
// update to parent zone if exist (client map show only zones without parents)
|
||||
AreaTableEntry const* zoneEntry = areaEntry->zone ? GetAreaEntryByAreaID(areaEntry->zone) : areaEntry;
|
||||
AreaTableEntry const* zoneEntry = areaEntry->zone ? sAreaTableStore.LookupEntry(areaEntry->zone) : areaEntry;
|
||||
|
||||
Map const* map = sMapMgr->CreateBaseMap(zoneEntry->mapid);
|
||||
|
||||
|
||||
@@ -86,9 +86,9 @@ public:
|
||||
wstrToLower(wNamePart);
|
||||
|
||||
// Search in AreaTable.dbc
|
||||
for (uint32 areaflag = 0; areaflag < sAreaStore.GetNumRows(); ++areaflag)
|
||||
for (uint32 i = 0; i < sAreaTableStore.GetNumRows(); ++i)
|
||||
{
|
||||
AreaTableEntry const* areaEntry = sAreaStore.LookupEntry(areaflag);
|
||||
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(i);
|
||||
if (areaEntry)
|
||||
{
|
||||
int locale = handler->GetSessionDbcLocale();
|
||||
|
||||
@@ -400,8 +400,8 @@ public:
|
||||
object->GetZoneAndAreaId(zoneId, areaId);
|
||||
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(object->GetMapId());
|
||||
AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zoneId);
|
||||
AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId);
|
||||
AreaTableEntry const* zoneEntry = sAreaTableStore.LookupEntry(zoneId);
|
||||
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId);
|
||||
|
||||
float zoneX = object->GetPositionX();
|
||||
float zoneY = object->GetPositionY();
|
||||
@@ -1280,7 +1280,7 @@ public:
|
||||
|
||||
uint32 zoneId = player->GetZoneId();
|
||||
|
||||
AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId);
|
||||
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(zoneId);
|
||||
if (!areaEntry || areaEntry->zone !=0)
|
||||
{
|
||||
handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, graveyardId, zoneId);
|
||||
@@ -1411,17 +1411,23 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 area = GetAreaFlagByAreaID(atoi((char*)args));
|
||||
int32 offset = area / 32;
|
||||
uint32 val = uint32((1 << (area % 32)));
|
||||
|
||||
if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE)
|
||||
AreaTableEntry const* area = sAreaTableStore.LookupEntry(atoi(args));
|
||||
if (!area)
|
||||
{
|
||||
handler->SendSysMessage(LANG_BAD_VALUE);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 offset = area->exploreFlag / 32;
|
||||
if (offset >= PLAYER_EXPLORED_ZONES_SIZE)
|
||||
{
|
||||
handler->SendSysMessage(LANG_BAD_VALUE);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 val = uint32((1 << (area->exploreFlag % 32)));
|
||||
uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
|
||||
playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields | val)));
|
||||
|
||||
@@ -1442,17 +1448,23 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 area = GetAreaFlagByAreaID(atoi((char*)args));
|
||||
int32 offset = area / 32;
|
||||
uint32 val = uint32((1 << (area % 32)));
|
||||
|
||||
if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE)
|
||||
AreaTableEntry const* area = sAreaTableStore.LookupEntry(atoi(args));
|
||||
if (!area)
|
||||
{
|
||||
handler->SendSysMessage(LANG_BAD_VALUE);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 offset = area->exploreFlag / 32;
|
||||
if (offset >= PLAYER_EXPLORED_ZONES_SIZE)
|
||||
{
|
||||
handler->SendSysMessage(LANG_BAD_VALUE);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 val = uint32((1 << (area->exploreFlag % 32)));
|
||||
uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
|
||||
playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields ^ val)));
|
||||
|
||||
@@ -2025,12 +2037,12 @@ public:
|
||||
|
||||
MapEntry const* map = sMapStore.LookupEntry(mapId);
|
||||
|
||||
AreaTableEntry const* area = GetAreaEntryByAreaID(areaId);
|
||||
AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId);
|
||||
if (area)
|
||||
{
|
||||
areaName = area->area_name[locale];
|
||||
|
||||
AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone);
|
||||
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(area->zone);
|
||||
if (zone)
|
||||
zoneName = zone->area_name[locale];
|
||||
}
|
||||
|
||||
305
src/scripts/Commands/cs_mmaps.cpp
Normal file
305
src/scripts/Commands/cs_mmaps.cpp
Normal file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cs_mmaps.cpp
|
||||
* @brief .mmap related commands
|
||||
*
|
||||
* This file contains the CommandScripts for all
|
||||
* mmap sub-commands
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "Chat.h"
|
||||
#include "DisableMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "PointMovementGenerator.h"
|
||||
#include "PathGenerator.h"
|
||||
#include "MMapFactory.h"
|
||||
#include "Map.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "CellImpl.h"
|
||||
|
||||
class mmaps_commandscript : public CommandScript
|
||||
{
|
||||
public:
|
||||
mmaps_commandscript() : CommandScript("mmaps_commandscript") { }
|
||||
|
||||
std::vector<ChatCommand> GetCommands() const override
|
||||
{
|
||||
static std::vector<ChatCommand> mmapCommandTable =
|
||||
{
|
||||
{ "loadedtiles", SEC_ADMINISTRATOR, false, &HandleMmapLoadedTilesCommand, "" },
|
||||
{ "loc", SEC_ADMINISTRATOR, false, &HandleMmapLocCommand, "" },
|
||||
{ "path", SEC_ADMINISTRATOR, false, &HandleMmapPathCommand, "" },
|
||||
{ "stats", SEC_ADMINISTRATOR, false, &HandleMmapStatsCommand, "" },
|
||||
{ "testarea", SEC_ADMINISTRATOR, false, &HandleMmapTestArea, "" },
|
||||
};
|
||||
|
||||
static std::vector<ChatCommand> commandTable =
|
||||
{
|
||||
{ "mmap", SEC_ADMINISTRATOR, true, NULL, "", mmapCommandTable },
|
||||
};
|
||||
return commandTable;
|
||||
}
|
||||
|
||||
static bool HandleMmapPathCommand(ChatHandler* handler, char const* args)
|
||||
{
|
||||
if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()))
|
||||
{
|
||||
handler->PSendSysMessage("NavMesh not loaded for current map.");
|
||||
return true;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("mmap path:");
|
||||
|
||||
// units
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
Unit* target = handler->getSelectedUnit();
|
||||
if (!player || !target)
|
||||
{
|
||||
handler->PSendSysMessage("Invalid target/source selection.");
|
||||
return true;
|
||||
}
|
||||
|
||||
char* para = strtok((char*)args, " ");
|
||||
|
||||
bool useStraightPath = false;
|
||||
if (para && strcmp(para, "true") == 0)
|
||||
useStraightPath = true;
|
||||
|
||||
bool useStraightLine = false;
|
||||
if (para && strcmp(para, "line") == 0)
|
||||
useStraightLine = true;
|
||||
|
||||
// unit locations
|
||||
float x, y, z;
|
||||
player->GetPosition(x, y, z);
|
||||
|
||||
// path
|
||||
PathGenerator path(target);
|
||||
path.SetUseStraightPath(useStraightPath);
|
||||
bool result = path.CalculatePath(x, y, z, false);
|
||||
|
||||
Movement::PointsArray const& pointPath = path.GetPath();
|
||||
handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str());
|
||||
handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : useStraightLine ? "Raycast" : "SmoothPath");
|
||||
handler->PSendSysMessage("Result: %s - Length: %zu - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType());
|
||||
|
||||
G3D::Vector3 const &start = path.GetStartPosition();
|
||||
G3D::Vector3 const &end = path.GetEndPosition();
|
||||
G3D::Vector3 const &actualEnd = path.GetActualEndPosition();
|
||||
|
||||
handler->PSendSysMessage("StartPosition (%.3f, %.3f, %.3f)", start.x, start.y, start.z);
|
||||
handler->PSendSysMessage("EndPosition (%.3f, %.3f, %.3f)", end.x, end.y, end.z);
|
||||
handler->PSendSysMessage("ActualEndPosition (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z);
|
||||
|
||||
if (!player->IsGameMaster())
|
||||
handler->PSendSysMessage("Enable GM mode to see the path points.");
|
||||
|
||||
for (uint32 i = 0; i < pointPath.size(); ++i)
|
||||
player->SummonCreature(VISUAL_WAYPOINT, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleMmapLocCommand(ChatHandler* handler, char const* /*args*/)
|
||||
{
|
||||
handler->PSendSysMessage("mmap tileloc:");
|
||||
|
||||
// grid tile location
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
|
||||
int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS;
|
||||
int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS;
|
||||
|
||||
handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gx, gy);
|
||||
handler->PSendSysMessage("gridloc [%i, %i]", gy, gx);
|
||||
|
||||
// calculate navmesh tile location
|
||||
dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId());
|
||||
dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(handler->GetSession()->GetPlayer()->GetMapId(), player->GetInstanceId());
|
||||
if (!navmesh || !navmeshquery)
|
||||
{
|
||||
handler->PSendSysMessage("NavMesh not loaded for current map.");
|
||||
return true;
|
||||
}
|
||||
|
||||
float const* min = navmesh->getParams()->orig;
|
||||
float x, y, z;
|
||||
player->GetPosition(x, y, z);
|
||||
float location[VERTEX_SIZE] = {y, z, x};
|
||||
float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f};
|
||||
|
||||
int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS);
|
||||
int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS);
|
||||
|
||||
handler->PSendSysMessage("Calc [%02i, %02i]", tilex, tiley);
|
||||
|
||||
// navmesh poly -> navmesh tile location
|
||||
dtQueryFilter filter = dtQueryFilter();
|
||||
dtPolyRef polyRef = INVALID_POLYREF;
|
||||
if (dtStatusFailed(navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL)))
|
||||
{
|
||||
handler->PSendSysMessage("Dt [??,??] (invalid poly, probably no tile loaded)");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (polyRef == INVALID_POLYREF)
|
||||
handler->PSendSysMessage("Dt [??, ??] (invalid poly, probably no tile loaded)");
|
||||
else
|
||||
{
|
||||
dtMeshTile const* tile;
|
||||
dtPoly const* poly;
|
||||
if (dtStatusSucceed(navmesh->getTileAndPolyByRef(polyRef, &tile, &poly)))
|
||||
{
|
||||
if (tile)
|
||||
{
|
||||
handler->PSendSysMessage("Dt [%02i,%02i]", tile->header->x, tile->header->y);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("Dt [??,??] (no tile loaded)");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleMmapLoadedTilesCommand(ChatHandler* handler, char const* /*args*/)
|
||||
{
|
||||
uint32 mapid = handler->GetSession()->GetPlayer()->GetMapId();
|
||||
dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(mapid);
|
||||
dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(mapid, handler->GetSession()->GetPlayer()->GetInstanceId());
|
||||
if (!navmesh || !navmeshquery)
|
||||
{
|
||||
handler->PSendSysMessage("NavMesh not loaded for current map.");
|
||||
return true;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("mmap loadedtiles:");
|
||||
|
||||
for (int32 i = 0; i < navmesh->getMaxTiles(); ++i)
|
||||
{
|
||||
dtMeshTile const* tile = navmesh->getTile(i);
|
||||
if (!tile || !tile->header)
|
||||
continue;
|
||||
|
||||
handler->PSendSysMessage("[%02i, %02i]", tile->header->x, tile->header->y);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleMmapStatsCommand(ChatHandler* handler, char const* /*args*/)
|
||||
{
|
||||
handler->PSendSysMessage("mmap stats:");
|
||||
//handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(mapId) ? "en" : "dis");
|
||||
|
||||
MMAP::MMapManager* manager = MMAP::MMapFactory::createOrGetMMapManager();
|
||||
handler->PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount());
|
||||
|
||||
dtNavMesh const* navmesh = manager->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId());
|
||||
if (!navmesh)
|
||||
{
|
||||
handler->PSendSysMessage("NavMesh not loaded for current map.");
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 tileCount = 0;
|
||||
uint32 nodeCount = 0;
|
||||
uint32 polyCount = 0;
|
||||
uint32 vertCount = 0;
|
||||
uint32 triCount = 0;
|
||||
uint32 triVertCount = 0;
|
||||
uint32 dataSize = 0;
|
||||
for (int32 i = 0; i < navmesh->getMaxTiles(); ++i)
|
||||
{
|
||||
dtMeshTile const* tile = navmesh->getTile(i);
|
||||
if (!tile || !tile->header)
|
||||
continue;
|
||||
|
||||
tileCount++;
|
||||
nodeCount += tile->header->bvNodeCount;
|
||||
polyCount += tile->header->polyCount;
|
||||
vertCount += tile->header->vertCount;
|
||||
triCount += tile->header->detailTriCount;
|
||||
triVertCount += tile->header->detailVertCount;
|
||||
dataSize += tile->dataSize;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("Navmesh stats:");
|
||||
handler->PSendSysMessage(" %u tiles loaded", tileCount);
|
||||
handler->PSendSysMessage(" %u BVTree nodes", nodeCount);
|
||||
handler->PSendSysMessage(" %u polygons (%u vertices)", polyCount, vertCount);
|
||||
handler->PSendSysMessage(" %u triangles (%u vertices)", triCount, triVertCount);
|
||||
handler->PSendSysMessage(" %.2f MB of data (not including pointers)", ((float)dataSize / sizeof(unsigned char)) / 1048576);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleMmapTestArea(ChatHandler* handler, char const* /*args*/)
|
||||
{
|
||||
float radius = 40.0f;
|
||||
WorldObject* object = handler->GetSession()->GetPlayer();
|
||||
|
||||
CellCoord pair(Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()));
|
||||
Cell cell(pair);
|
||||
cell.SetNoCreate();
|
||||
|
||||
std::list<Creature*> creatureList;
|
||||
|
||||
Trinity::AnyUnitInObjectRangeCheck go_check(object, radius);
|
||||
Trinity::CreatureListSearcher<Trinity::AnyUnitInObjectRangeCheck> go_search(object, creatureList, go_check);
|
||||
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AnyUnitInObjectRangeCheck>, GridTypeMapContainer> go_visit(go_search);
|
||||
|
||||
// Get Creatures
|
||||
cell.Visit(pair, go_visit, *(object->GetMap()), *object, radius);
|
||||
|
||||
if (!creatureList.empty())
|
||||
{
|
||||
handler->PSendSysMessage("Found %zu Creatures.", creatureList.size());
|
||||
|
||||
uint32 paths = 0;
|
||||
uint32 uStartTime = getMSTime();
|
||||
|
||||
float gx, gy, gz;
|
||||
object->GetPosition(gx, gy, gz);
|
||||
for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr)
|
||||
{
|
||||
PathGenerator path(*itr);
|
||||
path.CalculatePath(gx, gy, gz);
|
||||
++paths;
|
||||
}
|
||||
|
||||
uint32 uPathLoadTime = getMSTimeDiff(uStartTime, getMSTime());
|
||||
handler->PSendSysMessage("Generated %i paths in %i ms", paths, uPathLoadTime);
|
||||
}
|
||||
else
|
||||
handler->PSendSysMessage("No creatures in %f yard range.", radius);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_mmaps_commandscript()
|
||||
{
|
||||
new mmaps_commandscript();
|
||||
}
|
||||
@@ -46,6 +46,7 @@ void AddSC_list_commandscript();
|
||||
void AddSC_lookup_commandscript();
|
||||
void AddSC_message_commandscript();
|
||||
void AddSC_misc_commandscript();
|
||||
void AddSC_mmaps_commandscript();
|
||||
void AddSC_modify_commandscript();
|
||||
void AddSC_npc_commandscript();
|
||||
void AddSC_quest_commandscript();
|
||||
@@ -616,6 +617,7 @@ void AddCommandScripts()
|
||||
AddSC_lookup_commandscript();
|
||||
AddSC_message_commandscript();
|
||||
AddSC_misc_commandscript();
|
||||
AddSC_mmaps_commandscript();
|
||||
AddSC_modify_commandscript();
|
||||
AddSC_npc_commandscript();
|
||||
AddSC_quest_commandscript();
|
||||
|
||||
@@ -4431,10 +4431,7 @@ class spell_gen_mount : public SpellScriptLoader
|
||||
if (map == 530 || (map == 571 && target->HasSpell(SPELL_COLD_WEATHER_FLYING)))
|
||||
canFly = true;
|
||||
|
||||
float x, y, z;
|
||||
target->GetPosition(x, y, z);
|
||||
uint32 areaFlag = target->GetBaseMap()->GetAreaFlag(x, y, z);
|
||||
AreaTableEntry const* area = sAreaStore.LookupEntry(areaFlag);
|
||||
AreaTableEntry const* area = sAreaTableStore.LookupEntry(target->GetAreaId());
|
||||
// Xinef: add battlefield check
|
||||
Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(target->GetZoneId());
|
||||
if (!area || (canFly && ((area->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))))
|
||||
|
||||
Reference in New Issue
Block a user