From 9d4d4bb9247085a427814983cad0954288f92871 Mon Sep 17 00:00:00 2001 From: Vapre Date: Fri, 10 Sep 2021 00:49:44 +0200 Subject: [PATCH] Locomotor, PathGraph, trivial optimizations. --- OpenRA.Mods.Common/Traits/World/ActorMap.cs | 77 ++++++++++++++------ OpenRA.Mods.Common/Traits/World/Locomotor.cs | 6 +- 2 files changed, 57 insertions(+), 26 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/World/ActorMap.cs b/OpenRA.Mods.Common/Traits/World/ActorMap.cs index 60261b7fb3..ea1b9c6973 100644 --- a/OpenRA.Mods.Common/Traits/World/ActorMap.cs +++ b/OpenRA.Mods.Common/Traits/World/ActorMap.cs @@ -272,9 +272,10 @@ namespace OpenRA.Mods.Common.Traits if (!influence.Contains(uv)) yield break; + var always = sub == SubCell.FullCell || sub == SubCell.Any; var layer = a.Layer == 0 ? influence : customInfluence[a.Layer]; for (var i = layer[uv]; i != null; i = i.Next) - if (!i.Actor.Disposed && (i.SubCell == sub || i.SubCell == SubCell.FullCell || sub == SubCell.FullCell || sub == SubCell.Any)) + if (!i.Actor.Disposed && (i.SubCell == sub || i.SubCell == SubCell.FullCell || always)) yield return i.Actor; } @@ -285,14 +286,18 @@ namespace OpenRA.Mods.Common.Traits public SubCell FreeSubCell(CPos cell, SubCell preferredSubCell = SubCell.Any, bool checkTransient = true) { - if (preferredSubCell != SubCell.Any && !AnyActorsAt(cell, preferredSubCell, checkTransient)) + var uv = cell.ToMPos(map); + if (!influence.Contains(uv)) + return preferredSubCell != SubCell.Any ? preferredSubCell : SubCell.First; + + if (preferredSubCell != SubCell.Any && !AnyActorsAt(uv, cell, preferredSubCell, checkTransient)) return preferredSubCell; - if (!AnyActorsAt(cell)) + if (!AnyActorsAt(uv, cell.Layer)) return map.Grid.DefaultSubCell; for (var i = (int)SubCell.First; i < map.Grid.SubCellOffsets.Length; i++) - if (i != (int)preferredSubCell && !AnyActorsAt(cell, (SubCell)i, checkTransient)) + if (i != (int)preferredSubCell && !AnyActorsAt(uv, cell, (SubCell)i, checkTransient)) return (SubCell)i; return SubCell.Invalid; @@ -300,18 +305,30 @@ namespace OpenRA.Mods.Common.Traits public SubCell FreeSubCell(CPos cell, SubCell preferredSubCell, Func checkIfBlocker) { - if (preferredSubCell != SubCell.Any && !AnyActorsAt(cell, preferredSubCell, checkIfBlocker)) + var uv = cell.ToMPos(map); + if (!influence.Contains(uv)) + return preferredSubCell != SubCell.Any ? preferredSubCell : SubCell.First; + + if (preferredSubCell != SubCell.Any && !AnyActorsAt(uv, cell, preferredSubCell, checkIfBlocker)) return preferredSubCell; - if (!AnyActorsAt(cell)) + if (!AnyActorsAt(uv, cell.Layer)) return map.Grid.DefaultSubCell; for (var i = (byte)SubCell.First; i < map.Grid.SubCellOffsets.Length; i++) - if (i != (byte)preferredSubCell && !AnyActorsAt(cell, (SubCell)i, checkIfBlocker)) + if (i != (byte)preferredSubCell && !AnyActorsAt(uv, cell, (SubCell)i, checkIfBlocker)) return (SubCell)i; + return SubCell.Invalid; } + // NOTE: pos required to be in map bounds + bool AnyActorsAt(MPos uv, int layerIndex) + { + var layer = layerIndex == 0 ? influence : customInfluence[layerIndex]; + return layer[uv] != null; + } + // NOTE: always includes transients with influence public bool AnyActorsAt(CPos a) { @@ -319,17 +336,12 @@ namespace OpenRA.Mods.Common.Traits if (!influence.Contains(uv)) return false; - var layer = a.Layer == 0 ? influence : customInfluence[a.Layer]; - return layer[uv] != null; + return AnyActorsAt(uv, a.Layer); } - // NOTE: can not check aircraft - public bool AnyActorsAt(CPos a, SubCell sub, bool checkTransient = true) + // NOTE: pos required to be in map bounds + bool AnyActorsAt(MPos uv, CPos a, SubCell sub, bool checkTransient) { - var uv = a.ToMPos(map); - if (!influence.Contains(uv)) - return false; - var always = sub == SubCell.FullCell || sub == SubCell.Any; var layer = a.Layer == 0 ? influence : customInfluence[a.Layer]; for (var i = layer[uv]; i != null; i = i.Next) @@ -349,12 +361,18 @@ namespace OpenRA.Mods.Common.Traits } // NOTE: can not check aircraft - public bool AnyActorsAt(CPos a, SubCell sub, Func withCondition) + public bool AnyActorsAt(CPos a, SubCell sub, bool checkTransient = true) { var uv = a.ToMPos(map); if (!influence.Contains(uv)) return false; + return AnyActorsAt(uv, a, sub, checkTransient); + } + + // NOTE: can not check aircraft + bool AnyActorsAt(MPos uv, CPos a, SubCell sub, Func withCondition) + { var always = sub == SubCell.FullCell || sub == SubCell.Any; var layer = a.Layer == 0 ? influence : customInfluence[a.Layer]; for (var i = layer[uv]; i != null; i = i.Next) @@ -364,6 +382,16 @@ namespace OpenRA.Mods.Common.Traits return false; } + // NOTE: can not check aircraft + public bool AnyActorsAt(CPos a, SubCell sub, Func withCondition) + { + var uv = a.ToMPos(map); + if (!influence.Contains(uv)) + return false; + + return AnyActorsAt(uv, a, sub, withCondition); + } + public void AddInfluence(Actor self, IOccupySpace ios) { foreach (var c in ios.OccupiedCells()) @@ -428,15 +456,18 @@ namespace OpenRA.Mods.Common.Traits { // Position updates are done in one pass // to ensure consistency during a tick - foreach (var bin in bins) + if (removeActorPosition.Count > 0) { - var removed = bin.Actors.RemoveAll(actorShouldBeRemoved); - if (removed > 0) - foreach (var t in bin.ProximityTriggers) - t.Dirty = true; - } + foreach (var bin in bins) + { + var removed = bin.Actors.RemoveAll(actorShouldBeRemoved); + if (removed > 0) + foreach (var t in bin.ProximityTriggers) + t.Dirty = true; + } - removeActorPosition.Clear(); + removeActorPosition.Clear(); + } foreach (var a in addActorPosition) { diff --git a/OpenRA.Mods.Common/Traits/World/Locomotor.cs b/OpenRA.Mods.Common/Traits/World/Locomotor.cs index 0f177d3ce1..8fb5844e48 100644 --- a/OpenRA.Mods.Common/Traits/World/Locomotor.cs +++ b/OpenRA.Mods.Common/Traits/World/Locomotor.cs @@ -209,13 +209,13 @@ namespace OpenRA.Mods.Common.Traits public bool CanMoveFreelyInto(Actor actor, CPos cell, SubCell subCell, BlockedByActor check, Actor ignoreActor) { - var cellCache = GetCache(cell); - var cellFlag = cellCache.CellFlag; - // If the check allows: We are not blocked by transient actors. if (check == BlockedByActor.None) return true; + var cellCache = GetCache(cell); + var cellFlag = cellCache.CellFlag; + // No actor in the cell or free SubCell. if (cellFlag == CellFlag.HasFreeSpace) return true;