diff --git a/OpenRa.Game/Effects/PowerDownIndicator.cs b/OpenRa.Game/Effects/PowerDownIndicator.cs deleted file mode 100755 index dc064e4484..0000000000 --- a/OpenRa.Game/Effects/PowerDownIndicator.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.Collections.Generic; -using OpenRa.Graphics; -using OpenRa.Traits; - -namespace OpenRa.Effects -{ - class PowerDownIndicator : IEffect - { - Actor a; - Building b; - Animation anim = new Animation("powerdown"); - bool removeNextFrame = false; - bool indicatorState = true; - int stateTicks = 0; - - public PowerDownIndicator(Actor a) - { - this.a = a; - this.b = a.traits.Get(); - anim.PlayRepeating("disabled"); - } - - public void Tick( World world ) - { - if (removeNextFrame == true) - world.AddFrameEndTask(w => w.Remove(this)); - - // Fix off-by one frame bug with undisabling causing low-power - if (!b.Disabled || a.IsDead) - removeNextFrame = true; - - // Flash power icon - if (++stateTicks == 15) - { - stateTicks = 0; - indicatorState = !indicatorState; - } - } - - public IEnumerable Render() - { - foreach (var r in a.Render()) - yield return r.WithPalette(PaletteType.Disabled); - - if (b.ManuallyDisabled && indicatorState) - yield return new Renderable(anim.Image, - a.CenterLocation - .5f * anim.Image.size, PaletteType.Chrome); - } - } -} diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 21466b0a3d..f0977e2ca8 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -83,7 +83,6 @@ - @@ -101,6 +100,7 @@ + True True @@ -109,7 +109,6 @@ - @@ -204,6 +203,7 @@ + diff --git a/OpenRa.Game/Orders/PowerDownOrderGenerator.cs b/OpenRa.Game/Orders/PowerDownOrderGenerator.cs index b4e7144ff3..0878f49464 100644 --- a/OpenRa.Game/Orders/PowerDownOrderGenerator.cs +++ b/OpenRa.Game/Orders/PowerDownOrderGenerator.cs @@ -24,8 +24,8 @@ namespace OpenRa.Orders var loc = mi.Location + Game.viewport.Location; var underCursor = world.FindUnits(loc, loc) .Where(a => a.Owner == world.LocalPlayer - && a.traits.Contains() - && a.traits.Contains()).FirstOrDefault(); + && a.traits.Contains()) + .FirstOrDefault(); if (underCursor != null) yield return new Order("PowerDown", underCursor); @@ -39,7 +39,7 @@ namespace OpenRa.Orders { mi.Button = MouseButton.Left; return OrderInner(world, xy, mi).Any() - ? Cursor.PowerDown : Cursor.PowerDown; + ? Cursor.PowerDown : Cursor.RepairBlocked; } } } diff --git a/OpenRa.Game/Traits/Building.cs b/OpenRa.Game/Traits/Building.cs index bdca74a47b..fe1821df7b 100644 --- a/OpenRa.Game/Traits/Building.cs +++ b/OpenRa.Game/Traits/Building.cs @@ -1,7 +1,10 @@ using System; +using System.Linq; using OpenRa.Effects; using OpenRa.GameRules; using OpenRa.Traits.Activities; +using OpenRa.Graphics; +using System.Collections.Generic; namespace OpenRa.Traits { @@ -17,7 +20,6 @@ namespace OpenRa.Traits public class BuildingInfo : OwnedActorInfo, ITraitInfo { public readonly int Power = 0; - public readonly bool RequiresPower = false; public readonly bool BaseNormal = true; public readonly int Adjacent = 2; public readonly bool Bib = false; @@ -31,25 +33,18 @@ namespace OpenRa.Traits public object Create(Actor self) { return new Building(self); } } - public class Building : INotifyDamage, IResolveOrder, ITick + public class Building : INotifyDamage, IResolveOrder, ITick, IRenderModifier { readonly Actor self; public readonly BuildingInfo Info; [Sync] bool isRepairing = false; - [Sync] - bool manuallyDisabled = false; - public bool ManuallyDisabled { get { return manuallyDisabled; } } + public bool Disabled { - get - { - return (manuallyDisabled || - (Info.RequiresPower && self.Owner.GetPowerState() != PowerState.Normal)); - } + get { return self.traits.WithInterface().Any(t => t.Disabled); } } - bool wasDisabled = false; - + public Building(Actor self) { this.self = self; @@ -60,15 +55,17 @@ namespace OpenRa.Traits public int GetPowerUsage() { - if (manuallyDisabled) - return 0; - + var modifier = self.traits + .WithInterface() + .Select(t => t.GetPowerModifier()) + .Product(); + var maxHP = self.Info.Traits.Get().HP; if (Info.Power > 0) - return (self.Health * Info.Power) / maxHP; + return (int)(modifier*(self.Health * Info.Power) / maxHP); else - return Info.Power; + return (int)(modifier * Info.Power); } public void Damaged(Actor self, AttackInfo e) @@ -89,23 +86,12 @@ namespace OpenRa.Traits { isRepairing = !isRepairing; } - - if (order.OrderString == "PowerDown") - { - manuallyDisabled = !manuallyDisabled; - Sound.Play((manuallyDisabled) ? "bleep12.aud" : "bleep11.aud"); - } } int remainingTicks; public void Tick(Actor self) { - // If the disabled state has changed since the last frame - if (Disabled ^ wasDisabled - && (wasDisabled = Disabled)) // Yes, I mean assignment - self.World.AddFrameEndTask(w => w.Add(new PowerDownIndicator(self))); - if (!isRepairing) return; if (remainingTicks == 0) @@ -132,5 +118,15 @@ namespace OpenRa.Traits else --remainingTicks; } + + public IEnumerable ModifyRender(Actor self, IEnumerable r) + { + foreach (var a in r) + { + yield return a; + if (Disabled) + yield return a.WithPalette(PaletteType.Disabled); + } + } } } diff --git a/OpenRa.Game/Traits/CanPowerDown.cs b/OpenRa.Game/Traits/CanPowerDown.cs new file mode 100644 index 0000000000..0f19527739 --- /dev/null +++ b/OpenRa.Game/Traits/CanPowerDown.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRa.Traits; + +namespace OpenRa.Traits +{ + public class CanPowerDownInfo : ITraitInfo + { + public object Create(Actor self) { return new CanPowerDown(self); } + } + + public class CanPowerDown : IDisable, IPowerModifier, IResolveOrder + { + readonly Actor self; + [Sync] + bool IsDisabled = false; + + public CanPowerDown(Actor self) + { + this.self = self; + } + + public bool Disabled + { + get { return IsDisabled; } + set { IsDisabled = value; } + } + + public float GetPowerModifier() { return (IsDisabled) ? 0.0f : 1.0f; } + + public void ResolveOrder(Actor self, Order order) + { + if (order.OrderString == "PowerDown") + { + IsDisabled = !IsDisabled; + Sound.Play((IsDisabled) ? "bleep12.aud" : "bleep11.aud"); + } + } + } +} diff --git a/OpenRa.Game/Traits/TraitsInterfaces.cs b/OpenRa.Game/Traits/TraitsInterfaces.cs index ad2094dc40..94435ed44d 100644 --- a/OpenRa.Game/Traits/TraitsInterfaces.cs +++ b/OpenRa.Game/Traits/TraitsInterfaces.cs @@ -26,7 +26,9 @@ namespace OpenRa.Traits public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); } public interface ICustomTerrain { float GetCost(int2 p, UnitMovementType umt); } - + + public interface IDisable { bool Disabled { get; set; } } + interface IProducer { bool Produce( Actor self, ActorInfo producee ); @@ -37,6 +39,7 @@ namespace OpenRa.Traits public interface IRenderModifier { IEnumerable ModifyRender(Actor self, IEnumerable r); } public interface IDamageModifier { float GetDamageModifier(); } public interface ISpeedModifier { float GetSpeedModifier(); } + public interface IPowerModifier { float GetPowerModifier(); } public interface IPaletteModifier { void AdjustPalette(Bitmap b); } public interface IPips { IEnumerable GetPips(Actor self); } public interface ITags { IEnumerable GetTags(); } diff --git a/OpenRa.Mods.RA/OpenRa.Mods.RA.csproj b/OpenRa.Mods.RA/OpenRa.Mods.RA.csproj index a27a5f26fb..15986d235e 100644 --- a/OpenRa.Mods.RA/OpenRa.Mods.RA.csproj +++ b/OpenRa.Mods.RA/OpenRa.Mods.RA.csproj @@ -53,6 +53,7 @@ + @@ -72,6 +73,9 @@ OpenRa.Game + + +