diff --git a/OpenRa.Game/Traits/Bridge.cs b/OpenRa.Game/Traits/Bridge.cs index 84e0de14cc..cbbb238513 100644 --- a/OpenRa.Game/Traits/Bridge.cs +++ b/OpenRa.Game/Traits/Bridge.cs @@ -13,6 +13,8 @@ namespace OpenRa.Traits { public readonly bool Long = false; public readonly bool UseAlternateNames = false; + public readonly int[] NorthOffset = null; + public readonly int[] SouthOffset = null; public object Create(Actor self) { return new Bridge(self); } } @@ -24,6 +26,8 @@ namespace OpenRa.Traits Actor self; int state; + Bridge northNeighbour, southNeighbour; + public Bridge(Actor self) { this.self = self; self.RemoveOnDeath = false; } static string cachedTheater; @@ -87,9 +91,22 @@ namespace OpenRa.Traits 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(); + 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) @@ -100,11 +117,42 @@ namespace OpenRa.Traits Templates[state].TerrainType[Tiles[p]]); } + bool IsIntact(Bridge b) + { + return b != null && b.self.IsInWorld && b.self.Health > 0; + } + + bool IsLong(Bridge b) + { + return b != null && b.self.IsInWorld && b.self.Info.Traits.Get().Long; + } + + void UpdateState() + { + var ds = self.GetDamageState(); + if (!self.Info.Traits.Get().Long) + { + state = (int)ds; + return; + } + + 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; + } + public void Damaged(Actor self, AttackInfo e) { - // todo: long bridges have d/e/f states too. if (e.DamageStateChanged) - state = (int)e.DamageState; + { + UpdateState(); + if (northNeighbour != null) northNeighbour.UpdateState(); + if (southNeighbour != null) southNeighbour.UpdateState(); + } } } } diff --git a/merge-ra.yaml b/merge-ra.yaml index 4c28e1dd42..9a7ddcdd3c 100644 --- a/merge-ra.yaml +++ b/merge-ra.yaml @@ -29,9 +29,17 @@ MINV: TriggeredBy: Wheel, Track AvoidFriendly: yes +BR1: + Bridge: + SouthOffset:0,2 +BR2: + Bridge: + NorthOffset:3,0 BR3: Bridge: Long: yes + NorthOffset: 2,0 + SouthOffset: 0,1 BRIDGE1: Bridge: diff --git a/ra.yaml b/ra.yaml index 4005550a1a..c4dd2271b0 100644 --- a/ra.yaml +++ b/ra.yaml @@ -83,9 +83,33 @@ MINV: -Selectable: -Building: +BR1: + Bridge: + SouthOffset: 0,2 + Category: Building + Selectable: + BelowUnits: + Building: + Footprint: ____ ____ + Dimensions: 4,2 + HP: 1000 + +BR2: + Bridge: + NorthOffset: 3,0 + Category: Building + Selectable: + BelowUnits: + Building: + Footprint: ____ ____ + Dimensions: 4,2 + HP: 1000 + BR3: Bridge: Long: yes + NorthOffset: 2,0 + SouthOffset: 0,1 Category: Building Selectable: BelowUnits: @@ -1470,26 +1494,6 @@ DOMF: Image: DOME Fake: -BR1: - Category: Building - Selectable: - Bridge: - BelowUnits: - Building: - Footprint: ____ ____ - Dimensions: 4,2 - HP: 1000 - -BR2: - Category: Building - Selectable: - Bridge: - BelowUnits: - Building: - Footprint: ____ ____ - Dimensions: 4,2 - HP: 1000 - T01: Inherits: ^Building Building: