unit influence blocks building

This commit is contained in:
Chris Forbes
2009-10-24 22:39:07 +13:00
parent 2b60a31c0c
commit 021e41a5bf
6 changed files with 91 additions and 46 deletions

View File

@@ -33,6 +33,13 @@ namespace OpenRa
return (T)inner[ typeof( T ) ]; return (T)inner[ typeof( T ) ];
} }
public T GetOrDefault<T>()
{
object o = null;
inner.TryGetValue(typeof(T), out o);
return (T)o;
}
public IEnumerable<T> WithInterface<T>() public IEnumerable<T> WithInterface<T>()
{ {
foreach( var i in inner ) foreach( var i in inner )

View File

@@ -14,7 +14,7 @@ namespace OpenRa.Game
readonly int maxDistance; /* clip limit for voronoi cells */ readonly int maxDistance; /* clip limit for voronoi cells */
static readonly Pair<Actor, float> NoClaim = Pair.New((Actor)null, float.MaxValue); static readonly Pair<Actor, float> NoClaim = Pair.New((Actor)null, float.MaxValue);
public BuildingInfluenceMap(World world, int maxDistance) public BuildingInfluenceMap(int maxDistance)
{ {
this.maxDistance = maxDistance; this.maxDistance = maxDistance;
@@ -22,9 +22,9 @@ namespace OpenRa.Game
for (int i = 0; i < 128; i++) for (int i = 0; i < 128; i++)
influence[i, j] = NoClaim; influence[i, j] = NoClaim;
world.ActorAdded += Game.world.ActorAdded +=
a => { if (a.traits.Contains<Traits.Building>()) AddInfluence(a); }; a => { if (a.traits.Contains<Traits.Building>()) AddInfluence(a); };
world.ActorRemoved += Game.world.ActorRemoved +=
a => { if (a.traits.Contains<Traits.Building>()) RemoveInfluence(a); }; a => { if (a.traits.Contains<Traits.Building>()) RemoveInfluence(a); };
} }

View File

@@ -32,20 +32,21 @@ namespace OpenRa.Game
public static Player LocalPlayer { get { return players[localPlayerIndex]; } } public static Player LocalPlayer { get { return players[localPlayerIndex]; } }
public static BuildingInfluenceMap BuildingInfluence; public static BuildingInfluenceMap BuildingInfluence;
public static UnitInfluenceMap UnitInfluence;
static ISoundEngine soundEngine; static ISoundEngine soundEngine;
public static void Initialize(string mapName, Renderer renderer, int2 clientSize, int localPlayer) public static void Initialize(string mapName, Renderer renderer, int2 clientSize, int localPlayer)
{ {
Rules.LoadRules( mapName ); Rules.LoadRules(mapName);
for( int i = 0 ; i < 8 ; i++ ) for (int i = 0; i < 8; i++)
players.Add(i, new Player(i, string.Format("Multi{0}", i), Race.Soviet)); players.Add(i, new Player(i, string.Format("Multi{0}", i), Race.Soviet));
localPlayerIndex = localPlayer; localPlayerIndex = localPlayer;
var mapFile = new IniFile( FileSystem.Open( mapName ) ); var mapFile = new IniFile(FileSystem.Open(mapName));
map = new Map( mapFile ); map = new Map(mapFile);
FileSystem.Mount(new Package(map.Theater + ".mix")); FileSystem.Mount(new Package(map.Theater + ".mix"));
viewport = new Viewport(clientSize, map.Size, renderer); viewport = new Viewport(clientSize, map.Size, renderer);
@@ -54,13 +55,14 @@ namespace OpenRa.Game
world = new World(); world = new World();
treeCache = new TreeCache(map); treeCache = new TreeCache(map);
foreach( TreeReference treeReference in map.Trees ) foreach (TreeReference treeReference in map.Trees)
world.Add( new Actor( treeReference, treeCache, map.Offset ) ); world.Add(new Actor(treeReference, treeCache, map.Offset));
BuildingInfluence = new BuildingInfluenceMap(world, 8); BuildingInfluence = new BuildingInfluenceMap(8);
UnitInfluence = new UnitInfluenceMap();
LoadMapBuildings( mapFile ); LoadMapBuildings(mapFile);
LoadMapUnits( mapFile ); LoadMapUnits(mapFile);
pathFinder = new PathFinder(map, terrain.tileSet, BuildingInfluence); pathFinder = new PathFinder(map, terrain.tileSet, BuildingInfluence);
@@ -123,6 +125,7 @@ namespace OpenRa.Game
{ {
var stuffFromOtherPlayers = network.Tick(); // todo: actually use the orders! var stuffFromOtherPlayers = network.Tick(); // todo: actually use the orders!
world.Update(); world.Update();
UnitInfluence.Tick();
viewport.DrawRegions(); viewport.DrawRegions();
} }
@@ -130,6 +133,7 @@ namespace OpenRa.Game
public static bool IsCellBuildable(int2 a, UnitMovementType umt) public static bool IsCellBuildable(int2 a, UnitMovementType umt)
{ {
if (BuildingInfluence.GetBuildingAt(a) != null) return false; if (BuildingInfluence.GetBuildingAt(a) != null) return false;
if (UnitInfluence.GetUnitAt(a) != null) return false;
a += map.Offset; a += map.Offset;

View File

@@ -149,6 +149,7 @@
<Compile Include="Graphics\Util.cs" /> <Compile Include="Graphics\Util.cs" />
<Compile Include="Graphics\Vertex.cs" /> <Compile Include="Graphics\Vertex.cs" />
<Compile Include="Graphics\Viewport.cs" /> <Compile Include="Graphics\Viewport.cs" />
<Compile Include="UnitInfluenceMap.cs" />
<Compile Include="UnitOrderGenerator.cs" /> <Compile Include="UnitOrderGenerator.cs" />
<Compile Include="VoicePool.cs" /> <Compile Include="VoicePool.cs" />
<Compile Include="World.cs" /> <Compile Include="World.cs" />

View File

@@ -63,6 +63,11 @@ namespace OpenRa.Game.Traits
currentAction.Cancel(self, this); currentAction.Cancel(self, this);
} }
public IEnumerable<int2> OccupiedCells()
{
return new[] { fromCell, toCell };
}
public interface CurrentAction public interface CurrentAction
{ {
CurrentAction NextAction { get; set; } CurrentAction NextAction { get; set; }

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OpenRa.Game
{
class UnitInfluenceMap
{
Actor[,] influence = new Actor[128, 128];
/* todo: incremental updates for great justice [and perf] */
public void Tick()
{
influence = new Actor[128, 128];
var units = Game.world.Actors
.Select( a => a.traits.GetOrDefault<Traits.Mobile>() ).Where( m => m != null );
foreach (var u in units)
foreach (var c in u.OccupiedCells())
influence[c.X, c.Y] = u.self;
}
public Actor GetUnitAt(int2 a) { return influence[a.X, a.Y]; }
}
}