diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
index 7ddbb3a6a0..d1ba89c909 100644
--- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
+++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
@@ -199,6 +199,7 @@
+
diff --git a/OpenRA.Mods.Common/Scripting/Properties/UpgradeProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/UpgradeProperties.cs
index eba3b40e6e..c0d016b38b 100644
--- a/OpenRA.Mods.Common/Scripting/Properties/UpgradeProperties.cs
+++ b/OpenRA.Mods.Common/Scripting/Properties/UpgradeProperties.cs
@@ -8,6 +8,9 @@
*/
#endregion
+using System;
+using System.IO;
+using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Scripting;
using OpenRA.Traits;
@@ -17,35 +20,56 @@ namespace OpenRA.Mods.Common.Scripting
[ScriptPropertyGroup("General")]
public class UpgradeProperties : ScriptActorProperties, Requires
{
- UpgradeManager um;
+ readonly UpgradeManager um;
+ readonly ScriptUpgradesCache validUpgrades;
+
public UpgradeProperties(ScriptContext context, Actor self)
: base(context, self)
{
um = self.Trait();
+ validUpgrades = self.World.WorldActor.TraitOrDefault();
}
[Desc("Grant an upgrade to this actor.")]
public void GrantUpgrade(string upgrade)
{
- um.GrantUpgrade(Self, upgrade, this);
+ if (validUpgrades == null)
+ throw new InvalidOperationException("Can not grant upgrades because there is no ScriptUpgradesCache defined!");
+
+ if (validUpgrades.Info.Upgrades.Contains(upgrade))
+ um.GrantUpgrade(Self, upgrade, this);
+ else
+ throw new InvalidDataException("The ScriptUpgradesCache does not contain a definition for upgrade `{0}`".F(upgrade));
}
[Desc("Revoke an upgrade that was previously granted using GrantUpgrade.")]
public void RevokeUpgrade(string upgrade)
{
- um.RevokeUpgrade(Self, upgrade, this);
+ if (validUpgrades == null)
+ throw new InvalidOperationException("Can not grant upgrades because there is no ScriptUpgradesCache defined!");
+
+ if (validUpgrades.Info.Upgrades.Contains(upgrade))
+ um.RevokeUpgrade(Self, upgrade, this);
+ else
+ throw new InvalidDataException("The ScriptUpgradesCache does not contain a definition for upgrade `{0}`".F(upgrade));
}
[Desc("Grant a limited-time upgrade to this actor.")]
public void GrantTimedUpgrade(string upgrade, int duration)
{
- um.GrantTimedUpgrade(Self, upgrade, duration);
+ if (validUpgrades == null)
+ throw new InvalidOperationException("Can not grant upgrades because there is no ScriptUpgradesCache defined!");
+
+ if (validUpgrades.Info.Upgrades.Contains(upgrade))
+ um.GrantTimedUpgrade(Self, upgrade, duration);
+ else
+ throw new InvalidDataException("The ScriptUpgradesCache does not contain a definition for upgrade `{0}`".F(upgrade));
}
[Desc("Check whether this actor accepts a specific upgrade.")]
public bool AcceptsUpgrade(string upgrade)
{
- return um.AcceptsUpgrade(Self, upgrade);
+ return validUpgrades != null && validUpgrades.Info.Upgrades.Contains(upgrade) && um.AcceptsUpgrade(Self, upgrade);
}
}
}
\ No newline at end of file
diff --git a/OpenRA.Mods.Common/Scripting/ScriptUpgradesCache.cs b/OpenRA.Mods.Common/Scripting/ScriptUpgradesCache.cs
new file mode 100644
index 0000000000..8ed69dfc0c
--- /dev/null
+++ b/OpenRA.Mods.Common/Scripting/ScriptUpgradesCache.cs
@@ -0,0 +1,33 @@
+#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 OpenRA.Traits;
+
+namespace OpenRA.Mods.Common.Scripting
+{
+ [Desc("Allows granting upgrades to actors from Lua scripts.")]
+ public class ScriptUpgradesCacheInfo : ITraitInfo
+ {
+ [Desc("Upgrades that can be granted from the scripts.")]
+ public readonly string[] Upgrades = { };
+
+ public object Create(ActorInitializer init) { return new ScriptUpgradesCache(this); }
+ }
+
+ public sealed class ScriptUpgradesCache
+ {
+ public readonly ScriptUpgradesCacheInfo Info;
+
+ public ScriptUpgradesCache(ScriptUpgradesCacheInfo info)
+ {
+ Info = info;
+ }
+ }
+}
diff --git a/mods/ra/maps/desert-shellmap/map.yaml b/mods/ra/maps/desert-shellmap/map.yaml
index f1a3e27e83..04ffff3df0 100644
--- a/mods/ra/maps/desert-shellmap/map.yaml
+++ b/mods/ra/maps/desert-shellmap/map.yaml
@@ -1259,6 +1259,8 @@ Rules:
ValuePerUnit: 0
LuaScript:
Scripts: desert-shellmap.lua
+ ScriptUpgradesCache:
+ Upgrades: unkillable
-StartGameNotification:
^Vehicle:
GivesBounty:
diff --git a/mods/ra/maps/fort-lonestar/map.yaml b/mods/ra/maps/fort-lonestar/map.yaml
index 175e16a0ee..b05d28267f 100644
--- a/mods/ra/maps/fort-lonestar/map.yaml
+++ b/mods/ra/maps/fort-lonestar/map.yaml
@@ -488,6 +488,8 @@ Rules:
-MPStartLocations:
LuaScript:
Scripts: fort-lonestar.lua
+ ScriptUpgradesCache:
+ Upgrades: unkillable
FORTCRATE:
Inherits: ^Crate
SupportPowerCrateAction@parabombs: