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:
parent
d98ba9cdaa
commit
e772b08c68
79 changed files with 5037 additions and 3018 deletions
|
|
@ -429,7 +429,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
|||
sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Map entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.respawn.map);
|
||||
return false;
|
||||
}
|
||||
if (e.event.respawn.type == SMART_SCRIPT_RESPAWN_CONDITION_AREA && !GetAreaEntryByAreaID(e.event.respawn.area))
|
||||
if (e.event.respawn.type == SMART_SCRIPT_RESPAWN_CONDITION_AREA && !sAreaTableStore.LookupEntry(e.event.respawn.area))
|
||||
{
|
||||
sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Area entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.respawn.area);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
|||
return true;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA:
|
||||
if (!GetAreaEntryByAreaID(area.id))
|
||||
if (!sAreaTableStore.LookupEntry(area.id))
|
||||
{
|
||||
sLog->outErrorDb("Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA (%u) has wrong area id in value1 (%u), ignored.",
|
||||
criteria->ID, criteria->requiredType, dataType, area.id);
|
||||
|
|
@ -1277,17 +1277,15 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
bool matchFound = false;
|
||||
for (int j = 0; j < MAX_WORLD_MAP_OVERLAY_AREA_IDX; ++j)
|
||||
{
|
||||
uint32 area_id = worldOverlayEntry->areatableID[j];
|
||||
if (!area_id) // array have 0 only in empty tail
|
||||
AreaTableEntry const* area = sAreaTableStore.LookupEntry(worldOverlayEntry->areatableID[j]);
|
||||
if (!area)
|
||||
break;
|
||||
|
||||
int32 exploreFlag = GetAreaFlagByAreaID(area_id);
|
||||
if (exploreFlag < 0)
|
||||
uint32 playerIndexOffset = uint32(area->exploreFlag) / 32;
|
||||
if (playerIndexOffset >= PLAYER_EXPLORED_ZONES_SIZE)
|
||||
continue;
|
||||
|
||||
uint32 playerIndexOffset = uint32(exploreFlag) / 32;
|
||||
uint32 mask = 1<< (uint32(exploreFlag) % 32);
|
||||
|
||||
uint32 mask = 1 << (uint32(area->exploreFlag) % 32);
|
||||
if (GetPlayer()->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask)
|
||||
{
|
||||
matchFound = true;
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ set(game_STAT_SRCS
|
|||
include_directories(
|
||||
${game_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
|
||||
|
|
|
|||
|
|
@ -301,11 +301,11 @@ bool ChatHandler::ExecuteCommandInTable(std::vector<ChatCommand> const& table, c
|
|||
uint32 areaId = player->GetAreaId();
|
||||
std::string areaName = "Unknown";
|
||||
std::string zoneName = "Unknown";
|
||||
if (AreaTableEntry const* area = GetAreaEntryByAreaID(areaId))
|
||||
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId))
|
||||
{
|
||||
int locale = GetSessionDbcLocale();
|
||||
areaName = area->area_name[locale];
|
||||
if (AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone))
|
||||
if (AreaTableEntry const* zone = sAreaTableStore.LookupEntry(area->zone))
|
||||
zoneName = zone->area_name[locale];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1658,7 +1658,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
|
|||
}
|
||||
case CONDITION_ZONEID:
|
||||
{
|
||||
AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(cond->ConditionValue1);
|
||||
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(cond->ConditionValue1);
|
||||
if (!areaEntry)
|
||||
{
|
||||
sLog->outErrorDb("ZoneID condition has non existing area (%u), skipped", cond->ConditionValue1);
|
||||
|
|
|
|||
|
|
@ -38,11 +38,9 @@ struct WMOAreaTableTripple
|
|||
|
||||
typedef std::map<WMOAreaTableTripple, WMOAreaTableEntry const*> WMOAreaInfoByTripple;
|
||||
|
||||
DBCStorage <AreaTableEntry> sAreaStore(AreaTableEntryfmt);
|
||||
DBCStorage <AreaTableEntry> sAreaTableStore(AreaTableEntryfmt);
|
||||
DBCStorage <AreaGroupEntry> sAreaGroupStore(AreaGroupEntryfmt);
|
||||
DBCStorage <AreaPOIEntry> sAreaPOIStore(AreaPOIEntryfmt);
|
||||
static AreaFlagByAreaID sAreaFlagByAreaID;
|
||||
static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files
|
||||
|
||||
static WMOAreaInfoByTripple sWMOAreaInfoByTripple;
|
||||
|
||||
|
|
@ -255,21 +253,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
StoreProblemList bad_dbc_files;
|
||||
uint32 availableDbcLocales = 0xFFFFFFFF;
|
||||
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sAreaStore, dbcPath, "AreaTable.dbc");
|
||||
|
||||
// must be after sAreaStore loading
|
||||
for (uint32 i = 0; i < sAreaStore.GetNumRows(); ++i) // areaflag numbered from 0
|
||||
{
|
||||
if (AreaTableEntry const* area = sAreaStore.LookupEntry(i))
|
||||
{
|
||||
// fill AreaId->DBC records
|
||||
sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID), area->exploreFlag));
|
||||
|
||||
// fill MapId->DBC records (skip sub zones and continents)
|
||||
if (area->zone == 0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571)
|
||||
sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid, area->exploreFlag));
|
||||
}
|
||||
}
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sAreaTableStore, dbcPath, "AreaTable.dbc");
|
||||
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementStore, dbcPath, "Achievement.dbc", &CustomAchievementfmt, &CustomAchievementIndex);
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementCriteriaStore, dbcPath, "Achievement_Criteria.dbc");
|
||||
|
|
@ -626,7 +610,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
}
|
||||
|
||||
// Check loaded DBC files proper version
|
||||
if (!sAreaStore.LookupEntry(3617) || // last area (areaflag) added in 3.3.5a
|
||||
if (!sAreaTableStore.LookupEntry(4987) || // last area added in 3.3.5a
|
||||
!sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.5a
|
||||
!sGemPropertiesStore.LookupEntry(1629) || // last added spell in 3.3.5a
|
||||
!sItemStore.LookupEntry(56806) || // last gem property added in 3.3.5a
|
||||
|
|
@ -678,50 +662,12 @@ uint32 GetTalentSpellCost(uint32 spellId)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32 GetAreaFlagByAreaID(uint32 area_id)
|
||||
{
|
||||
AreaFlagByAreaID::iterator i = sAreaFlagByAreaID.find(area_id);
|
||||
if (i == sAreaFlagByAreaID.end())
|
||||
return -1;
|
||||
|
||||
return i->second;
|
||||
}
|
||||
|
||||
WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid)
|
||||
{
|
||||
WMOAreaInfoByTripple::iterator i = sWMOAreaInfoByTripple.find(WMOAreaTableTripple(rootid, adtid, groupid));
|
||||
if (i == sWMOAreaInfoByTripple.end())
|
||||
return NULL;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id)
|
||||
{
|
||||
int32 areaflag = GetAreaFlagByAreaID(area_id);
|
||||
if (areaflag < 0)
|
||||
if (i == sWMOAreaInfoByTripple.end())
|
||||
return NULL;
|
||||
|
||||
return sAreaStore.LookupEntry(areaflag);
|
||||
}
|
||||
|
||||
AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag, uint32 map_id)
|
||||
{
|
||||
if (area_flag)
|
||||
return sAreaStore.LookupEntry(area_flag);
|
||||
|
||||
if (MapEntry const* mapEntry = sMapStore.LookupEntry(map_id))
|
||||
return GetAreaEntryByAreaID(mapEntry->linked_zone);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32 GetAreaFlagByMapId(uint32 mapid)
|
||||
{
|
||||
AreaFlagByMapID::iterator i = sAreaFlagByMapID.find(mapid);
|
||||
if (i == sAreaFlagByMapID.end())
|
||||
return 0;
|
||||
else
|
||||
return i->second;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)
|
||||
|
|
|
|||
|
|
@ -20,11 +20,6 @@ char* GetPetName(uint32 petfamily, uint32 dbclang);
|
|||
uint32 GetTalentSpellCost(uint32 spellId);
|
||||
TalentSpellPos const* GetTalentSpellPos(uint32 spellId);
|
||||
|
||||
int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found
|
||||
AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id);
|
||||
AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag, uint32 map_id);
|
||||
uint32 GetAreaFlagByMapId(uint32 mapid);
|
||||
|
||||
WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid);
|
||||
|
||||
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId);
|
||||
|
|
@ -58,7 +53,7 @@ uint32 GetDefaultMapLight(uint32 mapId);
|
|||
|
||||
extern DBCStorage <AchievementEntry> sAchievementStore;
|
||||
extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
|
||||
extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions
|
||||
extern DBCStorage <AreaTableEntry> sAreaTableStore;
|
||||
extern DBCStorage <AreaGroupEntry> sAreaGroupStore;
|
||||
extern DBCStorage <AreaPOIEntry> sAreaPOIStore;
|
||||
extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ char const Achievementfmt[] = "niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxx
|
|||
const std::string CustomAchievementfmt="pppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapapaaaaaaaaaaaaaaaaaapp";
|
||||
const std::string CustomAchievementIndex = "ID";
|
||||
char const AchievementCriteriafmt[] = "niiiiiiiixxxxxxxxxxxxxxxxxiiiix";
|
||||
char const AreaTableEntryfmt[] = "iiinixxxxxissssssssssssssssxiiiiixxx";
|
||||
char const AreaTableEntryfmt[] = "niiiixxxxxissssssssssssssssxiiiiixxx";
|
||||
char const AreaGroupEntryfmt[] = "niiiiiii";
|
||||
char const AreaPOIEntryfmt[] = "niiiiiiiiiiifffixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix";
|
||||
char const AreaTriggerEntryfmt[] = "niffffffff";
|
||||
|
|
|
|||
|
|
@ -5577,11 +5577,11 @@ void Player::RepopAtGraveyard()
|
|||
// note: this can be called also when the player is alive
|
||||
// for example from WorldSession::HandleMovementOpcodes
|
||||
|
||||
AreaTableEntry const* zone = GetAreaEntryByAreaID(GetAreaId());
|
||||
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetAreaId());
|
||||
|
||||
// Such zones are considered unreachable as a ghost and the player must be automatically revived
|
||||
// Xinef: Get Transport Check is not needed
|
||||
if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) /*|| GetTransport()*/ || GetPositionZ() < -500.0f)
|
||||
if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) /*|| GetTransport()*/ || GetPositionZ() < GetMap()->GetMinHeight(GetPositionX(), GetPositionY()))
|
||||
{
|
||||
ResurrectPlayer(0.5f);
|
||||
SpawnCorpseBones();
|
||||
|
|
@ -5618,8 +5618,10 @@ void Player::RepopAtGraveyard()
|
|||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
else if (GetPositionZ() < -500.0f)
|
||||
else if (GetPositionZ() < GetMap()->GetMinHeight(GetPositionX(), GetPositionY()))
|
||||
TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation());
|
||||
|
||||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
bool Player::CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone)
|
||||
|
|
@ -5671,7 +5673,7 @@ void Player::UpdateLocalChannels(uint32 newZone)
|
|||
if (GetSession()->PlayerLoading() && !IsBeingTeleportedFar())
|
||||
return; // The client handles it automatically after loading, but not after teleporting
|
||||
|
||||
AreaTableEntry const* current_zone = GetAreaEntryByAreaID(newZone);
|
||||
AreaTableEntry const* current_zone = sAreaTableStore.LookupEntry(newZone);
|
||||
if (!current_zone)
|
||||
return;
|
||||
|
||||
|
|
@ -6894,24 +6896,33 @@ void Player::CheckAreaExploreAndOutdoor()
|
|||
return;
|
||||
|
||||
bool isOutdoor = IsOutdoors();
|
||||
uint32 areaFlag = GetAreaFlagByAreaID(GetAreaId());
|
||||
|
||||
uint32 areaId = GetBaseMap()->GetAreaId(GetPositionX(), GetPositionY(), GetPositionZ(), &isOutdoor);
|
||||
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId);
|
||||
|
||||
if (sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK) && !isOutdoor)
|
||||
RemoveAurasWithAttribute(SPELL_ATTR0_OUTDOORS_ONLY);
|
||||
|
||||
if (areaFlag == 0xffff)
|
||||
if (!areaId)
|
||||
return;
|
||||
int offset = areaFlag / 32;
|
||||
|
||||
if (!areaEntry)
|
||||
{
|
||||
sLog->outError("Player '%s' (%u) discovered unknown area (x: %f y: %f z: %f map: %u)",
|
||||
GetName().c_str(), GetGUIDLow(), GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId());
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 offset = areaEntry->exploreFlag / 32;
|
||||
|
||||
if (offset >= PLAYER_EXPLORED_ZONES_SIZE)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outError("Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < %u ).", areaFlag, GetPositionX(), GetPositionY(), offset, offset, PLAYER_EXPLORED_ZONES_SIZE);
|
||||
sLog->outError("Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < %u ).", areaEntry->flags, GetPositionX(), GetPositionY(), offset, offset, PLAYER_EXPLORED_ZONES_SIZE);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 val = (uint32)(1 << (areaFlag % 32));
|
||||
uint32 val = (uint32)(1 << (areaEntry->exploreFlag % 32));
|
||||
uint32 currFields = GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
|
||||
|
||||
if (!(currFields & val))
|
||||
|
|
@ -6920,19 +6931,11 @@ void Player::CheckAreaExploreAndOutdoor()
|
|||
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA, GetAreaId());
|
||||
|
||||
AreaTableEntry const* areaEntry = GetAreaEntryByAreaFlagAndMap(areaFlag, GetMapId());
|
||||
if (!areaEntry)
|
||||
{
|
||||
sLog->outError("Player %u discovered unknown area (x: %f y: %f z: %f map: %u", GetGUIDLow(), GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId());
|
||||
return;
|
||||
}
|
||||
|
||||
if (areaEntry->area_level > 0)
|
||||
{
|
||||
uint32 area = areaEntry->ID;
|
||||
if (getLevel() >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
{
|
||||
SendExplorationExperience(area, 0);
|
||||
SendExplorationExperience(areaId, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -6958,10 +6961,10 @@ void Player::CheckAreaExploreAndOutdoor()
|
|||
}
|
||||
|
||||
GiveXP(XP, NULL);
|
||||
SendExplorationExperience(area, XP);
|
||||
SendExplorationExperience(areaId, XP);
|
||||
}
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDetail("Player %u discovered a new area: %u", GetGUIDLow(), area);
|
||||
sLog->outDetail("Player %u discovered a new area: %u", GetGUIDLow(), areaId);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -7533,7 +7536,7 @@ void Player::UpdateArea(uint32 newArea)
|
|||
// so apply them accordingly
|
||||
m_areaUpdateId = newArea;
|
||||
|
||||
AreaTableEntry const* area = GetAreaEntryByAreaID(newArea);
|
||||
AreaTableEntry const* area = sAreaTableStore.LookupEntry(newArea);
|
||||
bool oldFFAPvPArea = pvpInfo.IsInFFAPvPArea;
|
||||
pvpInfo.IsInFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA);
|
||||
UpdatePvPState(true);
|
||||
|
|
@ -7568,7 +7571,7 @@ void Player::UpdateArea(uint32 newArea)
|
|||
}
|
||||
|
||||
// Xinef: area should inherit zone flags
|
||||
AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone);
|
||||
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(area->zone);
|
||||
uint32 areaFlags = area->flags;
|
||||
bool isSanctuary = area->IsSanctuary();
|
||||
bool isInn = area->IsInn(GetTeamId(true));
|
||||
|
|
@ -7656,7 +7659,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
|
|||
// zone changed, so area changed as well, update it
|
||||
UpdateArea(newArea);
|
||||
|
||||
AreaTableEntry const* zone = GetAreaEntryByAreaID(newZone);
|
||||
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(newZone);
|
||||
if (!zone)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -3395,6 +3395,15 @@ int32 Unit::GetCurrentSpellCastTime(uint32 spell_id) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool Unit::CanMoveDuringChannel() const
|
||||
{
|
||||
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
|
||||
if (spell->getState() != SPELL_STATE_FINISHED)
|
||||
return spell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING) && spell->IsChannelActive();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const
|
||||
{
|
||||
return IsWithinDistInMap(target, distance) && HasInArc(arc, target);
|
||||
|
|
|
|||
|
|
@ -2048,6 +2048,9 @@ class Unit : public WorldObject
|
|||
// delayed+channeled spells are always interrupted
|
||||
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0, bool withInstant = true, bool bySelf = false);
|
||||
|
||||
// Check if our current channel spell has attribute SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING
|
||||
bool CanMoveDuringChannel() const;
|
||||
|
||||
Spell* GetCurrentSpell(CurrentSpellTypes spellType) const { return m_currentSpells[spellType]; }
|
||||
Spell* GetCurrentSpell(uint32 spellType) const { return m_currentSpells[spellType]; }
|
||||
Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;
|
||||
|
|
|
|||
|
|
@ -2720,7 +2720,7 @@ void ObjectMgr::LoadItemTemplates()
|
|||
itemTemplate.ItemSet = 0;
|
||||
}
|
||||
|
||||
if (itemTemplate.Area && !GetAreaEntryByAreaID(itemTemplate.Area))
|
||||
if (itemTemplate.Area && !sAreaTableStore.LookupEntry(itemTemplate.Area))
|
||||
sLog->outErrorDb("Item (Entry: %u) has wrong Area (%u)", entry, itemTemplate.Area);
|
||||
|
||||
if (itemTemplate.Map && !sMapStore.LookupEntry(itemTemplate.Map))
|
||||
|
|
@ -4022,7 +4022,7 @@ void ObjectMgr::LoadQuests()
|
|||
// client quest log visual (area case)
|
||||
if (qinfo->ZoneOrSort > 0)
|
||||
{
|
||||
if (!GetAreaEntryByAreaID(qinfo->ZoneOrSort))
|
||||
if (!sAreaTableStore.LookupEntry(qinfo->ZoneOrSort))
|
||||
{
|
||||
sLog->outErrorDb("Quest %u has `ZoneOrSort` = %u (zone case) but zone with this id does not exist.",
|
||||
qinfo->GetQuestId(), qinfo->ZoneOrSort);
|
||||
|
|
@ -5845,7 +5845,7 @@ void ObjectMgr::LoadGraveyardZones()
|
|||
continue;
|
||||
}
|
||||
|
||||
AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId);
|
||||
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(zoneId);
|
||||
if (!areaEntry)
|
||||
{
|
||||
sLog->outErrorDb("Table `game_graveyard_zone` has a record for not existing zone id (%u), skipped.", zoneId);
|
||||
|
|
@ -7893,7 +7893,7 @@ void ObjectMgr::LoadFishingBaseSkillLevel()
|
|||
uint32 entry = fields[0].GetUInt32();
|
||||
int32 skill = fields[1].GetInt16();
|
||||
|
||||
AreaTableEntry const* fArea = GetAreaEntryByAreaID(entry);
|
||||
AreaTableEntry const* fArea = sAreaTableStore.LookupEntry(entry);
|
||||
if (!fArea)
|
||||
{
|
||||
sLog->outErrorDb("AreaId %u defined in `skill_fishing_base_level` does not exist", entry);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class Player;
|
|||
|
||||
#define MAX_NUMBER_OF_GRIDS 64
|
||||
|
||||
#define SIZE_OF_GRIDS 533.33333f
|
||||
#define SIZE_OF_GRIDS 533.3333f
|
||||
#define CENTER_GRID_ID (MAX_NUMBER_OF_GRIDS/2)
|
||||
|
||||
#define CENTER_GRID_OFFSET (SIZE_OF_GRIDS/2)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
|
|||
if (!channel)
|
||||
return;
|
||||
|
||||
AreaTableEntry const* zone = GetAreaEntryByAreaID(GetPlayer()->GetZoneId());
|
||||
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetPlayer()->GetZoneId());
|
||||
if (!zone || !GetPlayer()->CanJoinConstantChannelInZone(channel, zone))
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
|
|||
continue;
|
||||
|
||||
std::string aname;
|
||||
if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(itr->second->GetZoneId()))
|
||||
if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(itr->second->GetZoneId()))
|
||||
aname = areaEntry->area_name[GetSessionDbcLocale()];
|
||||
|
||||
bool s_show = true;
|
||||
|
|
@ -1934,7 +1934,7 @@ void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recv_data*/)
|
|||
return;
|
||||
}
|
||||
|
||||
AreaTableEntry const* atEntry = GetAreaEntryByAreaID(_player->GetAreaId());
|
||||
AreaTableEntry const* atEntry = sAreaTableStore.LookupEntry(_player->GetAreaId());
|
||||
if (!atEntry || !(atEntry->flags & AREA_FLAG_WINTERGRASP_2))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -474,16 +474,26 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData)
|
|||
|
||||
plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);
|
||||
|
||||
if (movementInfo.pos.GetPositionZ() < -500.0f)
|
||||
if (movementInfo.pos.GetPositionZ() < plrMover->GetMap()->GetMinHeight(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY()))
|
||||
if (!plrMover->GetBattleground() || !plrMover->GetBattleground()->HandlePlayerUnderMap(_player))
|
||||
{
|
||||
if (plrMover->IsAlive())
|
||||
{
|
||||
plrMover->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS);
|
||||
plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
|
||||
// player can be alive if GM
|
||||
if (plrMover->IsAlive())
|
||||
plrMover->KillPlayer();
|
||||
}
|
||||
else if (!plrMover->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS))
|
||||
{
|
||||
WorldSafeLocsEntry const* grave = sObjectMgr->GetClosestGraveyard(plrMover->GetPositionX(), plrMover->GetPositionY(), plrMover->GetPositionZ(), plrMover->GetMapId(), plrMover->GetTeamId());
|
||||
|
||||
if ( grave)
|
||||
plrMover->TeleportTo(grave->map_id, grave->x, grave->y, grave->z, plrMover->GetOrientation());
|
||||
plrMover->Relocate(grave->x, grave->y, grave->z, plrMover->GetOrientation());
|
||||
}
|
||||
|
||||
plrMover->StopMovingOnCurrentPos(); // pussywizard: moving corpse can't release spirit
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1598,8 +1598,8 @@ void LoadLootTemplates_Fishing()
|
|||
uint32 count = LootTemplates_Fishing.LoadAndCollectLootIds(lootIdSet);
|
||||
|
||||
// remove real entries and check existence loot
|
||||
for (uint32 i = 1; i < sAreaStore.GetNumRows(); ++i)
|
||||
if (AreaTableEntry const* areaEntry = sAreaStore.LookupEntry(i))
|
||||
for (uint32 i = 1; i < sAreaTableStore.GetNumRows(); ++i)
|
||||
if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(i))
|
||||
if (lootIdSet.find(areaEntry->ID) != lootIdSet.end())
|
||||
lootIdSet.erase(areaEntry->ID);
|
||||
|
||||
|
|
@ -1784,8 +1784,8 @@ void LoadLootTemplates_Mail()
|
|||
uint32 count = LootTemplates_Mail.LoadAndCollectLootIds(lootIdSet);
|
||||
|
||||
// remove real entries and check existence loot
|
||||
for (uint32 i = 1; i < sMailTemplateStore.GetNumRows(); ++i)
|
||||
if (sMailTemplateStore.LookupEntry(i))
|
||||
for (uint32 i = 1; i < sAreaTableStore.GetNumRows(); ++i)
|
||||
if (sAreaTableStore.LookupEntry(i))
|
||||
if (lootIdSet.find(i) != lootIdSet.end())
|
||||
lootIdSet.erase(i);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ union u_map_magic
|
|||
};
|
||||
|
||||
u_map_magic MapMagic = { {'M','A','P','S'} };
|
||||
u_map_magic MapVersionMagic = { {'v','1','.','3'} };
|
||||
u_map_magic MapVersionMagic = { {'v','1','.','8'} };
|
||||
u_map_magic MapAreaMagic = { {'A','R','E','A'} };
|
||||
u_map_magic MapHeightMagic = { {'M','H','G','T'} };
|
||||
u_map_magic MapLiquidMagic = { {'M','L','I','Q'} };
|
||||
|
|
@ -1200,13 +1200,15 @@ GridMap::GridMap()
|
|||
_flags = 0;
|
||||
// Area data
|
||||
_gridArea = 0;
|
||||
_areaMap = NULL;
|
||||
_areaMap = nullptr;
|
||||
// Height level data
|
||||
_gridHeight = INVALID_HEIGHT;
|
||||
_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
_gridIntHeightMultiplier = 0;
|
||||
m_V9 = NULL;
|
||||
m_V8 = NULL;
|
||||
m_V9 = nullptr;
|
||||
m_V8 = nullptr;
|
||||
_maxHeight = nullptr;
|
||||
_minHeight = nullptr;
|
||||
// Liquid data
|
||||
_liquidType = 0;
|
||||
_liquidOffX = 0;
|
||||
|
|
@ -1214,9 +1216,9 @@ GridMap::GridMap()
|
|||
_liquidWidth = 0;
|
||||
_liquidHeight = 0;
|
||||
_liquidLevel = INVALID_HEIGHT;
|
||||
_liquidEntry = NULL;
|
||||
_liquidFlags = NULL;
|
||||
_liquidMap = NULL;
|
||||
_liquidEntry = nullptr;
|
||||
_liquidFlags = nullptr;
|
||||
_liquidMap = nullptr;
|
||||
}
|
||||
|
||||
GridMap::~GridMap()
|
||||
|
|
@ -1277,15 +1279,19 @@ void GridMap::unloadData()
|
|||
delete[] _areaMap;
|
||||
delete[] m_V9;
|
||||
delete[] m_V8;
|
||||
delete[] _maxHeight;
|
||||
delete[] _minHeight;
|
||||
delete[] _liquidEntry;
|
||||
delete[] _liquidFlags;
|
||||
delete[] _liquidMap;
|
||||
_areaMap = NULL;
|
||||
m_V9 = NULL;
|
||||
m_V8 = NULL;
|
||||
_liquidEntry = NULL;
|
||||
_liquidFlags = NULL;
|
||||
_liquidMap = NULL;
|
||||
_areaMap = nullptr;
|
||||
m_V9 = nullptr;
|
||||
m_V8 = nullptr;
|
||||
_maxHeight = nullptr;
|
||||
_minHeight = nullptr;
|
||||
_liquidEntry = nullptr;
|
||||
_liquidFlags = nullptr;
|
||||
_liquidMap = nullptr;
|
||||
_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
}
|
||||
|
||||
|
|
@ -1350,6 +1356,16 @@ bool GridMap::loadHeightData(FILE* in, uint32 offset, uint32 /*size*/)
|
|||
}
|
||||
else
|
||||
_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
|
||||
if (header.flags & MAP_HEIGHT_HAS_FLIGHT_BOUNDS)
|
||||
{
|
||||
_maxHeight = new int16[3 * 3];
|
||||
_minHeight = new int16[3 * 3];
|
||||
if (fread(_maxHeight, sizeof(int16), 3 * 3, in) != 3 * 3 ||
|
||||
fread(_minHeight, sizeof(int16), 3 * 3, in) != 3 * 3)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1620,6 +1636,66 @@ float GridMap::getHeightFromUint16(float x, float y) const
|
|||
return (float)((a * x) + (b * y) + c)*_gridIntHeightMultiplier + _gridHeight;
|
||||
}
|
||||
|
||||
float GridMap::getMinHeight(float x, float y) const
|
||||
{
|
||||
if (!_minHeight)
|
||||
return -500.0f;
|
||||
|
||||
static uint32 const indices[] =
|
||||
{
|
||||
3, 0, 4,
|
||||
0, 1, 4,
|
||||
1, 2, 4,
|
||||
2, 5, 4,
|
||||
5, 8, 4,
|
||||
8, 7, 4,
|
||||
7, 6, 4,
|
||||
6, 3, 4
|
||||
};
|
||||
|
||||
static float const boundGridCoords[] =
|
||||
{
|
||||
0.0f, 0.0f,
|
||||
0.0f, -266.66666f,
|
||||
0.0f, -533.33331f,
|
||||
-266.66666f, 0.0f,
|
||||
-266.66666f, -266.66666f,
|
||||
-266.66666f, -533.33331f,
|
||||
-533.33331f, 0.0f,
|
||||
-533.33331f, -266.66666f,
|
||||
-533.33331f, -533.33331f
|
||||
};
|
||||
|
||||
Cell cell(x, y);
|
||||
float gx = x - (int32(cell.GridX()) - CENTER_GRID_ID + 1) * SIZE_OF_GRIDS;
|
||||
float gy = y - (int32(cell.GridY()) - CENTER_GRID_ID + 1) * SIZE_OF_GRIDS;
|
||||
|
||||
uint32 quarterIndex = 0;
|
||||
if (cell.CellY() < MAX_NUMBER_OF_CELLS / 2)
|
||||
{
|
||||
if (cell.CellX() < MAX_NUMBER_OF_CELLS / 2)
|
||||
{
|
||||
quarterIndex = 4 + (gy > gx);
|
||||
}
|
||||
else
|
||||
quarterIndex = 2 + ((-SIZE_OF_GRIDS - gx) > gy);
|
||||
}
|
||||
else if (cell.CellX() < MAX_NUMBER_OF_CELLS / 2)
|
||||
{
|
||||
quarterIndex = 6 + ((-SIZE_OF_GRIDS - gx) <= gy);
|
||||
}
|
||||
else
|
||||
quarterIndex = gx > gy;
|
||||
|
||||
quarterIndex *= 3;
|
||||
|
||||
return G3D::Plane(
|
||||
G3D::Vector3(boundGridCoords[indices[quarterIndex + 0] * 2 + 0], boundGridCoords[indices[quarterIndex + 0] * 2 + 1], _minHeight[indices[quarterIndex + 0]]),
|
||||
G3D::Vector3(boundGridCoords[indices[quarterIndex + 1] * 2 + 0], boundGridCoords[indices[quarterIndex + 1] * 2 + 1], _minHeight[indices[quarterIndex + 1]]),
|
||||
G3D::Vector3(boundGridCoords[indices[quarterIndex + 2] * 2 + 0], boundGridCoords[indices[quarterIndex + 2] * 2 + 1], _minHeight[indices[quarterIndex + 2]])
|
||||
).distance(G3D::Vector3(gx, gy, 0.0f));
|
||||
}
|
||||
|
||||
float GridMap::getLiquidLevel(float x, float y) const
|
||||
{
|
||||
if (!_liquidMap)
|
||||
|
|
@ -1679,12 +1755,12 @@ inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 R
|
|||
uint32 liqTypeIdx = liquidEntry->Type;
|
||||
if (entry < 21)
|
||||
{
|
||||
if (AreaTableEntry const* area = GetAreaEntryByAreaFlagAndMap(getArea(x, y), MAPID_INVALID))
|
||||
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(getArea(x, y)))
|
||||
{
|
||||
uint32 overrideLiquid = area->LiquidTypeOverride[liquidEntry->Type];
|
||||
if (!overrideLiquid && area->zone)
|
||||
{
|
||||
area = GetAreaEntryByAreaID(area->zone);
|
||||
area = sAreaTableStore.LookupEntry(area->zone);
|
||||
if (area)
|
||||
overrideLiquid = area->LiquidTypeOverride[liquidEntry->Type];
|
||||
}
|
||||
|
|
@ -1835,7 +1911,7 @@ float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float
|
|||
|
||||
// we are already under the surface or vmap height above map heigt
|
||||
// or if the distance of the vmap height is less the land height distance
|
||||
if (vmapHeight > mapHeight || std::fabs(mapHeight - z) > std::fabs(vmapHeight - z))
|
||||
if (vmapHeight > mapHeight || fabs(mapHeight-z) > fabs(vmapHeight-z))
|
||||
return vmapHeight;
|
||||
else
|
||||
return mapHeight; // better use .map surface height
|
||||
|
|
@ -1847,6 +1923,15 @@ float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float
|
|||
return mapHeight; // explicitly use map data
|
||||
}
|
||||
|
||||
float Map::GetMinHeight(float x, float y) const
|
||||
{
|
||||
if (GridMap const* grid = const_cast<Map*>(this)->GetGrid(x, y))
|
||||
return grid->getMinHeight(x, y);
|
||||
|
||||
return -500.0f;
|
||||
}
|
||||
|
||||
|
||||
inline bool IsOutdoorWMO(uint32 mogpFlags, int32 /*adtId*/, int32 /*rootId*/, int32 /*groupId*/, WMOAreaTableEntry const* wmoEntry, AreaTableEntry const* atEntry)
|
||||
{
|
||||
bool outdoor = true;
|
||||
|
|
@ -1887,7 +1972,7 @@ bool Map::IsOutdoors(float x, float y, float z) const
|
|||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outStaticDebug("Got WMOAreaTableEntry! flag %u, areaid %u", wmoEntry->Flags, wmoEntry->areaId);
|
||||
#endif
|
||||
atEntry = GetAreaEntryByAreaID(wmoEntry->areaId);
|
||||
atEntry = sAreaTableStore.LookupEntry(wmoEntry->areaId);
|
||||
}
|
||||
return IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry);
|
||||
}
|
||||
|
|
@ -1911,7 +1996,7 @@ bool Map::GetAreaInfo(float x, float y, float z, uint32 &flags, int32 &adtId, in
|
|||
return false;
|
||||
}
|
||||
|
||||
uint16 Map::GetAreaFlag(float x, float y, float z, bool *isOutdoors) const
|
||||
uint32 Map::GetAreaId(float x, float y, float z, bool *isOutdoors) const
|
||||
{
|
||||
uint32 mogpFlags;
|
||||
int32 adtId, rootId, groupId;
|
||||
|
|
@ -1924,20 +2009,20 @@ uint16 Map::GetAreaFlag(float x, float y, float z, bool *isOutdoors) const
|
|||
haveAreaInfo = true;
|
||||
wmoEntry = GetWMOAreaTableEntryByTripple(rootId, adtId, groupId);
|
||||
if (wmoEntry)
|
||||
atEntry = GetAreaEntryByAreaID(wmoEntry->areaId);
|
||||
atEntry = sAreaTableStore.LookupEntry(wmoEntry->areaId);
|
||||
}
|
||||
|
||||
uint16 areaflag;
|
||||
uint16 areaId;
|
||||
|
||||
if (atEntry)
|
||||
areaflag = atEntry->exploreFlag;
|
||||
areaId = atEntry->ID;
|
||||
else
|
||||
{
|
||||
if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
|
||||
areaflag = gmap->getArea(x, y);
|
||||
areaId = gmap->getArea(x, y);
|
||||
// this used while not all *.map files generated (instances)
|
||||
else
|
||||
areaflag = GetAreaFlagByMapId(i_mapEntry->MapID);
|
||||
areaId = i_mapEntry->linked_zone;
|
||||
}
|
||||
|
||||
if (isOutdoors)
|
||||
|
|
@ -1947,8 +2032,31 @@ uint16 Map::GetAreaFlag(float x, float y, float z, bool *isOutdoors) const
|
|||
else
|
||||
*isOutdoors = true;
|
||||
}
|
||||
return areaflag;
|
||||
}
|
||||
return areaId;
|
||||
}
|
||||
|
||||
uint32 Map::GetAreaId(float x, float y, float z) const
|
||||
{
|
||||
return GetAreaId(x, y, z, nullptr);
|
||||
}
|
||||
|
||||
uint32 Map::GetZoneId(float x, float y, float z) const
|
||||
{
|
||||
uint32 areaId = GetAreaId(x, y, z);
|
||||
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId))
|
||||
if (area->zone)
|
||||
return area->zone;
|
||||
|
||||
return areaId;
|
||||
}
|
||||
|
||||
void Map::GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const
|
||||
{
|
||||
areaid = zoneid = GetAreaId(x, y, z);
|
||||
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaid))
|
||||
if (area->zone)
|
||||
zoneid = area->zone;
|
||||
}
|
||||
|
||||
uint8 Map::GetTerrainType(float x, float y) const
|
||||
{
|
||||
|
|
@ -1986,12 +2094,12 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
|
|||
|
||||
if (liquid_type && liquid_type < 21)
|
||||
{
|
||||
if (AreaTableEntry const* area = GetAreaEntryByAreaFlagAndMap(GetAreaFlag(x, y, z), GetId()))
|
||||
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(x, y, z)))
|
||||
{
|
||||
uint32 overrideLiquid = area->LiquidTypeOverride[liquidFlagType];
|
||||
if (!overrideLiquid && area->zone)
|
||||
{
|
||||
area = GetAreaEntryByAreaID(area->zone);
|
||||
area = sAreaTableStore.LookupEntry(area->zone);
|
||||
if (area)
|
||||
overrideLiquid = area->LiquidTypeOverride[liquidFlagType];
|
||||
}
|
||||
|
|
@ -2053,34 +2161,6 @@ float Map::GetWaterLevel(float x, float y) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint32 Map::GetAreaIdByAreaFlag(uint16 areaflag, uint32 map_id)
|
||||
{
|
||||
AreaTableEntry const* entry = GetAreaEntryByAreaFlagAndMap(areaflag, map_id);
|
||||
|
||||
if (entry)
|
||||
return entry->ID;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 Map::GetZoneIdByAreaFlag(uint16 areaflag, uint32 map_id)
|
||||
{
|
||||
AreaTableEntry const* entry = GetAreaEntryByAreaFlagAndMap(areaflag, map_id);
|
||||
|
||||
if (entry)
|
||||
return (entry->zone != 0) ? entry->zone : entry->ID;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag, uint32 map_id)
|
||||
{
|
||||
AreaTableEntry const* entry = GetAreaEntryByAreaFlagAndMap(areaflag, map_id);
|
||||
|
||||
areaid = entry ? entry->ID : 0;
|
||||
zoneid = entry ? ((entry->zone != 0) ? entry->zone : entry->ID) : 0;
|
||||
}
|
||||
|
||||
bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const
|
||||
{
|
||||
return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2)
|
||||
|
|
|
|||
|
|
@ -85,9 +85,10 @@ struct map_areaHeader
|
|||
uint16 gridArea;
|
||||
};
|
||||
|
||||
#define MAP_HEIGHT_NO_HEIGHT 0x0001
|
||||
#define MAP_HEIGHT_AS_INT16 0x0002
|
||||
#define MAP_HEIGHT_AS_INT8 0x0004
|
||||
#define MAP_HEIGHT_NO_HEIGHT 0x0001
|
||||
#define MAP_HEIGHT_AS_INT16 0x0002
|
||||
#define MAP_HEIGHT_AS_INT8 0x0004
|
||||
#define MAP_HEIGHT_HAS_FLIGHT_BOUNDS 0x0008
|
||||
|
||||
struct map_heightHeader
|
||||
{
|
||||
|
|
@ -153,6 +154,8 @@ class GridMap
|
|||
uint16* m_uint16_V8;
|
||||
uint8* m_uint8_V8;
|
||||
};
|
||||
int16* _maxHeight;
|
||||
int16* _minHeight;
|
||||
// Height level data
|
||||
float _gridHeight;
|
||||
float _gridIntHeightMultiplier;
|
||||
|
|
@ -193,6 +196,7 @@ public:
|
|||
|
||||
uint16 getArea(float x, float y) const;
|
||||
inline float getHeight(float x, float y) const {return (this->*_gridGetHeight)(x, y);}
|
||||
float getMinHeight(float x, float y) const;
|
||||
float getLiquidLevel(float x, float y) const;
|
||||
uint8 getTerrainType(float x, float y) const;
|
||||
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0);
|
||||
|
|
@ -327,12 +331,16 @@ class Map : public GridRefManager<NGridType>
|
|||
// some calls like isInWater should not use vmaps due to processor power
|
||||
// can return INVALID_HEIGHT if under z+2 z coord not found height
|
||||
float GetHeight(float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
|
||||
float GetMinHeight(float x, float y) const;
|
||||
Transport* GetTransportForPos(uint32 phase, float x, float y, float z, WorldObject* worldobject = NULL);
|
||||
|
||||
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0) const;
|
||||
|
||||
uint16 GetAreaFlag(float x, float y, float z, bool *isOutdoors=0) const;
|
||||
bool GetAreaInfo(float x, float y, float z, uint32 &mogpflags, int32 &adtId, int32 &rootId, int32 &groupId) const;
|
||||
uint32 GetAreaId(float x, float y, float z, bool *isOutdoors) const;
|
||||
bool GetAreaInfo(float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const;
|
||||
uint32 GetAreaId(float x, float y, float z) const;
|
||||
uint32 GetZoneId(float x, float y, float z) const;
|
||||
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const;
|
||||
|
||||
bool IsOutdoors(float x, float y, float z) const;
|
||||
|
||||
|
|
@ -341,25 +349,6 @@ class Map : public GridRefManager<NGridType>
|
|||
bool IsInWater(float x, float y, float z, LiquidData* data = 0) const;
|
||||
bool IsUnderWater(float x, float y, float z) const;
|
||||
|
||||
static uint32 GetAreaIdByAreaFlag(uint16 areaflag, uint32 map_id);
|
||||
static uint32 GetZoneIdByAreaFlag(uint16 areaflag, uint32 map_id);
|
||||
static void GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 areaflag, uint32 map_id);
|
||||
|
||||
uint32 GetAreaId(float x, float y, float z) const
|
||||
{
|
||||
return GetAreaIdByAreaFlag(GetAreaFlag(x, y, z), GetId());
|
||||
}
|
||||
|
||||
uint32 GetZoneId(float x, float y, float z) const
|
||||
{
|
||||
return GetZoneIdByAreaFlag(GetAreaFlag(x, y, z), GetId());
|
||||
}
|
||||
|
||||
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const
|
||||
{
|
||||
GetZoneAndAreaIdByAreaFlag(zoneid, areaid, GetAreaFlag(x, y, z), GetId());
|
||||
}
|
||||
|
||||
void MoveAllCreaturesInMoveList();
|
||||
void MoveAllGameObjectsInMoveList();
|
||||
void MoveAllDynamicObjectsInMoveList();
|
||||
|
|
|
|||
|
|
@ -36,22 +36,20 @@ class MapManager
|
|||
return (iter == i_maps.end() ? NULL : iter->second);
|
||||
}
|
||||
|
||||
uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const
|
||||
{
|
||||
Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid);
|
||||
return m->GetAreaFlag(x, y, z);
|
||||
}
|
||||
uint32 GetAreaId(uint32 mapid, float x, float y, float z) const
|
||||
{
|
||||
return Map::GetAreaIdByAreaFlag(GetAreaFlag(mapid, x, y, z), mapid);
|
||||
Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid);
|
||||
return m->GetAreaId(x, y, z);
|
||||
}
|
||||
uint32 GetZoneId(uint32 mapid, float x, float y, float z) const
|
||||
{
|
||||
return Map::GetZoneIdByAreaFlag(GetAreaFlag(mapid, x, y, z), mapid);
|
||||
Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid);
|
||||
return m->GetZoneId(x, y, z);
|
||||
}
|
||||
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z)
|
||||
{
|
||||
Map::GetZoneAndAreaIdByAreaFlag(zoneid, areaid, GetAreaFlag(mapid, x, y, z), mapid);
|
||||
Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid);
|
||||
m->GetZoneAndAreaId(zoneid, areaid, x, y, z);
|
||||
}
|
||||
|
||||
void Initialize(void);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ void WhoListCacheMgr::Update()
|
|||
wstrToLower(wgname);
|
||||
|
||||
std::string aname;
|
||||
if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(itr->second->GetZoneId()))
|
||||
if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(itr->second->GetZoneId()))
|
||||
aname = areaEntry->area_name[sWorld->GetDefaultDbcLocale()];
|
||||
|
||||
if (itr->second->IsSpectator())
|
||||
|
|
|
|||
|
|
@ -444,7 +444,7 @@ enum SpellAttr4
|
|||
|
||||
enum SpellAttr5
|
||||
{
|
||||
SPELL_ATTR5_UNK0 = 0x00000001, // 0
|
||||
SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING = 0x00000001, // 0
|
||||
SPELL_ATTR5_NO_REAGENT_WHILE_PREP = 0x00000002, // 1 not need reagents if UNIT_FLAG_PREPARATION
|
||||
SPELL_ATTR5_REMOVE_ON_ARENA_ENTER = 0x00000004, // 2 xinef: remove this aura on arena enter
|
||||
SPELL_ATTR5_USABLE_WHILE_STUNNED = 0x00000008, // 3 usable while stunned
|
||||
|
|
@ -3531,7 +3531,7 @@ enum PartyResult
|
|||
};
|
||||
|
||||
#define MMAP_MAGIC 0x4d4d4150 // 'MMAP'
|
||||
#define MMAP_VERSION 3
|
||||
#define MMAP_VERSION 6
|
||||
|
||||
struct MmapTileHeader
|
||||
{
|
||||
|
|
@ -3539,12 +3539,23 @@ struct MmapTileHeader
|
|||
uint32 dtVersion;
|
||||
uint32 mmapVersion;
|
||||
uint32 size;
|
||||
bool usesLiquids : 1;
|
||||
char usesLiquids;
|
||||
char padding[3];
|
||||
|
||||
MmapTileHeader() : mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION),
|
||||
mmapVersion(MMAP_VERSION), size(0), usesLiquids(true) {}
|
||||
mmapVersion(MMAP_VERSION), size(0), usesLiquids(true), padding() { }
|
||||
};
|
||||
|
||||
// All padding fields must be handled and initialized to ensure mmaps_generator will produce binary-identical *.mmtile files
|
||||
static_assert(sizeof(MmapTileHeader) == 20, "MmapTileHeader size is not correct, adjust the padding field size");
|
||||
static_assert(sizeof(MmapTileHeader) == (sizeof(MmapTileHeader::mmapMagic) +
|
||||
sizeof(MmapTileHeader::dtVersion) +
|
||||
sizeof(MmapTileHeader::mmapVersion) +
|
||||
sizeof(MmapTileHeader::size) +
|
||||
sizeof(MmapTileHeader::usesLiquids) +
|
||||
sizeof(MmapTileHeader::padding)), "MmapTileHeader has uninitialized padding fields");
|
||||
|
||||
|
||||
enum NavTerrain
|
||||
{
|
||||
NAV_EMPTY = 0x00,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "MoveSplineInit.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "Player.h"
|
||||
#include "VMapFactory.h"
|
||||
|
||||
#define MIN_QUIET_DISTANCE 28.0f
|
||||
#define MAX_QUIET_DISTANCE 43.0f
|
||||
|
|
@ -32,6 +33,19 @@ void FleeingMovementGenerator<T>::_setTargetLocation(T* owner)
|
|||
if (!_getPoint(owner, x, y, z))
|
||||
return;
|
||||
|
||||
// Add LOS check for target point
|
||||
bool isInLOS = VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(owner->GetMapId(),
|
||||
owner->GetPositionX(),
|
||||
owner->GetPositionY(),
|
||||
owner->GetPositionZ() + 2.0f,
|
||||
x, y, z + 2.0f);
|
||||
|
||||
if (!isInLOS)
|
||||
{
|
||||
i_nextCheckTime.Reset(500);
|
||||
return;
|
||||
}
|
||||
|
||||
owner->AddUnitState(UNIT_STATE_FLEEING_MOVE);
|
||||
|
||||
Movement::MoveSplineInit init(owner);
|
||||
|
|
|
|||
|
|
@ -152,9 +152,10 @@ dtPolyRef PathGenerator::GetPolyByLocation(float* point, float* distance) const
|
|||
|
||||
// still nothing ..
|
||||
// try with bigger search box
|
||||
extents[1] = 80.0f;
|
||||
result = _navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint);
|
||||
if (DT_SUCCESS == result && polyRef != INVALID_POLYREF)
|
||||
// Note that the extent should not overlap more than 128 polygons in the navmesh (see dtNavMeshQuery::findNearestPoly)
|
||||
extents[1] = 50.0f;
|
||||
|
||||
if (dtStatusSucceed(_navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint)) && polyRef != INVALID_POLYREF)
|
||||
{
|
||||
*distance = dtVdist(closestPoint, point);
|
||||
return polyRef;
|
||||
|
|
@ -339,7 +340,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
|
|||
if (startPoly != endPoly || !endInWaterFar)
|
||||
{
|
||||
float closestPoint[VERTEX_SIZE];
|
||||
if (DT_SUCCESS == _navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint))
|
||||
if (dtStatusSucceed(_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint, NULL)))
|
||||
{
|
||||
dtVcopy(endPoint, closestPoint);
|
||||
SetActualEndPosition(G3D::Vector3(endPoint[2], endPoint[0], endPoint[1]));
|
||||
|
|
@ -416,7 +417,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
|
|||
|
||||
// we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data
|
||||
float suffixEndPoint[VERTEX_SIZE];
|
||||
if (DT_SUCCESS != _navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint))
|
||||
if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint, NULL)))
|
||||
{
|
||||
// we can hit offmesh connection as last poly - closestPointOnPoly() don't like that
|
||||
// try to recover by using prev polyref
|
||||
|
|
@ -424,7 +425,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
|
|||
if (prefixPolyLength)
|
||||
{
|
||||
suffixStartPoly = _pathPolyRefs[prefixPolyLength-1];
|
||||
if (DT_SUCCESS != _navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint))
|
||||
if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint,NULL)))
|
||||
error = true;
|
||||
}
|
||||
else
|
||||
|
|
@ -445,7 +446,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
|
|||
(int*)&suffixPolyLength,
|
||||
MAX_PATH_LENGTH-prefixPolyLength); // max number of polygons in output path
|
||||
|
||||
if (!suffixPolyLength || dtResult != DT_SUCCESS)
|
||||
if (!_polyLength || dtStatusFailed(dtResult))
|
||||
{
|
||||
// this is probably an error state, but we'll leave it
|
||||
// and hopefully recover on the next Update
|
||||
|
|
@ -470,7 +471,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
|
|||
(int*)&_polyLength,
|
||||
MAX_PATH_LENGTH); // max number of polygons in output path
|
||||
|
||||
if (!_polyLength || dtResult != DT_SUCCESS)
|
||||
if (!_polyLength || dtStatusFailed(dtResult))
|
||||
{
|
||||
// only happens if we passed bad data to findPath(), or navmesh is messed up
|
||||
BuildShortcut();
|
||||
|
|
@ -499,7 +500,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
|
|||
(int*)&_polyLength,
|
||||
MAX_PATH_LENGTH); // max number of polygons in output path
|
||||
|
||||
if (!_polyLength || dtResult != DT_SUCCESS)
|
||||
if (!_polyLength || dtStatusFailed(dtResult))
|
||||
{
|
||||
// only happens if we passed bad data to findPath(), or navmesh is messed up
|
||||
BuildShortcut();
|
||||
|
|
@ -658,7 +659,7 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin
|
|||
_pointPathLimit); // maximum number of points
|
||||
}
|
||||
|
||||
if (pointCount < 2 || dtResult != DT_SUCCESS)
|
||||
if (pointCount < 2 || dtStatusFailed(dtResult))
|
||||
{
|
||||
// only happens if pass bad data to findStraightPath or navmesh is broken
|
||||
// single point paths can be generated here
|
||||
|
|
@ -784,7 +785,7 @@ bool PathGenerator::HaveTile(const G3D::Vector3& p) const
|
|||
if (tx < 0 || ty < 0)
|
||||
return false;
|
||||
|
||||
return (_navMesh->getTileAt(tx, ty) != NULL);
|
||||
return (_navMesh->getTileAt(tx, ty, 0) != NULL);
|
||||
}
|
||||
|
||||
uint32 PathGenerator::FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited)
|
||||
|
|
@ -844,7 +845,7 @@ bool PathGenerator::GetSteerTarget(float const* startPos, float const* endPos,
|
|||
uint32 nsteerPath = 0;
|
||||
dtStatus dtResult = _navMeshQuery->findStraightPath(startPos, endPos, path, pathSize,
|
||||
steerPath, steerPathFlags, steerPathPolys, (int*)&nsteerPath, MAX_STEER_POINTS);
|
||||
if (!nsteerPath || DT_SUCCESS != dtResult)
|
||||
if (!nsteerPath || dtStatusFailed(dtResult))
|
||||
return false;
|
||||
|
||||
// Find vertex far enough to steer to.
|
||||
|
|
@ -908,7 +909,7 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo
|
|||
// Find movement delta.
|
||||
float delta[VERTEX_SIZE];
|
||||
dtVsub(delta, steerPos, iterPos);
|
||||
float len = dtSqrt(dtVdot(delta,delta));
|
||||
float len = dtMathSqrtf(dtVdot(delta,delta));
|
||||
// If the steer target is end of path or off-mesh link, do not move past the location.
|
||||
if ((endOfPath || offMeshConnection) && len < SMOOTH_PATH_STEP_SIZE)
|
||||
len = 1.0f;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class Unit;
|
|||
#define ALLOWED_DIST_FROM_POLY 2.5f
|
||||
#define ADDED_Z_FOR_POLY_LOOKUP 0.3f
|
||||
#define DISALLOW_TIME_AFTER_FAIL 3 // secs
|
||||
#define MAX_FIXABLE_Z_ERROR 12.0f
|
||||
#define MAX_FIXABLE_Z_ERROR 7.0f
|
||||
|
||||
#define VERTEX_SIZE 3
|
||||
#define INVALID_POLYREF 0
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T* owner, bool ini
|
|||
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE))
|
||||
return;
|
||||
|
||||
if (owner->HasUnitState(UNIT_STATE_CASTING) && !owner->CanMoveDuringChannel())
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
bool isPlayerPet = owner->IsPet() && IS_PLAYER_GUID(owner->GetOwnerGUID());
|
||||
bool sameTransport = owner->GetTransport() && owner->GetTransport() == i_target->GetTransport();
|
||||
|
|
@ -44,6 +47,9 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T* owner, bool ini
|
|||
(i_target->GetTypeId() == TYPEID_PLAYER && i_target->ToPlayer()->IsGameMaster()); // for .npc follow
|
||||
bool forcePoint = ((!isPlayerPet || owner->GetMapId() == 618) && (forceDest || !useMMaps)) || sameTransport;
|
||||
|
||||
if (owner->GetTypeId() == TYPEID_UNIT && !i_target->isInAccessiblePlaceFor(owner->ToCreature()) && !sameTransport && !forceDest && !forcePoint)
|
||||
return;
|
||||
|
||||
lastOwnerXYZ.Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ());
|
||||
lastTargetXYZ.Relocate(i_target->GetPositionX(), i_target->GetPositionY(), i_target->GetPositionZ());
|
||||
|
||||
|
|
@ -60,6 +66,9 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T* owner, bool ini
|
|||
owner->m_targetsNotAcceptable[i_target->GetGUID()] = MMapTargetData(sWorld->GetGameTime()+DISALLOW_TIME_AFTER_FAIL, owner, i_target.getTarget());
|
||||
return;
|
||||
}
|
||||
|
||||
// to nearest contact position
|
||||
i_target->GetContactPoint(owner, x, y, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -167,6 +176,7 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T* owner, bool ini
|
|||
else
|
||||
{
|
||||
owner->m_targetsNotAcceptable.erase(i_target->GetGUID());
|
||||
owner->AddUnitState(UNIT_STATE_CHASE);
|
||||
|
||||
init.MovebyPath(i_path->GetPath());
|
||||
if (i_angle == 0.f)
|
||||
|
|
@ -180,6 +190,8 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T* owner, bool ini
|
|||
// if failed to generate, just use normal MoveTo
|
||||
}
|
||||
|
||||
owner->AddUnitState(UNIT_STATE_CHASE);
|
||||
|
||||
init.MoveTo(x,y,z);
|
||||
// Using the same condition for facing target as the one that is used for SetInFront on movement end
|
||||
// - applies to ChaseMovementGenerator mostly
|
||||
|
|
@ -206,7 +218,7 @@ bool TargetedMovementGeneratorMedium<T,D>::DoUpdate(T* owner, uint32 time_diff)
|
|||
}
|
||||
|
||||
// prevent movement while casting spells with cast time or channel time
|
||||
if (owner->HasUnitState(UNIT_STATE_CASTING))
|
||||
if (owner->HasUnitState(UNIT_STATE_CASTING) && !owner->CanMoveDuringChannel())
|
||||
{
|
||||
bool stop = true;
|
||||
if (Spell* spell = owner->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
|
||||
|
|
|
|||
|
|
@ -6200,7 +6200,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
if (m_originalCaster && m_originalCaster->GetTypeId() == TYPEID_PLAYER && m_originalCaster->IsAlive())
|
||||
{
|
||||
Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
|
||||
if (AreaTableEntry const* pArea = GetAreaEntryByAreaID(m_originalCaster->GetAreaId()))
|
||||
if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
|
||||
if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
|
||||
return SPELL_FAILED_NOT_HERE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4241,14 +4241,14 @@ void Spell::EffectDuel(SpellEffIndex effIndex)
|
|||
return;
|
||||
|
||||
// Players can only fight a duel in zones with this flag
|
||||
AreaTableEntry const* casterAreaEntry = GetAreaEntryByAreaID(caster->GetAreaId());
|
||||
AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
|
||||
if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
|
||||
{
|
||||
SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
|
||||
return;
|
||||
}
|
||||
|
||||
AreaTableEntry const* targetAreaEntry = GetAreaEntryByAreaID(target->GetAreaId());
|
||||
AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
|
||||
if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
|
||||
{
|
||||
SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
|
||||
|
|
|
|||
|
|
@ -1069,7 +1069,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32
|
|||
if (!player)
|
||||
return false;
|
||||
|
||||
AreaTableEntry const* pArea = GetAreaEntryByAreaID(player->GetAreaId());
|
||||
AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(player->GetAreaId());
|
||||
if (!(pArea && pArea->flags & AREA_FLAG_NO_FLY_ZONE))
|
||||
return false;
|
||||
if (!player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !player->HasAuraType(SPELL_AURA_FLY))
|
||||
|
|
@ -2513,7 +2513,7 @@ void SpellMgr::LoadSpellAreas()
|
|||
}
|
||||
}
|
||||
|
||||
if (spellArea.areaId && !GetAreaEntryByAreaID(spellArea.areaId))
|
||||
if (spellArea.areaId && !sAreaTableStore.LookupEntry(spellArea.areaId))
|
||||
{
|
||||
sLog->outErrorDb("Spell %u listed in `spell_area` have wrong area (%u) requirement", spell, spellArea.areaId);
|
||||
continue;
|
||||
|
|
@ -6243,8 +6243,8 @@ void SpellMgr::LoadDbcDataCorrections()
|
|||
}
|
||||
|
||||
// Xinef: The Veiled Sea area in outlands (Draenei zone), client blocks casting flying mounts
|
||||
for (uint32 i = 0; i < sAreaStore.GetNumRows(); ++i)
|
||||
if (AreaTableEntry* areaEntry = const_cast<AreaTableEntry*>(sAreaStore.LookupEntry(i)))
|
||||
for (uint32 i = 0; i < sAreaTableStore.GetNumRows(); ++i)
|
||||
if (AreaTableEntry* areaEntry = const_cast<AreaTableEntry*>(sAreaTableStore.LookupEntry(i)))
|
||||
{
|
||||
if (areaEntry->ID == 3479)
|
||||
areaEntry->flags |= AREA_FLAG_NO_FLY_ZONE;
|
||||
|
|
|
|||
|
|
@ -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()))))
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ endif()
|
|||
include_directories(
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/modules/worldengine/deps/g3dlite/include
|
||||
${CMAKE_SOURCE_DIR}/modules/worldengine/deps/recastnavigation/Detour
|
||||
${CMAKE_SOURCE_DIR}/modules/worldengine/deps/recastnavigation/Detour/Include
|
||||
${CMAKE_SOURCE_DIR}/modules/worldengine/deps/gsoap
|
||||
${CMAKE_SOURCE_DIR}/modules/worldengine/deps/sockets/include
|
||||
${CMAKE_SOURCE_DIR}/modules/worldengine/deps/SFMT
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue