#W# Confict: Fixed BaseCreature git merge conflict.
This commit is contained in:
commit
ad38314ca7
112 changed files with 5397 additions and 616 deletions
|
|
@ -85,6 +85,9 @@ public partial class Map
|
|||
private Rectangle2D _bounds;
|
||||
|
||||
private int _sectorStartX;
|
||||
private int _sectorStartY;
|
||||
private int _sectorEndX;
|
||||
private int _sectorEndY;
|
||||
private int _maxRing;
|
||||
|
||||
private int _ring; // -1 = uninitialized, then 0.._maxRing
|
||||
|
|
@ -115,11 +118,11 @@ public partial class Map
|
|||
var centerSectorX = center.m_X / SectorSize;
|
||||
var centerSectorY = center.m_Y / SectorSize;
|
||||
|
||||
map.CalculateSectors(_bounds, out _sectorStartX, out var sectorStartY, out var sectorEndX, out var sectorEndY);
|
||||
map.CalculateSectors(_bounds, out _sectorStartX, out _sectorStartY, out _sectorEndX, out _sectorEndY);
|
||||
|
||||
// Calculate max ring based on bounds
|
||||
var dx = Math.Max(centerSectorX - _sectorStartX, sectorEndX - centerSectorX);
|
||||
var dy = Math.Max(centerSectorY - sectorStartY, sectorEndY - centerSectorY);
|
||||
var dx = Math.Max(centerSectorX - _sectorStartX, _sectorEndX - centerSectorX);
|
||||
var dy = Math.Max(centerSectorY - _sectorStartY, _sectorEndY - centerSectorY);
|
||||
_maxRing = Math.Max(dx, dy);
|
||||
}
|
||||
|
||||
|
|
@ -202,7 +205,7 @@ public partial class Map
|
|||
_ringIndex = 0;
|
||||
sx = _center.m_X / SectorSize;
|
||||
sy = _center.m_Y / SectorSize;
|
||||
return sx >= _sectorStartX;
|
||||
return IsSectorInBounds(sx, sy);
|
||||
}
|
||||
|
||||
sx = sy = 0;
|
||||
|
|
@ -225,7 +228,7 @@ public partial class Map
|
|||
_ringIndex = nextIndex;
|
||||
CalculatePositionFromIndex(nextIndex, out sx, out sy);
|
||||
|
||||
if (sx >= _sectorStartX)
|
||||
if (IsSectorInBounds(sx, sy))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -233,6 +236,11 @@ public partial class Map
|
|||
}
|
||||
|
||||
|
||||
// Ring cells outside the clamped sector range would resolve to the shared invalid sector, once per cell
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private bool IsSectorInBounds(int sx, int sy) =>
|
||||
sx >= _sectorStartX && sx <= _sectorEndX && sy >= _sectorStartY && sy <= _sectorEndY;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void CalculatePositionFromIndex(int index, out int x, out int y)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -113,6 +113,9 @@ public partial class Map
|
|||
private Rectangle2D _bounds;
|
||||
|
||||
private int _sectorStartX;
|
||||
private int _sectorStartY;
|
||||
private int _sectorEndX;
|
||||
private int _sectorEndY;
|
||||
private int _maxRing;
|
||||
|
||||
private int _ring; // -1 = uninitialized, then 0.._maxRing
|
||||
|
|
@ -143,11 +146,11 @@ public partial class Map
|
|||
var centerSectorX = center.m_X / SectorSize;
|
||||
var centerSectorY = center.m_Y / SectorSize;
|
||||
|
||||
map.CalculateSectors(_bounds, out _sectorStartX, out var sectorStartY, out var sectorEndX, out var sectorEndY);
|
||||
map.CalculateSectors(_bounds, out _sectorStartX, out _sectorStartY, out _sectorEndX, out _sectorEndY);
|
||||
|
||||
// Calculate max ring based on bounds
|
||||
var dx = Math.Max(centerSectorX - _sectorStartX, sectorEndX - centerSectorX);
|
||||
var dy = Math.Max(centerSectorY - sectorStartY, sectorEndY - centerSectorY);
|
||||
var dx = Math.Max(centerSectorX - _sectorStartX, _sectorEndX - centerSectorX);
|
||||
var dy = Math.Max(centerSectorY - _sectorStartY, _sectorEndY - centerSectorY);
|
||||
_maxRing = Math.Max(dx, dy);
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +231,7 @@ public partial class Map
|
|||
_ringIndex = 0;
|
||||
sx = _center.m_X / SectorSize;
|
||||
sy = _center.m_Y / SectorSize;
|
||||
return sx >= _sectorStartX;
|
||||
return IsSectorInBounds(sx, sy);
|
||||
}
|
||||
|
||||
sx = sy = 0;
|
||||
|
|
@ -251,7 +254,7 @@ public partial class Map
|
|||
_ringIndex = nextIndex;
|
||||
CalculatePositionFromIndex(nextIndex, out sx, out sy);
|
||||
|
||||
if (sx >= _sectorStartX)
|
||||
if (IsSectorInBounds(sx, sy))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -259,6 +262,11 @@ public partial class Map
|
|||
}
|
||||
|
||||
|
||||
// Ring cells outside the clamped sector range would resolve to the shared invalid sector, once per cell
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private bool IsSectorInBounds(int sx, int sy) =>
|
||||
sx >= _sectorStartX && sx <= _sectorEndX && sy >= _sectorStartY && sy <= _sectorEndY;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void CalculatePositionFromIndex(int index, out int x, out int y)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -108,6 +108,9 @@ public partial class Map
|
|||
private Rectangle2D _bounds;
|
||||
|
||||
private int _sectorStartX;
|
||||
private int _sectorStartY;
|
||||
private int _sectorEndX;
|
||||
private int _sectorEndY;
|
||||
private int _maxRing;
|
||||
|
||||
private int _ring; // -1 = uninitialized, then 0.._maxRing
|
||||
|
|
@ -138,11 +141,11 @@ public partial class Map
|
|||
var centerSectorX = center.m_X / SectorSize;
|
||||
var centerSectorY = center.m_Y / SectorSize;
|
||||
|
||||
map.CalculateSectors(_bounds, out _sectorStartX, out var sectorStartY, out var sectorEndX, out var sectorEndY);
|
||||
map.CalculateSectors(_bounds, out _sectorStartX, out _sectorStartY, out _sectorEndX, out _sectorEndY);
|
||||
|
||||
// Calculate max ring based on bounds
|
||||
var dx = Math.Max(centerSectorX - _sectorStartX, sectorEndX - centerSectorX);
|
||||
var dy = Math.Max(centerSectorY - sectorStartY, sectorEndY - centerSectorY);
|
||||
var dx = Math.Max(centerSectorX - _sectorStartX, _sectorEndX - centerSectorX);
|
||||
var dy = Math.Max(centerSectorY - _sectorStartY, _sectorEndY - centerSectorY);
|
||||
_maxRing = Math.Max(dx, dy);
|
||||
}
|
||||
|
||||
|
|
@ -223,7 +226,7 @@ public partial class Map
|
|||
_ringIndex = 0;
|
||||
sx = _center.m_X / SectorSize;
|
||||
sy = _center.m_Y / SectorSize;
|
||||
return sx >= _sectorStartX;
|
||||
return IsSectorInBounds(sx, sy);
|
||||
}
|
||||
|
||||
sx = sy = 0;
|
||||
|
|
@ -246,7 +249,7 @@ public partial class Map
|
|||
_ringIndex = nextIndex;
|
||||
CalculatePositionFromIndex(nextIndex, out sx, out sy);
|
||||
|
||||
if (sx >= _sectorStartX)
|
||||
if (IsSectorInBounds(sx, sy))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -254,6 +257,11 @@ public partial class Map
|
|||
}
|
||||
|
||||
|
||||
// Ring cells outside the clamped sector range would resolve to the shared invalid sector, once per cell
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private bool IsSectorInBounds(int sx, int sy) =>
|
||||
sx >= _sectorStartX && sx <= _sectorEndX && sy >= _sectorStartY && sy <= _sectorEndY;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void CalculatePositionFromIndex(int index, out int x, out int y)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -85,8 +85,6 @@ public partial class Map
|
|||
public MultiBoundsEnumerable<T> GetMultisInBounds<T>(Rectangle2D bounds, bool makeBoundsInclusive = false) where T : BaseMulti =>
|
||||
new(this, bounds, makeBoundsInclusive);
|
||||
|
||||
private static readonly HashSet<Serial> _sharedDupes = [];
|
||||
|
||||
public ref struct MultiSectorEnumerable<T>(Map map, Point2D loc) where T : BaseMulti
|
||||
{
|
||||
public static MultiSectorEnumerable<T> Empty
|
||||
|
|
@ -193,13 +191,11 @@ public partial class Map
|
|||
private int _currentVersion;
|
||||
private Sector _currentSector;
|
||||
private T _current;
|
||||
|
||||
private HashSet<Serial> _unanchoredSeen;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public MultiBoundsEnumerator(Map map, Rectangle2D bounds, bool makeBoundsInclusive)
|
||||
{
|
||||
_sharedDupes.Clear();
|
||||
|
||||
_map = map;
|
||||
_bounds = bounds;
|
||||
|
||||
|
|
@ -255,14 +251,10 @@ public partial class Map
|
|||
while (++_currentIndex < _currentList.Length)
|
||||
{
|
||||
var item = _currentList[_currentIndex];
|
||||
if (item is T { Deleted: false } o && bounds.Contains(o.Location))
|
||||
if (item is T { Deleted: false } o && bounds.Contains(o.Location) && ShouldYieldFromCurrentSector(map, o))
|
||||
{
|
||||
// Multis can span multiple sectors, so we need to deduplicate
|
||||
if (_sharedDupes.Add(o.Serial))
|
||||
{
|
||||
_current = o;
|
||||
return true;
|
||||
}
|
||||
_current = o;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -290,6 +282,27 @@ public partial class Map
|
|||
}
|
||||
}
|
||||
|
||||
// A multi is listed in every sector it spans, but its location is in exactly one sector, which the bounds
|
||||
// filter guarantees is visited. Yield it from that sector only. A multi missing from its location's sector
|
||||
// (components changed after it was placed) falls back to a per-enumerator set, so nested queries stay independent.
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private bool ShouldYieldFromCurrentSector(Map map, T multi)
|
||||
{
|
||||
var home = map.GetSector(map.Bound(multi.Location));
|
||||
|
||||
if (home == _currentSector)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (home.Multis.Contains(multi))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (_unanchoredSeen ??= []).Add(multi.Serial);
|
||||
}
|
||||
|
||||
public T Current
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
|
|
|
|||
|
|
@ -99,7 +99,12 @@ public partial class Map
|
|||
{
|
||||
_tiles = multi.Components.Tiles[offsetX][offsetY];
|
||||
_index = -1;
|
||||
return SetTile();
|
||||
|
||||
// A multi can have no tile at this cell; later multis in the sector still may
|
||||
if (SetTile())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue