From fc28d768f1d7d92f84458d0217ace6d5e5bf9c2c Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Thu, 7 Jan 2010 23:23:05 +1300 Subject: [PATCH 1/6] Primary buildings --- OpenRa.Game/Graphics/WorldRenderer.cs | 3 ++ OpenRa.Game/Traits/Production.cs | 45 ++++++++++++++++++++++++-- OpenRa.Game/Traits/ProductionQueue.cs | 36 +++++++++++++++++---- OpenRa.Game/Traits/TraitsInterfaces.cs | 6 +++- 4 files changed, 81 insertions(+), 9 deletions(-) diff --git a/OpenRa.Game/Graphics/WorldRenderer.cs b/OpenRa.Game/Graphics/WorldRenderer.cs index 157b9ee2ab..1060f5467a 100644 --- a/OpenRa.Game/Graphics/WorldRenderer.cs +++ b/OpenRa.Game/Graphics/WorldRenderer.cs @@ -242,6 +242,9 @@ namespace OpenRa.Game.Graphics { foreach (var tag in tags.GetTags()) { + if (tag == TagType.None) + continue; + var tagImages = new Animation("pips"); tagImages.PlayRepeating(tagStrings[(int)tag]); spriteRenderer.DrawSprite(tagImages.Image, tagxyBase + tagxyOffset, PaletteType.Chrome); diff --git a/OpenRa.Game/Traits/Production.cs b/OpenRa.Game/Traits/Production.cs index c4d1413f39..e24eec3a68 100755 --- a/OpenRa.Game/Traits/Production.cs +++ b/OpenRa.Game/Traits/Production.cs @@ -4,8 +4,11 @@ using System.Collections.Generic; namespace OpenRa.Game.Traits { - class Production : IProducer, ITags + class Production : IOrder, IProducer, ITags { + bool isPrimary = false; + public bool IsPrimary { get { return isPrimary; } } + public Production( Actor self ) { } public virtual int2? CreationLocation( Actor self, UnitInfo producee ) @@ -50,7 +53,45 @@ namespace OpenRa.Game.Traits public IEnumerable GetTags() { - yield return (true) ? TagType.Primary : TagType.None; + yield return (isPrimary) ? TagType.Primary : TagType.None; + } + + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + if (mi.Button == MouseButton.Right && underCursor == self) + return new Order("Deploy", self, null, int2.Zero, null); + return null; + } + + public void ResolveOrder(Actor self, Order order) + { + if (order.OrderString == "Deploy") + { + SetPrimaryProducer(self, !isPrimary); + } + } + + public void SetPrimaryProducer(Actor self, bool state) + { + if (state == false) + { + isPrimary = false; + return; + } + + // Cancel existing primaries + foreach (var p in (self.Info as BuildingInfo).Produces) + { + foreach (var b in Game.world.Actors.Where(x => x.traits.Contains() + && x.Owner == self.Owner + && x.traits.Get().IsPrimary == true + && (x.Info as BuildingInfo).Produces.Contains(p))) + { + b.traits.Get().SetPrimaryProducer(b, false); + } + } + isPrimary = true; + Sound.Play("pribldg1.aud"); } } } diff --git a/OpenRa.Game/Traits/ProductionQueue.cs b/OpenRa.Game/Traits/ProductionQueue.cs index 869277d5c8..0e58800572 100755 --- a/OpenRa.Game/Traits/ProductionQueue.cs +++ b/OpenRa.Game/Traits/ProductionQueue.cs @@ -128,12 +128,36 @@ namespace OpenRa.Game.Traits { var newUnitType = Rules.UnitInfo[ name ]; var producerTypes = Rules.TechTree.UnitBuiltAt( newUnitType ); - - // TODO: choose producer based on "primary building" - var producer = Game.world.Actors - .Where( x => producerTypes.Contains( x.Info ) && x.Owner == self.Owner ) - .FirstOrDefault(); - + Actor producer = null; + + // Prioritise primary structure in build order + var primaryProducers = Game.world.Actors + .Where(x => x.traits.Contains() + && producerTypes.Contains(x.Info) + && x.Owner == self.Owner + && x.traits.Get().IsPrimary == true); + + foreach (var p in primaryProducers) + { + // Ignore buildings that are disabled + if (p.traits.Contains() && p.traits.Get().InsuffientPower()) + continue; + producer = p; + break; + } + + // TODO: Be smart about disabled buildings. Units in progress should be paused(?) + // Ignore this for now + + // Pick the first available producer + if (producer == null) + { + producer = Game.world.Actors + .Where( x => producerTypes.Contains( x.Info ) && x.Owner == self.Owner ) + .FirstOrDefault(); + } + + // Something went wrong somewhere... if( producer == null ) { CancelProduction( Rules.UnitCategory[ name ] ); diff --git a/OpenRa.Game/Traits/TraitsInterfaces.cs b/OpenRa.Game/Traits/TraitsInterfaces.cs index da3e3bb431..5ee0a485ef 100644 --- a/OpenRa.Game/Traits/TraitsInterfaces.cs +++ b/OpenRa.Game/Traits/TraitsInterfaces.cs @@ -22,7 +22,11 @@ namespace OpenRa.Game.Traits Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor ); void ResolveOrder( Actor self, Order order ); } - interface IProducer { bool Produce( Actor self, UnitInfo producee ); } + interface IProducer + { + bool Produce( Actor self, UnitInfo producee ); + void SetPrimaryProducer(Actor self, bool isPrimary); + } interface IOccupySpace { IEnumerable OccupiedCells(); } interface INotifyAttack { void Attacking(Actor self); } interface IRenderModifier { IEnumerable ModifyRender(Actor self, IEnumerable r); } From 9df6d0157765bf272c8c99bf6ca449e51e5e2482 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 8 Jan 2010 00:18:06 +1300 Subject: [PATCH 2/6] Begin iron curtain impl --- OpenRa.Game/Chrome.cs | 15 +++ OpenRa.Game/Cursor.cs | 1 + OpenRa.Game/OpenRa.Game.csproj | 3 + .../Orders/IronCurtainOrderGenerator.cs | 57 +++++++++ OpenRa.Game/Traits/IronCurtain.cs | 12 ++ OpenRa.Game/Traits/IronCurtainable.cs | 57 +++++++++ sequences.xml | 6 +- units.ini | 108 +++++++++--------- 8 files changed, 203 insertions(+), 56 deletions(-) create mode 100644 OpenRa.Game/Orders/IronCurtainOrderGenerator.cs create mode 100644 OpenRa.Game/Traits/IronCurtain.cs create mode 100644 OpenRa.Game/Traits/IronCurtainable.cs diff --git a/OpenRa.Game/Chrome.cs b/OpenRa.Game/Chrome.cs index 786f8af667..3e7b531932 100644 --- a/OpenRa.Game/Chrome.cs +++ b/OpenRa.Game/Chrome.cs @@ -305,6 +305,21 @@ namespace OpenRa.Game AddButton(chronoshiftRect, isLmb => HandleChronosphereButton()); } buildPaletteRenderer.DrawSprite(repairButton.Image, chronoshiftDrawPos, PaletteType.Chrome); + + // Iron Curtain + Rectangle curtainRect = new Rectangle(6, 14+50, repairButton.Image.bounds.Width, repairButton.Image.bounds.Height); + var curtainDrawPos = Game.viewport.Location + new float2(curtainRect.Location); + + var hasCurtain = Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains()); + + if (!hasCurtain) + repairButton.ReplaceAnim("disabled"); + else + { + //repairButton.ReplaceAnim(Game.controller.orderGenerator is RepairOrderGenerator ? "pressed" : "normal"); + AddButton(curtainRect, isLmb => Game.controller.ToggleInputMode()); + } + buildPaletteRenderer.DrawSprite(repairButton.Image, curtainDrawPos, PaletteType.Chrome); // Repair diff --git a/OpenRa.Game/Cursor.cs b/OpenRa.Game/Cursor.cs index 54ebacc76d..89b5f12d94 100644 --- a/OpenRa.Game/Cursor.cs +++ b/OpenRa.Game/Cursor.cs @@ -25,6 +25,7 @@ namespace OpenRa.Game public static Cursor DeployBlocked { get { return new Cursor("deploy-blocked"); } } public static Cursor Chronoshift { get { return new Cursor("chrono-target"); } } public static Cursor ChronoshiftSelect { get { return new Cursor("chrono-select"); } } + public static Cursor Ability { get { return new Cursor("ability"); } } public static Cursor C4 { get { return new Cursor("c4"); } } public static Cursor Capture { get { return new Cursor("capture"); } } public static Cursor Heal { get { return new Cursor("heal"); } } diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 112d4802ea..df46a1172b 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -100,6 +100,7 @@ + @@ -217,6 +218,8 @@ + + diff --git a/OpenRa.Game/Orders/IronCurtainOrderGenerator.cs b/OpenRa.Game/Orders/IronCurtainOrderGenerator.cs new file mode 100644 index 0000000000..d73c787f19 --- /dev/null +++ b/OpenRa.Game/Orders/IronCurtainOrderGenerator.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.Game.GameRules; +using OpenRa.Game.Traits; + +namespace OpenRa.Game.Orders +{ + class IronCurtainOrderGenerator : IOrderGenerator + { + public IEnumerable Order(int2 xy, MouseInput mi) + { + if (mi.Button == MouseButton.Right) + Game.controller.CancelInputMode(); + + return OrderInner(xy, mi); + } + + IEnumerable OrderInner(int2 xy, MouseInput mi) + { + if (mi.Button == MouseButton.Left) + { + var loc = mi.Location + Game.viewport.Location; + var underCursor = Game.FindUnits(loc, loc) + .Where(a => a.Owner == Game.LocalPlayer + && a.traits.Contains() + && a.Info.Selectable).FirstOrDefault(); + + var unit = underCursor != null ? underCursor.Info as UnitInfo : null; + + if (unit != null) + { + yield return new Order("IronCurtain", underCursor, null, int2.Zero, null); + } + } + } + + public void Tick() + { + var hasStructure = Game.world.Actors + .Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains()); + + if (!hasStructure) + Game.controller.CancelInputMode(); + } + + public void Render() { } + + public Cursor GetCursor(int2 xy, MouseInput mi) + { + mi.Button = MouseButton.Left; + return OrderInner(xy, mi).Any() + ? Cursor.Ability : Cursor.MoveBlocked; + } + } +} diff --git a/OpenRa.Game/Traits/IronCurtain.cs b/OpenRa.Game/Traits/IronCurtain.cs new file mode 100644 index 0000000000..668b469bd1 --- /dev/null +++ b/OpenRa.Game/Traits/IronCurtain.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenRa.Game.Traits +{ + class IronCurtain + { + public IronCurtain(Actor self) {} + } +} diff --git a/OpenRa.Game/Traits/IronCurtainable.cs b/OpenRa.Game/Traits/IronCurtainable.cs new file mode 100644 index 0000000000..91716f6bab --- /dev/null +++ b/OpenRa.Game/Traits/IronCurtainable.cs @@ -0,0 +1,57 @@ +using OpenRa.Game.Traits; +using OpenRa.Game.Orders; +using System.Collections.Generic; +using System.Linq; +using System.Drawing; +using OpenRa.Game.Effects; +using OpenRa.Game.Graphics; + +namespace OpenRa.Game.Traits +{ + class IronCurtainable: IOrder, IDamageModifier, ITick, IRenderModifier + { + int RemainingTicks = 0; + + public IronCurtainable(Actor self) { } + + public void Tick(Actor self) + { + if (RemainingTicks > 0) + RemainingTicks--; + } + public float GetDamageModifier() + { + return (RemainingTicks > 0) ? 0.0f : 1.0f; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return null; // Chronoshift order is issued through Chrome. + } + + public void ResolveOrder(Actor self, Order order) + { + if (order.OrderString == "IronCurtain") + { + RemainingTicks = (int)(Rules.General.IronCurtain * 60 * 25); + // Play active anim + var ironCurtain = Game.world.Actors.Where(a => a.Owner == order.Subject.Owner && a.traits.Contains()).FirstOrDefault(); + Sound.Play("ironcur9.aud"); + if (ironCurtain != null) + ironCurtain.traits.Get().PlayCustomAnim(ironCurtain, "active"); + } + } + + public IEnumerable ModifyRender(Actor self, IEnumerable rs) + { + if (RemainingTicks <= 0) + return rs; + + List nrs = new List(rs); + foreach(var r in rs) + { + nrs.Add(r.WithPalette(PaletteType.Shadow)); + } + return nrs; + } + } +} diff --git a/sequences.xml b/sequences.xml index 499b7c30bb..ba46bfa4a9 100644 --- a/sequences.xml +++ b/sequences.xml @@ -201,8 +201,10 @@ - - + + + + diff --git a/units.ini b/units.ini index 54dc8f1e4f..6ed539a5f0 100644 --- a/units.ini +++ b/units.ini @@ -16,47 +16,47 @@ MNLY.AT [V2RL] Description=V2 Rocket -Traits=Unit, Mobile, AttackBase, RenderUnitReload, AutoTarget, Repairable, Chronoshiftable, Passenger +Traits=Unit, Mobile, AttackBase, RenderUnitReload, AutoTarget, Repairable, Chronoshiftable, Passenger, IronCurtainable Voice=VehicleVoice LongDesc=Long-range rocket artillery.\n Strong vs Infantry, Buildings\n Weak vs Tanks, Aircraft [1TNK] Description=Light Tank -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable, Chronoshiftable, Passenger +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable, Chronoshiftable, Passenger, IronCurtainable Recoil=2 Voice=VehicleVoice LongDesc=Light Tank, good for scouting.\n Strong vs Light Vehicles\n Weak vs Tanks, Aircraft [2TNK] Description=Medium Tank -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable, Chronoshiftable, Passenger +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable, Chronoshiftable, Passenger, IronCurtainable Recoil=3 Voice=VehicleVoice LongDesc=Allied Main Battle Tank.\n Strong vs Tanks, Light Vehicles\n Weak vs Infantry, Aircraft [3TNK] Description=Heavy Tank -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable, Chronoshiftable, Passenger +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable, Chronoshiftable, Passenger, IronCurtainable Recoil=3 Voice=VehicleVoice LongDesc=Soviet Main Battle Tank, with dual cannons\n Strong vs Tanks, Light Vehicles\n Weak vs Infantry, Aircraft [4TNK] Description=Mammoth Tank -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable, Chronoshiftable, Passenger +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable, Chronoshiftable, Passenger, IronCurtainable Voice=VehicleVoice LongDesc=Big and slow tank, with anti-air capability.\n Strong vs Tanks, Aircraft\n Weak vs Infantry [ARTY] Description=Artillery -Traits=Unit, Mobile, AttackBase, RenderUnit, Explodes, AutoTarget, Repairable, Chronoshiftable, Passenger +Traits=Unit, Mobile, AttackBase, RenderUnit, Explodes, AutoTarget, Repairable, Chronoshiftable, Passenger, IronCurtainable Voice=VehicleVoice LongDesc=Long-range artillery.\n Strong vs Infantry, Buildings\n Weak vs Tanks, Aircraft [JEEP] Description=Ranger -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable, Chronoshiftable, Passenger +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable, Chronoshiftable, Passenger, IronCurtainable PrimaryOffset=0,0,0,-2 MuzzleFlash=yes Voice=VehicleVoice LongDesc=Fast scout & anti-infantry vehicle.\n Strong vs Infantry\n Weak vs Tanks, Aircraft [APC] Description=Armored Personnel Carrier -Traits=Unit, Mobile, AttackBase, RenderUnitMuzzleFlash, AutoTarget, Repairable, Chronoshiftable, Cargo, Passenger +Traits=Unit, Mobile, AttackBase, RenderUnitMuzzleFlash, AutoTarget, Repairable, Chronoshiftable, Cargo, Passenger, IronCurtainable PrimaryOffset=0,0,0,-4 MuzzleFlash=yes Voice=VehicleVoice @@ -67,40 +67,40 @@ PassengerTypes=Foot ;; non-combat vehicles [MRJ] Description=Radar Jammer -Traits=Unit, Mobile, RenderUnitSpinner, Repairable, Chronoshiftable, Passenger +Traits=Unit, Mobile, RenderUnitSpinner, Repairable, Chronoshiftable, Passenger, IronCurtainable PrimaryOffset=0,4,0,-6 SelectionPriority=3 Voice=VehicleVoice LongDesc=Hides nearby units on the enemy's minimap.\n Unarmed [MGG] Description=Mobile Gap Generator -Traits=Unit, Mobile, RenderUnitSpinner, Repairable, Chronoshiftable, Passenger +Traits=Unit, Mobile, RenderUnitSpinner, Repairable, Chronoshiftable, Passenger, IronCurtainable PrimaryOffset=0,6,0,-3 SelectionPriority=3 Voice=VehicleVoice LongDesc=Regenerates Fog of War in a small area \naround the unit.\n Unarmed [HARV] Description=Ore Truck -Traits=Harvester, Unit, Mobile, RenderUnit, Repairable, Chronoshiftable, Passenger +Traits=Harvester, Unit, Mobile, RenderUnit, Repairable, Chronoshiftable, Passenger, IronCurtainable SelectionPriority=7 Voice=VehicleVoice LongDesc=Collects Ore and Gems for processing.\n Unarmed [MCV] Description=Mobile Construction Vehicle -Traits=Unit, Mobile, McvDeploy, RenderUnit, Repairable, Chronoshiftable, Passenger +Traits=Unit, Mobile, McvDeploy, RenderUnit, Repairable, Chronoshiftable, Passenger, IronCurtainable SelectionPriority=3 Voice=VehicleVoice LongDesc=Deploys into another Construction Yard.\n Unarmed [MNLY.AP] Description=Minelayer (Anti-Personnel) -Traits=Unit, Mobile, RenderUnit, Minelayer, MineImmune, Repairable, LimitedAmmo, Chronoshiftable, Passenger +Traits=Unit, Mobile, RenderUnit, Minelayer, MineImmune, Repairable, LimitedAmmo, Chronoshiftable, Passenger, IronCurtainable Voice=VehicleVoice LongDesc=Lays mines to destroy unwary enemy units.\n Unarmed Primary=MINP ;; temporary hack [MNLY.AT] Description=Minelayer (Anti-Tank) -Traits=Unit, Mobile, RenderUnit, Minelayer, MineImmune, Repairable, LimitedAmmo, Chronoshiftable, Passenger +Traits=Unit, Mobile, RenderUnit, Minelayer, MineImmune, Repairable, LimitedAmmo, Chronoshiftable, Passenger, IronCurtainable Voice=VehicleVoice LongDesc=Lays mines to destroy unwary enemy units.\n Unarmed Primary=MINV ;; temporary hack @@ -118,21 +118,21 @@ PT Description=Submarine WaterBound=yes BuiltAt=spen -Traits=Unit, Mobile, RenderUnit, Submarine, AttackBase, Chronoshiftable +Traits=Unit, Mobile, RenderUnit, Submarine, AttackBase, Chronoshiftable, IronCurtainable FireDelay=2 LongDesc=Submerged anti-ship unit armed with \ntorpedoes.\n Strong vs Ships\n Weak vs Everything\n Special Ability: Submerge [DD] Description=Destroyer WaterBound=yes BuiltAt=syrd -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Chronoshiftable +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Chronoshiftable, IronCurtainable PrimaryOffset=0,-8,0,-3 LongDesc=Fast multi-role ship. \n Strong vs Submarines, Aircraft\n Weak vs Infantry, Tanks [CA] Description=Cruiser WaterBound=yes BuiltAt=syrd -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Chronoshiftable +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Chronoshiftable, IronCurtainable PrimaryOffset=0,17,0,-2 SecondaryOffset=0,-17,0,-2 LongDesc=Very slow long-range ship. \n Strong vs Buildings\n Weak vs Ships, Submarines @@ -140,14 +140,14 @@ Recoil=3 [LST] Description=Transport WaterBound=yes -Traits=Unit, Mobile, RenderUnit, Cargo +Traits=Unit, Mobile, RenderUnit, Cargo, IronCurtainable LongDesc=General-purpose naval transport.\nCan carry infantry and tanks.\n Unarmed PassengerTypes=Foot,Wheel,Track [PT] Description=Gunboat WaterBound=yes BuiltAt=syrd -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Chronoshiftable +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Chronoshiftable, IronCurtainable PrimaryOffset=0,-6,0,-1 LongDesc=Light scout & support ship. \n Strong vs Ships, Submarines\n Weak vs Aircraft @@ -168,13 +168,13 @@ HIND [MIG] Description=Mig Attack Plane BuiltAt=afld -Traits=Unit, AttackPlane, Plane, RenderUnit, WithShadow, LimitedAmmo +Traits=Unit, AttackPlane, Plane, RenderUnit, WithShadow, LimitedAmmo, IronCurtainable InitialFacing=192 LongDesc=Fast Ground-Attack Plane.\n Strong vs Buildings\n Weak vs Infantry, Light Vehicles [YAK] Description=Yak Attack Plane BuiltAt=afld -Traits=Unit, AttackPlane, Plane, RenderUnit, WithShadow, LimitedAmmo +Traits=Unit, AttackPlane, Plane, RenderUnit, WithShadow, LimitedAmmo, IronCurtainable InitialFacing=192 LongDesc=Anti-Tanks & Anti-Infantry Plane.\n Strong vs Infantry, Tanks\n Weak vs Buildings [TRAN] @@ -182,14 +182,14 @@ Description=Transport Helicopter RotorOffset=0,14,0,-4 RotorOffset2=0,-14,0,-2 BuiltAt=hpad -Traits=Unit, Helicopter, RenderUnitRotor, WithShadow, Cargo +Traits=Unit, Helicopter, RenderUnitRotor, WithShadow, Cargo, IronCurtainable InitialFacing=20 LongDesc=Fast Infantry Transport Helicopter.\n Unarmed PassengerTypes=Foot [HELI] Description=Longbow BuiltAt=hpad -Traits=Unit, AttackHeli, Helicopter, RenderUnitRotor, WithShadow, LimitedAmmo +Traits=Unit, AttackHeli, Helicopter, RenderUnitRotor, WithShadow, LimitedAmmo, IronCurtainable RotorOffset=0,0,0,-2 PrimaryOffset=-5,0,0,2 SecondaryOffset=5,0,0,2 @@ -198,7 +198,7 @@ LongDesc=Helicopter Gunship with AG Missiles.\n Strong vs Buildings, Tanks\n W [HIND] Description=Hind BuiltAt=hpad -Traits=Unit, AttackHeli, Helicopter, RenderUnitRotor, WithShadow, LimitedAmmo +Traits=Unit, AttackHeli, Helicopter, RenderUnitRotor, WithShadow, LimitedAmmo, IronCurtainable PrimaryOffset=-5,0,0,2 SecondaryOffset=5,0,0,2 InitialFacing=20 @@ -226,21 +226,21 @@ MSLO [PBOX] Description=Pillbox -Traits=Building, Turreted, RenderBuilding, AttackTurreted, AutoTarget +Traits=Building, Turreted, RenderBuilding, AttackTurreted, AutoTarget, IronCurtainable Dimensions=1,1 Footprint=x SelectionPriority=3 LongDesc=Basic defensive structure.\n Strong vs Infantry, Light Vehicles\n Weak vs Tanks, Aircraft [HBOX] Description=Camo Pillbox -Traits=Building, Turreted, RenderBuilding, AttackTurreted, AutoTarget +Traits=Building, Turreted, RenderBuilding, AttackTurreted, AutoTarget, IronCurtainable Dimensions=1,1 Footprint=x SelectionPriority=3 LongDesc=Hidden defensive structure.\n Strong vs Infantry, Light Vehicles\n Weak vs Tanks, Aircraft [TSLA] Description=Tesla Coil -Traits=Building, Turreted, RenderBuildingCharge, AttackTurreted, AutoTarget +Traits=Building, Turreted, RenderBuildingCharge, AttackTurreted, AutoTarget, IronCurtainable Dimensions=1,2 Footprint=_ x SelectionPriority=3 @@ -248,7 +248,7 @@ FireDelay=8 LongDesc=Advanced base defense. Requires power\nto operate.\n Strong vs Tanks, Infantry\n Weak vs Aircraft [GUN] Description=Turret -Traits=Building, Turreted, RenderBuildingTurreted, AttackTurreted, AutoTarget +Traits=Building, Turreted, RenderBuildingTurreted, AttackTurreted, AutoTarget, IronCurtainable Dimensions=1,1 Footprint=x SelectionPriority=3 @@ -256,7 +256,7 @@ InitialFacing=50 LongDesc=Anti-Armor base defense.\n Strong vs Tanks\n Weak vs Infantry, Aircraft [AGUN] Description=AA Gun -Traits=Building, Turreted, RenderBuildingTurreted, AttackTurreted, AutoTarget +Traits=Building, Turreted, RenderBuildingTurreted, AttackTurreted, AutoTarget, IronCurtainable Dimensions=1,2 Footprint=_ x SelectionPriority=3 @@ -264,14 +264,14 @@ InitialFacing=224 LongDesc=Anti-Air base defense.\n Strong vs Aircraft\n Weak vs Infantry, Tanks [FTUR] Description=Flame Turret -Traits=Turreted, Building, RenderBuilding, AttackTurreted, AutoTarget +Traits=Turreted, Building, RenderBuilding, AttackTurreted, AutoTarget, IronCurtainable Dimensions=1,1 Footprint=x SelectionPriority=3 LongDesc=Anti-Infantry base defense.\n Strong vs Infantry\n Weak vs Aircraft [SAM] Description=SAM Site -Traits=Building, Turreted, RenderBuildingTurreted, AttackTurreted, AutoTarget +Traits=Building, Turreted, RenderBuildingTurreted, AttackTurreted, AutoTarget, IronCurtainable Dimensions=2,1 Footprint=xx SelectionPriority=3 @@ -279,28 +279,28 @@ LongDesc=Anti-Air base defense.\n Strong vs Aircraft\n Weak vs Infantry, Tanks [MSLO] Description=Missile Silo -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, IronCurtainable Dimensions=2,1 Footprint=xx SelectionPriority=3 LongDesc=Launches a devastating nuclear strike.\n Strong vs Infantry, Buildings\n Weak vs Tanks\n Special Ability: Nuclear Missile [IRON] Description=Iron Curtain -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, IronCurtainable, IronCurtain Dimensions=2,2 Footprint=xx xx SelectionPriority=3 LongDesc=Makes a group of units invulnerable for a \nshort time.\n Special Ability: Invulnerability [PDOX] Description=Chronosphere -Traits=Building, RenderBuilding, Chronosphere +Traits=Building, RenderBuilding, Chronosphere, IronCurtainable Dimensions=2,2 Footprint=xx xx SelectionPriority=3 LongDesc=Teleports a unit from one place \nto another, for a limited time.\n Special Ability: Chronoshift [GAP] Description=Gap Generator -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, IronCurtainable Dimensions=1,2 Footprint=_ x SelectionPriority=3 @@ -345,14 +345,14 @@ MINV ; `Produces` is a category of objects that this building can produce. [ATEK] Description=Allied Tech Center -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, IronCurtainable Dimensions=2,2 Footprint=xx xx SelectionPriority=3 LongDesc=Provides Allied advanced technologies.\n Special Ability: GPS Satellite [WEAP] Description=War Factory -Traits=Building, RenderWarFactory, RenderBuilding, RallyPoint, Production +Traits=Building, RenderWarFactory, RenderBuilding, RallyPoint, Production, IronCurtainable Dimensions=3,2 Footprint=xxx xxx Produces=Vehicle @@ -361,7 +361,7 @@ SelectionPriority=3 LongDesc=Produces tanks & light vehicles. [SYRD] Description=Shipyard -Traits=Building, RenderBuilding, ProductionSurround +Traits=Building, RenderBuilding, ProductionSurround, IronCurtainable Dimensions=3,3 Footprint=xxx xxx xxx Produces=Ship @@ -369,7 +369,7 @@ SelectionPriority=3 LongDesc=Produces and repairs ships [SPEN] Description=Sub Pen -Traits=Building, RenderBuilding, ProductionSurround +Traits=Building, RenderBuilding, ProductionSurround, IronCurtainable Dimensions=3,3 Footprint=xxx xxx xxx Produces=Ship @@ -377,7 +377,7 @@ SelectionPriority=3 LongDesc=Produces and repairs submarines and \ntransports [FACT] Description=Construction Yard -Traits=Building, RenderBuilding, ConstructionYard +Traits=Building, RenderBuilding, ConstructionYard, IronCurtainable Dimensions=3,3 Footprint=xxx xxx xxx Produces=Building,Defense @@ -385,7 +385,7 @@ SelectionPriority=3 LongDesc=Produces other structures [PROC] Description=Ore Refinery -Traits=Building, RenderBuilding, AcceptsOre, StoresOre +Traits=Building, RenderBuilding, AcceptsOre, StoresOre, IronCurtainable Dimensions=3,3 Footprint=_x_ xxx x== SelectionPriority=3 @@ -393,7 +393,7 @@ OrePips=17 LongDesc=Converts Ore and Gems into money [SILO] Description=Silo -Traits=Building, RenderBuildingOre, StoresOre +Traits=Building, RenderBuildingOre, StoresOre, IronCurtainable Dimensions=1,1 Footprint=x SelectionPriority=3 @@ -402,7 +402,7 @@ LongDesc=Stores excess harvested Ore [HPAD] Description=Helipad -Traits=Building, RenderBuilding, Production, BelowUnits, Reservable +Traits=Building, RenderBuilding, Production, BelowUnits, Reservable, IronCurtainable Dimensions=2,2 Footprint=xx xx Produces=Plane @@ -411,14 +411,14 @@ SpawnOffset=0,-4 LongDesc=Produces and reloads helicopters [DOME] Description=Radar Dome -Traits=Building, RenderBuilding, ProvidesRadar +Traits=Building, RenderBuilding, ProvidesRadar, IronCurtainable Dimensions=2,2 Footprint=xx xx SelectionPriority=3 LongDesc=Provides an overview of the battlefield.\n Requires power to operate. [AFLD] Description=Airstrip -Traits=Building, RenderBuilding, Production, BelowUnits, Reservable +Traits=Building, RenderBuilding, Production, BelowUnits, Reservable, IronCurtainable Dimensions=3,2 Footprint=xxx xxx Produces=Plane @@ -426,28 +426,28 @@ SelectionPriority=3 LongDesc=Produces and reloads planes\n Special Ability: Paratroopers\n Special Ability: Spy Plane [POWR] Description=Power Plant -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, IronCurtainable Dimensions=2,2 Footprint=xx xx SelectionPriority=3 LongDesc=Provides power for other structures [APWR] Description=Advanced Power Plant -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, IronCurtainable Dimensions=3,3 Footprint=___ xxx xxx SelectionPriority=3 LongDesc=Provides more power, cheaper than the \nstandard Power Plant [STEK] Description=Soviet Tech Center -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, IronCurtainable Dimensions=3,2 Footprint=xxx xxx SelectionPriority=3 LongDesc=Provides Soviet advanced technologies [BARR] Description=Soviet Barracks -Traits=Building, RenderBuilding, RallyPoint, Production +Traits=Building, RenderBuilding, RallyPoint, Production, IronCurtainable Dimensions=2,2 Footprint=xx xx Produces=Infantry @@ -456,7 +456,7 @@ SelectionPriority=3 LongDesc=Produces infantry [TENT] Description=Allied Barracks -Traits=Building, RenderBuilding, RallyPoint, Production +Traits=Building, RenderBuilding, RallyPoint, Production, IronCurtainable Dimensions=2,2 Footprint=xx xx Produces=Infantry @@ -465,7 +465,7 @@ SelectionPriority=3 LongDesc=Produces infantry [KENN] Description=Kennel -Traits=Building, RenderBuilding, RallyPoint, Production +Traits=Building, RenderBuilding, RallyPoint, Production, IronCurtainable Dimensions=1,1 Footprint=x RallyPoint=1,2 @@ -473,21 +473,21 @@ SelectionPriority=3 LongDesc=Produces attack dogs [FIX] Description=Service Depot -Traits=Building, RenderBuilding, BelowUnits, Reservable +Traits=Building, RenderBuilding, BelowUnits, Reservable, IronCurtainable Dimensions=3,3 Footprint=_x_ xxx _x_ SelectionPriority=3 LongDesc=Repairs vehicles, reloads minelayers, and \nallows the construction of additional bases. [FACF] Description=Fake Construction Yard -Traits=Building, RenderBuilding, Fake +Traits=Building, RenderBuilding, Fake, IronCurtainable Dimensions=3,3 Footprint=xxx xxx xxx SelectionPriority=3 LongDesc=Looks like a Construction Yard. [WEAF] Description=Fake War Factory -Traits=Building, RenderWarFactory, RenderBuilding, Fake +Traits=Building, RenderWarFactory, RenderBuilding, Fake, IronCurtainable Dimensions=3,2 Footprint=xxx xxx SelectionPriority=3 From 0e05f4db5cec3a05b61cee6c83cf1da6ffc34e68 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 8 Jan 2010 00:45:41 +1300 Subject: [PATCH 3/6] Iron Curtain and Powerdown palette effects --- OpenRa.Game/Graphics/HardwarePalette.cs | 15 ++++++++------- OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Traits/Building.cs | 15 +++------------ OpenRa.Game/Traits/IronCurtainable.cs | 2 +- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/OpenRa.Game/Graphics/HardwarePalette.cs b/OpenRa.Game/Graphics/HardwarePalette.cs index 09132cc5be..147a639a34 100644 --- a/OpenRa.Game/Graphics/HardwarePalette.cs +++ b/OpenRa.Game/Graphics/HardwarePalette.cs @@ -5,8 +5,8 @@ namespace OpenRa.Game.Graphics { public enum PaletteType { - Gold, Blue, Red, Orange, Teal, Salmon, Green, Gray, - Shadow, Invuln, Chrome, Shroud, Highlight, + Gold, Blue, Red, Orange, Teal, Salmon, Green, Gray, + Shadow, Invuln, Disabled, Highlight, Shroud, Chrome, }; class HardwarePalette : Sheet @@ -23,11 +23,12 @@ namespace OpenRa.Game.Graphics foreach (string remap in new string[] { "blue", "red", "orange", "teal", "salmon", "green", "gray" }) AddPalette(new Palette(pal, new PlayerColorRemap(FileSystem.Open(remap + ".rem")))); - AddPalette(new Palette(pal, new SingleColorRemap(Color.FromArgb(140, 0, 0, 0)))); - AddPalette(pal); // iron curtain. todo: remap! - AddPalette(pal); // chrome (it's like gold, but we're not going to hax it in palettemods) - AddPalette(new Palette(pal, new ShroudPaletteRemap())); - AddPalette(new Palette(pal, new SingleColorRemap(Color.FromArgb(128, 255, 255, 255)))); + AddPalette(new Palette(pal, new SingleColorRemap(Color.FromArgb(140, 0, 0, 0)))); // Shadow + AddPalette(new Palette(pal, new SingleColorRemap(Color.FromArgb(128, 128, 0, 0)))); // Invulnerable (Iron Curtain) + AddPalette(new Palette(pal, new SingleColorRemap(Color.FromArgb(180, 0, 0, 0)))); // Disabled / Low power + AddPalette(new Palette(pal, new SingleColorRemap(Color.FromArgb(128, 255, 255, 255)))); // Highlight + AddPalette(new Palette(pal, new ShroudPaletteRemap())); // Shroud + AddPalette(pal); // Chrome (it's like gold, but we're not going to hax it in palettemods) } int AddPalette(Palette p) diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index df46a1172b..edc3f28fc9 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -84,6 +84,7 @@ + diff --git a/OpenRa.Game/Traits/Building.cs b/OpenRa.Game/Traits/Building.cs index dfb870285c..22bf173a80 100644 --- a/OpenRa.Game/Traits/Building.cs +++ b/OpenRa.Game/Traits/Building.cs @@ -15,6 +15,7 @@ namespace OpenRa.Game.Traits public readonly BuildingInfo unitInfo; bool isRepairing = false; bool isPoweredDown = false; + public bool IsPoweredDown { get { return isPoweredDown; } } public Building(Actor self) { @@ -50,19 +51,8 @@ namespace OpenRa.Game.Traits List nrs = new List(rs); foreach(var r in rs) { - // Need 2 shadows to make it dark enough - nrs.Add(r.WithPalette(PaletteType.Shadow)); - nrs.Add(r.WithPalette(PaletteType.Shadow)); + nrs.Add(r.WithPalette(PaletteType.Disabled)); } - - if (isPoweredDown) - { - iconAnim = new Animation("powerdown"); - iconAnim.PlayRepeating("disabled"); - nrs.Add(new Renderable(iconAnim.Image, self.CenterLocation - 0.5f*iconAnim.Image.size, PaletteType.Chrome)); - } - - return nrs; } @@ -93,6 +83,7 @@ namespace OpenRa.Game.Traits if (order.OrderString == "PowerDown") { isPoweredDown = !isPoweredDown; + if (isPoweredDown) Game.world.AddFrameEndTask(w => w.Add(new PowerDownIndicator(self))); Sound.Play((isPoweredDown) ? "bleep12.aud" : "bleep11.aud"); } } diff --git a/OpenRa.Game/Traits/IronCurtainable.cs b/OpenRa.Game/Traits/IronCurtainable.cs index 91716f6bab..eb15272a02 100644 --- a/OpenRa.Game/Traits/IronCurtainable.cs +++ b/OpenRa.Game/Traits/IronCurtainable.cs @@ -49,7 +49,7 @@ namespace OpenRa.Game.Traits List nrs = new List(rs); foreach(var r in rs) { - nrs.Add(r.WithPalette(PaletteType.Shadow)); + nrs.Add(r.WithPalette(PaletteType.Invuln)); } return nrs; } From 42cfa7ec59af258917b955fabdeb22e03853c3c0 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 8 Jan 2010 00:52:00 +1300 Subject: [PATCH 4/6] Iron curtain targetting polish --- OpenRa.Game/Chrome.cs | 8 +++++++- OpenRa.Game/Traits/IronCurtainable.cs | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/OpenRa.Game/Chrome.cs b/OpenRa.Game/Chrome.cs index 3e7b531932..ea84206eb9 100644 --- a/OpenRa.Game/Chrome.cs +++ b/OpenRa.Game/Chrome.cs @@ -317,7 +317,7 @@ namespace OpenRa.Game else { //repairButton.ReplaceAnim(Game.controller.orderGenerator is RepairOrderGenerator ? "pressed" : "normal"); - AddButton(curtainRect, isLmb => Game.controller.ToggleInputMode()); + AddButton(curtainRect, isLmb => HandleIronCurtainButton()); } buildPaletteRenderer.DrawSprite(repairButton.Image, curtainDrawPos, PaletteType.Chrome); @@ -391,6 +391,12 @@ namespace OpenRa.Game Sound.Play("slcttgt1.aud"); } + void HandleIronCurtainButton() + { + if (Game.controller.ToggleInputMode()) + Sound.Play("slcttgt1.aud"); + } + void DrawChat() { var chatpos = new int2(400, Game.viewport.Height - 20); diff --git a/OpenRa.Game/Traits/IronCurtainable.cs b/OpenRa.Game/Traits/IronCurtainable.cs index eb15272a02..0b01d5fbf7 100644 --- a/OpenRa.Game/Traits/IronCurtainable.cs +++ b/OpenRa.Game/Traits/IronCurtainable.cs @@ -32,10 +32,11 @@ namespace OpenRa.Game.Traits { if (order.OrderString == "IronCurtain") { + Game.controller.CancelInputMode(); RemainingTicks = (int)(Rules.General.IronCurtain * 60 * 25); + Sound.Play("ironcur9.aud"); // Play active anim var ironCurtain = Game.world.Actors.Where(a => a.Owner == order.Subject.Owner && a.traits.Contains()).FirstOrDefault(); - Sound.Play("ironcur9.aud"); if (ironCurtain != null) ironCurtain.traits.Get().PlayCustomAnim(ironCurtain, "active"); } From f3fd108a23d590a949e36c32257a3b27fabd6c12 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 8 Jan 2010 01:26:30 +1300 Subject: [PATCH 5/6] Refactor building power-down and Invulnerable effect. Introduces render bugs on state change (effects appearing/dissapearing a frame too late) --- OpenRa.Game/Effects/InvulnEffect.cs | 30 ++++++++++++++++ OpenRa.Game/Effects/PowerDownIndicator.cs | 36 +++++++++++++++++++ OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Traits/AttackTurreted.cs | 2 +- OpenRa.Game/Traits/Building.cs | 42 ++++++++--------------- OpenRa.Game/Traits/IronCurtainable.cs | 17 ++------- OpenRa.Game/Traits/ProductionQueue.cs | 2 +- OpenRa.Game/Traits/ProvidesRadar.cs | 2 +- 8 files changed, 87 insertions(+), 45 deletions(-) create mode 100644 OpenRa.Game/Effects/InvulnEffect.cs create mode 100644 OpenRa.Game/Effects/PowerDownIndicator.cs diff --git a/OpenRa.Game/Effects/InvulnEffect.cs b/OpenRa.Game/Effects/InvulnEffect.cs new file mode 100644 index 0000000000..b7f28a0a49 --- /dev/null +++ b/OpenRa.Game/Effects/InvulnEffect.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using OpenRa.Game.Graphics; +using OpenRa.Game.Traits; + +namespace OpenRa.Game.Effects +{ + class InvulnEffect : IEffect + { + Actor a; + IronCurtainable b; + + public InvulnEffect(Actor a) + { + this.a = a; + this.b = a.traits.Get(); + } + + public void Tick() + { + if (a.IsDead || b.GetDamageModifier() > 0) + Game.world.AddFrameEndTask(w => w.Remove(this)); + } + + public IEnumerable Render() + { + foreach (var r in a.Render()) + yield return r.WithPalette(PaletteType.Invuln); + } + } +} diff --git a/OpenRa.Game/Effects/PowerDownIndicator.cs b/OpenRa.Game/Effects/PowerDownIndicator.cs new file mode 100644 index 0000000000..185366a078 --- /dev/null +++ b/OpenRa.Game/Effects/PowerDownIndicator.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using OpenRa.Game.Graphics; +using OpenRa.Game.Traits; + +namespace OpenRa.Game.Effects +{ + class PowerDownIndicator : IEffect + { + Actor a; + Building b; + Animation anim = new Animation("powerdown"); + + public PowerDownIndicator(Actor a) + { + this.a = a; + this.b = a.traits.Get(); + anim.PlayRepeating("disabled"); + } + + public void Tick() + { + if (!b.Disabled || a.IsDead) + Game.world.AddFrameEndTask(w => w.Remove(this)); + } + + public IEnumerable Render() + { + foreach (var r in a.Render()) + yield return r.WithPalette(PaletteType.Disabled); + + if (b.ManuallyDisabled) + 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 edc3f28fc9..80e5bc199f 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -83,6 +83,7 @@ + diff --git a/OpenRa.Game/Traits/AttackTurreted.cs b/OpenRa.Game/Traits/AttackTurreted.cs index 20941b5886..9c0f513251 100755 --- a/OpenRa.Game/Traits/AttackTurreted.cs +++ b/OpenRa.Game/Traits/AttackTurreted.cs @@ -26,7 +26,7 @@ namespace OpenRa.Game.Traits protected override void QueueAttack( Actor self, Order order ) { - if (self.traits.Contains() && self.traits.Get().InsuffientPower()) + if (self.traits.Contains() && self.traits.Get().Disabled) return; const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */ diff --git a/OpenRa.Game/Traits/Building.cs b/OpenRa.Game/Traits/Building.cs index 22bf173a80..da1b4408a0 100644 --- a/OpenRa.Game/Traits/Building.cs +++ b/OpenRa.Game/Traits/Building.cs @@ -9,14 +9,16 @@ using OpenRa.Game.Graphics; namespace OpenRa.Game.Traits { - class Building : INotifyDamage, IOrder, ITick, IRenderModifier + class Building : INotifyDamage, IOrder, ITick { readonly Actor self; public readonly BuildingInfo unitInfo; bool isRepairing = false; - bool isPoweredDown = false; - public bool IsPoweredDown { get { return isPoweredDown; } } - + bool isManuallyDisabled = false; + bool wasManuallyDisabled = false; + public bool ManuallyDisabled { get { return isManuallyDisabled; } } + public bool Disabled { get { return (isManuallyDisabled || (unitInfo.Powered && self.Owner.GetPowerState() != PowerState.Normal)); } } + public Building(Actor self) { this.self = self; @@ -25,14 +27,9 @@ namespace OpenRa.Game.Traits * ((float2)self.Location + .5f * (float2)unitInfo.Dimensions); } - public bool InsuffientPower() - { - return (isPoweredDown || (unitInfo.Powered && self.Owner.GetPowerState() != PowerState.Normal)); - } - public int GetPowerUsage() { - if (isPoweredDown) + if (isManuallyDisabled) return 0; if (unitInfo.Power > 0) /* todo: is this how real-ra scales it? */ @@ -41,21 +38,6 @@ namespace OpenRa.Game.Traits return unitInfo.Power; } - public Animation iconAnim; - public IEnumerable - ModifyRender(Actor self, IEnumerable rs) - { - if (!InsuffientPower()) - return rs; - - List nrs = new List(rs); - foreach(var r in rs) - { - nrs.Add(r.WithPalette(PaletteType.Disabled)); - } - return nrs; - } - public void Damaged(Actor self, AttackInfo e) { if (e.DamageState == DamageState.Dead) @@ -82,9 +64,8 @@ namespace OpenRa.Game.Traits if (order.OrderString == "PowerDown") { - isPoweredDown = !isPoweredDown; - if (isPoweredDown) Game.world.AddFrameEndTask(w => w.Add(new PowerDownIndicator(self))); - Sound.Play((isPoweredDown) ? "bleep12.aud" : "bleep11.aud"); + isManuallyDisabled = !isManuallyDisabled; + Sound.Play((isManuallyDisabled) ? "bleep12.aud" : "bleep11.aud"); } } @@ -92,6 +73,11 @@ namespace OpenRa.Game.Traits public void Tick(Actor self) { + // If the disabled state has changed since the last frame + if (Disabled ^ wasManuallyDisabled + && (wasManuallyDisabled = Disabled)) // Yes, I mean assignment + Game.world.AddFrameEndTask(w => w.Add(new PowerDownIndicator(self))); + if (!isRepairing) return; if (remainingTicks == 0) diff --git a/OpenRa.Game/Traits/IronCurtainable.cs b/OpenRa.Game/Traits/IronCurtainable.cs index 0b01d5fbf7..685075273f 100644 --- a/OpenRa.Game/Traits/IronCurtainable.cs +++ b/OpenRa.Game/Traits/IronCurtainable.cs @@ -8,7 +8,7 @@ using OpenRa.Game.Graphics; namespace OpenRa.Game.Traits { - class IronCurtainable: IOrder, IDamageModifier, ITick, IRenderModifier + class IronCurtainable: IOrder, IDamageModifier, ITick { int RemainingTicks = 0; @@ -23,6 +23,7 @@ namespace OpenRa.Game.Traits { return (RemainingTicks > 0) ? 0.0f : 1.0f; } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { return null; // Chronoshift order is issued through Chrome. @@ -33,6 +34,7 @@ namespace OpenRa.Game.Traits if (order.OrderString == "IronCurtain") { Game.controller.CancelInputMode(); + Game.world.AddFrameEndTask(w => w.Add(new InvulnEffect(self))); RemainingTicks = (int)(Rules.General.IronCurtain * 60 * 25); Sound.Play("ironcur9.aud"); // Play active anim @@ -41,18 +43,5 @@ namespace OpenRa.Game.Traits ironCurtain.traits.Get().PlayCustomAnim(ironCurtain, "active"); } } - - public IEnumerable ModifyRender(Actor self, IEnumerable rs) - { - if (RemainingTicks <= 0) - return rs; - - List nrs = new List(rs); - foreach(var r in rs) - { - nrs.Add(r.WithPalette(PaletteType.Invuln)); - } - return nrs; - } } } diff --git a/OpenRa.Game/Traits/ProductionQueue.cs b/OpenRa.Game/Traits/ProductionQueue.cs index 0e58800572..824229b64d 100755 --- a/OpenRa.Game/Traits/ProductionQueue.cs +++ b/OpenRa.Game/Traits/ProductionQueue.cs @@ -140,7 +140,7 @@ namespace OpenRa.Game.Traits foreach (var p in primaryProducers) { // Ignore buildings that are disabled - if (p.traits.Contains() && p.traits.Get().InsuffientPower()) + if (p.traits.Contains() && p.traits.Get().Disabled) continue; producer = p; break; diff --git a/OpenRa.Game/Traits/ProvidesRadar.cs b/OpenRa.Game/Traits/ProvidesRadar.cs index 41c3ced78c..7a4ba5e0c6 100644 --- a/OpenRa.Game/Traits/ProvidesRadar.cs +++ b/OpenRa.Game/Traits/ProvidesRadar.cs @@ -19,7 +19,7 @@ namespace OpenRa.Game.Traits // Check if powered var b = self.traits.Get(); - if (b != null && b.InsuffientPower()) + if (b != null && b.Disabled) return false; return true; From b570f3c9a716b352cbce0c6232870be356b53461 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 8 Jan 2010 01:32:50 +1300 Subject: [PATCH 6/6] Pedantic about wording --- OpenRa.Game/Traits/Building.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/OpenRa.Game/Traits/Building.cs b/OpenRa.Game/Traits/Building.cs index da1b4408a0..bd48fc1c0d 100644 --- a/OpenRa.Game/Traits/Building.cs +++ b/OpenRa.Game/Traits/Building.cs @@ -14,10 +14,10 @@ namespace OpenRa.Game.Traits readonly Actor self; public readonly BuildingInfo unitInfo; bool isRepairing = false; - bool isManuallyDisabled = false; - bool wasManuallyDisabled = false; - public bool ManuallyDisabled { get { return isManuallyDisabled; } } - public bool Disabled { get { return (isManuallyDisabled || (unitInfo.Powered && self.Owner.GetPowerState() != PowerState.Normal)); } } + bool manuallyDisabled = false; + public bool ManuallyDisabled { get { return manuallyDisabled; } } + public bool Disabled { get { return (manuallyDisabled || (unitInfo.Powered && self.Owner.GetPowerState() != PowerState.Normal)); } } + bool wasDisabled = false; public Building(Actor self) { @@ -29,7 +29,7 @@ namespace OpenRa.Game.Traits public int GetPowerUsage() { - if (isManuallyDisabled) + if (manuallyDisabled) return 0; if (unitInfo.Power > 0) /* todo: is this how real-ra scales it? */ @@ -64,8 +64,8 @@ namespace OpenRa.Game.Traits if (order.OrderString == "PowerDown") { - isManuallyDisabled = !isManuallyDisabled; - Sound.Play((isManuallyDisabled) ? "bleep12.aud" : "bleep11.aud"); + manuallyDisabled = !manuallyDisabled; + Sound.Play((manuallyDisabled) ? "bleep12.aud" : "bleep11.aud"); } } @@ -74,8 +74,8 @@ namespace OpenRa.Game.Traits public void Tick(Actor self) { // If the disabled state has changed since the last frame - if (Disabled ^ wasManuallyDisabled - && (wasManuallyDisabled = Disabled)) // Yes, I mean assignment + if (Disabled ^ wasDisabled + && (wasDisabled = Disabled)) // Yes, I mean assignment Game.world.AddFrameEndTask(w => w.Add(new PowerDownIndicator(self))); if (!isRepairing) return;