diff --git a/OpenRA.Mods.RA/Bridge.cs b/OpenRA.Mods.RA/Bridge.cs index 717a5ae1fe..ebad07fc7f 100644 --- a/OpenRA.Mods.RA/Bridge.cs +++ b/OpenRA.Mods.RA/Bridge.cs @@ -34,7 +34,6 @@ namespace OpenRA.Mods.RA public readonly bool Long = false; public readonly ushort Template; - public readonly float DamagedThreshold = 0.5f; public readonly ushort DamagedTemplate; public readonly ushort DestroyedTemplate; @@ -42,6 +41,7 @@ namespace OpenRA.Mods.RA public readonly ushort DestroyedPlusNorthTemplate; public readonly ushort DestroyedPlusSouthTemplate; public readonly ushort DestroyedPlusBothTemplate; + public readonly string[] ShorePieces = {"br1", "br2"}; public readonly bool UseAlternateNames = false; public readonly int[] NorthOffset = null; @@ -85,21 +85,24 @@ namespace OpenRA.Mods.RA BridgeInfo info; Bridge northNeighbour, southNeighbour; + public string Type; + public Bridge(Actor self, BridgeInfo info) { this.self = self; self.RemoveOnDeath = false; this.info = info; + this.Type = self.Info.Name; } public void Create(ushort template, Dictionary subtiles) { currentTemplate = template; if (template == info.DamagedTemplate) - self.Health = (int)(info.DamagedThreshold*self.GetMaxHP()); + self.Health = (int)(self.World.Defaults.ConditionYellow*self.GetMaxHP()); else if (template != info.Template) self.Health = 0; - + // Create a new cache to store the tile data if (cachedTileset != self.World.Map.Tileset) { @@ -148,7 +151,7 @@ namespace OpenRA.Mods.RA yield return new Renderable(t.Value, Game.CellSize * t.Key, "terrain"); } - static bool IsIntact(Bridge b) + bool IsIntact(Bridge b) { return b != null && b.self.IsInWorld && b.self.Health > 0; } @@ -159,32 +162,44 @@ namespace OpenRA.Mods.RA } void UpdateState() - { - /*var ds = self.GetDamageState(); - if (!self.Info.Traits.Get().Long) + { + var ds = self.GetDamageState(); + + // If this is a long bridge next to a destroyed shore piece, we need die to give clean edges to the break + if (info.Long && ds != DamageState.Dead && + ((southNeighbour != null && info.ShorePieces.Contains(southNeighbour.Type) && !IsIntact(southNeighbour)) || + (northNeighbour != null && info.ShorePieces.Contains(northNeighbour.Type) && !IsIntact(northNeighbour)))) { - state = (int)ds; - return; + self.Health = 0; + ds = DamageState.Dead; } + + currentTemplate = (ds == DamageState.Half && info.DamagedTemplate > 0) ? info.DamagedTemplate : + (ds == DamageState.Dead && info.DestroyedTemplate > 0) ? info.DestroyedTemplate : info.Template; - bool waterToSouth = !IsIntact(southNeighbour) && (!IsLong(southNeighbour) || !IsIntact(this)); - bool waterToNorth = !IsIntact(northNeighbour) && (!IsLong(northNeighbour) || !IsIntact(this)); - - if (waterToSouth && waterToNorth) { state = 5; return; } - if (waterToNorth) { state = 4; return; } - if (waterToSouth) { state = 3; return; } - state = (int)ds; - */ + if (!(info.Long && ds == DamageState.Dead)) + return; + + // Long bridges have custom art for multiple segments being destroyed + bool waterToSouth = !IsIntact(southNeighbour); + bool waterToNorth = !IsIntact(northNeighbour); + + if (waterToSouth && waterToNorth) + currentTemplate = info.DestroyedPlusBothTemplate; + else if (waterToNorth) + currentTemplate = info.DestroyedPlusNorthTemplate; + else if (waterToSouth) + currentTemplate = info.DestroyedPlusSouthTemplate; } public void Damaged(Actor self, AttackInfo e) { - /*if (e.DamageStateChanged) + if (e.DamageStateChanged) { UpdateState(); if (northNeighbour != null) northNeighbour.UpdateState(); if (southNeighbour != null) southNeighbour.UpdateState(); - }*/ + } } } } diff --git a/OpenRA.Mods.RA/BridgeLayer.cs b/OpenRA.Mods.RA/BridgeLayer.cs index 8e0ea9e4a8..5091a8e955 100644 --- a/OpenRA.Mods.RA/BridgeLayer.cs +++ b/OpenRA.Mods.RA/BridgeLayer.cs @@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA { class BridgeLayerInfo : ITraitInfo { - public readonly string[] Bridges = {"br1", "br2", "br3", "bridge1", "bridge2"}; + public readonly string[] Bridges = {"bridge1", "bridge2"}; public object Create(ActorInitializer init) { return new BridgeLayer(init.self, this); } } @@ -95,21 +95,26 @@ namespace OpenRA.Mods.RA var bridge = w.CreateActor(BridgeTypes[tile], new int2(ni, nj), w.WorldActor.Owner).traits.Get(); Dictionary subTiles = new Dictionary(); - // Loop through the cells on the bridge template; mark each cell that is part - // of the bridge and add to the bridges array - for (var x = ni; x < ni + template.Size.X; x++) - for (var y = nj; y < nj + template.Size.Y; y++) - { - // This isn't the bridge we're looking for - if (!w.Map.IsInMap(x, y) || w.Map.MapTiles[x, y].type != tile) - continue; - - Log.Write("debug", "Adding tile {0} {1} for type {2}", x,y,tile); - - subTiles.Add(new int2(x,y),w.Map.MapTiles[x, y].image); - Bridges[x,y] = bridge; - } - + // For each subtile in the template + for (byte ind = 0; ind < template.Size.X*template.Size.Y; ind++) + { + // Is this tile actually included in the bridge template? + if (!template.Tiles.Keys.Contains(ind)) + continue; + + // Where do we expect to find the subtile + var x = ni + ind % template.Size.X; + var y = nj + ind / template.Size.X; + + // This isn't the bridge you're looking for + if (!w.Map.IsInMap(x, y) || w.Map.MapTiles[x, y].image != ind) + continue; + + Log.Write("debug", "Adding tile {0} {1} for type {2}", x,y,tile); + + subTiles.Add(new int2(x,y),ind); + Bridges[x,y] = bridge; + } bridge.Create(tile, subTiles); } diff --git a/mods/ra/civilian.yaml b/mods/ra/civilian.yaml index db276828f9..b21bfb1c91 100644 --- a/mods/ra/civilian.yaml +++ b/mods/ra/civilian.yaml @@ -411,6 +411,7 @@ BR3: Inherits: ^Bridge Bridge: Long: yes + ShorePieces: br1,br2 Template: 241 DamagedTemplate: 242 DestroyedTemplate: 243 diff --git a/mods/ra/system.yaml b/mods/ra/system.yaml index b447e5dc6a..57f17601d6 100644 --- a/mods/ra/system.yaml +++ b/mods/ra/system.yaml @@ -95,6 +95,7 @@ World: UnitInfluence: ChoosePaletteOnSelect: BridgeLayer: + Bridges: bridge1, bridge2, br1, br2, br3 CrateDrop: Minimum: 1 Maximum: 3