From 3b0fd0e22cfa8e82bc04eb6c0a666876043bbf65 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 4 Jan 2010 13:42:53 +1300 Subject: [PATCH 1/6] Fix Damage spread --- OpenRa.Game/Combat.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/OpenRa.Game/Combat.cs b/OpenRa.Game/Combat.cs index ea855f1f38..b6cb373754 100644 --- a/OpenRa.Game/Combat.cs +++ b/OpenRa.Game/Combat.cs @@ -32,7 +32,7 @@ namespace OpenRa.Game var maxSpread = GetMaximumSpread(weapon, warhead); var hitActors = Game.FindUnitsInCircle(loc, maxSpread); - + foreach (var victim in hitActors) victim.InflictDamage(firedBy, (int)GetDamageToInflict(victim, loc, weapon, warhead), warhead); } @@ -46,11 +46,10 @@ namespace OpenRa.Game { if (!WeaponValidForTarget(weapon, target)) return 0f; - - var distance = (target.CenterLocation - loc).Length; + + var distance = (target.CenterLocation - loc).Length*1/24f; var rawDamage = weapon.Damage * (float)Math.Exp(-distance / warhead.Spread); var multiplier = warhead.EffectivenessAgainst(target.Info.Armor); - return rawDamage * multiplier; } From 88c3e21ed091caed05b9aa289ce84b2305f93cab Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 4 Jan 2010 21:04:57 +1300 Subject: [PATCH 2/6] Selectively power-up/down buildings via chrome --- OpenRa.Game/Chrome.cs | 23 ++++++++- OpenRa.Game/Cursor.cs | 1 + OpenRa.Game/GameRules/UserSettings.cs | 1 + OpenRa.Game/Graphics/CursorSheetBuilder.cs | 12 ++++- OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Orders/PowerDownOrderGenerator.cs | 47 +++++++++++++++++++ OpenRa.Game/Player.cs | 9 ++-- OpenRa.Game/Traits/AttackTurreted.cs | 7 +-- OpenRa.Game/Traits/Building.cs | 24 ++++++++++ sequences.xml | 3 ++ 10 files changed, 115 insertions(+), 13 deletions(-) create mode 100644 OpenRa.Game/Orders/PowerDownOrderGenerator.cs diff --git a/OpenRa.Game/Chrome.cs b/OpenRa.Game/Chrome.cs index 7c775fd7a2..b7010bbdbe 100644 --- a/OpenRa.Game/Chrome.cs +++ b/OpenRa.Game/Chrome.cs @@ -26,6 +26,7 @@ namespace OpenRa.Game readonly Animation repairButton; readonly Animation sellButton; + readonly Animation pwrdownButton; readonly SpriteRenderer buildPaletteRenderer; readonly Animation cantBuild; @@ -77,6 +78,9 @@ namespace OpenRa.Game sellButton = new Animation("sell"); sellButton.PlayRepeating("normal"); + + pwrdownButton = new Animation("repair"); + pwrdownButton.PlayRepeating("normal"); blank = SheetBuilder.Add(new Size(64, 48), 16); @@ -285,7 +289,7 @@ namespace OpenRa.Game // Repair - Rectangle repairRect = new Rectangle(Game.viewport.Width - 100, 5, repairButton.Image.bounds.Width, repairButton.Image.bounds.Height); + Rectangle repairRect = new Rectangle(Game.viewport.Width - 120, 5, repairButton.Image.bounds.Width, repairButton.Image.bounds.Height); var repairDrawPos = Game.viewport.Location + new float2(repairRect.Location); var hasFact = Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains()); @@ -300,7 +304,7 @@ namespace OpenRa.Game buildPaletteRenderer.DrawSprite(repairButton.Image, repairDrawPos, PaletteType.Chrome); // Sell - Rectangle sellRect = new Rectangle(Game.viewport.Width - 60, 5, + Rectangle sellRect = new Rectangle(Game.viewport.Width - 80, 5, sellButton.Image.bounds.Width, sellButton.Image.bounds.Height); var sellDrawPos = Game.viewport.Location + new float2(sellRect.Location); @@ -310,6 +314,21 @@ namespace OpenRa.Game AddButton(sellRect, isLmb => Game.controller.ToggleInputMode()); buildPaletteRenderer.DrawSprite(sellButton.Image, sellDrawPos, PaletteType.Chrome); buildPaletteRenderer.Flush(); + + if (Game.Settings.PowerDownBuildings) + { + // Power Down + Rectangle pwrdownRect = new Rectangle(Game.viewport.Width - 40, 5, + pwrdownButton.Image.bounds.Width, pwrdownButton.Image.bounds.Height); + + var pwrdownDrawPos = Game.viewport.Location + new float2(pwrdownRect.Location); + + pwrdownButton.ReplaceAnim(Game.controller.orderGenerator is PowerDownOrderGenerator ? "pressed" : "normal"); + + AddButton(pwrdownRect, isLmb => Game.controller.ToggleInputMode()); + buildPaletteRenderer.DrawSprite(pwrdownButton.Image, pwrdownDrawPos, PaletteType.Chrome); + } + buildPaletteRenderer.Flush(); } void HandleChronosphereButton() diff --git a/OpenRa.Game/Cursor.cs b/OpenRa.Game/Cursor.cs index ee4115a229..54ebacc76d 100644 --- a/OpenRa.Game/Cursor.cs +++ b/OpenRa.Game/Cursor.cs @@ -32,5 +32,6 @@ namespace OpenRa.Game public static Cursor SellBlocked { get { return new Cursor("sell-blocked"); } } public static Cursor Repair { get { return new Cursor("repair"); } } public static Cursor RepairBlocked { get { return new Cursor("repair-blocked"); } } + public static Cursor PowerDown { get { return new Cursor("powerdown"); } } } } diff --git a/OpenRa.Game/GameRules/UserSettings.cs b/OpenRa.Game/GameRules/UserSettings.cs index fd102cf4bd..8c441320f3 100644 --- a/OpenRa.Game/GameRules/UserSettings.cs +++ b/OpenRa.Game/GameRules/UserSettings.cs @@ -27,6 +27,7 @@ namespace OpenRa.Game.GameRules // Gameplay options public readonly bool RepairRequiresConyard = true; + public readonly bool PowerDownBuildings = true; } } diff --git a/OpenRa.Game/Graphics/CursorSheetBuilder.cs b/OpenRa.Game/Graphics/CursorSheetBuilder.cs index 333a225da9..1a6b7291e3 100644 --- a/OpenRa.Game/Graphics/CursorSheetBuilder.cs +++ b/OpenRa.Game/Graphics/CursorSheetBuilder.cs @@ -11,8 +11,16 @@ namespace OpenRa.Game.Graphics static Sprite[] LoadCursors(string filename) { - var shp = new Dune2ShpReader(FileSystem.OpenWithExts(filename, exts)); - return shp.Select(a => SheetBuilder.Add(a.Image, a.Size)).ToArray(); + try + { + var shp = new Dune2ShpReader(FileSystem.OpenWithExts(filename, exts)); + return shp.Select(a => SheetBuilder.Add(a.Image, a.Size)).ToArray(); + } + catch (System.IndexOutOfRangeException) // This will occur when loading a custom (RA-format) .shp + { + var shp = new ShpReader(FileSystem.OpenWithExts(filename, exts)); + return shp.Select(a => SheetBuilder.Add(a.Image, shp.Size)).ToArray(); + } } public static Sprite[] LoadAllSprites(string filename) { return cursors[filename]; } diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 72f4caec37..5aa72ea0c5 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -103,6 +103,7 @@ + diff --git a/OpenRa.Game/Orders/PowerDownOrderGenerator.cs b/OpenRa.Game/Orders/PowerDownOrderGenerator.cs new file mode 100644 index 0000000000..5779e81a20 --- /dev/null +++ b/OpenRa.Game/Orders/PowerDownOrderGenerator.cs @@ -0,0 +1,47 @@ +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 PowerDownOrderGenerator : 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 building = underCursor != null ? underCursor.Info as BuildingInfo : null; + + if (building != null) + yield return new Order("PowerDown", underCursor, null, int2.Zero, null); + } + } + + public void Tick() { } + public void Render() { } + + public Cursor GetCursor(int2 xy, MouseInput mi) + { + mi.Button = MouseButton.Left; + return OrderInner(xy, mi).Any() + ? Cursor.PowerDown : Cursor.PowerDown; + } + } +} diff --git a/OpenRa.Game/Player.cs b/OpenRa.Game/Player.cs index 5e40e92b32..5f1684ef50 100644 --- a/OpenRa.Game/Player.cs +++ b/OpenRa.Game/Player.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Collections.Generic; using OpenRa.Game.GameRules; using OpenRa.Game.Graphics; using OpenRa.Game.Traits; @@ -52,11 +53,11 @@ namespace OpenRa.Game foreach (var a in myBuildings) { - var bi = a.Info as BuildingInfo; - if (bi.Power > 0) /* todo: is this how real-ra scales it? */ - PowerProvided += (a.Health * bi.Power) / bi.Strength; + var p = a.traits.Get().GetPowerUsage(); + if (p > 0) + PowerProvided += p; else - PowerDrained -= bi.Power; + PowerDrained -= p; } if (PowerProvided - PowerDrained < 0) diff --git a/OpenRa.Game/Traits/AttackTurreted.cs b/OpenRa.Game/Traits/AttackTurreted.cs index 256bd25379..5ccfbdaeb5 100755 --- a/OpenRa.Game/Traits/AttackTurreted.cs +++ b/OpenRa.Game/Traits/AttackTurreted.cs @@ -26,12 +26,9 @@ namespace OpenRa.Game.Traits protected override void QueueAttack( Actor self, Order order ) { - var bi = self.Info as BuildingInfo; - if (bi != null && bi.Powered && self.Owner.GetPowerState() != PowerState.Normal) - { - if (self.Owner == Game.LocalPlayer) Sound.Play("nopowr1.aud"); + var bi = self.traits.Get(); + if (bi != null && !bi.IsActive()) return; - } const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */ /* todo: choose the appropriate weapon, when only one works against this target */ diff --git a/OpenRa.Game/Traits/Building.cs b/OpenRa.Game/Traits/Building.cs index 5beea8d05f..ffdc657b17 100644 --- a/OpenRa.Game/Traits/Building.cs +++ b/OpenRa.Game/Traits/Building.cs @@ -10,15 +10,34 @@ namespace OpenRa.Game.Traits { class Building : INotifyDamage, IOrder, ITick { + readonly Actor self; public readonly BuildingInfo unitInfo; bool isRepairing = false; + bool isPoweredDown = false; public Building(Actor self) { + this.self = self; unitInfo = (BuildingInfo)self.Info; self.CenterLocation = Game.CellSize * ((float2)self.Location + .5f * (float2)unitInfo.Dimensions); } + + public bool IsActive() + { + return !(isPoweredDown || (unitInfo.Powered && self.Owner.GetPowerState() != PowerState.Normal)); + } + + public int GetPowerUsage() + { + if (isPoweredDown) + return 0; + + if (unitInfo.Power > 0) /* todo: is this how real-ra scales it? */ + return (self.Health * unitInfo.Power) / unitInfo.Strength; + else + return unitInfo.Power; + } public void Damaged(Actor self, AttackInfo e) { @@ -43,6 +62,11 @@ namespace OpenRa.Game.Traits { isRepairing = !isRepairing; } + + if (order.OrderString == "PowerDown") + { + isPoweredDown = !isPoweredDown; + } } int remainingTicks; diff --git a/sequences.xml b/sequences.xml index f659cf186a..2abe5428ed 100644 --- a/sequences.xml +++ b/sequences.xml @@ -401,6 +401,9 @@ + + + From 5fdba51536599363595d70e6ae6ecb8e65885100 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 4 Jan 2010 21:12:35 +1300 Subject: [PATCH 3/6] Clarify method name --- OpenRa.Game/Traits/AttackTurreted.cs | 4 ++-- OpenRa.Game/Traits/Building.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenRa.Game/Traits/AttackTurreted.cs b/OpenRa.Game/Traits/AttackTurreted.cs index 5ccfbdaeb5..1d0007e223 100755 --- a/OpenRa.Game/Traits/AttackTurreted.cs +++ b/OpenRa.Game/Traits/AttackTurreted.cs @@ -26,8 +26,8 @@ namespace OpenRa.Game.Traits protected override void QueueAttack( Actor self, Order order ) { - var bi = self.traits.Get(); - if (bi != null && !bi.IsActive()) + var b = self.traits.Get(); + if (b != null && b.InsuffientPower()) 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 ffdc657b17..e1c6215a88 100644 --- a/OpenRa.Game/Traits/Building.cs +++ b/OpenRa.Game/Traits/Building.cs @@ -23,9 +23,9 @@ namespace OpenRa.Game.Traits * ((float2)self.Location + .5f * (float2)unitInfo.Dimensions); } - public bool IsActive() + public bool InsuffientPower() { - return !(isPoweredDown || (unitInfo.Powered && self.Owner.GetPowerState() != PowerState.Normal)); + return (isPoweredDown || (unitInfo.Powered && self.Owner.GetPowerState() != PowerState.Normal)); } public int GetPowerUsage() From bfc797441911b3b9af7451dc6bed777301d331d4 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 4 Jan 2010 21:35:33 +1300 Subject: [PATCH 4/6] Tie Minimap to ProvidesRadar trait --- OpenRa.Game/Chrome.cs | 13 +++++++++---- OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Traits/ProvidesRadar.cs | 28 ++++++++++++++++++++++++++++ units.ini | 2 +- 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 OpenRa.Game/Traits/ProvidesRadar.cs diff --git a/OpenRa.Game/Chrome.cs b/OpenRa.Game/Chrome.cs index b7010bbdbe..14a9484b76 100644 --- a/OpenRa.Game/Chrome.cs +++ b/OpenRa.Game/Chrome.cs @@ -143,16 +143,21 @@ namespace OpenRa.Game DrawPower(); chromeRenderer.Flush(); DrawButtons(); - + DrawMinimap(); int paletteHeight = DrawBuildPalette(currentTab); DrawBuildTabs(paletteHeight); DrawChat(); - - Game.minimap.Draw(new float2(Game.viewport.Width - 128,30)); } + void DrawMinimap() + { + var hasRadar = Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains() && a.traits.Get().IsActive()); + if (hasRadar) + Game.minimap.Draw(new float2(Game.viewport.Width - 128, 30)); + } + void AddButton(Rectangle r, Action b) { buttons.Add(Pair.New(r, b)); } - + void DrawBuildTabs(int paletteHeight) { const int tabWidth = 24; diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 5aa72ea0c5..fef5cc01aa 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -214,6 +214,7 @@ + diff --git a/OpenRa.Game/Traits/ProvidesRadar.cs b/OpenRa.Game/Traits/ProvidesRadar.cs new file mode 100644 index 0000000000..41c3ced78c --- /dev/null +++ b/OpenRa.Game/Traits/ProvidesRadar.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenRa.Game.Traits +{ + class ProvidesRadar + { + Actor self; + public ProvidesRadar(Actor self) + { + this.self = self; + } + + public bool IsActive() + { + // TODO: Check for nearby MRJ + + // Check if powered + var b = self.traits.Get(); + if (b != null && b.InsuffientPower()) + return false; + + return true; + } + } +} diff --git a/units.ini b/units.ini index 5b0d90121e..ad27a28435 100644 --- a/units.ini +++ b/units.ini @@ -407,7 +407,7 @@ SpawnOffset=0,-4 LongDesc=Produces and reloads helicopters [DOME] Description=Radar Dome -Traits=Building, RenderBuilding +Traits=Building, RenderBuilding, ProvidesRadar Dimensions=2,2 Footprint=xx xx SelectionPriority=3 From ac18d0ab449dedbaca943ae5d741e039c5de565d Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 5 Jan 2010 00:08:05 +1300 Subject: [PATCH 5/6] Temporarily hack in a powerdown effect until we do it properly --- OpenRa.Game/Traits/Building.cs | 29 ++++++++++++++++++++++++++++- sequences.xml | 3 +++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/OpenRa.Game/Traits/Building.cs b/OpenRa.Game/Traits/Building.cs index e1c6215a88..0b2da8e38d 100644 --- a/OpenRa.Game/Traits/Building.cs +++ b/OpenRa.Game/Traits/Building.cs @@ -5,10 +5,11 @@ using System.Collections.Generic; using System.Linq; using System.Text; using OpenRa.Game.Effects; +using OpenRa.Game.Graphics; namespace OpenRa.Game.Traits { - class Building : INotifyDamage, IOrder, ITick + class Building : INotifyDamage, IOrder, ITick, IRenderModifier { readonly Actor self; public readonly BuildingInfo unitInfo; @@ -39,6 +40,32 @@ 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) + { + // Need 2 shadows to make it dark enough + nrs.Add(r.WithPalette(PaletteType.Shadow)); + nrs.Add(r.WithPalette(PaletteType.Shadow)); + } + + 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; + } + public void Damaged(Actor self, AttackInfo e) { if (e.DamageState == DamageState.Dead) diff --git a/sequences.xml b/sequences.xml index 2abe5428ed..b27ced5362 100644 --- a/sequences.xml +++ b/sequences.xml @@ -404,6 +404,9 @@ + + + From b4f097c23c7bfa0e271f3661333232d6e633e7d2 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 5 Jan 2010 00:18:29 +1300 Subject: [PATCH 6/6] Audio feedback on powerdown/up --- OpenRa.Game/Traits/Building.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenRa.Game/Traits/Building.cs b/OpenRa.Game/Traits/Building.cs index 0b2da8e38d..dfb870285c 100644 --- a/OpenRa.Game/Traits/Building.cs +++ b/OpenRa.Game/Traits/Building.cs @@ -93,6 +93,7 @@ namespace OpenRa.Game.Traits if (order.OrderString == "PowerDown") { isPoweredDown = !isPoweredDown; + Sound.Play((isPoweredDown) ? "bleep12.aud" : "bleep11.aud"); } }