From dcc11c7a4153b576eb0273d0b6c839aa252e587c Mon Sep 17 00:00:00 2001 From: teinarss Date: Fri, 4 May 2018 21:20:50 +0200 Subject: [PATCH] Added HpPerStep to Repairable for enable repair speed to be changed per unit. --- OpenRA.Mods.Common/Activities/Repair.cs | 4 +++- OpenRA.Mods.Common/Traits/Repairable.cs | 15 +++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/OpenRA.Mods.Common/Activities/Repair.cs b/OpenRA.Mods.Common/Activities/Repair.cs index 71bee64b1a..7cc87b6e38 100644 --- a/OpenRA.Mods.Common/Activities/Repair.cs +++ b/OpenRA.Mods.Common/Activities/Repair.cs @@ -23,6 +23,7 @@ namespace OpenRA.Mods.Common.Activities readonly RepairsUnits[] allRepairsUnits; readonly Target host; readonly WDist closeEnough; + readonly Repairable repairable; int remainingTicks; bool played = false; @@ -33,6 +34,7 @@ namespace OpenRA.Mods.Common.Activities this.closeEnough = closeEnough; allRepairsUnits = host.TraitsImplementing().ToArray(); health = self.TraitOrDefault(); + repairable = self.TraitOrDefault(); } protected override void OnFirstRun(Actor self) @@ -97,7 +99,7 @@ namespace OpenRA.Mods.Common.Activities if (remainingTicks == 0) { var unitCost = self.Info.TraitInfo().Cost; - var hpToRepair = repairsUnits.Info.HpPerStep; + var hpToRepair = repairable != null && repairable.Info.HpPerStep > 0 ? repairable.Info.HpPerStep : repairsUnits.Info.HpPerStep; // Cast to long to avoid overflow when multiplying by the health var cost = Math.Max(1, (int)(((long)hpToRepair * unitCost * repairsUnits.Info.ValuePercentage) / (health.MaxHP * 100L))); diff --git a/OpenRA.Mods.Common/Traits/Repairable.cs b/OpenRA.Mods.Common/Traits/Repairable.cs index 7ba54e84e5..67e2b055b7 100644 --- a/OpenRA.Mods.Common/Traits/Repairable.cs +++ b/OpenRA.Mods.Common/Traits/Repairable.cs @@ -26,19 +26,22 @@ namespace OpenRA.Mods.Common.Traits [VoiceReference] public readonly string Voice = "Action"; + [Desc("The amount the unit will be repaired at each step. Use -1 for fallback behavior where HpPerStep from RepairUnit trait will be used.")] + public readonly int HpPerStep = -1; + public virtual object Create(ActorInitializer init) { return new Repairable(init.Self, this); } } class Repairable : IIssueOrder, IResolveOrder, IOrderVoice { - readonly RepairableInfo info; + public readonly RepairableInfo Info; readonly Health health; readonly IMove movement; readonly AmmoPool[] ammoPools; public Repairable(Actor self, RepairableInfo info) { - this.info = info; + Info = info; health = self.Trait(); movement = self.Trait(); ammoPools = self.TraitsImplementing().ToArray(); @@ -62,12 +65,12 @@ namespace OpenRA.Mods.Common.Traits bool CanRepairAt(Actor target) { - return info.RepairBuildings.Contains(target.Info.Name); + return Info.RepairBuildings.Contains(target.Info.Name); } bool CanRearmAt(Actor target) { - return info.RepairBuildings.Contains(target.Info.Name); + return Info.RepairBuildings.Contains(target.Info.Name); } bool CanRepair() @@ -82,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits public string VoicePhraseForOrder(Actor self, Order order) { - return (order.OrderString == "Repair" && CanRepair()) ? info.Voice : null; + return (order.OrderString == "Repair" && CanRepair()) ? Info.Voice : null; } public void ResolveOrder(Actor self, Order order) @@ -133,7 +136,7 @@ namespace OpenRA.Mods.Common.Traits var repairBuilding = self.World.ActorsWithTrait() .Where(a => !a.Actor.IsDead && a.Actor.IsInWorld && a.Actor.Owner.IsAlliedWith(self.Owner) && - info.RepairBuildings.Contains(a.Actor.Info.Name)) + Info.RepairBuildings.Contains(a.Actor.Info.Name)) .OrderBy(p => (self.Location - p.Actor.Location).LengthSquared); // Worst case FirstOrDefault() will return a TraitPair, which is OK.