Implement elevated bridge placeholders.

This commit is contained in:
Paul Chote
2017-01-11 22:08:22 +00:00
parent 5c77c0dc28
commit 4f41b6e9ce
7 changed files with 237 additions and 4 deletions

View File

@@ -798,6 +798,8 @@
<Compile Include="Traits\World\TerrainTunnel.cs" />
<Compile Include="Traits\World\SubterraneanActorLayer.cs" />
<Compile Include="Traits\World\JumpjetActorLayer.cs" />
<Compile Include="Traits\World\ElevatedBridgeLayer.cs" />
<Compile Include="Traits\World\ElevatedBridgePlaceholder.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="AfterBuild">

View File

@@ -44,6 +44,7 @@ namespace OpenRA.Mods.Common.Traits
public const byte Tunnel = 1;
public const byte Subterranean = 2;
public const byte Jumpjet = 3;
public const byte ElevatedBridge = 4;
}
[Desc("Unit is able to move.")]

View File

@@ -0,0 +1,95 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Collections.Generic;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
public class ElevatedBridgeLayerInfo : ITraitInfo, Requires<DomainIndexInfo>, ILobbyCustomRulesIgnore
{
[Desc("Terrain type used by cells outside any elevated bridge footprint.")]
public readonly string ImpassableTerrainType = "Impassable";
public object Create(ActorInitializer init) { return new ElevatedBridgeLayer(init.Self, this); }
}
// For now this is mostly copies TerrainTunnelLayer. This will change once bridge destruction is implemented
public class ElevatedBridgeLayer : ICustomMovementLayer, IWorldLoaded
{
readonly Map map;
readonly CellLayer<WPos> cellCenters;
readonly CellLayer<byte> terrainIndices;
readonly HashSet<CPos> ends = new HashSet<CPos>();
bool enabled;
public ElevatedBridgeLayer(Actor self, ElevatedBridgeLayerInfo info)
{
map = self.World.Map;
cellCenters = new CellLayer<WPos>(map);
terrainIndices = new CellLayer<byte>(map);
terrainIndices.Clear(map.Rules.TileSet.GetTerrainIndex(info.ImpassableTerrainType));
}
public void WorldLoaded(World world, WorldRenderer wr)
{
var domainIndex = world.WorldActor.Trait<DomainIndex>();
foreach (var tti in world.WorldActor.Info.TraitInfos<ElevatedBridgePlaceholderInfo>())
{
enabled = true;
var terrain = map.Rules.TileSet.GetTerrainIndex(tti.TerrainType);
foreach (var c in tti.BridgeCells())
{
var uv = c.ToMPos(map);
terrainIndices[uv] = terrain;
var pos = map.CenterOfCell(c);
cellCenters[uv] = pos - new WVec(0, 0, pos.Z - 512 * tti.Height);
}
var end = tti.EndCells();
domainIndex.AddFixedConnection(end);
foreach (var c in end)
{
// Need to explicitly set both default and tunnel layers, otherwise the .Contains check will fail
ends.Add(new CPos(c.X, c.Y, 0));
ends.Add(new CPos(c.X, c.Y, CustomMovementLayerType.ElevatedBridge));
}
}
}
bool ICustomMovementLayer.EnabledForActor(ActorInfo a, MobileInfo mi) { return enabled; }
byte ICustomMovementLayer.Index { get { return CustomMovementLayerType.ElevatedBridge; } }
bool ICustomMovementLayer.InteractsWithDefaultLayer { get { return true; } }
WPos ICustomMovementLayer.CenterOfCell(CPos cell)
{
return cellCenters[cell];
}
int ICustomMovementLayer.EntryMovementCost(ActorInfo a, MobileInfo mi, CPos cell)
{
return ends.Contains(cell) ? 0 : int.MaxValue;
}
int ICustomMovementLayer.ExitMovementCost(ActorInfo a, MobileInfo mi, CPos cell)
{
return ends.Contains(cell) ? 0 : int.MaxValue;
}
byte ICustomMovementLayer.GetTerrainIndex(CPos cell)
{
return terrainIndices[cell];
}
}
}

View File

@@ -0,0 +1,75 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
public enum ElevatedBridgePlaceholderOrientation { X, Y }
[Desc("Placeholder to make static elevated bridges work.",
"Define individual trait instances for each elevated bridge footprint in the map.")]
public class ElevatedBridgePlaceholderInfo : TraitInfo<ElevatedBridgePlaceholder>, Requires<ElevatedBridgeLayerInfo>, ILobbyCustomRulesIgnore
{
[FieldLoader.Require]
[Desc("Location of the bridge")]
public readonly CPos Location = CPos.Zero;
[FieldLoader.Require]
[Desc("Orientation of the bridge.")]
public readonly ElevatedBridgePlaceholderOrientation Orientation;
[FieldLoader.Require]
[Desc("Length of the bridge")]
public readonly int Length = 0;
[FieldLoader.Require]
[Desc("Height of the bridge in map height steps.")]
public readonly byte Height = 0;
[Desc("Terrain type of the bridge.")]
public readonly string TerrainType = "Road";
public IEnumerable<CPos> BridgeCells()
{
var dimensions = Orientation == ElevatedBridgePlaceholderOrientation.X ?
new CVec(Length + 1, 3) : new CVec(3, Length + 1);
for (var y = 0; y < dimensions.Y; y++)
for (var x = 0; x < dimensions.X; x++)
yield return Location + new CVec(x, y);
}
public IEnumerable<CPos> EndCells()
{
if (Orientation == ElevatedBridgePlaceholderOrientation.X)
{
for (var y = 0; y < 3; y++)
{
yield return Location + new CVec(0, y);
yield return Location + new CVec(Length, y);
}
}
else
{
for (var x = 0; x < 3; x++)
{
yield return Location + new CVec(x, 0);
yield return Location + new CVec(x, Length);
}
}
}
}
public class ElevatedBridgePlaceholder { }
}