Fix ICustomTerrain to also work for resources
This commit is contained in:
@@ -40,7 +40,21 @@ namespace OpenRA.GameRules
|
|||||||
public readonly bool AcceptSmudge = true;
|
public readonly bool AcceptSmudge = true;
|
||||||
|
|
||||||
public TerrainCost(MiniYaml y) { FieldLoader.Load(this, y); }
|
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)
|
public float GetCost(UnitMovementType umt)
|
||||||
{
|
{
|
||||||
switch (umt) /* todo: make this nice */
|
switch (umt) /* todo: make this nice */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
@@ -138,7 +138,6 @@
|
|||||||
<Compile Include="Traits\CustomSellValue.cs" />
|
<Compile Include="Traits\CustomSellValue.cs" />
|
||||||
<Compile Include="Traits\World\SpatialBins.cs" />
|
<Compile Include="Traits\World\SpatialBins.cs" />
|
||||||
<Compile Include="Traits\World\SpawnDefaultUnits.cs" />
|
<Compile Include="Traits\World\SpawnDefaultUnits.cs" />
|
||||||
<Compile Include="Traits\World\BridgeLoadHook.cs" />
|
|
||||||
<Compile Include="Traits\World\ChoosePaletteOnSelect.cs" />
|
<Compile Include="Traits\World\ChoosePaletteOnSelect.cs" />
|
||||||
<Compile Include="Traits\World\Country.cs" />
|
<Compile Include="Traits\World\Country.cs" />
|
||||||
<Compile Include="Traits\World\CrateSpawner.cs" />
|
<Compile Include="Traits\World\CrateSpawner.cs" />
|
||||||
@@ -304,6 +303,7 @@
|
|||||||
<Compile Include="Widgets\PerfGraphWidget.cs" />
|
<Compile Include="Widgets\PerfGraphWidget.cs" />
|
||||||
<Compile Include="Widgets\Delegates\PerfDebugDelegate.cs" />
|
<Compile Include="Widgets\Delegates\PerfDebugDelegate.cs" />
|
||||||
<Compile Include="Widgets\BuildPaletteWidget.cs" />
|
<Compile Include="Widgets\BuildPaletteWidget.cs" />
|
||||||
|
<Compile Include="Traits\World\BridgeLayer.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
||||||
@@ -339,4 +339,4 @@
|
|||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
||||||
@@ -69,12 +69,9 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
var p = queue.Pop();
|
var p = queue.Pop();
|
||||||
cellInfo[ p.Location.X, p.Location.Y ].Seen = true;
|
cellInfo[ p.Location.X, p.Location.Y ].Seen = true;
|
||||||
|
|
||||||
var custom2 = world.customTerrain[p.Location.X, p.Location.Y];
|
var thisCost = passableCost[(int)umt][p.Location.X, p.Location.Y]*
|
||||||
var thisCost = (custom2 != null)
|
world.WorldActor.traits.WithInterface<ICustomTerrain>().Aggregate(1f, (a, x) => a * x.GetCost(p.Location,umt));
|
||||||
? custom2.GetCost(p.Location, umt)
|
|
||||||
: passableCost[(int)umt][p.Location.X, p.Location.Y];
|
|
||||||
thisCost *= resources.GetPathCost(umt, p.Location);
|
|
||||||
|
|
||||||
if (thisCost == float.PositiveInfinity)
|
if (thisCost == float.PositiveInfinity)
|
||||||
return p.Location;
|
return p.Location;
|
||||||
@@ -87,9 +84,9 @@ namespace OpenRA
|
|||||||
if( cellInfo[ newHere.X, newHere.Y ].Seen )
|
if( cellInfo[ newHere.X, newHere.Y ].Seen )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var custom = world.customTerrain[newHere.X, newHere.Y];
|
var costHere = passableCost[(int)umt][newHere.X, newHere.Y]*
|
||||||
var costHere = (custom != null) ? custom.GetCost(newHere, umt) : passableCost[(int)umt][newHere.X, newHere.Y];
|
world.WorldActor.traits.WithInterface<ICustomTerrain>().Aggregate(1f, (a, x) => a * x.GetCost(p.Location,umt));
|
||||||
costHere *= resources.GetPathCost(umt, newHere);
|
|
||||||
if (costHere == float.PositiveInfinity)
|
if (costHere == float.PositiveInfinity)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -36,14 +36,13 @@ namespace OpenRA.Traits
|
|||||||
public object Create(Actor self) { return new Bridge(self); }
|
public object Create(Actor self) { return new Bridge(self); }
|
||||||
}
|
}
|
||||||
|
|
||||||
class Bridge: IRender, ICustomTerrain, INotifyDamage
|
class Bridge: IRender, INotifyDamage
|
||||||
{
|
{
|
||||||
Dictionary<int2, int> Tiles;
|
Dictionary<int2, int> Tiles;
|
||||||
List<Dictionary<int2, Sprite>> TileSprites = new List<Dictionary<int2,Sprite>>();
|
List<Dictionary<int2, Sprite>> TileSprites = new List<Dictionary<int2,Sprite>>();
|
||||||
List<TileTemplate> Templates = new List<TileTemplate>();
|
List<TileTemplate> Templates = new List<TileTemplate>();
|
||||||
Actor self;
|
Actor self;
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
Bridge northNeighbour, southNeighbour;
|
Bridge northNeighbour, southNeighbour;
|
||||||
|
|
||||||
public Bridge(Actor self) { this.self = self; self.RemoveOnDeath = false; }
|
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");
|
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<BridgeInfo>();
|
||||||
|
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)
|
public int StateFromTemplate(TileTemplate t)
|
||||||
{
|
{
|
||||||
var info = self.Info.Traits.Get<BridgeInfo>();
|
var info = self.Info.Traits.Get<BridgeInfo>();
|
||||||
@@ -83,10 +101,7 @@ namespace OpenRA.Traits
|
|||||||
{
|
{
|
||||||
Tiles = replacedTiles;
|
Tiles = replacedTiles;
|
||||||
state = StateFromTemplate(template);
|
state = StateFromTemplate(template);
|
||||||
|
|
||||||
foreach (var t in replacedTiles.Keys)
|
|
||||||
world.customTerrain[t.X, t.Y] = this;
|
|
||||||
|
|
||||||
if (cachedTileset != world.Map.Tileset)
|
if (cachedTileset != world.Map.Tileset)
|
||||||
{
|
{
|
||||||
cachedTileset = world.Map.Tileset;
|
cachedTileset = world.Map.Tileset;
|
||||||
@@ -109,24 +124,6 @@ namespace OpenRA.Traits
|
|||||||
self.Health = (int)(self.GetMaxHP() * template.HP);
|
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<BridgeInfo>();
|
|
||||||
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)
|
public float GetCost(int2 p, UnitMovementType umt)
|
||||||
{
|
{
|
||||||
return Rules.TerrainTypes[Templates[state].TerrainType[Tiles[p]]].GetCost(umt);
|
return Rules.TerrainTypes[Templates[state].TerrainType[Tiles[p]]].GetCost(umt);
|
||||||
|
|||||||
@@ -20,14 +20,18 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using OpenRA.GameRules;
|
||||||
|
|
||||||
namespace OpenRA.Traits
|
namespace OpenRA.Traits
|
||||||
{
|
{
|
||||||
class BridgeLoadHookInfo : TraitInfo<BridgeLoadHook> { }
|
class BridgeLayerInfo : TraitInfo<BridgeLayer> { }
|
||||||
|
|
||||||
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 tl = w.Map.TopLeft;
|
||||||
var br = w.Map.BottomRight;
|
var br = w.Map.BottomRight;
|
||||||
@@ -38,10 +42,10 @@ namespace OpenRA.Traits
|
|||||||
ConvertBridgeToActor(w, i, j);
|
ConvertBridgeToActor(w, i, j);
|
||||||
|
|
||||||
foreach (var b in w.Actors.SelectMany(a => a.traits.WithInterface<Bridge>()))
|
foreach (var b in w.Actors.SelectMany(a => a.traits.WithInterface<Bridge>()))
|
||||||
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);
|
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 a = w.CreateActor(template.Bridge, new int2(ni, nj), w.NeutralPlayer);
|
||||||
var br = a.traits.Get<Bridge>();
|
var br = a.traits.Get<Bridge>();
|
||||||
|
|
||||||
|
foreach (var t in replacedTiles.Keys)
|
||||||
|
customTerrain[t.X, t.Y] = br;
|
||||||
|
|
||||||
br.SetTiles(w, template, replacedTiles);
|
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)
|
static bool IsBridge(World w, ushort t)
|
||||||
{
|
{
|
||||||
return w.TileSet.walk[t].Bridge != null;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ namespace OpenRA.Traits
|
|||||||
public object Create(Actor self) { return new ResourceLayer(self); }
|
public object Create(Actor self) { return new ResourceLayer(self); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ResourceLayer: IRenderOverlay, ILoadWorldHook
|
public class ResourceLayer: IRenderOverlay, ILoadWorldHook, ICustomTerrain
|
||||||
{
|
{
|
||||||
SpriteRenderer sr;
|
SpriteRenderer sr;
|
||||||
World world;
|
World world;
|
||||||
@@ -88,18 +88,18 @@ namespace OpenRA.Traits
|
|||||||
content[x, y].density = GetIdealDensity(x, y);
|
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)
|
if (content[p.X,p.Y].type == null)
|
||||||
return 1.0f;
|
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)
|
if (content[p.X,p.Y].type == null)
|
||||||
return 1.0f;
|
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)
|
public Sprite[] ChooseContent(ResourceType t)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace OpenRA.Traits
|
|||||||
int growthTicks;
|
int growthTicks;
|
||||||
int spreadTicks;
|
int spreadTicks;
|
||||||
public ResourceTypeInfo info;
|
public ResourceTypeInfo info;
|
||||||
float[] movementCost = new float[4];
|
float[] movementSpeed = new float[4];
|
||||||
float[] pathCost = new float[4];
|
float[] pathCost = new float[4];
|
||||||
|
|
||||||
public ResourceType(ResourceTypeInfo info)
|
public ResourceType(ResourceTypeInfo info)
|
||||||
@@ -56,19 +56,20 @@ namespace OpenRA.Traits
|
|||||||
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++ )
|
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++ )
|
||||||
{
|
{
|
||||||
// HACK: hardcode "ore" terraintype for now
|
// HACK: hardcode "ore" terraintype for now
|
||||||
movementCost[(int)umt] = (info.MovementTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetCost(umt) : 1.0f;
|
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) : movementCost[(int)umt];
|
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;
|
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];
|
return pathCost[(int)umt];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,9 +70,6 @@ namespace OpenRA
|
|||||||
public readonly TileSet TileSet;
|
public readonly TileSet TileSet;
|
||||||
public GlobalDefaultsInfo Defaults { get {return WorldActor.Info.Traits.Get<GlobalDefaultsInfo>();}}
|
public GlobalDefaultsInfo Defaults { get {return WorldActor.Info.Traits.Get<GlobalDefaultsInfo>();}}
|
||||||
|
|
||||||
// for tricky things like bridges.
|
|
||||||
public readonly ICustomTerrain[,] customTerrain;
|
|
||||||
|
|
||||||
public readonly WorldRenderer WorldRenderer;
|
public readonly WorldRenderer WorldRenderer;
|
||||||
internal readonly Minimap Minimap;
|
internal readonly Minimap Minimap;
|
||||||
|
|
||||||
@@ -80,9 +77,6 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
Timer.Time( "----World.ctor" );
|
Timer.Time( "----World.ctor" );
|
||||||
Map = map;
|
Map = map;
|
||||||
|
|
||||||
customTerrain = new ICustomTerrain[Map.MapSize.X, Map.MapSize.Y];
|
|
||||||
Timer.Time( "new Map: {0}" );
|
|
||||||
|
|
||||||
Rules.LoadRules(manifest,Map);
|
Rules.LoadRules(manifest,Map);
|
||||||
Timer.Time( "load rules: {0}" );
|
Timer.Time( "load rules: {0}" );
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ World:
|
|||||||
ResourceLayer:
|
ResourceLayer:
|
||||||
ResourceType@green-tib:
|
ResourceType@green-tib:
|
||||||
ResourceType: 1
|
ResourceType: 1
|
||||||
|
MovementTerrainType: Tiberium
|
||||||
Palette: terrain
|
Palette: terrain
|
||||||
SpriteNames: ti1,ti2,ti3,ti4,ti5,ti6,ti7,ti8,ti9,ti10,ti11,ti12
|
SpriteNames: ti1,ti2,ti3,ti4,ti5,ti6,ti7,ti8,ti9,ti10,ti11,ti12
|
||||||
ValuePerUnit: 30
|
ValuePerUnit: 30
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ World:
|
|||||||
BuildingInfluence:
|
BuildingInfluence:
|
||||||
UnitInfluence:
|
UnitInfluence:
|
||||||
ChoosePaletteOnSelect:
|
ChoosePaletteOnSelect:
|
||||||
BridgeLoadHook:
|
BridgeLayer:
|
||||||
CrateSpawner:
|
CrateSpawner:
|
||||||
Minimum: 1
|
Minimum: 1
|
||||||
Maximum: 3
|
Maximum: 3
|
||||||
|
|||||||
Reference in New Issue
Block a user