From 6a5869f2c683c09e7f4d0e8e7f399ab330f31e81 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 25 Jun 2010 15:52:12 +1200 Subject: [PATCH] Begin cleaning up terraintypes/movetypes --- OpenRA.Game/PathFinder.cs | 16 +++------------- OpenRA.Game/PathSearch.cs | 18 ++++++------------ OpenRA.Game/Traits/Mobile.cs | 23 +++++++++++++++++------ OpenRA.Game/Traits/TraitsInterfaces.cs | 1 + OpenRA.Mods.Cnc/MobileAir.cs | 8 ++++++++ OpenRA.Mods.RA/Aircraft.cs | 4 +++- 6 files changed, 38 insertions(+), 32 deletions(-) diff --git a/OpenRA.Game/PathFinder.cs b/OpenRA.Game/PathFinder.cs index 29ae47f370..0ba5b4a399 100644 --- a/OpenRA.Game/PathFinder.cs +++ b/OpenRA.Game/PathFinder.cs @@ -31,21 +31,11 @@ namespace OpenRA public class PathFinder { readonly World world; - float[][,] passableCost = new float[5][,]; public PathFinder( World world ) { this.world = world; var map = world.Map; - for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Fly; umt++) - passableCost[(int)umt] = new float[map.MapSize.X, map.MapSize.Y]; - for( int x = 0 ; x < map.MapSize.X ; x++ ) - for( int y = 0 ; y < map.MapSize.Y ; y++ ) - for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Fly; umt++ ) - passableCost[(int)umt][ x, y ] = (umt == UnitMovementType.Fly) ? 1f : ( world.Map.IsInMap( x, y ) ) - ? (float)Rules.TerrainTypes[world.TileSet.GetTerrainType(world.Map.MapTiles[x, y])] - .GetCost(umt) - : float.PositiveInfinity; } class CachedPath @@ -117,7 +107,7 @@ namespace OpenRA { while (!search.queue.Empty) { - var p = search.Expand( world, passableCost ); + var p = search.Expand( world ); PerfHistory.Increment("nodes_expanded", .01); if (search.heuristic(p) == 0) @@ -154,13 +144,13 @@ namespace OpenRA while (!fromSrc.queue.Empty && !fromDest.queue.Empty) { /* make some progress on the first search */ - var p = fromSrc.Expand( world, passableCost ); + var p = fromSrc.Expand( world ); if (fromDest.cellInfo[p.X, p.Y].Seen && fromDest.cellInfo[p.X, p.Y].MinCost < float.PositiveInfinity) return MakeBidiPath(fromSrc, fromDest, p); /* make some progress on the second search */ - var q = fromDest.Expand( world, passableCost ); + var q = fromDest.Expand( world ); if (fromSrc.cellInfo[q.X, q.Y].Seen && fromSrc.cellInfo[q.X, q.Y].MinCost < float.PositiveInfinity) return MakeBidiPath(fromSrc, fromDest, q); diff --git a/OpenRA.Game/PathSearch.cs b/OpenRA.Game/PathSearch.cs index 814555d5cc..bd7c8e657b 100755 --- a/OpenRA.Game/PathSearch.cs +++ b/OpenRA.Game/PathSearch.cs @@ -39,15 +39,12 @@ namespace OpenRA Actor self; public bool inReverse; - BuildingInfluence buildingInfluence; - public PathSearch(Actor self) { this.self = self; world = self.World; cellInfo = InitCellInfo(); queue = new PriorityQueue(); - buildingInfluence = world.WorldActor.traits.Get(); } public PathSearch InReverse() @@ -82,16 +79,16 @@ namespace OpenRA const float LaneBias = .5f; - public int2 Expand( World world, float[][ , ] passableCost ) + public int2 Expand( World world ) { var umt = self.traits.Get().GetMovementType(); var p = queue.Pop(); cellInfo[ p.Location.X, p.Location.Y ].Seen = true; - var thisCost = passableCost[(int)umt][p.Location.X, p.Location.Y]* - world.WorldActor.traits.WithInterface().Aggregate(1f, (a, x) => a * x.GetCost(p.Location,self)); - + var mobile = self.traits.Get(); + var thisCost = mobile.MovementCostForCell(self, p.Location); + if (thisCost == float.PositiveInfinity) return p.Location; @@ -103,14 +100,11 @@ namespace OpenRA if( cellInfo[ newHere.X, newHere.Y ].Seen ) continue; - var costHere = passableCost[(int)umt][newHere.X, newHere.Y]* - world.WorldActor.traits.WithInterface() - .Aggregate(1f, (a, x) => a * x.GetCost(newHere,self)); - + var costHere = mobile.MovementCostForCell(self, newHere); + if (costHere == float.PositiveInfinity) continue; - var mobile = self.traits.Get(); if (checkForBlocked && !mobile.CanEnterCell(newHere, ignoreBuilding, checkForBlocked)) continue; diff --git a/OpenRA.Game/Traits/Mobile.cs b/OpenRA.Game/Traits/Mobile.cs index 017e142afd..9b652d08ad 100644 --- a/OpenRA.Game/Traits/Mobile.cs +++ b/OpenRA.Game/Traits/Mobile.cs @@ -124,15 +124,15 @@ namespace OpenRA.Traits return CanEnterCell(p, null, true); } - public virtual bool CanEnterCell(int2 p, Actor ignoreActor, bool checkTransientActors) + public virtual bool CanEnterCell(int2 cell, Actor ignoreActor, bool checkTransientActors) { - if (!self.World.WorldActor.traits.Get().CanMoveHere(p, ignoreActor)) + if (!self.World.WorldActor.traits.Get().CanMoveHere(cell, ignoreActor)) return false; if (checkTransientActors) { var canShare = self.traits.Contains(); - var actors = self.World.WorldActor.traits.Get().GetUnitsAt(p).Where(a => a != self && a != ignoreActor); + var actors = self.World.WorldActor.traits.Get().GetUnitsAt(cell).Where(a => a != self && a != ignoreActor); var nonshareable = actors.Where(a => !(canShare && a.traits.Contains())); var shareable = actors.Where(a => canShare && a.traits.Contains()); @@ -146,9 +146,20 @@ namespace OpenRA.Traits return false; } - return self.World.Map.IsInMap(p.X, p.Y) && - Rules.TerrainTypes[self.World.TileSet.GetTerrainType(self.World.Map.MapTiles[p.X, p.Y])] - .GetCost(GetMovementType()) < float.PositiveInfinity; + return MovementCostForCell(self, cell) < float.PositiveInfinity; + } + + public float MovementCostForCell(Actor self, int2 cell) + { + if (!self.World.Map.IsInMap(cell.X,cell.Y)) + return float.PositiveInfinity; + + var type = self.World.TileSet.GetTerrainType(self.World.Map.MapTiles[cell.X, cell.Y]); + var umt = self.Info.Traits.Get().MovementType; + + // Todo: Cache cost for each terraintype + return (float)Rules.TerrainTypes[type].GetCost(umt)* + self.World.WorldActor.traits.WithInterface().Aggregate(1f, (a, x) => a * x.GetCost(cell,self)); } public IEnumerable GetCurrentPath(Actor self) diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index e1ee021cdb..3c44d1bc84 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -109,6 +109,7 @@ namespace OpenRA.Traits { UnitMovementType GetMovementType(); bool CanEnterCell(int2 location); + float MovementCostForCell(Actor self, int2 cell); IEnumerable GetCurrentPath(Actor self); void SetPosition(Actor self, int2 cell); } diff --git a/OpenRA.Mods.Cnc/MobileAir.cs b/OpenRA.Mods.Cnc/MobileAir.cs index dbd2e0f5dc..1c6378c139 100644 --- a/OpenRA.Mods.Cnc/MobileAir.cs +++ b/OpenRA.Mods.Cnc/MobileAir.cs @@ -61,6 +61,14 @@ namespace OpenRA.Traits return self.World.WorldActor.traits.Get().GetUnitsAt(p).Count() == 0; } + + public float MovementCostForCell(Actor self, int2 cell) + { + if (!self.World.Map.IsInMap(cell.X,cell.Y)) + return float.PositiveInfinity; + + return self.World.WorldActor.traits.WithInterface().Aggregate(1f, (a, x) => a * x.GetCost(cell,self)); + } public override IEnumerable OccupiedCells() { diff --git a/OpenRA.Mods.RA/Aircraft.cs b/OpenRA.Mods.RA/Aircraft.cs index 0f9fae58d4..e2bfa89be8 100755 --- a/OpenRA.Mods.RA/Aircraft.cs +++ b/OpenRA.Mods.RA/Aircraft.cs @@ -72,7 +72,9 @@ namespace OpenRA.Mods.RA public UnitMovementType GetMovementType() { return UnitMovementType.Fly; } public bool CanEnterCell(int2 location) { return true; } - + + public float MovementCostForCell(Actor self, int2 cell) { return 1f; } + int2[] noCells = new int2[] { }; public IEnumerable OccupiedCells() { return noCells; } }