diff --git a/CHANGELOG b/CHANGELOG index 52c4cc9bd8..0fdffab12a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,10 @@ NEW: + Dune 2000: + Added the Atreides grenadier from the 1.06 patch. + Red Alert: + Tanya can now plant C4 on bridges. + Tiberian Dawn: + Commando can now plant C4 on bridges. Engine: Converted Aircraft CruiseAltitude to world coordinates. Converted Health Radius to world coordinates. @@ -9,8 +15,7 @@ NEW: Altitude is no longer parsed from actor templates in maps. Specify CenterPosition instead. Run `OpenRA.Utility.exe --upgrade-mod 20131223` to automatically upgrade mod rules. Run `OpenRA.Utility.exe --upgrade-map 20131223` to automatically upgrade custom map rules. - Dune 2000: - Added the Atreides grenadier from the 1.06 patch. + Added a new trait Demolishable for buildings to handle the C4 demolition. 20131223: All mods: diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index c95ef77b3f..528720ad72 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -77,6 +77,11 @@ namespace OpenRA.Traits public interface INotifyHarvest { void Harvested(Actor self, ResourceType resource); } public interface IAcceptInfiltrator { void OnInfiltrate(Actor self, Actor infiltrator); } + public interface IDemolishable + { + void Demolish(Actor self, Actor saboteur); + bool IsValidTarget(Actor self, Actor saboteur); + } public interface IStoreOre { int Capacity { get; } } public interface IToolTip { diff --git a/OpenRA.Mods.RA/Activities/Demolish.cs b/OpenRA.Mods.RA/Activities/Demolish.cs index 4371a2c723..cba9b993f7 100644 --- a/OpenRA.Mods.RA/Activities/Demolish.cs +++ b/OpenRA.Mods.RA/Activities/Demolish.cs @@ -41,8 +41,12 @@ namespace OpenRA.Mods.RA.Activities .Concat(self.Owner.PlayerActor.TraitsImplementing()) .Select(t => t.GetDamageModifier(self, null)).Product(); + var demolishable = target.Actor.TraitOrDefault(); + if (demolishable == null || !demolishable.IsValidTarget(target.Actor, self)) + return; + if (modifier > 0) - target.Actor.Kill(self); + demolishable.Demolish(target.Actor, self); }))); return NextActivity; diff --git a/OpenRA.Mods.RA/Bridge.cs b/OpenRA.Mods.RA/Bridge.cs index 6f3f6d9ec7..8177a02d9a 100644 --- a/OpenRA.Mods.RA/Bridge.cs +++ b/OpenRA.Mods.RA/Bridge.cs @@ -288,5 +288,13 @@ namespace OpenRA.Mods.RA return damage; } + + public void Demolish(Actor saboteur) + { + // TODO: completely destroy long bridges in a chain reaction + Combat.DoExplosion(saboteur, "Demolish", self.CenterPosition); + self.World.WorldActor.Trait().AddEffect(15, self.CenterPosition, 6); + self.Kill(saboteur); + } } } diff --git a/OpenRA.Mods.RA/BridgeHut.cs b/OpenRA.Mods.RA/BridgeHut.cs index c80605a763..b476966b37 100644 --- a/OpenRA.Mods.RA/BridgeHut.cs +++ b/OpenRA.Mods.RA/BridgeHut.cs @@ -17,7 +17,7 @@ namespace OpenRA.Mods.RA public object Create(ActorInitializer init) { return new BridgeHut(init); } } - class BridgeHut + class BridgeHut : IDemolishable { public Bridge bridge; @@ -31,6 +31,16 @@ namespace OpenRA.Mods.RA bridge.Repair(repairer, true, true); } + public void Demolish(Actor self, Actor saboteur) + { + bridge.Demolish(saboteur); + } + + public bool IsValidTarget(Actor self, Actor saboteur) + { + return BridgeDamageState == DamageState.Undamaged; + } + public DamageState BridgeDamageState { get { return bridge.AggregateDamageState(); } } } } diff --git a/OpenRA.Mods.RA/Buildings/Demolishable.cs b/OpenRA.Mods.RA/Buildings/Demolishable.cs new file mode 100644 index 0000000000..194298a755 --- /dev/null +++ b/OpenRA.Mods.RA/Buildings/Demolishable.cs @@ -0,0 +1,34 @@ +#region Copyright & License Information +/* + * Copyright 2007-2013 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. For more information, + * see COPYING. + */ +#endregion +using System; +using OpenRA.Traits; +using OpenRA.FileFormats; + +namespace OpenRA.Mods.RA +{ + [Desc("Handle demolitions from C4 explosives.")] + public class DemolishableInfo : TraitInfo { } + + public class Demolishable : IDemolishable + { + public Demolishable() { } + + public void Demolish(Actor self, Actor saboteur) + { + self.Kill(saboteur); + } + + public bool IsValidTarget(Actor self, Actor saboteur) + { + return true; + } + } +} + diff --git a/OpenRA.Mods.RA/C4Demolition.cs b/OpenRA.Mods.RA/C4Demolition.cs index efe655ce03..da0dd64ab2 100644 --- a/OpenRA.Mods.RA/C4Demolition.cs +++ b/OpenRA.Mods.RA/C4Demolition.cs @@ -56,6 +56,10 @@ namespace OpenRA.Mods.RA if (target.Type != TargetType.Actor) return; + var demolishable = order.TargetActor.TraitOrDefault(); + if (demolishable == null || !demolishable.IsValidTarget(target.Actor, self)) + return; + if (!order.Queued) self.CancelActivity(); diff --git a/OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs b/OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs index 0b567afa2c..775165c0dc 100644 --- a/OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs +++ b/OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs @@ -125,12 +125,8 @@ namespace OpenRA.Mods.RA.Missions startJeep.QueueActivity(new Turn(128)); startJeep.QueueActivity(new CallFunc(() => { - var bridge = world.Actors - .Where(a => a.HasTrait() && !a.IsDead()) - .ClosestTo(startJeep); - Combat.DoExplosion(bridge, "Demolish", bridge.CenterPosition); - world.WorldActor.Trait().AddEffect(15, bridge.CenterPosition, 6); - bridge.Kill(bridge); + var bridge = world.Actors.Where(a => a.HasTrait()).ClosestTo(startJeep); + bridge.Trait().Demolish(bridge, startJeep); })); } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 0e28d6d8a2..94c65c9e66 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -484,6 +484,7 @@ + diff --git a/mods/cnc/rules/civilian.yaml b/mods/cnc/rules/civilian.yaml index f5a58cea80..6d09667a7d 100644 --- a/mods/cnc/rules/civilian.yaml +++ b/mods/cnc/rules/civilian.yaml @@ -363,7 +363,7 @@ BRIDGEHUT: Bounds: 48,48 BridgeHut: TargetableBuilding: - TargetTypes: BridgeHut + TargetTypes: BridgeHut, C4 C1: Inherits: ^CivInfantry @@ -455,4 +455,3 @@ VICE: QuantizedFacings: 8 PoisonedByTiberium: Weapon: Heal - diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index bbd885aeed..1a9d889471 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -353,6 +353,7 @@ EngineerRepairable: Huntable: LuaScriptEvents: + Demolishable: ^CivBuilding: Inherits: ^Building @@ -456,6 +457,7 @@ BodyOrientation: FrozenUnderFog: LuaScriptEvents: + Demolishable: ^Tree: Tooltip: diff --git a/mods/cnc/weapons.yaml b/mods/cnc/weapons.yaml index 73900210d7..bb8e997b2f 100644 --- a/mods/cnc/weapons.yaml +++ b/mods/cnc/weapons.yaml @@ -1027,3 +1027,7 @@ Claw: InfDeath: 1 Damage: 60 +Demolish: + Warhead: + ImpactSound: xplobig6.aud + Explosion: building \ No newline at end of file diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index 59cf1f916c..c3748d0cf6 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -249,4 +249,4 @@ WithCrumbleOverlay: Huntable: LuaScriptEvents: - + Demolishable: diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml index ce94979cb5..65fd2f16db 100644 --- a/mods/d2k/rules/structures.yaml +++ b/mods/d2k/rules/structures.yaml @@ -384,6 +384,7 @@ Sellable: Guardable: BodyOrientation: + Demolishable: WALL: Inherits: ^WALL diff --git a/mods/ra/rules/civilian.yaml b/mods/ra/rules/civilian.yaml index 505cb22a4c..fa7c22068b 100644 --- a/mods/ra/rules/civilian.yaml +++ b/mods/ra/rules/civilian.yaml @@ -488,7 +488,7 @@ BRIDGEHUT: Bounds: 48,48 BridgeHut: TargetableBuilding: - TargetTypes: BridgeHut + TargetTypes: BridgeHut, C4 BRIDGEHUT.small: Building: @@ -499,7 +499,7 @@ BRIDGEHUT.small: Bounds: 24,24 BridgeHut: TargetableBuilding: - TargetTypes: BridgeHut + TargetTypes: BridgeHut, C4 V20: Inherits: ^DesertCivBuilding diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index 116b28977d..1ce009a9fd 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -264,6 +264,7 @@ String: Structure Huntable: LuaScriptEvents: + Demolishable: ^Wall: AppearsOnRadar: @@ -300,6 +301,7 @@ BodyOrientation: FrozenUnderFog: LuaScriptEvents: + Demolishable: ^TechBuilding: Inherits: ^Building diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index fa3a5bac6a..0965cb5697 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -36,6 +36,7 @@ BodyOrientation: Huntable: LuaScriptEvents: + Demolishable: ^Infantry: AppearsOnRadar: @@ -176,6 +177,7 @@ UpdatesPlayerStatistics: BodyOrientation: LuaScriptEvents: + Demolishable: ^Helicopter: AppearsOnRadar: