Core/Entities: Phase Rework (main commit)
This commit is contained in:
1 parent
4a268b3fd3
commit
e44bb5f387
79 files changed
+1738
-851
No files matched your search
@@ -45,6 +45,7 @@
|
||||
#include "TemporarySummon.h"
|
||||
#include "Totem.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "MovementPacketBuilder.h"
|
||||
#include "DynamicTree.h"
|
||||
#include "Unit.h"
|
||||
@@ -1446,7 +1447,7 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz, LineOfSightChecks ch
|
||||
else
|
||||
GetHitSpherePointFor({ ox, oy, oz }, x, y, z);
|
||||
|
||||
return GetMap()->isInLineOfSight(x, y, z + 2.0f, ox, oy, oz + 2.0f, GetPhases(), checks, ignoreFlags);
|
||||
return GetMap()->isInLineOfSight(GetPhaseShift(), x, y, z + 2.0f, ox, oy, oz + 2.0f, checks, ignoreFlags);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1621,7 +1622,7 @@ Position WorldObject::GetRandomPoint(const Position &srcPos, float distance) con
|
||||
|
||||
void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const
|
||||
{
|
||||
float new_z = GetMap()->GetHeight(GetPhases(), x, y, z + 2.0f, true);
|
||||
float new_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z + 2.0f, true);
|
||||
if (new_z > INVALID_HEIGHT)
|
||||
z = new_z + 0.05f; // just to be sure that we are not a few pixel under the surface
|
||||
}
|
||||
@@ -1643,8 +1644,8 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
bool canSwim = ToCreature()->CanSwim();
|
||||
float ground_z = z;
|
||||
float max_z = canSwim
|
||||
? GetMap()->GetWaterOrGroundLevel(GetPhases(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK))
|
||||
: ((ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true)));
|
||||
? GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK))
|
||||
: ((ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true)));
|
||||
if (max_z > INVALID_HEIGHT)
|
||||
{
|
||||
if (z > max_z)
|
||||
@@ -1655,7 +1656,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
}
|
||||
else
|
||||
{
|
||||
float ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true);
|
||||
float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
if (z < ground_z)
|
||||
z = ground_z;
|
||||
}
|
||||
@@ -1667,7 +1668,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
if (!ToPlayer()->CanFly())
|
||||
{
|
||||
float ground_z = z;
|
||||
float max_z = GetMap()->GetWaterOrGroundLevel(GetPhases(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK));
|
||||
float max_z = GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK));
|
||||
if (max_z > INVALID_HEIGHT)
|
||||
{
|
||||
if (z > max_z)
|
||||
@@ -1678,7 +1679,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
}
|
||||
else
|
||||
{
|
||||
float ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true);
|
||||
float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
if (z < ground_z)
|
||||
z = ground_z;
|
||||
}
|
||||
@@ -1686,7 +1687,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
}
|
||||
default:
|
||||
{
|
||||
float ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true);
|
||||
float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
if (ground_z > INVALID_HEIGHT)
|
||||
z = ground_z;
|
||||
break;
|
||||
@@ -2100,7 +2101,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
|
||||
}
|
||||
|
||||
// Set the summon to the summoner's phase
|
||||
summon->CopyPhaseFrom(summoner);
|
||||
PhasingHandler::InheritPhaseShift(summon, summoner);
|
||||
|
||||
summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);
|
||||
|
||||
@@ -2204,7 +2205,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, Position const& pos, G3D
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
go->CopyPhaseFrom(this);
|
||||
PhasingHandler::InheritPhaseShift(go, this);
|
||||
|
||||
go->SetRespawnTime(respawnTime);
|
||||
if (GetTypeId() == TYPEID_PLAYER || (GetTypeId() == TYPEID_UNIT && summonType == GO_SUMMON_TIMED_OR_CORPSE_DESPAWN)) //not sure how to handle this
|
||||
@@ -2430,8 +2431,8 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
|
||||
return;
|
||||
}
|
||||
|
||||
ground = GetMap()->GetHeight(GetPhases(), destx, desty, MAX_HEIGHT, true);
|
||||
floor = GetMap()->GetHeight(GetPhases(), destx, desty, pos.m_positionZ, true);
|
||||
ground = GetMap()->GetHeight(GetPhaseShift(), destx, desty, MAX_HEIGHT, true);
|
||||
floor = GetMap()->GetHeight(GetPhaseShift(), destx, desty, pos.m_positionZ, true);
|
||||
destz = std::fabs(ground - pos.m_positionZ) <= std::fabs(floor - pos.m_positionZ) ? ground : floor;
|
||||
|
||||
float step = dist/10.0f;
|
||||
@@ -2443,8 +2444,8 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
|
||||
{
|
||||
destx -= step * std::cos(angle);
|
||||
desty -= step * std::sin(angle);
|
||||
ground = GetMap()->GetHeight(GetPhases(), destx, desty, MAX_HEIGHT, true);
|
||||
floor = GetMap()->GetHeight(GetPhases(), destx, desty, pos.m_positionZ, true);
|
||||
ground = GetMap()->GetHeight(GetPhaseShift(), destx, desty, MAX_HEIGHT, true);
|
||||
floor = GetMap()->GetHeight(GetPhaseShift(), destx, desty, pos.m_positionZ, true);
|
||||
destz = std::fabs(ground - pos.m_positionZ) <= std::fabs(floor - pos.m_positionZ) ? ground : floor;
|
||||
}
|
||||
// we have correct destz now
|
||||
@@ -2464,8 +2465,8 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
|
||||
// @todo: replace with WorldObject::UpdateAllowedPositionZ
|
||||
float NormalizeZforCollision(WorldObject* obj, float x, float y, float z)
|
||||
{
|
||||
float ground = obj->GetMap()->GetHeight(obj->GetPhases(), x, y, MAX_HEIGHT, true);
|
||||
float floor = obj->GetMap()->GetHeight(obj->GetPhases(), x, y, z + 2.0f, true);
|
||||
float ground = obj->GetMap()->GetHeight(obj->GetPhaseShift(), x, y, MAX_HEIGHT, true);
|
||||
float floor = obj->GetMap()->GetHeight(obj->GetPhaseShift(), x, y, z + 2.0f, true);
|
||||
float helper = std::fabs(ground - z) <= std::fabs(floor - z) ? ground : floor;
|
||||
if (z > helper) // must be above ground
|
||||
{
|
||||
@@ -2514,7 +2515,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
|
||||
}
|
||||
|
||||
// check dynamic collision
|
||||
col = GetMap()->getObjectHitPos(GetPhases(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
|
||||
col = GetMap()->getObjectHitPos(GetPhaseShift(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
|
||||
|
||||
// Collided with a gameobject
|
||||
if (col)
|
||||
@@ -2557,165 +2558,6 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
bool WorldObject::HasInPhaseList(uint32 phase)
|
||||
{
|
||||
return _phases.find(phase) != _phases.end();
|
||||
}
|
||||
|
||||
// Updates Area based phases, does not remove phases from auras
|
||||
// Phases from gm commands are not taken into calculations, they can be lost!!
|
||||
void WorldObject::UpdateAreaPhase()
|
||||
{
|
||||
bool updateNeeded = false;
|
||||
PhaseInfo const& phases = sObjectMgr->GetAreaPhases();
|
||||
for (PhaseInfo::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
|
||||
{
|
||||
uint32 areaId = itr->first;
|
||||
for (PhaseInfoStruct const& phase : itr->second)
|
||||
{
|
||||
if (areaId == GetAreaId())
|
||||
{
|
||||
if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions))
|
||||
{
|
||||
// add new phase if condition passed, true if it wasnt added before
|
||||
bool up = SetInPhase(phase.Id, false, true);
|
||||
if (!updateNeeded && up)
|
||||
updateNeeded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// condition failed, remove phase, true if there was something removed
|
||||
bool up = SetInPhase(phase.Id, false, false);
|
||||
if (!updateNeeded && up)
|
||||
updateNeeded = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// not in area, remove phase, true if there was something removed
|
||||
bool up = SetInPhase(phase.Id, false, false);
|
||||
if (!updateNeeded && up)
|
||||
updateNeeded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do not remove a phase if it would be removed by an area but we have the same phase from an aura
|
||||
if (Unit* unit = ToUnit())
|
||||
{
|
||||
Unit::AuraEffectList const& auraPhaseList = unit->GetAuraEffectsByType(SPELL_AURA_PHASE);
|
||||
for (Unit::AuraEffectList::const_iterator itr = auraPhaseList.begin(); itr != auraPhaseList.end(); ++itr)
|
||||
{
|
||||
uint32 phase = uint32((*itr)->GetMiscValueB());
|
||||
bool up = SetInPhase(phase, false, true);
|
||||
if (!updateNeeded && up)
|
||||
updateNeeded = true;
|
||||
}
|
||||
Unit::AuraEffectList const& auraPhaseGroupList = unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP);
|
||||
for (Unit::AuraEffectList::const_iterator itr = auraPhaseGroupList.begin(); itr != auraPhaseGroupList.end(); ++itr)
|
||||
{
|
||||
bool up = false;
|
||||
uint32 phaseGroup = uint32((*itr)->GetMiscValueB());
|
||||
std::set<uint32> const& phases = GetPhasesForGroup(phaseGroup);
|
||||
for (uint32 phase : phases)
|
||||
up = SetInPhase(phase, false, true);
|
||||
if (!updateNeeded && up)
|
||||
updateNeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
// only update visibility and send packets if there was a change in the phase list
|
||||
if (updateNeeded && GetTypeId() == TYPEID_PLAYER && IsInWorld())
|
||||
ToPlayer()->GetSession()->SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), GetWorldMapAreaSwaps());
|
||||
|
||||
// only update visibilty once, to prevent objects appearing for a moment while adding in multiple phases
|
||||
if (updateNeeded && IsInWorld())
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
bool WorldObject::SetInPhase(uint32 id, bool update, bool apply)
|
||||
{
|
||||
if (id)
|
||||
{
|
||||
if (apply)
|
||||
{
|
||||
if (HasInPhaseList(id)) // do not run the updates if we are already in this phase
|
||||
return false;
|
||||
|
||||
_phases.insert(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if area phase passes the condition we should not remove it (ie: if remove called from aura remove)
|
||||
// this however breaks the .mod phase command, you wont be able to remove any area based phases with it
|
||||
PhaseInfo const& phases = sObjectMgr->GetAreaPhases();
|
||||
for (PhaseInfo::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
|
||||
if (itr->first == GetAreaId() || itr->first == GetZoneId())
|
||||
for (PhaseInfoStruct const& phase : itr->second)
|
||||
if (id == phase.Id)
|
||||
if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions))
|
||||
return false;
|
||||
|
||||
if (!HasInPhaseList(id)) // do not run the updates if we are not in this phase
|
||||
return false;
|
||||
|
||||
_phases.erase(id);
|
||||
}
|
||||
}
|
||||
|
||||
RebuildTerrainSwaps();
|
||||
|
||||
if (update && IsInWorld())
|
||||
UpdateObjectVisibility();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorldObject::CopyPhaseFrom(WorldObject* obj, bool update)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
for (uint32 phase : obj->GetPhases())
|
||||
SetInPhase(phase, false, true);
|
||||
|
||||
if (update && IsInWorld())
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
void WorldObject::ClearPhases(bool update)
|
||||
{
|
||||
_phases.clear();
|
||||
|
||||
RebuildTerrainSwaps();
|
||||
|
||||
if (update && IsInWorld())
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
bool WorldObject::IsInPhase(std::set<uint32> const& phases) const
|
||||
{
|
||||
// PhaseId 169 is the default fallback phase
|
||||
if (_phases.empty() && phases.empty())
|
||||
return true;
|
||||
|
||||
if (_phases.empty() && phases.count(DEFAULT_PHASE) > 0)
|
||||
return true;
|
||||
|
||||
if (phases.empty() && _phases.count(DEFAULT_PHASE) > 0)
|
||||
return true;
|
||||
|
||||
return Trinity::Containers::Intersects(_phases.begin(), _phases.end(), phases.begin(), phases.end());
|
||||
}
|
||||
|
||||
bool WorldObject::IsInPhase(WorldObject const* obj) const
|
||||
{
|
||||
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->IsGameMaster())
|
||||
return true;
|
||||
|
||||
return IsInPhase(obj->GetPhases());
|
||||
}
|
||||
|
||||
void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/)
|
||||
{
|
||||
WorldPacket data(SMSG_PLAY_OBJECT_SOUND, 4 + 8);
|
||||
@@ -2882,7 +2724,7 @@ float WorldObject::GetFloorZ() const
|
||||
{
|
||||
if (!IsInWorld())
|
||||
return m_staticFloorZ;
|
||||
return std::max<float>(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhases(), GetPositionX(), GetPositionY(), GetPositionZ()));
|
||||
return std::max<float>(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()));
|
||||
}
|
||||
|
||||
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>&, uint32, float) const;
|
||||
@@ -2944,63 +2786,3 @@ void WorldObject::SetMeleeAnimKitId(uint16 animKitId)
|
||||
data << uint16(animKitId);
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
void WorldObject::RebuildTerrainSwaps()
|
||||
{
|
||||
// Clear all terrain swaps, will be rebuilt below
|
||||
// Reason for this is, multiple phases can have the same terrain swap, we should not remove the swap if another phase still use it
|
||||
_terrainSwaps.clear();
|
||||
|
||||
// Check all applied phases for terrain swap and add it only once
|
||||
for (uint32 phaseId : _phases)
|
||||
{
|
||||
if (std::vector<uint32> const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId))
|
||||
{
|
||||
for (uint32 const& swap : *swaps)
|
||||
{
|
||||
// only add terrain swaps for current map
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(swap);
|
||||
if (!mapEntry || mapEntry->rootPhaseMap != int32(GetMapId()))
|
||||
continue;
|
||||
|
||||
if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this))
|
||||
_terrainSwaps.insert(swap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get default terrain swaps, only for current map always
|
||||
if (std::vector<uint32> const* mapSwaps = sObjectMgr->GetDefaultTerrainSwaps(GetMapId()))
|
||||
for (uint32 const& swap : *mapSwaps)
|
||||
if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this))
|
||||
_terrainSwaps.insert(swap);
|
||||
|
||||
// online players have a game client with world map display
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
RebuildWorldMapAreaSwaps();
|
||||
}
|
||||
|
||||
void WorldObject::RebuildWorldMapAreaSwaps()
|
||||
{
|
||||
// Clear all world map area swaps, will be rebuilt below
|
||||
_worldMapAreaSwaps.clear();
|
||||
|
||||
// get ALL default terrain swaps, if we are using it (condition is true)
|
||||
// send the worldmaparea for it, to see swapped worldmaparea in client from other maps too, not just from our current
|
||||
TerrainPhaseInfo const& defaults = sObjectMgr->GetDefaultTerrainSwapStore();
|
||||
for (TerrainPhaseInfo::const_iterator itr = defaults.begin(); itr != defaults.end(); ++itr)
|
||||
for (uint32 const& swap : itr->second)
|
||||
if (std::vector<uint32> const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap))
|
||||
if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this))
|
||||
for (uint32 worldMapAreaId : *uiMapSwaps)
|
||||
_worldMapAreaSwaps.insert(worldMapAreaId);
|
||||
|
||||
// Check all applied phases for world map area swaps
|
||||
for (uint32 phaseId : _phases)
|
||||
if (std::vector<uint32> const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId))
|
||||
for (uint32 const& swap : *swaps)
|
||||
if (std::vector<uint32> const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap))
|
||||
if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this))
|
||||
for (uint32 worldMapAreaId : *uiMapSwaps)
|
||||
_worldMapAreaSwaps.insert(worldMapAreaId);
|
||||
}
|
||||
Reference in new issue
Block a user