Core/Entities: Phasing rewrite
This commit is contained in:
@@ -24,6 +24,7 @@ using Game.Network.Packets;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Game;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
@@ -125,7 +126,7 @@ namespace Game.Entities
|
||||
if (GetMiscTemplate().ScaleInfo.ExtraScale[scaleCurveIndex].AsInt32 != 0)
|
||||
SetUInt32Value(AreaTriggerFields.ExtraScaleCurve + scaleCurveIndex, (uint)GetMiscTemplate().ScaleInfo.ExtraScale[scaleCurveIndex].AsInt32);
|
||||
|
||||
CopyPhaseFrom(caster);
|
||||
PhasingHandler.InheritPhaseShift(this, caster);
|
||||
|
||||
if (target && GetTemplate().HasFlag(AreaTriggerFlags.HasAttached))
|
||||
{
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace Game.Entities
|
||||
Relocate(pos);
|
||||
|
||||
base._Create(ObjectGuid.Create(HighGuid.Conversation, GetMapId(), conversationEntry, lowGuid));
|
||||
CopyPhaseFrom(creator);
|
||||
PhasingHandler.InheritPhaseShift(this, creator);
|
||||
|
||||
SetEntry(conversationEntry);
|
||||
SetObjectScale(1.0f);
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace Game.Entities
|
||||
|
||||
_cellCoord = GridDefines.ComputeCellCoord(GetPositionX(), GetPositionY());
|
||||
|
||||
CopyPhaseFrom(owner);
|
||||
PhasingHandler.InheritPhaseShift(this, owner);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -114,12 +114,12 @@ namespace Game.Entities
|
||||
stmt.AddValue(index++, GetInstanceId()); // instanceId
|
||||
trans.Append(stmt);
|
||||
|
||||
foreach (uint phaseId in GetPhases())
|
||||
foreach (PhaseRef phase in GetPhaseShift().GetPhases())
|
||||
{
|
||||
index = 0;
|
||||
stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CORPSE_PHASES);
|
||||
stmt.AddValue(index++, GetOwnerGUID().GetCounter()); // OwnerGuid
|
||||
stmt.AddValue(index++, phaseId); // PhaseId
|
||||
stmt.AddValue(index++, phase.Id); // PhaseId
|
||||
trans.Append(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,12 +741,11 @@ namespace Game.Entities
|
||||
{
|
||||
SetMap(map);
|
||||
|
||||
if (data != null && data.phaseId != 0)
|
||||
SetInPhase(data.phaseId, false, true);
|
||||
|
||||
if (data != null && data.phaseGroup != 0)
|
||||
foreach (var ph in Global.DB2Mgr.GetPhasesForGroup(data.phaseGroup))
|
||||
SetInPhase(ph, false, true);
|
||||
if (data != null)
|
||||
{
|
||||
PhasingHandler.InitDbPhaseShift(GetPhaseShift(), data.phaseUseFlags, data.phaseId, data.phaseGroup);
|
||||
PhasingHandler.InitDbVisibleMapId(GetPhaseShift(), data.terrainSwapMap);
|
||||
}
|
||||
|
||||
CreatureTemplate cinfo = Global.ObjectMgr.GetCreatureTemplate(entry);
|
||||
if (cinfo == null)
|
||||
@@ -2623,7 +2622,7 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
// Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
|
||||
float ground = GetMap().GetHeight(GetPhases(), GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
|
||||
float ground = GetMap().GetHeight(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
|
||||
|
||||
bool isInAir = (MathFunctions.fuzzyGt(GetPositionZMinusOffset(), ground + 0.05f) || MathFunctions.fuzzyLt(GetPositionZMinusOffset(), ground - 0.05f)); // Can be underground too, prevent the falling
|
||||
|
||||
@@ -2934,7 +2933,7 @@ namespace Game.Entities
|
||||
m_deathState = DeathState.Dead;
|
||||
if (CanFly())
|
||||
{
|
||||
float tz = map.GetHeight(GetPhases(), data.posX, data.posY, data.posZ, true, MapConst.MaxFallDistance);
|
||||
float tz = map.GetHeight(GetPhaseShift(), data.posX, data.posY, data.posZ, true, MapConst.MaxFallDistance);
|
||||
if (data.posZ - tz > 0.1f && GridDefines.IsValidMapCoord(tz))
|
||||
Relocate(data.posX, data.posY, tz);
|
||||
}
|
||||
|
||||
@@ -297,8 +297,10 @@ namespace Game.Entities
|
||||
public uint unit_flags2; // enum UnitFlags2 mask values
|
||||
public uint unit_flags3; // enum UnitFlags3 mask values
|
||||
public uint dynamicflags;
|
||||
public PhaseUseFlagsValues phaseUseFlags;
|
||||
public uint phaseId;
|
||||
public uint phaseGroup;
|
||||
public int terrainSwapMap;
|
||||
public uint ScriptId;
|
||||
public bool dbData;
|
||||
}
|
||||
|
||||
@@ -948,15 +948,8 @@ namespace Game.Entities
|
||||
if (!Create(entry, map, pos, data.rotation, animprogress, go_state, artKit))
|
||||
return false;
|
||||
|
||||
if (data.phaseId != 0)
|
||||
SetInPhase(data.phaseId, false, true);
|
||||
|
||||
if (data.phaseGroup != 0)
|
||||
{
|
||||
// Set the gameobject in all the phases of the phasegroup
|
||||
foreach (var ph in Global.DB2Mgr.GetPhasesForGroup(data.phaseGroup))
|
||||
SetInPhase(ph, false, true);
|
||||
}
|
||||
PhasingHandler.InitDbPhaseShift(GetPhaseShift(), data.phaseUseFlags, data.phaseId, data.phaseGroup);
|
||||
PhasingHandler.InitDbVisibleMapId(GetPhaseShift(), data.terrainSwapMap);
|
||||
|
||||
if (data.spawntimesecs >= 0)
|
||||
{
|
||||
@@ -2766,7 +2759,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
public override uint GetDisplayId() { return _owner.GetDisplayId(); }
|
||||
public override bool IsInPhase(List<uint> phases) { return _owner.IsInPhase(phases); }
|
||||
public override bool IsInPhase(PhaseShift phaseShift) { return _owner.GetPhaseShift().CanSee(phaseShift); }
|
||||
public override Vector3 GetPosition() { return new Vector3(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZ()); }
|
||||
public override float GetOrientation() { return _owner.GetOrientation(); }
|
||||
public override float GetScale() { return _owner.GetObjectScale(); }
|
||||
|
||||
@@ -1089,8 +1089,10 @@ namespace Game.Entities
|
||||
public GameObjectState go_state;
|
||||
public ulong spawnMask;
|
||||
public byte artKit;
|
||||
public PhaseUseFlagsValues phaseUseFlags;
|
||||
public uint phaseId;
|
||||
public uint phaseGroup;
|
||||
public int terrainSwapMap;
|
||||
public uint ScriptId;
|
||||
public bool dbData = true;
|
||||
}
|
||||
|
||||
@@ -1608,17 +1608,17 @@ namespace Game.Entities
|
||||
|
||||
public uint GetZoneId()
|
||||
{
|
||||
return GetMap().GetZoneId(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
return GetMap().GetZoneId(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
}
|
||||
|
||||
public uint GetAreaId()
|
||||
{
|
||||
return GetMap().GetAreaId(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
return GetMap().GetAreaId(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
}
|
||||
|
||||
public void GetZoneAndAreaId(out uint zoneid, out uint areaid)
|
||||
{
|
||||
GetMap().GetZoneAndAreaId(out zoneid, out areaid, posX, posY, posZ);
|
||||
GetMap().GetZoneAndAreaId(GetPhaseShift(), out zoneid, out areaid, posX, posY, posZ);
|
||||
}
|
||||
|
||||
public InstanceScript GetInstanceScript()
|
||||
@@ -2047,7 +2047,7 @@ namespace Game.Entities
|
||||
if (!go)
|
||||
return null;
|
||||
|
||||
go.CopyPhaseFrom(this);
|
||||
PhasingHandler.InheritPhaseShift(go, this);
|
||||
|
||||
go.SetRespawnTime((int)respawnTime);
|
||||
if (IsTypeId(TypeId.Player) || IsTypeId(TypeId.Unit)) //not sure how to handle this
|
||||
@@ -2154,242 +2154,15 @@ namespace Game.Entities
|
||||
return (valuesCount > (uint)UnitFields.CombatReach) ? GetFloatValue(UnitFields.CombatReach) : SharedConst.DefaultWorldObjectSize;
|
||||
}
|
||||
|
||||
bool HasInPhaseList(uint phase)
|
||||
{
|
||||
return _phases.Contains(phase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates Area based phases, does not remove phases from auras
|
||||
/// Phases from gm commands are not taken into calculations, they can be lost!!
|
||||
/// </summary>
|
||||
public void UpdateAreaAndZonePhase()
|
||||
{
|
||||
bool updateNeeded = false;
|
||||
var allAreasPhases = Global.ObjectMgr.GetAreaAndZonePhases();
|
||||
uint[] zoneAndArea = { GetZoneId(), GetAreaId() };
|
||||
|
||||
// We first remove all phases from other areas & zones
|
||||
foreach (var key in allAreasPhases.Keys)
|
||||
foreach (PhaseInfoStruct phase in allAreasPhases[key])
|
||||
if (!Global.DB2Mgr.IsInArea(GetAreaId(), key))
|
||||
updateNeeded = SetInPhase(phase.Id, false, false) || updateNeeded; // not in area, remove phase, true if there was something removed
|
||||
|
||||
// Then we add the phases from this area and zone if conditions are met
|
||||
// Zone is done before Area, so if Area does not meet condition, the phase will be removed
|
||||
foreach (uint area in zoneAndArea)
|
||||
{
|
||||
var currentPhases = Global.ObjectMgr.GetPhasesForArea(area);
|
||||
if (currentPhases != null)
|
||||
{
|
||||
foreach (PhaseInfoStruct phaseInfoStruct in currentPhases)
|
||||
{
|
||||
bool apply = Global.ConditionMgr.IsObjectMeetToConditions(this, phaseInfoStruct.Conditions);
|
||||
|
||||
// add or remove phase depending of condition
|
||||
updateNeeded = SetInPhase(phaseInfoStruct.Id, false, apply) || updateNeeded;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do not remove a phase if it would be removed by an area but we have the same phase from an aura
|
||||
Unit unit = ToUnit();
|
||||
if (unit)
|
||||
{
|
||||
var auraPhaseList = unit.GetAuraEffectsByType(AuraType.Phase);
|
||||
foreach (var eff in auraPhaseList)
|
||||
{
|
||||
uint phase = (uint)eff.GetMiscValueB();
|
||||
updateNeeded = SetInPhase(phase, false, true) || updateNeeded;
|
||||
}
|
||||
var auraPhaseGroupList = unit.GetAuraEffectsByType(AuraType.PhaseGroup);
|
||||
foreach (var eff in auraPhaseGroupList)
|
||||
{
|
||||
uint phaseGroup = (uint)eff.GetMiscValueB();
|
||||
foreach (uint phase in Global.DB2Mgr.GetPhasesForGroup(phaseGroup))
|
||||
updateNeeded = SetInPhase(phase, false, true) || updateNeeded;
|
||||
}
|
||||
}
|
||||
|
||||
// only update visibility and send packets if there was a change in the phase list
|
||||
|
||||
if (updateNeeded && IsTypeId(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();
|
||||
}
|
||||
|
||||
public virtual bool SetInPhase(uint id, bool update, bool apply)
|
||||
{
|
||||
if (id != 0)
|
||||
{
|
||||
if (apply)
|
||||
{
|
||||
// do not run the updates if we are already in this phase
|
||||
if (_phases.Contains(id))
|
||||
return false;
|
||||
|
||||
_phases.Add(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_phases.Contains(id))
|
||||
return false;
|
||||
|
||||
// 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
|
||||
var phases = Global.ObjectMgr.GetPhasesForArea(GetAreaId());
|
||||
if (phases != null)
|
||||
{
|
||||
foreach (PhaseInfoStruct phase in phases)
|
||||
{
|
||||
if (id == phase.Id)
|
||||
if (Global.ConditionMgr.IsObjectMeetToConditions(this, phase.Conditions))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_phases.Remove(id);
|
||||
}
|
||||
}
|
||||
RebuildTerrainSwaps();
|
||||
|
||||
if (update && IsInWorld)
|
||||
UpdateObjectVisibility();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void CopyPhaseFrom(WorldObject obj, bool update = false)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
foreach (uint phase in obj.GetPhases())
|
||||
SetInPhase(phase, false, true);
|
||||
|
||||
if (update && IsInWorld)
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
public void ClearPhases(bool update = false)
|
||||
{
|
||||
_phases.Clear();
|
||||
|
||||
RebuildTerrainSwaps();
|
||||
|
||||
if (update && IsInWorld)
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
public bool IsInPhase(uint phase) { return _phases.Contains(phase); }
|
||||
|
||||
public bool IsInPhase(List<uint> phases)
|
||||
{
|
||||
// PhaseId 169 is the default fallback phase
|
||||
if (_phases.Empty() && phases.Empty())
|
||||
return true;
|
||||
|
||||
if (_phases.Empty() && phases.Contains(169))
|
||||
return true;
|
||||
|
||||
if (phases.Empty() && _phases.Contains(169))
|
||||
return true;
|
||||
|
||||
return _phases.Intersect(phases).Any();
|
||||
}
|
||||
|
||||
public bool IsInPhase(WorldObject obj)
|
||||
{
|
||||
// PhaseId 169 is the default fallback phase
|
||||
if (_phases.Empty() && obj.GetPhases().Empty())
|
||||
return true;
|
||||
|
||||
if (_phases.Empty() && obj.IsInPhase(169))
|
||||
return true;
|
||||
|
||||
if (obj.GetPhases().Empty() && IsInPhase(169))
|
||||
return true;
|
||||
|
||||
if (IsTypeId(TypeId.Player) && ToPlayer().IsGameMaster())
|
||||
return true;
|
||||
|
||||
return IsInPhase(obj.GetPhases());
|
||||
return GetPhaseShift().CanSee(obj.GetPhaseShift());
|
||||
}
|
||||
|
||||
public bool IsInTerrainSwap(uint terrainSwap) { return _terrainSwaps.Contains(terrainSwap); }
|
||||
|
||||
public void 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
|
||||
foreach (uint phaseId in _phases)
|
||||
{
|
||||
var swaps = Global.ObjectMgr.GetPhaseTerrainSwaps(phaseId);
|
||||
foreach (uint swap in swaps)
|
||||
{
|
||||
// only add terrain swaps for current map
|
||||
MapRecord mapEntry = CliDB.MapStorage.LookupByKey(swap);
|
||||
if (mapEntry == null || mapEntry.ParentMapID != GetMapId())
|
||||
continue;
|
||||
|
||||
if (Global.ConditionMgr.IsObjectMeetingNotGroupedConditions(ConditionSourceType.TerrainSwap, swap, this))
|
||||
_terrainSwaps.Add(swap);
|
||||
}
|
||||
}
|
||||
|
||||
// get default terrain swaps, only for current map always
|
||||
var mapSwaps = Global.ObjectMgr.GetDefaultTerrainSwaps(GetMapId());
|
||||
foreach (uint swap in mapSwaps)
|
||||
{
|
||||
if (Global.ConditionMgr.IsObjectMeetingNotGroupedConditions(ConditionSourceType.TerrainSwap, swap, this))
|
||||
_terrainSwaps.Add(swap);
|
||||
}
|
||||
|
||||
// online players have a game client with world map display
|
||||
if (IsTypeId(TypeId.Player))
|
||||
RebuildWorldMapAreaSwaps();
|
||||
}
|
||||
|
||||
void 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
|
||||
var defaults = Global.ObjectMgr.GetDefaultTerrainSwapStore();
|
||||
foreach (uint swap in defaults.Values)
|
||||
{
|
||||
var uiMapSwaps = Global.ObjectMgr.GetTerrainWorldMaps(swap);
|
||||
if (Global.ConditionMgr.IsObjectMeetingNotGroupedConditions(ConditionSourceType.TerrainSwap, swap, this))
|
||||
{
|
||||
foreach (uint worldMapAreaId in uiMapSwaps)
|
||||
_worldMapAreaSwaps.Add(worldMapAreaId);
|
||||
}
|
||||
}
|
||||
|
||||
// Check all applied phases for world map area swaps
|
||||
foreach (uint phaseId in _phases)
|
||||
{
|
||||
var swaps = Global.ObjectMgr.GetPhaseTerrainSwaps(phaseId);
|
||||
foreach (uint swap in swaps)
|
||||
{
|
||||
var uiMapSwaps = Global.ObjectMgr.GetTerrainWorldMaps(swap);
|
||||
if (Global.ConditionMgr.IsObjectMeetingNotGroupedConditions(ConditionSourceType.TerrainSwap, swap, this))
|
||||
foreach (uint worldMapAreaId in uiMapSwaps)
|
||||
_worldMapAreaSwaps.Add(worldMapAreaId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<uint> GetPhases() { return _phases; }
|
||||
public List<uint> GetTerrainSwaps() { return _terrainSwaps; }
|
||||
public List<uint> GetWorldMapAreaSwaps() { return _worldMapAreaSwaps; }
|
||||
public PhaseShift GetPhaseShift() { return _phaseShift; }
|
||||
public void SetPhaseShift(PhaseShift phaseShift) { _phaseShift = phaseShift; }
|
||||
public PhaseShift GetSuppressedPhaseShift() { return _suppressedPhaseShift; }
|
||||
public void SetSuppressedPhaseShift(PhaseShift phaseShift) { _suppressedPhaseShift = phaseShift; }
|
||||
public int GetDBPhase() { return _dbPhase; }
|
||||
|
||||
// if negative it is used as PhaseGroupId
|
||||
@@ -2707,7 +2480,7 @@ namespace Game.Entities
|
||||
else
|
||||
GetHitSpherePointFor(new Position(ox, oy, oz), out x, out y, out z);
|
||||
|
||||
return GetMap().isInLineOfSight(x, y, z + 2.0f, ox, oy, oz + 2.0f, GetPhases());
|
||||
return GetMap().isInLineOfSight(GetPhaseShift(), x, y, z + 2.0f, ox, oy, oz + 2.0f);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2838,7 +2611,7 @@ namespace Game.Entities
|
||||
|
||||
public void UpdateGroundPositionZ(float x, float y, ref float z)
|
||||
{
|
||||
float new_z = GetMap().GetHeight(GetPhases(), x, y, z, true);
|
||||
float new_z = GetMap().GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
if (new_z > MapConst.InvalidHeight)
|
||||
z = new_z + 0.05f; // just to be sure that we are not a few pixel under the surface
|
||||
}
|
||||
@@ -2860,8 +2633,8 @@ namespace Game.Entities
|
||||
bool canSwim = ToCreature().CanSwim();
|
||||
float ground_z = z;
|
||||
float max_z = canSwim
|
||||
? GetMap().GetWaterOrGroundLevel(GetPhases(), x, y, z, ref ground_z, !ToUnit().HasAuraType(AuraType.WaterWalk))
|
||||
: ((ground_z = GetMap().GetHeight(GetPhases(), x, y, z, true)));
|
||||
? GetMap().GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, ref ground_z, !ToUnit().HasAuraType(AuraType.WaterWalk))
|
||||
: ((ground_z = GetMap().GetHeight(GetPhaseShift(), x, y, z, true)));
|
||||
if (max_z > MapConst.InvalidHeight)
|
||||
{
|
||||
if (z > max_z)
|
||||
@@ -2872,7 +2645,7 @@ namespace Game.Entities
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -2884,7 +2657,7 @@ namespace Game.Entities
|
||||
if (!ToPlayer().CanFly())
|
||||
{
|
||||
float ground_z = z;
|
||||
float max_z = GetMap().GetWaterOrGroundLevel(GetPhases(), x, y, z, ref ground_z, !ToUnit().HasAuraType(AuraType.WaterWalk));
|
||||
float max_z = GetMap().GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, ref ground_z, !ToUnit().HasAuraType(AuraType.WaterWalk));
|
||||
if (max_z > MapConst.InvalidHeight)
|
||||
{
|
||||
if (z > max_z)
|
||||
@@ -2895,7 +2668,7 @@ namespace Game.Entities
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -2903,7 +2676,7 @@ namespace Game.Entities
|
||||
}
|
||||
default:
|
||||
{
|
||||
float ground_z = GetMap().GetHeight(GetPhases(), x, y, z, true);
|
||||
float ground_z = GetMap().GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
if (ground_z > MapConst.InvalidHeight)
|
||||
z = ground_z;
|
||||
break;
|
||||
@@ -3002,8 +2775,8 @@ namespace Game.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
ground = GetMap().GetHeight(GetPhases(), destx, desty, MapConst.MaxHeight, true);
|
||||
floor = GetMap().GetHeight(GetPhases(), destx, desty, pos.posZ, true);
|
||||
ground = GetMap().GetHeight(GetPhaseShift(), destx, desty, MapConst.MaxHeight, true);
|
||||
floor = GetMap().GetHeight(GetPhaseShift(), destx, desty, pos.posZ, true);
|
||||
destz = Math.Abs(ground - pos.posZ) <= Math.Abs(floor - pos.posZ) ? ground : floor;
|
||||
|
||||
float step = dist / 10.0f;
|
||||
@@ -3015,8 +2788,8 @@ namespace Game.Entities
|
||||
{
|
||||
destx -= step * (float)Math.Cos(angle);
|
||||
desty -= step * (float)Math.Sin(angle);
|
||||
ground = GetMap().GetHeight(GetPhases(), destx, desty, MapConst.MaxHeight, true);
|
||||
floor = GetMap().GetHeight(GetPhases(), destx, desty, pos.posZ, true);
|
||||
ground = GetMap().GetHeight(GetPhaseShift(), destx, desty, MapConst.MaxHeight, true);
|
||||
floor = GetMap().GetHeight(GetPhaseShift(), destx, desty, pos.posZ, true);
|
||||
destz = Math.Abs(ground - pos.posZ) <= Math.Abs(floor - pos.posZ) ? ground : floor;
|
||||
}
|
||||
// we have correct destz now
|
||||
@@ -3035,8 +2808,8 @@ namespace Game.Entities
|
||||
|
||||
float NormalizeZforCollision(WorldObject obj, float x, float y, float z)
|
||||
{
|
||||
float ground = obj.GetMap().GetHeight(obj.GetPhases(), x, y, MapConst.MaxHeight, true);
|
||||
float floor = obj.GetMap().GetHeight(obj.GetPhases(), x, y, z + 2.0f, true);
|
||||
float ground = obj.GetMap().GetHeight(obj.GetPhaseShift(), x, y, MapConst.MaxHeight, true);
|
||||
float floor = obj.GetMap().GetHeight(obj.GetPhaseShift(), x, y, z + 2.0f, true);
|
||||
float helper = Math.Abs(ground - z) <= Math.Abs(floor - z) ? ground : floor;
|
||||
if (z > helper) // must be above ground
|
||||
{
|
||||
@@ -3047,7 +2820,7 @@ namespace Game.Entities
|
||||
return z;
|
||||
}
|
||||
LiquidData liquid_status;
|
||||
ZLiquidStatus res = obj.GetMap().getLiquidStatus(x, y, z, MapConst.MapAllLiquidTypes, out liquid_status);
|
||||
ZLiquidStatus res = obj.GetMap().getLiquidStatus(obj.GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out liquid_status);
|
||||
if (res != 0 && liquid_status.level > helper) // water must be above ground
|
||||
{
|
||||
if (liquid_status.level > z) // z is underwater
|
||||
@@ -3074,7 +2847,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
destz = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ());
|
||||
bool col = Global.VMapMgr.getObjectHitPos(GetMapId(), pos.posX, pos.posY, pos.posZ + 0.5f, destx, desty, destz + 0.5f, out destx, out desty, out destz, -0.5f);
|
||||
bool col = Global.VMapMgr.getObjectHitPos(PhasingHandler.GetTerrainMapId(GetPhaseShift(), GetMap(), pos.posX, pos.posY), pos.posX, pos.posY, pos.posZ + 0.5f, destx, desty, destz + 0.5f, out destx, out desty, out destz, -0.5f);
|
||||
|
||||
// collision occured
|
||||
if (col)
|
||||
@@ -3086,7 +2859,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// check dynamic collision
|
||||
col = GetMap().getObjectHitPos(GetPhases(), pos.posX, pos.posY, pos.posZ + 0.5f, destx, desty, destz + 0.5f, out destx, out desty, out destz, -0.5f);
|
||||
col = GetMap().getObjectHitPos(GetPhaseShift(), pos.posX, pos.posY, pos.posZ + 0.5f, destx, desty, destz + 0.5f, out destx, out desty, out destz, -0.5f);
|
||||
|
||||
// Collided with a gameobject
|
||||
if (col)
|
||||
@@ -3150,9 +2923,8 @@ namespace Game.Entities
|
||||
Transport m_transport;
|
||||
Map _currMap;
|
||||
uint instanceId;
|
||||
List<uint> _phases = new List<uint>();
|
||||
List<uint> _terrainSwaps = new List<uint>();
|
||||
List<uint> _worldMapAreaSwaps = new List<uint>();
|
||||
PhaseShift _phaseShift= new PhaseShift();
|
||||
PhaseShift _suppressedPhaseShift = new PhaseShift(); // contains phases for current area but not applied due to conditions
|
||||
int _dbPhase;
|
||||
public bool IsInWorld { get; set; }
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ namespace Game.Entities
|
||||
if (!Create(map.GenerateLowGuid(HighGuid.Pet), map, petEntry))
|
||||
return false;
|
||||
|
||||
CopyPhaseFrom(owner);
|
||||
PhasingHandler.InheritPhaseShift(this, owner);
|
||||
|
||||
setPetType(petType);
|
||||
SetFaction(owner.getFaction());
|
||||
|
||||
@@ -3550,7 +3550,7 @@ namespace Game.Entities
|
||||
if (!CliDB.MapStorage.ContainsKey(map))
|
||||
return 0;
|
||||
|
||||
zone = Global.MapMgr.GetZoneId(map, posx, posy, posz);
|
||||
zone = Global.MapMgr.GetZoneId(PhasingHandler.EmptyPhaseShift, map, posx, posy, posz);
|
||||
|
||||
if (zone > 0)
|
||||
{
|
||||
|
||||
@@ -191,6 +191,7 @@ namespace Game.Entities
|
||||
|
||||
SpecializationInfo _specializationInfo;
|
||||
public List<ObjectGuid> m_clientGUIDs = new List<ObjectGuid>();
|
||||
public List<ObjectGuid> m_visibleTransports = new List<ObjectGuid>();
|
||||
public WorldObject seerView;
|
||||
// only changed for direct client control (possess, vehicle etc.), not stuff you control using pet commands
|
||||
public Unit m_unitMovedByMe;
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace Game.Entities
|
||||
UpdatePvPState(true);
|
||||
|
||||
UpdateAreaDependentAuras(newArea);
|
||||
UpdateAreaAndZonePhase();
|
||||
PhasingHandler.OnAreaChange(this);
|
||||
|
||||
if (IsAreaThatActivatesPvpTalents(newArea))
|
||||
EnablePvpRules();
|
||||
@@ -232,8 +232,6 @@ namespace Game.Entities
|
||||
UpdateLocalChannels(newZone);
|
||||
|
||||
UpdateZoneDependentAuras(newZone);
|
||||
|
||||
UpdateAreaAndZonePhase();
|
||||
}
|
||||
|
||||
public InstanceBind GetBoundInstance(uint mapid, Difficulty difficulty, bool withExpired = false)
|
||||
@@ -721,7 +719,7 @@ namespace Game.Entities
|
||||
public override void UpdateUnderwaterState(Map m, float x, float y, float z)
|
||||
{
|
||||
LiquidData liquid_status;
|
||||
ZLiquidStatus res = m.getLiquidStatus(x, y, z, MapConst.MapAllLiquidTypes, out liquid_status);
|
||||
ZLiquidStatus res = m.getLiquidStatus(GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out liquid_status);
|
||||
if (res == 0)
|
||||
{
|
||||
m_MirrorTimerFlags &= ~(PlayerUnderwaterState.InWater | PlayerUnderwaterState.InLava | PlayerUnderwaterState.InSlime | PlayerUnderwaterState.InDarkWater);
|
||||
|
||||
@@ -1817,7 +1817,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
UpdateForQuestWorldObjects();
|
||||
SendUpdatePhasing();
|
||||
PhasingHandler.OnConditionChange(this);
|
||||
}
|
||||
|
||||
public QuestGiverStatus GetQuestDialogStatus(WorldObject questgiver)
|
||||
|
||||
@@ -1937,7 +1937,7 @@ namespace Game.Entities
|
||||
public override bool IsUnderWater()
|
||||
{
|
||||
return IsInWater() &&
|
||||
GetPositionZ() < (GetMap().GetWaterLevel(GetPositionX(), GetPositionY()) - 2);
|
||||
GetPositionZ() < (GetMap().GetWaterLevel(GetPhaseShift(), GetPositionX(), GetPositionY()) - 2);
|
||||
}
|
||||
public override bool IsInWater()
|
||||
{
|
||||
@@ -2117,9 +2117,16 @@ namespace Game.Entities
|
||||
}
|
||||
public bool IsInAreaTriggerRadius(AreaTriggerRecord trigger)
|
||||
{
|
||||
if (trigger == null || GetMapId() != trigger.ContinentID)
|
||||
if (trigger == null)
|
||||
return false;
|
||||
|
||||
if (GetMapId() != trigger.ContinentID && !GetPhaseShift().HasVisibleMapId(trigger.ContinentID))
|
||||
return false;
|
||||
|
||||
if (trigger.PhaseID != 0 || trigger.PhaseGroupID != 0 || trigger.PhaseUseFlags != 0)
|
||||
if (!PhasingHandler.InDbPhaseShift(this, (PhaseUseFlagsValues)trigger.PhaseUseFlags, trigger.PhaseID, trigger.PhaseGroupID))
|
||||
return false;
|
||||
|
||||
if (trigger.Radius > 0.0f)
|
||||
{
|
||||
// if we have radius check it
|
||||
@@ -2203,10 +2210,13 @@ namespace Game.Entities
|
||||
getHostileRefManager().setOnlineOfflineState(false);
|
||||
CombatStopWithPets();
|
||||
|
||||
PhasingHandler.SetAlwaysVisible(GetPhaseShift(), true);
|
||||
m_serverSideVisibilityDetect.SetValue(ServerSideVisibilityType.GM, GetSession().GetSecurity());
|
||||
}
|
||||
else
|
||||
{
|
||||
PhasingHandler.SetAlwaysVisible(GetPhaseShift(), false);
|
||||
|
||||
m_ExtraFlags &= ~PlayerExtraFlags.GMOn;
|
||||
SetFactionForRace(GetRace());
|
||||
RemoveFlag(PlayerFields.Flags, PlayerFlags.GM);
|
||||
@@ -4820,7 +4830,7 @@ namespace Game.Entities
|
||||
return null;
|
||||
}
|
||||
|
||||
pet.CopyPhaseFrom(this);
|
||||
PhasingHandler.InheritPhaseShift(pet, this);
|
||||
|
||||
pet.SetCreatorGUID(GetGUID());
|
||||
pet.SetUInt32Value(UnitFields.FactionTemplate, getFaction());
|
||||
@@ -5691,6 +5701,8 @@ namespace Game.Entities
|
||||
SendRaidDifficulty(difficulty.Flags.HasAnyFlag(DifficultyFlags.Legacy));
|
||||
}
|
||||
|
||||
PhasingHandler.OnMapChange(this);
|
||||
|
||||
if (_garrison != null)
|
||||
_garrison.SendRemoteInfo();
|
||||
|
||||
@@ -6202,7 +6214,7 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
bool isOutdoor;
|
||||
uint areaId = GetMap().GetAreaId(GetPositionX(), GetPositionY(), GetPositionZ(), out isOutdoor);
|
||||
uint areaId = GetMap().GetAreaId(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), out isOutdoor);
|
||||
AreaTableRecord areaEntry = CliDB.AreaTableStorage.LookupByKey(areaId);
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.VmapIndoorCheck) && !isOutdoor)
|
||||
@@ -7307,16 +7319,6 @@ namespace Game.Entities
|
||||
SendMessageToSet(cancelAutoRepeat, false);
|
||||
}
|
||||
|
||||
public void SendUpdatePhasing()
|
||||
{
|
||||
if (!IsInWorld)
|
||||
return;
|
||||
|
||||
RebuildTerrainSwaps(); // to set default map swaps
|
||||
|
||||
GetSession().SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), GetWorldMapAreaSwaps());
|
||||
}
|
||||
|
||||
public override void BuildCreateUpdateBlockForPlayer(UpdateData data, Player target)
|
||||
{
|
||||
if (target == this)
|
||||
|
||||
@@ -338,15 +338,8 @@ namespace Game.Entities
|
||||
return null;
|
||||
}
|
||||
|
||||
if (data.phaseId != 0)
|
||||
creature.SetInPhase(data.phaseId, false, true);
|
||||
else if (data.phaseGroup != 0)
|
||||
{
|
||||
foreach (var phase in Global.DB2Mgr.GetPhasesForGroup(data.phaseGroup))
|
||||
creature.SetInPhase(phase, false, true);
|
||||
}
|
||||
else
|
||||
creature.CopyPhaseFrom(this);
|
||||
PhasingHandler.InitDbPhaseShift(creature.GetPhaseShift(), data.phaseUseFlags, data.phaseId, data.phaseGroup);
|
||||
PhasingHandler.InitDbVisibleMapId(creature.GetPhaseShift(), data.terrainSwapMap);
|
||||
|
||||
if (!map.AddToMap(creature))
|
||||
return null;
|
||||
@@ -383,6 +376,9 @@ namespace Game.Entities
|
||||
return null;
|
||||
}
|
||||
|
||||
PhasingHandler.InitDbPhaseShift(go.GetPhaseShift(), data.phaseUseFlags, data.phaseId, data.phaseGroup);
|
||||
PhasingHandler.InitDbVisibleMapId(go.GetPhaseShift(), data.terrainSwapMap);
|
||||
|
||||
if (!map.AddToMap(go))
|
||||
return null;
|
||||
|
||||
@@ -444,12 +440,6 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
List<uint> phases = new List<uint>();
|
||||
if (summoner)
|
||||
phases = summoner.GetPhases();
|
||||
else
|
||||
phases = GetPhases(); // If there was no summoner, try to use the transport phases
|
||||
|
||||
TempSummon summon = null;
|
||||
switch (mask)
|
||||
{
|
||||
@@ -477,8 +467,7 @@ namespace Game.Entities
|
||||
if (!summon.Create(map.GenerateLowGuid(HighGuid.Creature), map, entry, x, y, z, o, null, vehId))
|
||||
return null;
|
||||
|
||||
foreach (var phase in phases)
|
||||
summon.SetInPhase(phase, false, true);
|
||||
PhasingHandler.InheritPhaseShift(summon, summoner ? (WorldObject)summoner : this);
|
||||
|
||||
summon.SetUInt32Value(UnitFields.CreatedBySpell, spellId);
|
||||
|
||||
|
||||
@@ -64,11 +64,11 @@ namespace Game.Entities
|
||||
}
|
||||
public virtual bool IsInWater()
|
||||
{
|
||||
return GetMap().IsInWater(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
return GetMap().IsInWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
}
|
||||
public virtual bool IsUnderWater()
|
||||
{
|
||||
return GetMap().IsUnderWater(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
return GetMap().IsUnderWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
}
|
||||
|
||||
void propagateSpeedChange() { GetMotionMaster().propagateSpeedChange(); }
|
||||
@@ -677,7 +677,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
LiquidData liquid;
|
||||
ZLiquidStatus liquidStatus = GetMap().getLiquidStatus(GetPositionX(), GetPositionY(), GetPositionZ(), MapConst.MapAllLiquidTypes, out liquid);
|
||||
ZLiquidStatus liquidStatus = GetMap().getLiquidStatus(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), MapConst.MapAllLiquidTypes, out liquid);
|
||||
isSubmerged = liquidStatus.HasAnyFlag(ZLiquidStatus.UnderWater) || HasUnitMovementFlag(MovementFlag.Swimming);
|
||||
isInWater = liquidStatus.HasAnyFlag(ZLiquidStatus.InWater | ZLiquidStatus.UnderWater);
|
||||
|
||||
@@ -748,7 +748,7 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
LiquidData liquid_status;
|
||||
ZLiquidStatus res = m.getLiquidStatus(x, y, z, MapConst.MapAllLiquidTypes, out liquid_status);
|
||||
ZLiquidStatus res = m.getLiquidStatus(GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out liquid_status);
|
||||
if (res == 0)
|
||||
{
|
||||
if (_lastLiquid != null && _lastLiquid.SpellID != 0)
|
||||
|
||||
@@ -784,7 +784,7 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
pet.CopyPhaseFrom(this);
|
||||
PhasingHandler.InheritPhaseShift(pet, this);
|
||||
|
||||
pet.GetCharmInfo().SetPetNumber(Global.ObjectMgr.GeneratePetNumber(), true);
|
||||
// this enables pet details window (Shift+P)
|
||||
|
||||
@@ -3313,7 +3313,7 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
}
|
||||
public void RemoveNotOwnSingleTargetAuras(uint newPhase = 0, bool phaseid = false)
|
||||
public void RemoveNotOwnSingleTargetAuras(bool onPhaseChange = false)
|
||||
{
|
||||
// Iterate m_ownedAuras - aura is marked as single target in Unit::AddAura (and pushed to m_ownedAuras).
|
||||
// m_appliedAuras will NOT contain the aura before first Unit::Update after adding it to m_ownedAuras.
|
||||
@@ -3330,12 +3330,12 @@ namespace Game.Entities
|
||||
|
||||
if (aura.GetCasterGUID() != GetGUID() && aura.IsSingleTarget())
|
||||
{
|
||||
if (newPhase == 0 && !phaseid)
|
||||
if (onPhaseChange)
|
||||
RemoveOwnedAura(list[i]);
|
||||
else
|
||||
{
|
||||
Unit caster = aura.GetCaster();
|
||||
if (!caster || (newPhase != 0 && !caster.IsInPhase(newPhase)) || (newPhase == 0 && !caster.IsInPhase(this)))
|
||||
if (!caster || !caster.IsInPhase(this))
|
||||
RemoveOwnedAura(list[i]);
|
||||
}
|
||||
}
|
||||
@@ -3345,7 +3345,7 @@ namespace Game.Entities
|
||||
for (var i = 0; i < m_scAuras.Count; i++)
|
||||
{
|
||||
var aura = m_scAuras[i];
|
||||
if (aura.GetUnitOwner() != this && !aura.GetUnitOwner().IsInPhase(newPhase))
|
||||
if (aura.GetUnitOwner() != this && (!onPhaseChange || !aura.GetUnitOwner().IsInPhase(this)))
|
||||
aura.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,15 +416,6 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddToWorld()
|
||||
{
|
||||
if (!IsInWorld)
|
||||
{
|
||||
base.AddToWorld();
|
||||
}
|
||||
RebuildTerrainSwaps();
|
||||
}
|
||||
|
||||
public override void RemoveFromWorld()
|
||||
{
|
||||
// cleanup
|
||||
@@ -935,7 +926,7 @@ namespace Game.Entities
|
||||
MoveSplineInit init = new MoveSplineInit(this);
|
||||
|
||||
// Creatures without inhabit type air should begin falling after exiting the vehicle
|
||||
if (IsTypeId(TypeId.Unit) && !ToCreature().CanFly() && height > GetMap().GetWaterOrGroundLevel(GetPhases(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), ref height) + 0.1f)
|
||||
if (IsTypeId(TypeId.Unit) && !ToCreature().CanFly() && height > GetMap().GetWaterOrGroundLevel(GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), ref height) + 0.1f)
|
||||
init.SetFall();
|
||||
|
||||
init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), height, false);
|
||||
@@ -1099,14 +1090,12 @@ namespace Game.Entities
|
||||
|
||||
public HostileRefManager getHostileRefManager() { return m_HostileRefManager; }
|
||||
|
||||
public override bool SetInPhase(uint id, bool update, bool apply)
|
||||
public void OnPhaseChange()
|
||||
{
|
||||
bool res = base.SetInPhase(id, update, apply);
|
||||
|
||||
if (!IsInWorld)
|
||||
return res;
|
||||
return;
|
||||
|
||||
if (IsTypeId(TypeId.Unit) || (!ToPlayer().IsGameMaster() && !ToPlayer().GetSession().PlayerLogout()))
|
||||
if (IsTypeId(TypeId.Unit) || !ToPlayer().GetSession().PlayerLogout())
|
||||
{
|
||||
HostileRefManager refManager = getHostileRefManager();
|
||||
HostileReference refe = refManager.getFirst();
|
||||
@@ -1143,26 +1132,8 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (var unit in m_Controlled)
|
||||
if (unit.IsTypeId(TypeId.Unit))
|
||||
unit.SetInPhase(id, true, apply);
|
||||
|
||||
for (byte i = 0; i < SharedConst.MaxSummonSlot; ++i)
|
||||
{
|
||||
if (!m_SummonSlot[i].IsEmpty())
|
||||
{
|
||||
Creature summon = GetMap().GetCreature(m_SummonSlot[i]);
|
||||
if (summon != null)
|
||||
summon.SetInPhase(id, true, apply);
|
||||
}
|
||||
}
|
||||
|
||||
RemoveNotOwnSingleTargetAuras(0, true);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public uint GetModelForForm(ShapeShiftForm form)
|
||||
{
|
||||
if (IsTypeId(TypeId.Player))
|
||||
|
||||
Reference in New Issue
Block a user