diff --git a/OpenRA.Game/GameRules/TerrainCost.cs b/OpenRA.Game/GameRules/TerrainCost.cs
index 5510e66a70..716bda50e3 100644
--- a/OpenRA.Game/GameRules/TerrainCost.cs
+++ b/OpenRA.Game/GameRules/TerrainCost.cs
@@ -40,7 +40,21 @@ namespace OpenRA.GameRules
public readonly bool AcceptSmudge = true;
public TerrainCost(MiniYaml y) { FieldLoader.Load(this, y); }
-
+
+ public float GetSpeedMultiplier(UnitMovementType umt)
+ {
+ switch (umt) /* todo: make this nice */
+ {
+ case UnitMovementType.Fly: return 1;
+ case UnitMovementType.Foot: return Foot;
+ case UnitMovementType.Wheel: return Wheel;
+ case UnitMovementType.Track: return Track;
+ case UnitMovementType.Float: return Float;
+ default:
+ throw new InvalidOperationException("wtf?");
+ }
+ }
+
public float GetCost(UnitMovementType umt)
{
switch (umt) /* todo: make this nice */
diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj
index dc051a956c..c9c3d24f78 100755
--- a/OpenRA.Game/OpenRA.Game.csproj
+++ b/OpenRA.Game/OpenRA.Game.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -138,7 +138,6 @@
-
@@ -304,6 +303,7 @@
+
@@ -339,4 +339,4 @@
-->
-
+
\ No newline at end of file
diff --git a/OpenRA.Game/PathSearch.cs b/OpenRA.Game/PathSearch.cs
index 71e34afb3e..60f8f42fc0 100755
--- a/OpenRA.Game/PathSearch.cs
+++ b/OpenRA.Game/PathSearch.cs
@@ -69,12 +69,9 @@ namespace OpenRA
{
var p = queue.Pop();
cellInfo[ p.Location.X, p.Location.Y ].Seen = true;
-
- var custom2 = world.customTerrain[p.Location.X, p.Location.Y];
- var thisCost = (custom2 != null)
- ? custom2.GetCost(p.Location, umt)
- : passableCost[(int)umt][p.Location.X, p.Location.Y];
- thisCost *= resources.GetPathCost(umt, p.Location);
+
+ var thisCost = passableCost[(int)umt][p.Location.X, p.Location.Y]*
+ world.WorldActor.traits.WithInterface().Aggregate(1f, (a, x) => a * x.GetCost(p.Location,umt));
if (thisCost == float.PositiveInfinity)
return p.Location;
@@ -87,9 +84,9 @@ namespace OpenRA
if( cellInfo[ newHere.X, newHere.Y ].Seen )
continue;
- var custom = world.customTerrain[newHere.X, newHere.Y];
- var costHere = (custom != null) ? custom.GetCost(newHere, umt) : passableCost[(int)umt][newHere.X, newHere.Y];
- costHere *= resources.GetPathCost(umt, newHere);
+ var costHere = passableCost[(int)umt][newHere.X, newHere.Y]*
+ world.WorldActor.traits.WithInterface().Aggregate(1f, (a, x) => a * x.GetCost(p.Location,umt));
+
if (costHere == float.PositiveInfinity)
continue;
diff --git a/OpenRA.Game/Traits/Bridge.cs b/OpenRA.Game/Traits/Bridge.cs
index b5c70cf3a4..a1f4039bd9 100644
--- a/OpenRA.Game/Traits/Bridge.cs
+++ b/OpenRA.Game/Traits/Bridge.cs
@@ -36,14 +36,13 @@ namespace OpenRA.Traits
public object Create(Actor self) { return new Bridge(self); }
}
- class Bridge: IRender, ICustomTerrain, INotifyDamage
+ class Bridge: IRender, INotifyDamage
{
Dictionary Tiles;
List> TileSprites = new List>();
List Templates = new List();
Actor self;
int state;
-
Bridge northNeighbour, southNeighbour;
public Bridge(Actor self) { this.self = self; self.RemoveOnDeath = false; }
@@ -57,6 +56,25 @@ namespace OpenRA.Traits
yield return new Renderable(t.Value, Game.CellSize * t.Key, "terrain");
}
+ public void FinalizeBridges(World world, Bridge[,] bridges)
+ {
+ // go looking for our neighbors, if this is a long bridge.
+ var info = self.Info.Traits.Get();
+ if (info.NorthOffset != null)
+ northNeighbour = GetNeighbor(world, info.NorthOffset, bridges);
+ if (info.SouthOffset != null)
+ southNeighbour = GetNeighbor(world, info.SouthOffset, bridges);
+ }
+
+ public Bridge GetNeighbor(World world, int[] offset, Bridge[,] bridges)
+ {
+ if (offset == null) return null;
+ var pos = self.Location + new int2(offset[0], offset[1]);
+ if (!world.Map.IsInMap(pos.X, pos.Y)) return null;
+ return bridges[pos.X, pos.Y];
+ }
+
+
public int StateFromTemplate(TileTemplate t)
{
var info = self.Info.Traits.Get();
@@ -83,10 +101,7 @@ namespace OpenRA.Traits
{
Tiles = replacedTiles;
state = StateFromTemplate(template);
-
- foreach (var t in replacedTiles.Keys)
- world.customTerrain[t.X, t.Y] = this;
-
+
if (cachedTileset != world.Map.Tileset)
{
cachedTileset = world.Map.Tileset;
@@ -109,24 +124,6 @@ namespace OpenRA.Traits
self.Health = (int)(self.GetMaxHP() * template.HP);
}
- Bridge GetNeighbor(World world, int[] offset)
- {
- if (offset == null) return null;
- var pos = self.Location + new int2(offset[0], offset[1]);
- if (!world.Map.IsInMap(pos.X, pos.Y)) return null;
- return world.customTerrain[pos.X, pos.Y] as Bridge;
- }
-
- public void FinalizeBridges(World world)
- {
- // go looking for our neighbors, if this is a long bridge.
- var info = self.Info.Traits.Get();
- if (info.NorthOffset != null)
- northNeighbour = GetNeighbor(world, info.NorthOffset);
- if (info.SouthOffset != null)
- southNeighbour = GetNeighbor(world, info.SouthOffset);
- }
-
public float GetCost(int2 p, UnitMovementType umt)
{
return Rules.TerrainTypes[Templates[state].TerrainType[Tiles[p]]].GetCost(umt);
diff --git a/OpenRA.Game/Traits/World/BridgeLoadHook.cs b/OpenRA.Game/Traits/World/BridgeLayer.cs
similarity index 75%
rename from OpenRA.Game/Traits/World/BridgeLoadHook.cs
rename to OpenRA.Game/Traits/World/BridgeLayer.cs
index 79fdda80e7..78ccb6a418 100644
--- a/OpenRA.Game/Traits/World/BridgeLoadHook.cs
+++ b/OpenRA.Game/Traits/World/BridgeLayer.cs
@@ -20,14 +20,18 @@
using System.Collections.Generic;
using System.Linq;
+using OpenRA.GameRules;
namespace OpenRA.Traits
{
- class BridgeLoadHookInfo : TraitInfo { }
+ class BridgeLayerInfo : TraitInfo { }
- class BridgeLoadHook : ILoadWorldHook
+ class BridgeLayer : ILoadWorldHook, ICustomTerrain
{
- static void MakeBridges(World w)
+ // for tricky things like bridges.
+ Bridge[,] customTerrain;
+
+ void MakeBridges(World w)
{
var tl = w.Map.TopLeft;
var br = w.Map.BottomRight;
@@ -38,10 +42,10 @@ namespace OpenRA.Traits
ConvertBridgeToActor(w, i, j);
foreach (var b in w.Actors.SelectMany(a => a.traits.WithInterface()))
- b.FinalizeBridges(w);
+ b.FinalizeBridges(w, customTerrain);
}
- static void ConvertBridgeToActor(World w, int i, int j)
+ void ConvertBridgeToActor(World w, int i, int j)
{
Log.Write("Converting bridge at {0} {1}",i,j);
@@ -77,15 +81,30 @@ namespace OpenRA.Traits
{
var a = w.CreateActor(template.Bridge, new int2(ni, nj), w.NeutralPlayer);
var br = a.traits.Get();
+
+ foreach (var t in replacedTiles.Keys)
+ customTerrain[t.X, t.Y] = br;
+
br.SetTiles(w, template, replacedTiles);
}
}
+
+ public float GetCost(int2 p, UnitMovementType umt)
+ {
+ if (customTerrain[p.X, p.Y] != null)
+ return customTerrain[p.X,p.Y].GetCost(p,umt);
+ return 1f;
+ }
static bool IsBridge(World w, ushort t)
{
return w.TileSet.walk[t].Bridge != null;
}
- public void WorldLoaded(World w) { MakeBridges(w); }
+ public void WorldLoaded(World w)
+ {
+ customTerrain = new Bridge[w.Map.MapSize.X, w.Map.MapSize.Y];
+ MakeBridges(w);
+ }
}
}
diff --git a/OpenRA.Game/Traits/World/ResourceLayer.cs b/OpenRA.Game/Traits/World/ResourceLayer.cs
index 50c8cd8c0a..3c1ef7faf3 100644
--- a/OpenRA.Game/Traits/World/ResourceLayer.cs
+++ b/OpenRA.Game/Traits/World/ResourceLayer.cs
@@ -30,7 +30,7 @@ namespace OpenRA.Traits
public object Create(Actor self) { return new ResourceLayer(self); }
}
- public class ResourceLayer: IRenderOverlay, ILoadWorldHook
+ public class ResourceLayer: IRenderOverlay, ILoadWorldHook, ICustomTerrain
{
SpriteRenderer sr;
World world;
@@ -88,18 +88,18 @@ namespace OpenRA.Traits
content[x, y].density = GetIdealDensity(x, y);
}
- public float GetMovementCost(UnitMovementType umt, int2 p)
+ public float GetSpeedMultiplier(UnitMovementType umt, int2 p)
{
if (content[p.X,p.Y].type == null)
return 1.0f;
- return content[p.X,p.Y].type.GetMovementCost(umt);
+ return content[p.X,p.Y].type.GetSpeedMultiplier(umt);
}
- public float GetPathCost(UnitMovementType umt, int2 p)
+ public float GetCost(int2 p,UnitMovementType umt)
{
if (content[p.X,p.Y].type == null)
return 1.0f;
- return content[p.X,p.Y].type.GetPathCost(umt);
+ return content[p.X,p.Y].type.GetCost(umt);
}
public Sprite[] ChooseContent(ResourceType t)
diff --git a/OpenRA.Game/Traits/World/ResourceType.cs b/OpenRA.Game/Traits/World/ResourceType.cs
index f354b8976d..42e9cbb4ff 100644
--- a/OpenRA.Game/Traits/World/ResourceType.cs
+++ b/OpenRA.Game/Traits/World/ResourceType.cs
@@ -48,7 +48,7 @@ namespace OpenRA.Traits
int growthTicks;
int spreadTicks;
public ResourceTypeInfo info;
- float[] movementCost = new float[4];
+ float[] movementSpeed = new float[4];
float[] pathCost = new float[4];
public ResourceType(ResourceTypeInfo info)
@@ -56,19 +56,20 @@ namespace OpenRA.Traits
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++ )
{
// HACK: hardcode "ore" terraintype for now
- movementCost[(int)umt] = (info.MovementTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetCost(umt) : 1.0f;
- pathCost[(int)umt] = (info.PathingTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetCost(umt) : movementCost[(int)umt];
+ movementSpeed[(int)umt] = (info.MovementTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetSpeedMultiplier(umt) : 1.0f;
+ pathCost[(int)umt] = (info.PathingTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetCost(umt)
+ : (info.MovementTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetCost(umt) : 1.0f;
}
this.info = info;
}
- public float GetMovementCost(UnitMovementType umt)
+ public float GetSpeedMultiplier(UnitMovementType umt)
{
- return movementCost[(int)umt];
+ return movementSpeed[(int)umt];
}
- public float GetPathCost(UnitMovementType umt)
+ public float GetCost(UnitMovementType umt)
{
return pathCost[(int)umt];
}
diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs
index d3e6768c5d..2660e86847 100644
--- a/OpenRA.Game/World.cs
+++ b/OpenRA.Game/World.cs
@@ -70,9 +70,6 @@ namespace OpenRA
public readonly TileSet TileSet;
public GlobalDefaultsInfo Defaults { get {return WorldActor.Info.Traits.Get();}}
- // for tricky things like bridges.
- public readonly ICustomTerrain[,] customTerrain;
-
public readonly WorldRenderer WorldRenderer;
internal readonly Minimap Minimap;
@@ -80,9 +77,6 @@ namespace OpenRA
{
Timer.Time( "----World.ctor" );
Map = map;
-
- customTerrain = new ICustomTerrain[Map.MapSize.X, Map.MapSize.Y];
- Timer.Time( "new Map: {0}" );
Rules.LoadRules(manifest,Map);
Timer.Time( "load rules: {0}" );
diff --git a/mods/cnc/system.yaml b/mods/cnc/system.yaml
index 2b54aa2423..c0cc1b6b6a 100644
--- a/mods/cnc/system.yaml
+++ b/mods/cnc/system.yaml
@@ -203,6 +203,7 @@ World:
ResourceLayer:
ResourceType@green-tib:
ResourceType: 1
+ MovementTerrainType: Tiberium
Palette: terrain
SpriteNames: ti1,ti2,ti3,ti4,ti5,ti6,ti7,ti8,ti9,ti10,ti11,ti12
ValuePerUnit: 30
diff --git a/mods/ra/system.yaml b/mods/ra/system.yaml
index a89d718433..d9e49ff51c 100644
--- a/mods/ra/system.yaml
+++ b/mods/ra/system.yaml
@@ -90,7 +90,7 @@ World:
BuildingInfluence:
UnitInfluence:
ChoosePaletteOnSelect:
- BridgeLoadHook:
+ BridgeLayer:
CrateSpawner:
Minimum: 1
Maximum: 3