From c0e0efd0efb864891624d0b4e4846ee09a08f6ed Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Wed, 26 Jun 2013 20:39:17 +1200 Subject: [PATCH] movement equivalence classes These can be used as a basis for a bunch of pathing optimizations. - Feasability of movement can be precomputed for each class, avoiding the worst-case pathfinding behavior - A path could potentially be shared between all members of a class. This isnt necessarily the best path for any single unit, as it doesn't care about efficiency of movement across various terrain -- but it would be a "reasonable" path that the whole group could take together. - General pathing checks can be converted from intersection of sets of strings to a simple AND. - Other, wilder things. V2: be paranoid about too-long bit vectors. --- OpenRA.FileFormats/Exts.cs | 14 ++++++++++++++ OpenRA.Mods.RA/Move/Mobile.cs | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/OpenRA.FileFormats/Exts.cs b/OpenRA.FileFormats/Exts.cs index 9c071b73e0..af2e5d98ef 100755 --- a/OpenRA.FileFormats/Exts.cs +++ b/OpenRA.FileFormats/Exts.cs @@ -225,6 +225,20 @@ namespace OpenRA } public static Rectangle Bounds(this Bitmap b) { return new Rectangle(0, 0, b.Width, b.Height); } + + public static int ToBits(this IEnumerable bits) + { + var i = 0; + var result = 0; + foreach (var b in bits) + if (b) + result |= (1 << i++); + else + i++; + if (i > 33) + throw new InvalidOperationException("ToBits only accepts up to 32 values."); + return result; + } } public static class Enum diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index 58180da219..f380906945 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -72,6 +72,15 @@ namespace OpenRA.Mods.RA.Move return TerrainSpeeds[type].Cost; } + public int GetMovementClass(TileSet tileset) + { + /* collect our ability to cross *all* terraintypes, in a bitvector */ + var passability = tileset.Terrain.OrderBy(t => t.Key) + .Select(t => TerrainSpeeds.ContainsKey(t.Key) && TerrainSpeeds[t.Key].Cost < int.MaxValue); + + return passability.ToBits(); + } + public readonly Dictionary SubCellOffsets = new Dictionary() { {SubCell.TopLeft, new PVecInt(-7,-6)},