diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
index 3bb01cbe2c..e94dceabe4 100644
--- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
+++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
@@ -434,6 +434,7 @@
+
diff --git a/OpenRA.Mods.Common/Orders/DeployOrderTargeter.cs b/OpenRA.Mods.Common/Orders/DeployOrderTargeter.cs
index 5450883ed4..8337d6dfc4 100644
--- a/OpenRA.Mods.Common/Orders/DeployOrderTargeter.cs
+++ b/OpenRA.Mods.Common/Orders/DeployOrderTargeter.cs
@@ -16,18 +16,18 @@ namespace OpenRA.Mods.Common.Orders
{
public class DeployOrderTargeter : IOrderTargeter
{
- readonly Func useDeployCursor;
+ readonly Func cursor;
public DeployOrderTargeter(string order, int priority)
- : this(order, priority, () => true)
+ : this(order, priority, () => "deploy")
{
}
- public DeployOrderTargeter(string order, int priority, Func useDeployCursor)
+ public DeployOrderTargeter(string order, int priority, Func cursor)
{
this.OrderID = order;
this.OrderPriority = priority;
- this.useDeployCursor = useDeployCursor;
+ this.cursor = cursor;
}
public string OrderID { get; private set; }
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Orders
return false;
IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
- cursor = useDeployCursor() ? "deploy" : "deploy-blocked";
+ cursor = this.cursor();
return self == target.Actor;
}
diff --git a/OpenRA.Mods.Common/Traits/Cargo.cs b/OpenRA.Mods.Common/Traits/Cargo.cs
index cae349598b..c973075599 100644
--- a/OpenRA.Mods.Common/Traits/Cargo.cs
+++ b/OpenRA.Mods.Common/Traits/Cargo.cs
@@ -30,6 +30,12 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Which direction the passenger will face (relative to the transport) when unloading.")]
public readonly int PassengerFacing = 128;
+ [Desc("Cursor to display when able to unload the passengers.")]
+ public readonly string UnloadCursor = "deploy";
+
+ [Desc("Cursor to display when unable to unload the passengers.")]
+ public readonly string UnloadBlockedCursor = "deploy-blocked";
+
public object Create(ActorInitializer init) { return new Cargo(init, this); }
}
@@ -99,7 +105,8 @@ namespace OpenRA.Mods.Common.Traits
public IEnumerable Orders
{
- get { yield return new DeployOrderTargeter("Unload", 10, CanUnload); }
+ get { yield return new DeployOrderTargeter("Unload", 10,
+ () => CanUnload() ? Info.UnloadCursor : Info.UnloadBlockedCursor); }
}
public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)
@@ -170,7 +177,7 @@ namespace OpenRA.Mods.Common.Traits
if (order.OrderString != "Unload")
return null;
- return CanUnload() ? "deploy" : "deploy-blocked";
+ return CanUnload() ? Info.UnloadCursor : Info.UnloadBlockedCursor;
}
public string VoicePhraseForOrder(Actor self, Order order)
diff --git a/OpenRA.Mods.Common/Traits/Transforms.cs b/OpenRA.Mods.Common/Traits/Transforms.cs
index 6bbe0cae65..c3f4845593 100644
--- a/OpenRA.Mods.Common/Traits/Transforms.cs
+++ b/OpenRA.Mods.Common/Traits/Transforms.cs
@@ -39,6 +39,12 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Notification to play when the transformation is blocked.")]
public readonly string NoTransformNotification = null;
+ [Desc("Cursor to display when able to (un)deploy the actor.")]
+ public readonly string DeployCursor = "deploy";
+
+ [Desc("Cursor to display when unable to (un)deploy the actor.")]
+ public readonly string DeployBlockedCursor = "deploy-blocked";
+
public virtual object Create(ActorInitializer init) { return new Transforms(init, this); }
}
@@ -73,7 +79,8 @@ namespace OpenRA.Mods.Common.Traits
public IEnumerable Orders
{
- get { yield return new DeployOrderTargeter("DeployTransform", 5, () => CanDeploy()); }
+ get { yield return new DeployOrderTargeter("DeployTransform", 5,
+ () => CanDeploy() ? info.DeployCursor : info.DeployBlockedCursor); }
}
public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)
diff --git a/OpenRA.Mods.Common/Traits/Upgrades/DeployToUpgrade.cs b/OpenRA.Mods.Common/Traits/Upgrades/DeployToUpgrade.cs
new file mode 100644
index 0000000000..e22fcb2cc2
--- /dev/null
+++ b/OpenRA.Mods.Common/Traits/Upgrades/DeployToUpgrade.cs
@@ -0,0 +1,101 @@
+#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;
+using System.Collections.Generic;
+using System.Linq;
+using OpenRA.Mods.Common.Orders;
+using OpenRA.Traits;
+
+namespace OpenRA.Mods.Common.Traits
+{
+ public class DeployToUpgradeInfo : ITraitInfo, Requires
+ {
+ [Desc("The upgrades to grant when deploying and revoke when undeploying.")]
+ public readonly string[] Upgrades = { };
+
+ [Desc("The terrain types that this actor can deploy on to receive these upgrades." +
+ "Leave empty to allow any.")]
+ public readonly string[] AllowedTerrainTypes = { };
+
+ [Desc("Cursor to display when able to (un)deploy the actor.")]
+ public readonly string DeployCursor = "deploy";
+
+ [Desc("Cursor to display when unable to (un)deploy the actor.")]
+ public readonly string DeployBlockedCursor = "deploy-blocked";
+
+ public object Create(ActorInitializer init) { return new DeployToUpgrade(init.Self, this); }
+ }
+
+ public class DeployToUpgrade : IResolveOrder, IIssueOrder
+ {
+ readonly Actor self;
+ readonly DeployToUpgradeInfo info;
+ readonly UpgradeManager manager;
+ readonly bool checkTerrainType;
+
+ bool isUpgraded;
+
+ public DeployToUpgrade(Actor self, DeployToUpgradeInfo info)
+ {
+ this.self = self;
+ this.info = info;
+ manager = self.Trait();
+ checkTerrainType = info.AllowedTerrainTypes.Length > 0;
+ }
+
+ public IEnumerable Orders
+ {
+ get { yield return new DeployOrderTargeter("DeployToUpgrade", 5,
+ () => OnValidTerrain() ? info.DeployCursor : info.DeployBlockedCursor); }
+ }
+
+ public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)
+ {
+ if (order.OrderID == "DeployToUpgrade")
+ return new Order(order.OrderID, self, queued);
+
+ return null;
+ }
+
+ public void ResolveOrder(Actor self, Order order)
+ {
+ if (order.OrderString != "DeployToUpgrade")
+ return;
+
+ if (!OnValidTerrain())
+ return;
+
+ if (isUpgraded)
+ foreach (var up in info.Upgrades)
+ manager.RevokeUpgrade(self, up, this);
+ else
+ foreach (var up in info.Upgrades)
+ manager.GrantUpgrade(self, up, this);
+
+ isUpgraded = !isUpgraded;
+ }
+
+ bool OnValidTerrain()
+ {
+ if (!self.World.Map.Contains(self.Location))
+ return false;
+
+ if (!checkTerrainType)
+ return true;
+
+ var tileSet = self.World.TileSet;
+ var tiles = self.World.Map.MapTiles.Value;
+ var terrainType = tileSet[tileSet.GetTerrainIndex(tiles[self.Location])].Type;
+
+ return info.AllowedTerrainTypes.Contains(terrainType);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs b/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs
index b40633b46f..a854713dff 100644
--- a/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs
+++ b/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs
@@ -135,6 +135,7 @@ namespace OpenRA.Mods.Common.Widgets
PerformKeyboardOrderOnSelection(a => new Order("DeployTransform", a, false));
PerformKeyboardOrderOnSelection(a => new Order("Unload", a, false));
PerformKeyboardOrderOnSelection(a => new Order("Detonate", a, false));
+ PerformKeyboardOrderOnSelection(a => new Order("DeployToUpgrade", a, false));
return true;
}
diff --git a/OpenRA.Mods.RA/Traits/PortableChrono.cs b/OpenRA.Mods.RA/Traits/PortableChrono.cs
index 5c7328f66a..3c67999a08 100644
--- a/OpenRA.Mods.RA/Traits/PortableChrono.cs
+++ b/OpenRA.Mods.RA/Traits/PortableChrono.cs
@@ -35,6 +35,12 @@ namespace OpenRA.Mods.RA.Traits
[Desc("Display rectangles indicating the current charge status")]
public readonly int Pips = 2;
+ [Desc("Cursor to display when able to deploy the actor.")]
+ public readonly string DeployCursor = "deploy";
+
+ [Desc("Cursor to display when unable to deploy the actor.")]
+ public readonly string DeployBlockedCursor = "deploy-blocked";
+
public object Create(ActorInitializer init) { return new PortableChrono(this); }
}
@@ -59,7 +65,8 @@ namespace OpenRA.Mods.RA.Traits
get
{
yield return new PortableChronoOrderTargeter();
- yield return new DeployOrderTargeter("PortableChronoDeploy", 5, () => CanTeleport);
+ yield return new DeployOrderTargeter("PortableChronoDeploy", 5,
+ () => CanTeleport ? Info.DeployCursor : Info.DeployBlockedCursor);
}
}