diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
index c1d5b9637b..1ba63077b9 100644
--- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
+++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
@@ -323,7 +323,6 @@
-
diff --git a/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs
index 5e87dcf2d5..90172da7f8 100644
--- a/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs
+++ b/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs
@@ -71,7 +71,20 @@ namespace OpenRA.Mods.Common.Scripting
if (!Context.World.Map.Rules.Actors.TryGetValue(type, out ai))
throw new LuaException("Unknown actor type '{0}'".F(type));
- return ai.GetBuildTime();
+ var bi = ai.TraitInfoOrDefault();
+
+ if (bi == null)
+ return 0;
+
+ var time = bi.BuildDuration;
+ if (time == -1)
+ {
+ var valued = ai.TraitInfoOrDefault();
+ time = valued != null ? valued.Cost : 0;
+ }
+
+ time = time * bi.BuildDurationModifier / 100;
+ return time;
}
[Desc("Returns the cruise altitude of the requested unit type (zero if it is ground-based).")]
diff --git a/OpenRA.Mods.Common/Traits/Buildable.cs b/OpenRA.Mods.Common/Traits/Buildable.cs
index b498deb16d..441d706cbd 100644
--- a/OpenRA.Mods.Common/Traits/Buildable.cs
+++ b/OpenRA.Mods.Common/Traits/Buildable.cs
@@ -37,6 +37,12 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Palette used for the production icon.")]
[PaletteReference] public readonly string IconPalette = "chrome";
+ [Desc("Base build time in frames (-1 indicates to use the unit's Value).")]
+ public readonly int BuildDuration = -1;
+
+ [Desc("Percentage modifier to apply to the build duration.")]
+ public readonly int BuildDurationModifier = 150;
+
// TODO: UI fluff; doesn't belong here
public readonly int BuildPaletteOrder = 9999;
}
diff --git a/OpenRA.Mods.Common/Traits/CustomBuildTimeValue.cs b/OpenRA.Mods.Common/Traits/CustomBuildTimeValue.cs
deleted file mode 100644
index 9c81615fc5..0000000000
--- a/OpenRA.Mods.Common/Traits/CustomBuildTimeValue.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-#region Copyright & License Information
-/*
- * Copyright 2007-2016 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 OpenRA.Traits;
-
-namespace OpenRA.Mods.Common.Traits
-{
- [Desc("Overrides the build time calculated by actor value.")]
- public class CustomBuildTimeValueInfo : TraitInfo
- {
- [FieldLoader.Require]
- [Desc("Measured in ticks.")]
- public readonly int Value = 0;
- }
-
- public class CustomBuildTimeValue { }
-
- public static class CustomBuildTimeValueExts
- {
- const int FramesPerMin = 25 * 60;
-
- public static int GetBuildTime(this ActorInfo a)
- {
- var csv = a.TraitInfoOrDefault();
- if (csv != null)
- return csv.Value;
-
- var cost = a.HasTraitInfo() ? a.TraitInfo().Cost : 0;
- return cost * FramesPerMin / 1000;
- }
- }
-}
diff --git a/OpenRA.Mods.Common/Traits/Player/ClassicProductionQueue.cs b/OpenRA.Mods.Common/Traits/Player/ClassicProductionQueue.cs
index ebbc5c6839..d6da7ea755 100644
--- a/OpenRA.Mods.Common/Traits/Player/ClassicProductionQueue.cs
+++ b/OpenRA.Mods.Common/Traits/Player/ClassicProductionQueue.cs
@@ -120,19 +120,20 @@ namespace OpenRA.Mods.Common.Traits
public override int GetBuildTime(string unitString)
{
- return GetBuildTime(self.World.Map.Rules.Actors[unitString]);
+ var actorInfo = self.World.Map.Rules.Actors[unitString];
+ return GetBuildTime(actorInfo, actorInfo.TraitInfo());
}
- public override int GetBuildTime(ActorInfo unit, BuildableInfo bi = null)
+ public override int GetBuildTime(ActorInfo unit, BuildableInfo bi)
{
if (developerMode.FastBuild)
return 0;
- var time = unit.GetBuildTime() * Info.BuildSpeed / 100;
+ var time = base.GetBuildTime(unit, bi);
if (info.SpeedUp)
{
- var type = (bi ?? unit.TraitInfo()).BuildAtProductionType ?? info.Type;
+ var type = bi.BuildAtProductionType ?? info.Type;
var selfsameProductionsCount = self.World.ActorsWithTrait()
.Count(p => p.Actor.Owner == self.Owner && p.Trait.Info.Produces.Contains(type));
diff --git a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs
index 51c92e46de..81f7d01f20 100644
--- a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs
+++ b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs
@@ -311,15 +311,23 @@ namespace OpenRA.Mods.Common.Traits
public virtual int GetBuildTime(string unitString)
{
- return GetBuildTime(self.World.Map.Rules.Actors[unitString]);
+ var actorInfo = self.World.Map.Rules.Actors[unitString];
+ return GetBuildTime(actorInfo, actorInfo.TraitInfo());
}
- public virtual int GetBuildTime(ActorInfo unit, BuildableInfo bi = null)
+ public virtual int GetBuildTime(ActorInfo unit, BuildableInfo bi)
{
if (developerMode.FastBuild)
return 0;
- var time = unit.GetBuildTime() * Info.BuildSpeed / 100;
+ var time = bi.BuildDuration;
+ if (time == -1)
+ {
+ var valued = unit.TraitInfoOrDefault();
+ time = valued != null ? valued.Cost : 0;
+ }
+
+ time = time * bi.BuildDurationModifier * Info.BuildSpeed / 10000;
return time;
}
diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs
index 91d6fc7dec..367b2bf19f 100644
--- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs
+++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs
@@ -292,7 +292,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
// DisplayTimer was replaced by DisplayTimerStances
- if (engineVersion < 20160710)
+ if (engineVersion < 20160820)
{
if (node.Key == "DisplayTimer")
{
@@ -305,6 +305,30 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
}
+ if (engineVersion < 20160821)
+ {
+ // Shifted custom build time properties to Buildable
+ if (depth == 0)
+ {
+ var cbtv = node.Value.Nodes.FirstOrDefault(n => n.Key == "CustomBuildTimeValue");
+ if (cbtv != null)
+ {
+ var bi = node.Value.Nodes.FirstOrDefault(n => n.Key == "Buildable");
+
+ if (bi == null)
+ node.Value.Nodes.Add(bi = new MiniYamlNode("Buildable", ""));
+
+ var value = cbtv.Value.Nodes.First(n => n.Key == "Value");
+ value.Key = "BuildDuration";
+ bi.Value.Nodes.Add(value);
+ bi.Value.Nodes.Add(new MiniYamlNode("BuildDurationModifier", "100"));
+ }
+
+ node.Value.Nodes.RemoveAll(n => n.Key == "CustomBuildTimeValue");
+ node.Value.Nodes.RemoveAll(n => n.Key == "-CustomBuildTimeValue");
+ }
+ }
+
UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1);
}