diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
index b7545db6da..f4d9622074 100644
--- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
+++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
@@ -421,7 +421,6 @@
-
@@ -718,6 +717,7 @@
+
diff --git a/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs
deleted file mode 100644
index 22d17f6eda..0000000000
--- a/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-#region Copyright & License Information
-/*
- * Copyright 2007-2015 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.Collections.Generic;
-using System.Linq;
-using OpenRA.Graphics;
-using OpenRA.Traits;
-
-namespace OpenRA.Mods.Common.Traits
-{
- [Desc("Replaces the idle animation of a building.")]
- public class WithActiveAnimationInfo : ITraitInfo, Requires
- {
- [Desc("Sequence name to use")]
- [SequenceReference] public readonly string Sequence = "active";
-
- public readonly int Interval = 750;
-
- public readonly bool PauseOnLowPower = false;
-
- public object Create(ActorInitializer init) { return new WithActiveAnimation(init.Self, this); }
- }
-
- public class WithActiveAnimation : ITick, INotifyBuildComplete, INotifySold
- {
- readonly WithActiveAnimationInfo info;
- readonly WithSpriteBody wsb;
-
- public WithActiveAnimation(Actor self, WithActiveAnimationInfo info)
- {
- wsb = self.Trait();
- this.info = info;
- }
-
- int ticks;
- public void Tick(Actor self)
- {
- if (!buildComplete)
- return;
-
- if (--ticks <= 0)
- {
- if (!(info.PauseOnLowPower && self.IsDisabled()))
- wsb.PlayCustomAnimation(self, info.Sequence, () => wsb.CancelCustomAnimation(self));
- ticks = info.Interval;
- }
- }
-
- bool buildComplete = false;
-
- public void BuildingComplete(Actor self)
- {
- buildComplete = true;
- }
-
- public void Selling(Actor self)
- {
- buildComplete = false;
- }
-
- public void Sold(Actor self) { }
- }
-}
diff --git a/OpenRA.Mods.Common/Traits/Render/WithIdleAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithIdleAnimation.cs
new file mode 100644
index 0000000000..bf6ec6cf4c
--- /dev/null
+++ b/OpenRA.Mods.Common/Traits/Render/WithIdleAnimation.cs
@@ -0,0 +1,71 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2015 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.Collections.Generic;
+using System.Linq;
+using OpenRA.Graphics;
+using OpenRA.Traits;
+
+namespace OpenRA.Mods.Common.Traits
+{
+ [Desc("Periodically plays an idle animation, replacing the default body animation.")]
+ public class WithIdleAnimationInfo : UpgradableTraitInfo, Requires
+ {
+ [SequenceReference, Desc("Sequence names to use.")]
+ public readonly string[] Sequences = { "active" };
+
+ public readonly int Interval = 750;
+
+ [Desc("Pause when the actor is disabled. Deprecated. Use upgrades instead.")]
+ public readonly bool PauseOnLowPower = false;
+
+ public override object Create(ActorInitializer init) { return new WithIdleAnimation(init.Self, this); }
+ }
+
+ public class WithIdleAnimation : UpgradableTrait, ITick, INotifyBuildComplete, INotifySold
+ {
+ readonly WithSpriteBody wsb;
+ bool buildComplete;
+ int ticks;
+
+ public WithIdleAnimation(Actor self, WithIdleAnimationInfo info)
+ : base(info)
+ {
+ wsb = self.Trait();
+ buildComplete = !self.Info.HasTraitInfo(); // always render instantly for units
+ ticks = info.Interval;
+ }
+
+ public void Tick(Actor self)
+ {
+ if (!buildComplete || IsTraitDisabled)
+ return;
+
+ if (--ticks <= 0)
+ {
+ if (!(Info.PauseOnLowPower && self.IsDisabled()))
+ wsb.PlayCustomAnimation(self, Info.Sequences.Random(Game.CosmeticRandom), () => wsb.CancelCustomAnimation(self));
+ ticks = Info.Interval;
+ }
+ }
+
+ public void BuildingComplete(Actor self)
+ {
+ buildComplete = true;
+ }
+
+ public void Selling(Actor self)
+ {
+ buildComplete = false;
+ }
+
+ public void Sold(Actor self) { }
+ }
+}
diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs
index f2e612b9dd..c681f7f856 100644
--- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs
+++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs
@@ -2818,6 +2818,18 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
}
+ if (engineVersion < 20160103)
+ {
+ // Overhauled WithActiveAnimation -> WithIdleAnimation
+ if (node.Key == "WithActiveAnimation")
+ {
+ node.Key = "WithIdleAnimation";
+ foreach (var n in node.Value.Nodes)
+ if (n.Key == "Sequence")
+ n.Key = "Sequences";
+ }
+ }
+
UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1);
}
}
diff --git a/mods/cnc/rules/trees.yaml b/mods/cnc/rules/trees.yaml
index 2bff4b0382..eaefa4a9a7 100644
--- a/mods/cnc/rules/trees.yaml
+++ b/mods/cnc/rules/trees.yaml
@@ -3,7 +3,7 @@ SPLIT2:
SeedsResource:
ResourceType: Tiberium
Interval: 55
- WithActiveAnimation:
+ WithIdleAnimation:
SPLIT3:
Inherits: ^TibTree
@@ -12,7 +12,7 @@ SPLIT3:
SeedsResource:
ResourceType: Tiberium
Interval: 55
- WithActiveAnimation:
+ WithIdleAnimation:
SPLITBLUE:
Inherits: ^TibTree
@@ -21,7 +21,7 @@ SPLITBLUE:
SeedsResource:
ResourceType: BlueTiberium
Interval: 110
- WithActiveAnimation:
+ WithIdleAnimation:
Tooltip:
Name: Blossom Tree (blue)
RadarColorFromTerrain:
diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml
index c6b22f5ea0..f1b8070d92 100644
--- a/mods/ts/rules/defaults.yaml
+++ b/mods/ts/rules/defaults.yaml
@@ -571,7 +571,7 @@
SeedsResource:
ResourceType: Tiberium
Interval: 55
- WithActiveAnimation:
+ WithIdleAnimation:
^Tree:
Inherits@1: ^SpriteActor