diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
index 3dbfd11e0b..89b91993f0 100644
--- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
+++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
@@ -798,6 +798,8 @@
+
+
diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs
index 4692bd7067..c9b0022e6c 100644
--- a/OpenRA.Mods.Common/Traits/Mobile.cs
+++ b/OpenRA.Mods.Common/Traits/Mobile.cs
@@ -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.")]
diff --git a/OpenRA.Mods.Common/Traits/World/ElevatedBridgeLayer.cs b/OpenRA.Mods.Common/Traits/World/ElevatedBridgeLayer.cs
new file mode 100644
index 0000000000..1683a36bce
--- /dev/null
+++ b/OpenRA.Mods.Common/Traits/World/ElevatedBridgeLayer.cs
@@ -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, 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 cellCenters;
+ readonly CellLayer terrainIndices;
+ readonly HashSet ends = new HashSet();
+ bool enabled;
+
+ public ElevatedBridgeLayer(Actor self, ElevatedBridgeLayerInfo info)
+ {
+ map = self.World.Map;
+ cellCenters = new CellLayer(map);
+ terrainIndices = new CellLayer(map);
+ terrainIndices.Clear(map.Rules.TileSet.GetTerrainIndex(info.ImpassableTerrainType));
+ }
+
+ public void WorldLoaded(World world, WorldRenderer wr)
+ {
+ var domainIndex = world.WorldActor.Trait();
+ foreach (var tti in world.WorldActor.Info.TraitInfos())
+ {
+ 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];
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/Traits/World/ElevatedBridgePlaceholder.cs b/OpenRA.Mods.Common/Traits/World/ElevatedBridgePlaceholder.cs
new file mode 100644
index 0000000000..21cd19895f
--- /dev/null
+++ b/OpenRA.Mods.Common/Traits/World/ElevatedBridgePlaceholder.cs
@@ -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, Requires, 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 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 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 { }
+}
diff --git a/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs b/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs
index 1e1be0b113..11f4c98afc 100644
--- a/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs
+++ b/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs
@@ -31,10 +31,8 @@ namespace OpenRA.Mods.TS.UtilityCommands
{
{ 0x01, "gasand" },
{ 0x03, "gawall" },
- /*
{ 0x18, "bridge1" },
{ 0x19, "bridge2" },
- */
{ 0x1A, "nawall" },
{ 0x27, "tracks01" },
{ 0x28, "tracks02" },
@@ -56,10 +54,8 @@ namespace OpenRA.Mods.TS.UtilityCommands
{ 0x38, "tracktunnel02" },
{ 0x39, "tracktunnel03" },
{ 0x3A, "tracktunnel04" },
- /*
{ 0x3B, "railbrdg1" },
{ 0x3C, "railbrdg2" },
- */
{ 0x3D, "crat01" },
{ 0x3E, "crat02" },
{ 0x3F, "crat03" },
diff --git a/mods/ts/rules/bridges.yaml b/mods/ts/rules/bridges.yaml
index 4eb711f46a..091fe027a1 100644
--- a/mods/ts/rules/bridges.yaml
+++ b/mods/ts/rules/bridges.yaml
@@ -152,3 +152,34 @@ LOBRDG_R_SW:
NeighbourOffsets: 1,-1
EditorOnlyTooltip:
Name: Bridge Ramp
+
+^ElevatedBridgePlaceholder:
+ AlwaysVisible:
+ RenderSprites:
+ Palette: terraindecoration
+ WithSpriteBody:
+ AutoSelectionSize:
+ AppearsOnRadar:
+ RadarColorFromTerrain:
+ Terrain: Bridge
+ BodyOrientation:
+ UseClassicPerspectiveFudge: false
+ QuantizedFacings: 1
+ Tooltip:
+ Name: Bridge
+ Immobile:
+ OccupiesSpace: false
+ CustomSelectionSize:
+ CustomBounds: 96, 144
+
+BRIDGE1:
+ Inherits: ^ElevatedBridgePlaceholder
+
+BRIDGE2:
+ Inherits: ^ElevatedBridgePlaceholder
+
+RAILBRDG1:
+ Inherits: ^ElevatedBridgePlaceholder
+
+RAILBRDG2:
+ Inherits: ^ElevatedBridgePlaceholder
diff --git a/mods/ts/sequences/bridges.yaml b/mods/ts/sequences/bridges.yaml
index 76102f50f5..ecfb189457 100644
--- a/mods/ts/sequences/bridges.yaml
+++ b/mods/ts/sequences/bridges.yaml
@@ -62,3 +62,36 @@ lobrdg_r_sw:
idle: lobrdg25
damaged-idle: lobrdg26
+bridge1:
+ idle: bridge
+ # Disabled to avoid glitches until shadow rendering is fixed
+ # ShadowStart: 18
+ UseTilesetExtension: true
+ ZRamp: 1
+ Offset: 0, -13, 3.5
+
+bridge2:
+ idle: bridge
+ Start: 9
+ # Disabled to avoid glitches until shadow rendering is fixed
+ # ShadowStart: 27
+ UseTilesetExtension: true
+ ZRamp: 1
+ Offset: 0, -25, 3.5
+
+railbrdg1:
+ idle: railbrdg
+ # Disabled to avoid glitches until shadow rendering is fixed
+ # ShadowStart: 18
+ UseTilesetExtension: true
+ ZRamp: 1
+ Offset: 0, -13, 3.5
+
+railbrdg2:
+ idle: railbrdg
+ Start: 9
+ # Disabled to avoid glitches until shadow rendering is fixed
+ # ShadowStart: 27
+ UseTilesetExtension: true
+ ZRamp: 1
+ Offset: 0, -25, 3.5