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