Core/Phasing: Implemented db spawns in personal phases

Port From (https://github.com/TrinityCore/TrinityCore/commit/8fabe5a3aacf7797f03d074ab8434f445be64955)
This commit is contained in:
hondacrx
2022-01-27 14:01:49 -05:00
parent 6c0e21b4de
commit 7531735669
18 changed files with 555 additions and 123 deletions
+29 -1
View File
@@ -461,6 +461,9 @@ namespace Game.Maps
EnsureGridLoaded(cell);
Grid grid = GetGrid(cell.GetGridX(), cell.GetGridY());
if (obj.IsPlayer())
GetMultiPersonalPhaseTracker().LoadGrid(obj.GetPhaseShift(), grid, this, cell);
// refresh grid state & timer
if (grid.GetGridState() != GridState.Active)
{
@@ -526,6 +529,11 @@ namespace Game.Maps
EnsureGridLoaded(new Cell(x, y));
}
public void LoadGridForActiveObject(float x, float y, WorldObject obj)
{
EnsureGridLoadedForActiveObject(new Cell(x, y), obj);
}
public virtual bool AddPlayerToMap(Player player, bool initPlayer = true)
{
CellCoord cellCoord = GridDefines.ComputeCellCoord(player.GetPositionX(), player.GetPositionY());
@@ -563,6 +571,12 @@ namespace Game.Maps
return true;
}
public void UpdatePersonalPhasesForPlayer(Player player)
{
Cell cell = new(player.GetPositionX(), player.GetPositionY());
GetMultiPersonalPhaseTracker().OnOwnerPhaseChanged(player, GetGrid(cell.GetGridX(), cell.GetGridY()), this, cell);
}
void InitializeObject(WorldObject obj)
{
if (!obj.IsTypeId(TypeId.Unit) || !obj.IsTypeId(TypeId.GameObject))
@@ -823,6 +837,9 @@ namespace Game.Maps
_weatherUpdateTimer.Reset();
}
// update phase shift objects
GetMultiPersonalPhaseTracker().Update(this, diff);
MoveAllCreaturesInMoveList();
MoveAllGameObjectsInMoveList();
MoveAllAreaTriggersInMoveList();
@@ -930,6 +947,8 @@ namespace Game.Maps
player.UpdateZone(MapConst.InvalidZone, 0);
Global.ScriptMgr.OnPlayerLeaveMap(this, player);
GetMultiPersonalPhaseTracker().MarkAllPhasesForDeletion(player.GetGUID());
player.CombatStop();
bool inWorld = player.IsInWorld;
@@ -955,6 +974,8 @@ namespace Game.Maps
if (obj.IsActiveObject())
RemoveFromActive(obj);
GetMultiPersonalPhaseTracker().UnregisterTrackedObject(obj);
if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
obj.DestroyForNearbyPlayers(); // previous obj.UpdateObjectVisibility(true)
@@ -1575,6 +1596,9 @@ namespace Game.Maps
RemoveAllObjectsInRemoveList();
// After removing all objects from the map, purge empty tracked phases
GetMultiPersonalPhaseTracker().UnloadGrid(grid);
{
ObjectGridUnloader worker = new();
var visitor = new Visitor(worker, GridMapTypeMask.AllGrid);
@@ -3789,7 +3813,7 @@ namespace Game.Maps
public InstanceMap ToInstanceMap() { return IsDungeon() ? (this as InstanceMap) : null; }
public BattlegroundMap ToBattlegroundMap() { return IsBattlegroundOrArena() ? (this as BattlegroundMap) : null; }
void Balance()
public void Balance()
{
_dynamicTree.Balance();
}
@@ -4118,6 +4142,8 @@ namespace Game.Maps
return map != null;
}
public MultiPersonalPhaseTracker GetMultiPersonalPhaseTracker() { return _multiPersonalPhaseTracker; }
#region Scripts
// Put scripts in the execution queue
@@ -5086,6 +5112,8 @@ namespace Game.Maps
public delegate void FarSpellCallback(Map map);
Queue<FarSpellCallback> _farSpellCallbacks = new();
MultiPersonalPhaseTracker _multiPersonalPhaseTracker;
#endregion
}
+99 -38
View File
@@ -22,16 +22,71 @@ using System.Collections.Generic;
namespace Game.Maps
{
class ObjectGridLoader : Notifier
class ObjectGridLoaderBase : Notifier
{
public ObjectGridLoader(Grid grid, Map map, Cell cell)
internal Cell i_cell;
internal Grid i_grid;
internal Map i_map;
internal uint i_gameObjects;
internal uint i_creatures;
internal uint i_corpses;
internal uint i_areaTriggers;
public ObjectGridLoaderBase(Grid grid, Map map, Cell cell)
{
i_cell = new Cell(cell);
i_grid = grid;
i_map = map;
}
public uint GetLoadedCreatures() { return i_creatures; }
public uint GetLoadedGameObjects() { return i_gameObjects; }
public uint GetLoadedCorpses() { return i_corpses; }
public uint GetLoadedAreaTriggers() { return i_areaTriggers; }
internal void LoadHelper<T>(SortedSet<ulong> guid_set, CellCoord cell, ref uint count, Map map, uint phaseId = 0, ObjectGuid? phaseOwner = null) where T : WorldObject, new()
{
foreach (var guid in guid_set)
{
// Don't spawn at all if there's a respawn timer
if (!map.ShouldBeSpawnedOnGridLoad<T>(guid))
continue;
T obj = new();
if (!obj.LoadFromDB(guid, map, false, phaseOwner.HasValue /*allowDuplicate*/))
{
obj.Dispose();
continue;
}
if (phaseOwner.HasValue)
{
PhasingHandler.InitDbPersonalOwnership(obj.GetPhaseShift(), phaseOwner.Value);
map.GetMultiPersonalPhaseTracker().RegisterTrackedObject(phaseId, phaseOwner.Value, obj);
}
AddObjectHelper(cell, ref count, map, obj);
}
}
void AddObjectHelper<T>(CellCoord cellCoord, ref uint count, Map map, T obj) where T : WorldObject
{
var cell = new Cell(cellCoord);
map.AddToGrid(obj, cell);
obj.AddToWorld();
if (obj.IsCreature())
if (obj.IsActiveObject())
map.AddToActive(obj);
++count;
}
}
class ObjectGridLoader : ObjectGridLoaderBase
{
public ObjectGridLoader(Grid grid, Map map, Cell cell) : base(grid, map, cell) { }
public void LoadN()
{
i_creatures = 0;
@@ -53,7 +108,7 @@ namespace Game.Maps
i_grid.VisitGrid(x, y, visitor);
}
}
Log.outDebug(LogFilter.Maps, "{0} GameObjects, {1} Creatures, and {2} Corpses/Bones loaded for grid {3} on map {4}", i_gameObjects, i_creatures, i_corpses, i_grid.GetGridId(), i_map.GetId());
Log.outDebug(LogFilter.Maps, $"{i_gameObjects} GameObjects, {i_creatures} Creatures, {i_areaTriggers} AreaTrriggers and {i_corpses} Corpses/Bones loaded for grid {i_grid.GetGridId()} on map {i_map.GetId()}");
}
public override void Visit(IList<GameObject> objs)
@@ -85,51 +140,57 @@ namespace Game.Maps
LoadHelper<AreaTrigger>(areaTriggers, cellCoord, ref i_areaTriggers, i_map);
}
}
void LoadHelper<T>(SortedSet<ulong> guid_set, CellCoord cell, ref uint count, Map map) where T : WorldObject, new()
class PersonalPhaseGridLoader : ObjectGridLoaderBase
{
uint _phaseId;
ObjectGuid _phaseOwner;
public PersonalPhaseGridLoader(Grid grid, Map map, Cell cell, ObjectGuid phaseOwner) : base(grid, map, cell)
{
foreach (var guid in guid_set)
_phaseId = 0;
_phaseOwner = phaseOwner;
}
public override void Visit(IList<GameObject> objs)
{
CellCoord cellCoord = i_cell.GetCellCoord();
CellObjectGuids cell_guids = Global.ObjectMgr.GetCellPersonalObjectGuids(i_map.GetId(), i_map.GetDifficultyID(), _phaseId, cellCoord.GetId());
if (cell_guids != null)
LoadHelper<GameObject>(cell_guids.gameobjects, cellCoord, ref i_gameObjects, i_map, _phaseId, _phaseOwner);
}
public override void Visit(IList<Creature> objs)
{
CellCoord cellCoord = i_cell.GetCellCoord();
CellObjectGuids cell_guids = Global.ObjectMgr.GetCellPersonalObjectGuids(i_map.GetId(), i_map.GetDifficultyID(), _phaseId, cellCoord.GetId());
if (cell_guids != null)
LoadHelper<Creature>(cell_guids.creatures, cellCoord, ref i_creatures, i_map, _phaseId, _phaseOwner);
}
public void Load(uint phaseId)
{
_phaseId = phaseId;
i_cell.data.cell_y = 0;
for (uint x = 0; x < MapConst.MaxCells; ++x)
{
// Don't spawn at all if there's a respawn timer
if (!map.ShouldBeSpawnedOnGridLoad<T>(guid))
continue;
T obj = new();
if (!obj.LoadFromDB(guid, map, false, false))
i_cell.data.cell_x = x;
for (uint y = 0; y < MapConst.MaxCells; ++y)
{
obj.Dispose();
continue;
}
i_cell.data.cell_y = y;
AddObjectHelper(cell, ref count, map, obj);
//Load creatures and game objects
var visitor = new Visitor(this, GridMapTypeMask.AllGrid);
i_grid.VisitGrid(x, y, visitor);
}
}
}
void AddObjectHelper<T>(CellCoord cellCoord, ref uint count, Map map, T obj) where T : WorldObject
{
var cell = new Cell(cellCoord);
map.AddToGrid(obj, cell);
obj.AddToWorld();
if (obj.IsCreature())
if (obj.IsActiveObject())
map.AddToActive(obj);
++count;
}
public Cell i_cell;
public Grid i_grid;
public Map i_map;
uint i_gameObjects;
uint i_creatures;
public uint i_corpses;
uint i_areaTriggers;
}
class ObjectWorldLoader : Notifier
{
public ObjectWorldLoader(ObjectGridLoader gloader)
public ObjectWorldLoader(ObjectGridLoaderBase gloader)
{
i_cell = gloader.i_cell;
i_map = gloader.i_map;
+2 -2
View File
@@ -38,14 +38,14 @@ namespace Game.Maps
public uint PhaseGroup;
public int terrainSwapMap;
public int spawntimesecs;
public List<Difficulty> spawnDifficulties;
public List<Difficulty> SpawnDifficulties;
public uint ScriptId;
public SpawnData(SpawnObjectType t) : base(t)
{
SpawnPoint = new Position();
terrainSwapMap = -1;
spawnDifficulties = new List<Difficulty>();
SpawnDifficulties = new List<Difficulty>();
}
public static SpawnObjectType TypeFor<T>()