From b86f76ce8ceb049414b2c5c1206c24cb0b544350 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 11 Jan 2010 22:35:48 +1300 Subject: [PATCH 1/4] Blinky lights --- OpenRa.Game/Game.cs | 1 + OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Traits/LightPaletteRotator.cs | 26 +++++++++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 OpenRa.Game/Traits/LightPaletteRotator.cs diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 4ce3d7d8c4..df65ce57c7 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -79,6 +79,7 @@ namespace OpenRa.Game var worldActor = new Actor(null, new int2(int.MaxValue, int.MaxValue), null); worldActor.traits.Add(new Traits.WaterPaletteRotation(worldActor)); + worldActor.traits.Add(new Traits.LightPaletteRotator(worldActor)); worldActor.traits.Add(new Traits.ChronoshiftPaletteEffect(worldActor)); Game.world.Add(worldActor); diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index aac3bc8b21..14c7838ece 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -234,6 +234,7 @@ + diff --git a/OpenRa.Game/Traits/LightPaletteRotator.cs b/OpenRa.Game/Traits/LightPaletteRotator.cs new file mode 100644 index 0000000000..65ed5c59d7 --- /dev/null +++ b/OpenRa.Game/Traits/LightPaletteRotator.cs @@ -0,0 +1,26 @@ +using System.Drawing; + +namespace OpenRa.Game.Traits +{ + class LightPaletteRotator : ITick, IPaletteModifier + { + public LightPaletteRotator(Actor self) { } + + float t = 0; + public void Tick(Actor self) + { + t += .5f; + } + + public void AdjustPalette(Bitmap b) + { + var rotate = (int)t % 18; + if (rotate > 9) + rotate = 18 - rotate; + + using (var bitmapCopy = new Bitmap(b)) + for (int j = 0; j < 16; j++) + b.SetPixel(0x67, j, b.GetPixel(230+rotate, j)); + } + } +} From bf1e7b86e1d0197658779835d1baf8021b60ce2b Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 12 Jan 2010 00:03:00 +1300 Subject: [PATCH 2/4] Gap generators --- OpenRa.Game/Chrome.cs | 4 +--- OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Player.cs | 1 + OpenRa.Game/Shroud.cs | 32 +++++++++++++++++++++++++++++- OpenRa.Game/Traits/GeneratesGap.cs | 29 +++++++++++++++++++++++++++ units.ini | 4 ++-- 6 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 OpenRa.Game/Traits/GeneratesGap.cs diff --git a/OpenRa.Game/Chrome.cs b/OpenRa.Game/Chrome.cs index 318120d691..f114ab494b 100644 --- a/OpenRa.Game/Chrome.cs +++ b/OpenRa.Game/Chrome.cs @@ -481,9 +481,7 @@ namespace OpenRa.Game } void TickPaletteAnimation() - { - Log.Write("{0} {1} {2} {3}", paletteAnimationFrame, paletteOrigin.X, paletteAnimating, paletteOpen); - + { if (!paletteAnimating) return; diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 14c7838ece..d3d3fc46b2 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -227,6 +227,7 @@ + diff --git a/OpenRa.Game/Player.cs b/OpenRa.Game/Player.cs index b4ff66fe75..79006dbff5 100644 --- a/OpenRa.Game/Player.cs +++ b/OpenRa.Game/Player.cs @@ -130,6 +130,7 @@ namespace OpenRa.Game { UpdatePower(); UpdateOreCapacity(); + Shroud.Tick(); foreach (var sp in SupportPowers.Values) sp.Tick(); diff --git a/OpenRa.Game/Shroud.cs b/OpenRa.Game/Shroud.cs index 697e774406..6ee7456142 100644 --- a/OpenRa.Game/Shroud.cs +++ b/OpenRa.Game/Shroud.cs @@ -4,12 +4,14 @@ using System.Linq; using System.Text; using IjwFramework.Types; using OpenRa.Game.Graphics; +using OpenRa.Game.Traits; namespace OpenRa.Game { class Shroud { bool[,] explored = new bool[128, 128]; + int[,] gapField = new int[128, 128]; Sprite[] shadowBits = SpriteSheetBuilder.LoadAllSprites("shadow"); Sprite[,] sprites = new Sprite[128, 128]; bool dirty; @@ -21,9 +23,35 @@ namespace OpenRa.Game set { hasGPS = value; dirty = true;} } + public void Tick() + { + // This is probably slow + bool[,] gapActive = new bool[128, 128]; + foreach (var a in Game.world.Actors.Where(a => a.traits.Contains())) + { + foreach (var t in a.traits.Get().GetShroudedTiles()) + gapActive[t.X, t.Y] = true; + } + + for (int j = 1; j < 127; j++) + for (int i = 1; i < 127; i++) + { + if (gapField[i, j] > 0 && !gapActive[i, j]) /*0 >= --gapField[i, j]*/ + { + gapField[i, j] = 0; + dirty = true; + } + if (gapActive[i, j] && 0 == gapField[i, j]++) + dirty = true; + } + } + public bool IsExplored(int2 xy) { return IsExplored(xy.X, xy.Y); } public bool IsExplored(int x, int y) { + if (gapField[ x, y ] >= Rules.General.GapRegenInterval * 25 * 60) + return false; + if (hasGPS) return true; @@ -33,8 +61,10 @@ namespace OpenRa.Game public void Explore(Actor a) { foreach (var t in Game.FindTilesInCircle((1f / Game.CellSize * a.CenterLocation).ToInt2(), a.Info.Sight)) + { explored[t.X, t.Y] = true; - + gapField[t.X, t.Y] = 0; + } dirty = true; } diff --git a/OpenRa.Game/Traits/GeneratesGap.cs b/OpenRa.Game/Traits/GeneratesGap.cs new file mode 100644 index 0000000000..5dcdf3c4f6 --- /dev/null +++ b/OpenRa.Game/Traits/GeneratesGap.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRa.FileFormats; +using OpenRa.Game.Support; +using OpenRa.Game.Traits; + +namespace OpenRa.Game.Traits +{ + class GeneratesGap + { + Actor self; + public GeneratesGap(Actor self) + { + this.self = self; + } + + public IEnumerableGetShroudedTiles() + { + // Gap Generator building; powered down + if (self.traits.Contains() && self.traits.Get().Disabled) + yield break; + + // It won't let me return Game.FindTilesInCircle directly...? + foreach (var t in Game.FindTilesInCircle(self.Location, Rules.General.GapRadius)) + yield return t; + } + } +} diff --git a/units.ini b/units.ini index 4e22c79415..089a0be145 100644 --- a/units.ini +++ b/units.ini @@ -77,7 +77,7 @@ 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, IronCurtainable +Traits=Unit, Mobile, RenderUnitSpinner, Repairable, Chronoshiftable, Passenger, IronCurtainable, GeneratesGap PrimaryOffset=0,6,0,-3 SelectionPriority=3 Voice=VehicleVoice @@ -303,7 +303,7 @@ 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, IronCurtainable +Traits=Building, RenderBuilding, IronCurtainable, GeneratesGap Dimensions=1,2 Footprint=_ x SelectionPriority=3 From 542a9ef2fc8d2626c342cda732b36aef36b36585 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Wed, 13 Jan 2010 19:23:56 +1300 Subject: [PATCH 3/4] Gap behaves like real-ra --- OpenRa.Game/Graphics/Minimap.cs | 2 +- OpenRa.Game/Shroud.cs | 31 +++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/OpenRa.Game/Graphics/Minimap.cs b/OpenRa.Game/Graphics/Minimap.cs index f80cb3a066..021abe1a8c 100644 --- a/OpenRa.Game/Graphics/Minimap.cs +++ b/OpenRa.Game/Graphics/Minimap.cs @@ -103,7 +103,7 @@ namespace OpenRa.Game.Graphics { for (var y = 0; y < 128; y++) for (var x = 0; x < 128; x++) - if (!Game.LocalPlayer.Shroud.IsExplored(new int2(x, y))) + if (!Game.LocalPlayer.Shroud.DisplayOnRadar(x,y)) *(c + (y * bitmapData.Stride >> 2) + x) = shroudColor.ToArgb(); } } diff --git a/OpenRa.Game/Shroud.cs b/OpenRa.Game/Shroud.cs index 6ee7456142..eb7dc5c196 100644 --- a/OpenRa.Game/Shroud.cs +++ b/OpenRa.Game/Shroud.cs @@ -11,12 +11,15 @@ namespace OpenRa.Game class Shroud { bool[,] explored = new bool[128, 128]; - int[,] gapField = new int[128, 128]; Sprite[] shadowBits = SpriteSheetBuilder.LoadAllSprites("shadow"); Sprite[,] sprites = new Sprite[128, 128]; bool dirty; bool hasGPS = false; + float gapOpaqueTicks = (int)(Rules.General.GapRegenInterval * 25 * 60); + int[,] gapField = new int[128, 128]; + bool[,] gapActive = new bool[128, 128]; + public bool HasGPS { get { return hasGPS; } @@ -25,8 +28,8 @@ namespace OpenRa.Game public void Tick() { - // This is probably slow - bool[,] gapActive = new bool[128, 128]; + // Clear active flags + gapActive = new bool[128, 128]; foreach (var a in Game.world.Actors.Where(a => a.traits.Contains())) { foreach (var t in a.traits.Get().GetShroudedTiles()) @@ -36,11 +39,17 @@ namespace OpenRa.Game for (int j = 1; j < 127; j++) for (int i = 1; i < 127; i++) { - if (gapField[i, j] > 0 && !gapActive[i, j]) /*0 >= --gapField[i, j]*/ + if (gapField[i, j] > 0 && !gapActive[i, j]) { + // Convert gap to shroud + if (gapField[i, j] >= gapOpaqueTicks && explored[i, j]) + explored[i, j] = false; + + // Clear gap gapField[i, j] = 0; dirty = true; } + // Increase gap tick; rerender if necessary if (gapActive[i, j] && 0 == gapField[i, j]++) dirty = true; } @@ -58,6 +67,15 @@ namespace OpenRa.Game return explored[ x, y ]; } + public bool DisplayOnRadar(int x, int y) + { + // Active gap is never shown on radar, even if a unit is in range + if (gapActive[x , y]) + return false; + + return IsExplored(x,y); + } + public void Explore(Actor a) { foreach (var t in Game.FindTilesInCircle((1f / Game.CellSize * a.CenterLocation).ToInt2(), a.Info.Sight)) @@ -68,6 +86,7 @@ namespace OpenRa.Game dirty = true; } + static readonly byte[] ShroudTiles = { 0xf,0xf,0xf,0xf, @@ -87,7 +106,7 @@ namespace OpenRa.Game 40, 37, 44, 34, 36, 33, 32, 47, }; - + Sprite ChooseShroud(int i, int j) { // bits are for exploredness: left, right, up, down, self @@ -101,7 +120,7 @@ namespace OpenRa.Game var x = ShroudTiles[v]; if (x != 0) return shadowBits[x]; - + // bits are for exploredness: TL, TR, BR, BL var u = 0; if (IsExplored(i - 1, j - 1)) u |= 1; From 34f90aca3c1c89f08358bd96b568122226d2f16e Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 15 Jan 2010 14:35:32 +1300 Subject: [PATCH 4/4] Port to new traits model (untested) --- OpenRa.Game/Traits/GeneratesGap.cs | 11 +++- merge-ra.yaml | 7 +++ ra.yaml | 92 +++++++++++++++--------------- 3 files changed, 62 insertions(+), 48 deletions(-) create mode 100644 merge-ra.yaml diff --git a/OpenRa.Game/Traits/GeneratesGap.cs b/OpenRa.Game/Traits/GeneratesGap.cs index 5dcdf3c4f6..5f21b48c05 100644 --- a/OpenRa.Game/Traits/GeneratesGap.cs +++ b/OpenRa.Game/Traits/GeneratesGap.cs @@ -7,6 +7,12 @@ using OpenRa.Game.Traits; namespace OpenRa.Game.Traits { + class GeneratesGapInfo : ITraitInfo + { + public readonly int Range = 10; + public object Create(Actor self) { return new GeneratesGap(self); } + } + class GeneratesGap { Actor self; @@ -17,12 +23,13 @@ namespace OpenRa.Game.Traits public IEnumerableGetShroudedTiles() { + int range = self.Info.Traits.Get().Range; + // Gap Generator building; powered down if (self.traits.Contains() && self.traits.Get().Disabled) yield break; - // It won't let me return Game.FindTilesInCircle directly...? - foreach (var t in Game.FindTilesInCircle(self.Location, Rules.General.GapRadius)) + foreach (var t in Game.FindTilesInCircle(self.Location, range)) yield return t; } } diff --git a/merge-ra.yaml b/merge-ra.yaml new file mode 100644 index 0000000000..72d19cb319 --- /dev/null +++ b/merge-ra.yaml @@ -0,0 +1,7 @@ +MGG: + GeneratesGap: + Range: 10 + +GAP: + GeneratesGap: + Range: 10 \ No newline at end of file diff --git a/ra.yaml b/ra.yaml index 78cfb50d3d..25c048f0b0 100644 --- a/ra.yaml +++ b/ra.yaml @@ -1,3 +1,49 @@ +MGG: + Inherits: DefaultVehicle + Buildable: + TechLevel: 11 + Tab: Vehicle + Prerequisites: weap,atek + Owner: allies + Cost: 600 + Description: Mobile Gap Generator + LongDesc: Regenerates Fog of War in a small area \naround the unit.\n Unarmed + Selectable: + Priority: 3 + Unit: + HP: 110 + Armor: light + Crewed: yes + Sight: 4 + Speed: 9 + RenderUnitSpinner: + Offset: 0,6,0,-3 + +GAP: + Inherits: DefaultDefense + Buildable: + TechLevel: 10 + Tab: Defense + Prerequisites: atek + Owner: allies + Cost: 500 + Description: Gap Generator + LongDesc: Regenerates the Fog of War nearby, \nobscuring the area.\n Unarmed + Selectable: + Priority: 3 + Building: + Power: -60 + RequiresPower: true + Footprint: _ x + Dimensions: 1,2 + Capturable: true + HP: 1000 + Armor: wood + Crewed: yes + Sight: 10 + RenderBuilding: + IronCurtainable: + V2RL: Inherits: DefaultVehicle Buildable: @@ -150,27 +196,6 @@ MRJ: RenderUnitSpinner: Offset: 0,4,0,-6 -MGG: - Inherits: DefaultVehicle - Buildable: - TechLevel: 11 - Tab: Vehicle - Prerequisites: weap,atek - Owner: allies - Cost: 600 - Description: Mobile Gap Generator - LongDesc: Regenerates Fog of War in a small area \naround the unit.\n Unarmed - Selectable: - Priority: 3 - Unit: - HP: 110 - Armor: light - Crewed: yes - Sight: 4 - Speed: 9 - RenderUnitSpinner: - Offset: 0,6,0,-3 - ARTY: Inherits: DefaultVehicle Buildable: @@ -856,31 +881,6 @@ FTUR: AutoTarget: IronCurtainable: -GAP: - Inherits: DefaultDefense - Buildable: - TechLevel: 10 - Tab: Defense - Prerequisites: atek - Owner: allies - Cost: 500 - Description: Gap Generator - LongDesc: Regenerates the Fog of War nearby, \nobscuring the area.\n Unarmed - Selectable: - Priority: 3 - Building: - Power: -60 - RequiresPower: true - Footprint: _ x - Dimensions: 1,2 - Capturable: true - HP: 1000 - Armor: wood - Crewed: yes - Sight: 10 - RenderBuilding: - IronCurtainable: - SAM: Inherits: DefaultDefense Buildable: