diff --git a/OpenRA.Game/Traits/Building.cs b/OpenRA.Game/Traits/Building.cs index 0f82aa7c56..b659ee42ae 100644 --- a/OpenRA.Game/Traits/Building.cs +++ b/OpenRA.Game/Traits/Building.cs @@ -65,34 +65,22 @@ namespace OpenRA.Traits public int GetPowerUsage() { - var modifier = self - .TraitsImplementing() - .Select(t => t.GetPowerModifier()) - .Product(); + if (Info.Power <= 0) + return Info.Power; - if (Info.Power > 0) - { - var health = self.TraitOrDefault(); - var healthFraction = (health == null) ? 1f : health.HPFraction; - return (int)(modifier * healthFraction * Info.Power); - } - else - return (int)(modifier * Info.Power); + var health = self.TraitOrDefault(); + var healthFraction = (health == null) ? 1f : health.HPFraction; + return (int)(healthFraction * Info.Power); } public void Damaged(Actor self, AttackInfo e) { // Power plants lose power with damage if (Info.Power > 0) - { - var modifier = self - .TraitsImplementing() - .Select(t => t.GetPowerModifier()) - .Product(); - + { var health = self.TraitOrDefault(); var healthFraction = (health == null) ? 1f : health.HPFraction; - PlayerPower.UpdateActor(self, (int)(modifier * healthFraction * Info.Power)); + PlayerPower.UpdateActor(self, (int)(healthFraction * Info.Power)); } if (e.DamageState == DamageState.Dead) diff --git a/OpenRA.Game/Traits/Player/PowerManager.cs b/OpenRA.Game/Traits/Player/PowerManager.cs index cafa2ec19e..f8fc78eafb 100644 --- a/OpenRA.Game/Traits/Player/PowerManager.cs +++ b/OpenRA.Game/Traits/Player/PowerManager.cs @@ -11,6 +11,7 @@ using System; using System.Linq; using System.Collections.Generic; +using OpenRA.FileFormats; namespace OpenRA.Traits { @@ -25,7 +26,8 @@ namespace OpenRA.Traits PowerManagerInfo Info; Player Player; - Dictionary PowerDrain = new Dictionary(); + Dictionary> Overrides = new Dictionary>(); + Dictionary PowerDrain = new Dictionary(); [Sync] int totalProvided; public int PowerProvided { get { return totalProvided; } } @@ -41,7 +43,7 @@ namespace OpenRA.Traits init.world.ActorRemoved += ActorRemoved; } - public void ActorAdded(Actor a) + void ActorAdded(Actor a) { if (a.Owner != Player || !a.HasTrait()) return; @@ -50,16 +52,7 @@ namespace OpenRA.Traits UpdateTotals(); } - public void UpdateActor(Actor a, int newPower) - { - if (a.Owner != Player || !a.HasTrait()) - return; - Game.Debug("Updated {0}: {1}->{2}",a.Info.Name, PowerDrain[a], newPower); - PowerDrain[a] = newPower; - UpdateTotals(); - } - - public void ActorRemoved(Actor a) + void ActorRemoved(Actor a) { if (a.Owner != Player || !a.HasTrait()) return; @@ -72,8 +65,12 @@ namespace OpenRA.Traits { totalProvided = 0; totalDrained = 0; - foreach (var p in PowerDrain.Values) + foreach (var kv in PowerDrain) { + if (Overrides.Keys.Contains(kv.Key)) + continue; + + var p = kv.Value; if (p > 0) totalProvided += p; else @@ -82,6 +79,15 @@ namespace OpenRA.Traits Game.Debug("Provided: {0} Drained: {1}",totalProvided, totalDrained); } + public void UpdateActor(Actor a, int newPower) + { + if (a.Owner != Player || !a.HasTrait()) + return; + + PowerDrain[a] = newPower; + UpdateTotals(); + } + int nextPowerAdviceTime = 0; bool wasLowPower = false; public void Tick(Actor self) @@ -91,7 +97,6 @@ namespace OpenRA.Traits nextPowerAdviceTime = 0; wasLowPower = lowPower; - if (--nextPowerAdviceTime <= 0) { if (lowPower) @@ -100,6 +105,46 @@ namespace OpenRA.Traits nextPowerAdviceTime = Info.AdviceInterval; } } + + // Force power down for power-down button, spy, emp, etc + public void Disable(Actor a, string key) + { + Game.Debug("Disabled {0}.{1}",a.Info.Name,key); + + if (Overrides.ContainsKey(a)) + { + if (Overrides[a].Contains(key)) + return; + + Overrides[a].Add(key); + } + else + Overrides.Add(a, new List() { key }); + + UpdateTotals(); + } + + public void RemoveDisable(Actor a, string key) + { + Game.Debug("Enabled {0}.{1}",a.Info.Name, key); + + if (!Overrides.ContainsKey(a) || !Overrides[a].Contains(key)) + return; + + Overrides[a].Remove(key); + if (Overrides[a].Count == 0) + Overrides.Remove(a); + + UpdateTotals(); + } + + public bool IsPowered(Actor a) + { + if (Overrides.ContainsKey(a)) + return false; + + return PowerProvided >= PowerDrained; + } public PowerState GetPowerState() { diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index c094380ca3..23bf38302e 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -99,7 +99,6 @@ namespace OpenRA.Traits public interface IRenderModifier { IEnumerable ModifyRender(Actor self, IEnumerable r); } public interface IDamageModifier { float GetDamageModifier( WarheadInfo warhead ); } public interface ISpeedModifier { float GetSpeedModifier(); } - public interface IPowerModifier { float GetPowerModifier(); } public interface IFirepowerModifier { float GetFirepowerModifier(); } public interface IPaletteModifier { void AdjustPalette(Dictionary b); } public interface IPips { IEnumerable GetPips(Actor self); } diff --git a/OpenRA.Mods.RA/CanPowerDown.cs b/OpenRA.Mods.RA/CanPowerDown.cs index 104aad4337..db37aa5f83 100755 --- a/OpenRA.Mods.RA/CanPowerDown.cs +++ b/OpenRA.Mods.RA/CanPowerDown.cs @@ -12,17 +12,23 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - public class CanPowerDownInfo : TraitInfo { } + public class CanPowerDownInfo : ITraitInfo + { + public object Create(ActorInitializer init) { return new CanPowerDown(init); } + } - public class CanPowerDown : IDisable, IPowerModifier, IResolveOrder + public class CanPowerDown : IResolveOrder { [Sync] bool disabled = false; - + + readonly PowerManager PlayerPower; + public CanPowerDown(ActorInitializer init) + { + PlayerPower = init.self.Owner.PlayerActor.Trait(); + } public bool Disabled { get { return disabled; } } - - public float GetPowerModifier() { return (disabled) ? 0.0f : 1.0f; } - + public void ResolveOrder(Actor self, Order order) { if (order.OrderString == "PowerDown") @@ -30,6 +36,11 @@ namespace OpenRA.Mods.RA disabled = !disabled; var eva = self.World.WorldActor.Info.Traits.Get(); Sound.PlayToPlayer(self.Owner, disabled ? eva.EnablePower : eva.DisablePower); + + if (disabled) + PlayerPower.Disable(self, "PowerDown"); + else + PlayerPower.RemoveDisable(self, "PowerDown"); } } } diff --git a/OpenRA.Mods.RA/RequiresPower.cs b/OpenRA.Mods.RA/RequiresPower.cs index bf0effc9dd..c1b5c2499c 100644 --- a/OpenRA.Mods.RA/RequiresPower.cs +++ b/OpenRA.Mods.RA/RequiresPower.cs @@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA public bool Disabled { - get { return (power.GetPowerState() != PowerState.Normal); } + get { return power.IsPowered(self); } } } }