Implemented InfiniteBuildAfter.
This commit is contained in:
@@ -53,7 +53,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
protected override void BeginProduction(ProductionItem item, bool hasPriority)
|
protected override void BeginProduction(ProductionItem item, bool hasPriority)
|
||||||
{
|
{
|
||||||
// Ignore `hasPriority` as it's not relevant in parallel production context.
|
// Ignore `hasPriority` as it's not relevant in parallel production context.
|
||||||
Queue.Add(item);
|
base.BeginProduction(item, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int RemainingTimeActual(ProductionItem item)
|
public override int RemainingTimeActual(ProductionItem item)
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
[Desc("The build time is multiplied with this percentage on low power.")]
|
[Desc("The build time is multiplied with this percentage on low power.")]
|
||||||
public readonly int LowPowerModifier = 100;
|
public readonly int LowPowerModifier = 100;
|
||||||
|
|
||||||
|
[Desc("Production items that have more than this many items in the queue will be produced in a loop.")]
|
||||||
|
public readonly int InfiniteBuildLimit = -1;
|
||||||
|
|
||||||
[NotificationReference("Speech")]
|
[NotificationReference("Speech")]
|
||||||
[Desc("Notification played when production is complete.",
|
[Desc("Notification played when production is complete.",
|
||||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||||
@@ -455,10 +458,20 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var item = Queue.LastOrDefault(a => a.Item == itemName);
|
var item = Queue.LastOrDefault(a => a.Item == itemName);
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
|
{
|
||||||
|
if (item.Infinite)
|
||||||
|
{
|
||||||
|
item.Infinite = false;
|
||||||
|
for (var i = 1; i < Info.InfiniteBuildLimit; i++)
|
||||||
|
Queue.Add(new ProductionItem(this, item.Item, item.TotalCost, playerPower, item.OnComplete));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// Refund what has been paid
|
// Refund what has been paid
|
||||||
playerResources.GiveCash(item.TotalCost - item.RemainingCost);
|
playerResources.GiveCash(item.TotalCost - item.RemainingCost);
|
||||||
EndProduction(item);
|
EndProduction(item);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,14 +481,37 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public void EndProduction(ProductionItem item)
|
public void EndProduction(ProductionItem item)
|
||||||
{
|
{
|
||||||
Queue.Remove(item);
|
Queue.Remove(item);
|
||||||
|
|
||||||
|
if (item.Infinite)
|
||||||
|
Queue.Add(new ProductionItem(this, item.Item, item.TotalCost, playerPower, item.OnComplete) { Infinite = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void BeginProduction(ProductionItem item, bool hasPriority)
|
protected virtual void BeginProduction(ProductionItem item, bool hasPriority)
|
||||||
{
|
{
|
||||||
|
if (Queue.Any(i => i.Item == item.Item && i.Infinite))
|
||||||
|
return;
|
||||||
|
|
||||||
if (hasPriority && Queue.Count > 1)
|
if (hasPriority && Queue.Count > 1)
|
||||||
Queue.Insert(1, item);
|
Queue.Insert(1, item);
|
||||||
else
|
else
|
||||||
Queue.Add(item);
|
Queue.Add(item);
|
||||||
|
|
||||||
|
if (Info.InfiniteBuildLimit < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var queued = Queue.FindAll(i => i.Item == item.Item);
|
||||||
|
|
||||||
|
if (queued.Count <= Info.InfiniteBuildLimit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
queued[0].Infinite = true;
|
||||||
|
|
||||||
|
for (var i = 1; i < queued.Count; i++)
|
||||||
|
{
|
||||||
|
// Refund what has been paid
|
||||||
|
playerResources.GiveCash(queued[i].TotalCost - queued[i].RemainingCost);
|
||||||
|
EndProduction(queued[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual int RemainingTimeActual(ProductionItem item)
|
public virtual int RemainingTimeActual(ProductionItem item)
|
||||||
@@ -552,6 +588,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public bool Done { get; private set; }
|
public bool Done { get; private set; }
|
||||||
public bool Started { get; private set; }
|
public bool Started { get; private set; }
|
||||||
public int Slowdown { get; private set; }
|
public int Slowdown { get; private set; }
|
||||||
|
public bool Infinite { get; set; }
|
||||||
|
|
||||||
readonly ActorInfo ai;
|
readonly ActorInfo ai;
|
||||||
readonly BuildableInfo bi;
|
readonly BuildableInfo bi;
|
||||||
@@ -567,6 +604,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
this.pm = pm;
|
this.pm = pm;
|
||||||
ai = Queue.Actor.World.Map.Rules.Actors[Item];
|
ai = Queue.Actor.World.Map.Rules.Actors[Item];
|
||||||
bi = ai.TraitInfo<BuildableInfo>();
|
bi = ai.TraitInfo<BuildableInfo>();
|
||||||
|
Infinite = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Tick(PlayerResources pr)
|
public void Tick(PlayerResources pr)
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
|
|
||||||
[Translate] public readonly string ReadyText = "";
|
[Translate] public readonly string ReadyText = "";
|
||||||
[Translate] public readonly string HoldText = "";
|
[Translate] public readonly string HoldText = "";
|
||||||
|
[Translate] public readonly string InfiniteSymbol = "\u221E";
|
||||||
|
|
||||||
public int DisplayedIconCount { get; private set; }
|
public int DisplayedIconCount { get; private set; }
|
||||||
public int TotalIconCount { get; private set; }
|
public int TotalIconCount { get; private set; }
|
||||||
@@ -102,8 +103,8 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
|
|
||||||
readonly WorldRenderer worldRenderer;
|
readonly WorldRenderer worldRenderer;
|
||||||
|
|
||||||
SpriteFont overlayFont;
|
SpriteFont overlayFont, symbolFont;
|
||||||
float2 holdOffset, readyOffset, timeOffset, queuedOffset;
|
float2 holdOffset, readyOffset, timeOffset, queuedOffset, infiniteOffset;
|
||||||
|
|
||||||
[CustomLintableHotkeyNames]
|
[CustomLintableHotkeyNames]
|
||||||
public static IEnumerable<string> LinterHotkeyNames(MiniYamlNode widgetNode, Action<string> emitError, Action<string> emitWarning)
|
public static IEnumerable<string> LinterHotkeyNames(MiniYamlNode widgetNode, Action<string> emitError, Action<string> emitWarning)
|
||||||
@@ -141,6 +142,9 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
cantBuild = new Animation(world, NotBuildableAnimation);
|
cantBuild = new Animation(world, NotBuildableAnimation);
|
||||||
cantBuild.PlayFetchIndex(NotBuildableSequence, () => 0);
|
cantBuild.PlayFetchIndex(NotBuildableSequence, () => 0);
|
||||||
clock = new Animation(world, ClockAnimation);
|
clock = new Animation(world, ClockAnimation);
|
||||||
|
|
||||||
|
overlayFont = Game.Renderer.Fonts["TinyBold"];
|
||||||
|
Game.Renderer.Fonts.TryGetValue("Symbols", out symbolFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize(WidgetArgs args)
|
public override void Initialize(WidgetArgs args)
|
||||||
@@ -283,6 +287,8 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
Game.Sound.Play(SoundType.UI, TabClick);
|
Game.Sound.Play(SoundType.UI, TabClick);
|
||||||
string notification;
|
string notification;
|
||||||
var canQueue = CurrentQueue.CanQueue(buildable, out notification);
|
var canQueue = CurrentQueue.CanQueue(buildable, out notification);
|
||||||
|
|
||||||
|
if (!CurrentQueue.AllQueued().Any(qi => qi.Item == icon.Name && !qi.Paused && qi.Infinite))
|
||||||
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", notification, World.LocalPlayer.Faction.InternalName);
|
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", notification, World.LocalPlayer.Faction.InternalName);
|
||||||
|
|
||||||
if (canQueue)
|
if (canQueue)
|
||||||
@@ -423,12 +429,16 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
{
|
{
|
||||||
var iconOffset = 0.5f * IconSize.ToFloat2() + IconSpriteOffset;
|
var iconOffset = 0.5f * IconSize.ToFloat2() + IconSpriteOffset;
|
||||||
|
|
||||||
overlayFont = Game.Renderer.Fonts["TinyBold"];
|
|
||||||
timeOffset = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0, World.Timestep)) / 2;
|
timeOffset = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0, World.Timestep)) / 2;
|
||||||
queuedOffset = new float2(4, 2);
|
queuedOffset = new float2(4, 2);
|
||||||
holdOffset = iconOffset - overlayFont.Measure(HoldText) / 2;
|
holdOffset = iconOffset - overlayFont.Measure(HoldText) / 2;
|
||||||
readyOffset = iconOffset - overlayFont.Measure(ReadyText) / 2;
|
readyOffset = iconOffset - overlayFont.Measure(ReadyText) / 2;
|
||||||
|
|
||||||
|
if (ChromeMetrics.TryGet("InfiniteOffset", out infiniteOffset))
|
||||||
|
infiniteOffset += queuedOffset;
|
||||||
|
else
|
||||||
|
infiniteOffset = queuedOffset;
|
||||||
|
|
||||||
if (CurrentQueue == null)
|
if (CurrentQueue == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -485,7 +495,11 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
icon.Pos + timeOffset,
|
icon.Pos + timeOffset,
|
||||||
Color.White, Color.Black, 1);
|
Color.White, Color.Black, 1);
|
||||||
|
|
||||||
if (total > 1 || waiting)
|
if (first.Infinite)
|
||||||
|
symbolFont.DrawTextWithContrast(InfiniteSymbol,
|
||||||
|
icon.Pos + infiniteOffset,
|
||||||
|
Color.White, Color.Black, 1);
|
||||||
|
else if (total > 1 || waiting)
|
||||||
overlayFont.DrawTextWithContrast(total.ToString(),
|
overlayFont.DrawTextWithContrast(total.ToString(),
|
||||||
icon.Pos + queuedOffset,
|
icon.Pos + queuedOffset,
|
||||||
Color.White, Color.Black, 1);
|
Color.White, Color.Black, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user