diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
index e80838673a..1ab61e7010 100644
--- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
+++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
@@ -288,7 +288,6 @@
-
@@ -599,6 +598,7 @@
+
diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackSuicides.cs b/OpenRA.Mods.Common/Traits/Attack/AttackSuicides.cs
deleted file mode 100644
index 795ad75939..0000000000
--- a/OpenRA.Mods.Common/Traits/Attack/AttackSuicides.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-#region Copyright & License Information
-/*
- * Copyright 2007-2019 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.Drawing;
-using OpenRA.Activities;
-using OpenRA.Mods.Common.Orders;
-using OpenRA.Primitives;
-using OpenRA.Traits;
-
-namespace OpenRA.Mods.Common.Traits
-{
- [Desc("Does a suicide attack where it moves next to the target when used in combination with `Explodes`.")]
- class AttackSuicidesInfo : ConditionalTraitInfo, Requires
- {
- [Desc("Types defined by `Targetable:` trait that this actor can target.")]
- public readonly BitSet TargetTypes = new BitSet("DetonateAttack");
-
- [Desc("Types of damage that this trait causes to self while suiciding. Leave empty for no damage types.")]
- public readonly BitSet DamageTypes = default(BitSet);
-
- [VoiceReference] public readonly string Voice = "Action";
-
- public override object Create(ActorInitializer init) { return new AttackSuicides(init.Self, this); }
- }
-
- class AttackSuicides : ConditionalTrait, IIssueOrder, IResolveOrder, IOrderVoice, IIssueDeployOrder
- {
- readonly IMove move;
-
- public AttackSuicides(Actor self, AttackSuicidesInfo info)
- : base(info)
- {
- move = self.Trait();
- }
-
- public IEnumerable Orders
- {
- get
- {
- if (IsTraitDisabled)
- yield break;
-
- yield return new TargetTypeOrderTargeter(Info.TargetTypes, "DetonateAttack", 5, "attack", true, false) { ForceAttack = false };
- yield return new DeployOrderTargeter("Detonate", 5);
- }
- }
-
- public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)
- {
- if (order.OrderID != "DetonateAttack" && order.OrderID != "Detonate")
- return null;
-
- return new Order(order.OrderID, self, target, queued);
- }
-
- Order IIssueDeployOrder.IssueDeployOrder(Actor self, bool queued)
- {
- return new Order("Detonate", self, queued);
- }
-
- bool IIssueDeployOrder.CanIssueDeployOrder(Actor self) { return true; }
-
- public string VoicePhraseForOrder(Actor self, Order order)
- {
- return Info.Voice;
- }
-
- public void ResolveOrder(Actor self, Order order)
- {
- if (order.OrderString == "DetonateAttack")
- {
- var target = self.ResolveFrozenActorOrder(order, Color.Red);
- if (target.Type != TargetType.Actor)
- return;
-
- if (!order.Queued)
- self.CancelActivity();
-
- self.SetTargetLine(target, Color.Red);
-
- self.QueueActivity(move.MoveToTarget(self, target, targetLineColor: Color.Red));
-
- self.QueueActivity(new CallFunc(() => self.Kill(self, Info.DamageTypes)));
- }
- else if (order.OrderString == "Detonate")
- self.Kill(self, Info.DamageTypes);
- }
- }
-}
diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/20181215/RemoveAttackSuicides.cs b/OpenRA.Mods.Common/UpdateRules/Rules/20181215/RemoveAttackSuicides.cs
new file mode 100644
index 0000000000..23e94d4e30
--- /dev/null
+++ b/OpenRA.Mods.Common/UpdateRules/Rules/20181215/RemoveAttackSuicides.cs
@@ -0,0 +1,51 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2018 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;
+
+namespace OpenRA.Mods.Common.UpdateRules.Rules
+{
+ public class RemoveAttackSuicides : UpdateRule
+ {
+ public override string Name { get { return "AttackSuicides trait has been removed."; } }
+ public override string Description
+ {
+ get
+ {
+ return "The AttackSuicides trait has been removed, and should be replaced by\n" +
+ "AttackFrontal + GrantConditionOnAttack + GrantConditionOnDeploy + a dummy\n" +
+ "weapon for targeting. Affected actors are listed so that these traits can be defined.";
+ }
+ }
+
+ readonly List locations = new List();
+
+ public override IEnumerable AfterUpdate(ModData modData)
+ {
+ if (locations.Any())
+ yield return "The AttackSuicides trait has been removed from the following actors.\n" +
+ "You must manually define AttackFrontal, GrantConditionOnAttack, GrantConditionOnDeploy\n" +
+ "traits and create a dummy weapon to use for targeting:\n" +
+ UpdateUtils.FormatMessageList(locations);
+
+ locations.Clear();
+ }
+
+ public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode)
+ {
+ if (actorNode.RemoveNodes("AttackSuicides") > 0)
+ locations.Add("{0} ({1})".F(actorNode.Key, actorNode.Location.Filename));
+
+ yield break;
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs
index d5313ef5f8..023e2e87c6 100644
--- a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs
+++ b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs
@@ -86,7 +86,7 @@ namespace OpenRA.Mods.Common.UpdateRules
new UpdatePath("release-20180923", "release-20181215", new UpdateRule[0]),
- new UpdatePath("release-20181215", new UpdateRule[]
+ new UpdatePath("release-20181215", "playtest-20190106", new UpdateRule[]
{
// Bleed only changes here
new AddCarryableHarvester(),
@@ -113,6 +113,11 @@ namespace OpenRA.Mods.Common.UpdateRules
new RemoveAttackIgnoresVisibility(),
new ReplacedWithChargeAnimation(),
new RefactorResourceLevelAnimating(),
+ }),
+
+ new UpdatePath("playtest-20190106", new UpdateRule[]
+ {
+ new RemoveAttackSuicides(),
})
};