diff --git a/OpenRa.DataStructures/float2.cs b/OpenRa.DataStructures/float2.cs index 5280a333f8..9544b94eb4 100644 --- a/OpenRa.DataStructures/float2.cs +++ b/OpenRa.DataStructures/float2.cs @@ -83,5 +83,8 @@ namespace OpenRa public override string ToString() { return string.Format("({0},{1})", X, Y); } public int2 ToInt2() { return new int2((int)X, (int)Y); } + + public static float2 Max(float2 a, float2 b) { return new float2(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); } + public static float2 Min(float2 a, float2 b) { return new float2(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); } } } diff --git a/OpenRa.FileFormats/Map.cs b/OpenRa.FileFormats/Map.cs index 99916e58ab..4c35caa74a 100644 --- a/OpenRa.FileFormats/Map.cs +++ b/OpenRa.FileFormats/Map.cs @@ -113,7 +113,7 @@ namespace OpenRa.FileFormats for( int i = 0 ; i < 128 ; i++ ) for( int j = 0 ; j < 128 ; j++ ) { - MapTiles[j, i].image = (byte)ms.ReadByte();// ReadByte(ms); + MapTiles[j, i].image = (byte)ms.ReadByte(); if( MapTiles[ j, i ].tile == 0xff || MapTiles[ j, i ].tile == 0xffff ) MapTiles[ j, i ].image = (byte)( i % 4 + ( j % 4 ) * 4 ); } diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index 7c169183c8..340f3d02fe 100755 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -6,7 +6,8 @@ using System.Text; using IjwFramework.Types; using OpenRa.FileFormats; using OpenRa.Game.GameRules; -using OpenRa.Game.Graphics; +using OpenRa.Game.Graphics; +using System.Drawing; namespace OpenRa.Game { @@ -141,6 +142,16 @@ namespace OpenRa.Game .Select( x => x.Order( this, game, xy ) ) .Where( x => x != null ) .FirstOrDefault(); + } + + public RectangleF Bounds + { + get + { + var size = SelectedSize; + var loc = CenterLocation - 0.5f * size; + return new RectangleF(loc.X, loc.Y, size.X, size.Y); + } } } diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index f1758de13e..5acfca610d 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -19,15 +19,11 @@ namespace OpenRa.Game this.game = game; } - float2 GetWorldPos(MouseInput mi) - { - return (1 / 24.0f) * (new float2(mi.Location.X, mi.Location.Y) + game.viewport.Location); - } - float2 dragStart, dragEnd; public void HandleMouseInput(MouseInput mi) { - var xy = GetWorldPos(mi); + var xy = game.viewport.ViewToWorld(mi); + if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Down) { if (!(orderGenerator is PlaceBuilding)) @@ -35,16 +31,16 @@ namespace OpenRa.Game } if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Move) - dragEnd = GetWorldPos(mi); + dragEnd = xy; if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Up) { if (!(orderGenerator is PlaceBuilding)) { - if (dragStart != GetWorldPos(mi)) - orderGenerator = new UnitOrderGenerator( FindUnits( game, 24 * dragStart, 24 * xy ) ); /* band-box select */ + if (dragStart != xy) + orderGenerator = new UnitOrderGenerator( game.FindUnits( 24 * dragStart, 24 * xy ) ); /* band-box select */ else - orderGenerator = new UnitOrderGenerator( FindUnits( game, 24 * xy, 24 * xy ) ); /* click select */ + orderGenerator = new UnitOrderGenerator( game.FindUnits( 24 * xy, 24 * xy ) ); /* click select */ } dragStart = dragEnd; @@ -58,37 +54,17 @@ namespace OpenRa.Game if( mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down ) if( orderGenerator != null ) - foreach( var order in orderGenerator.Order( game, new int2( (int)xy.X, (int)xy.Y ) ) ) + foreach( var order in orderGenerator.Order( game, xy.ToInt2() ) ) order.Apply( game ); } - public Actor FindUnit(float2 a, float2 b) - { - return FindUnits(game, 24 * a, 24 * b).FirstOrDefault(); - } - - public static IEnumerable FindUnits(Game game, float2 a, float2 b) - { - var min = new float2(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); - var max = new float2(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); - - var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y); - - return game.world.Actors - .Where(x => (x.Owner == game.LocalPlayer) && (UnitBounds(x).IntersectsWith(rect))); - } - - public static RectangleF UnitBounds( Actor actor ) - { - var size = actor.SelectedSize; - var loc = actor.CenterLocation - 0.5f * size; - return new System.Drawing.RectangleF( loc.X, loc.Y, size.X, size.Y ); - } - - public Pair? SelectionBox() - { - if (dragStart == dragEnd) return null; - return Pair.New(24 * dragStart, 24 * dragEnd); + public Pair? SelectionBox + { + get + { + if (dragStart == dragEnd) return null; + return Pair.New(24 * dragStart, 24 * dragEnd); + } } } } diff --git a/OpenRa.Game/Game Code.cd b/OpenRa.Game/Game Code.cd index b81041cb0b..8e1bb5eeb0 100644 --- a/OpenRa.Game/Game Code.cd +++ b/OpenRa.Game/Game Code.cd @@ -1,195 +1,40 @@  - - - - AAEAAAiAAAAAAAAAAQIAAIAAAQAAAAAAABAAAAAAQAA= - Actor.cs - - - - - - - - - AAYAACABABAAgAAAAIAABgAAAAAAAAAIAAAAAAAAAAA= - World.cs - - - - - - - - - + + + - AAAAEAAAAIAAAAEEBAAAIAAQQAAAAAAAJAAAAABAQAA= + AAAAEAAAAIAAAAEEBAEAIAAQQAAAAAAAJIAAAABAQAA= Game.cs - - - - - - - - - - - - - - - AAAAEAAAAAAAABAAAAAAAAAAAAAEEAAAMAAAAAAAAAA= - PathFinder.cs - - - - - - AAEAAAAAAAIAAAAAAAAAACAAAgAAAAAAAAAAAAAAAAA= - Player.cs - - - - - - - - - AAAAAAAAAIAAAiAAAAAQIABAAAAkAAAYAAAAAAQAAAA= - UiOverlay.cs - - - - - + + + - IAAAAAAIAAAAAAAAAAACAgAAABAAAAAIAIAAAIAABAA= + AAAAAAAIAAAAAAAAAAACAgAAABAAAAAIAAAAAIAAAAA= Controller.cs - - - - - - - AAAACAAAAAAAAAAAAAAEAAIgAQAAoyACAAAAAAAAAAA= - TechTree\TechTree.cs - - - - - - AACAEABAAAAAAmAAAAAAAAAIAAAAAAAAAAAAAAAAAAA= - Graphics\WorldRenderer.cs - - - - - - - + - AAAAAAAABAAAiAAAAIYAAEAAAABCAAAAAABgAAAAgBE= + AAAAAAAABAAAiABAAIYAAEAAAABCAAAAAABgAAAAgBE= Graphics\Viewport.cs - - - - - - - AACAEAACCAAAAgMAAAAAAEAAAAAAAAAAEAAAAAAAAAA= - Graphics\Renderer.cs - - - - - - AAAQQAAAAECAAAAAAAAAAAAAABAQABAAAAAAAACIwAQ= - Graphics\SpriteRenderer.cs - - - - - - - - - - AAAQQAAAACCAAAAAAAAAAAAAABIQAAAAAEAAAAAIwAA= - Graphics\LineRenderer.cs - - - - - - - - - AAAAAAAAAACAgAAACAgAAAAIAAAAAgAAAAIAAAAggAA= - Graphics\Sheet.cs - - - - - - - - - AACQEAAAAAAAAgAABAAACgAAABgAAAAAAAAAAAAAgAA= - Graphics\TerrainRenderer.cs - - - - - - - - - - - - AAAAEAAAABAAAiCAAEAAAAAAAAQAAABAAAAAEAAQAAA= - Graphics\OverlayRenderer.cs - - - - - - - - - - - - - AAKAAAAAgAAAAAAAAEAAAAAACAAAAABAAAAAJAAAQAA= - Network\Network.cs - - - - - - AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAA= - IOrderGenerator.cs - - \ No newline at end of file diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 21156f5a2c..7b0f86365e 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -1,10 +1,10 @@ -using System; using System.Collections.Generic; -using OpenRa.FileFormats; +using OpenRa.FileFormats; +using OpenRa.Game.Graphics; +using OpenRa.TechTree; +using System.Drawing; using System.Linq; -using OpenRa.Game.Graphics; - namespace OpenRa.Game { class Game @@ -30,7 +30,7 @@ namespace OpenRa.Game Rules.LoadRules(); for( int i = 0 ; i < 8 ; i++ ) - players.Add(i, new Player(i, string.Format("Multi{0}", i), OpenRa.TechTree.Race.Soviet)); + players.Add(i, new Player(i, string.Format("Multi{0}", i), Race.Soviet)); map = new Map(new IniFile(FileSystem.Open(mapName))); FileSystem.Mount(new Package(map.Theater + ".mix")); @@ -49,7 +49,7 @@ namespace OpenRa.Game network = new Network(); controller = new Controller(this); // CAREFUL THERES AN UGLY HIDDEN DEPENDENCY HERE STILL - worldRenderer = new WorldRenderer(renderer, world); + worldRenderer = new WorldRenderer(renderer, this); } public void Tick() @@ -58,6 +58,26 @@ namespace OpenRa.Game world.Update(); viewport.DrawRegions(); + } + + public bool IsCellBuildable(int2 a) + { + a += map.Offset; + + return map.IsInMap(a.X, a.Y) && + TerrainCosts.Cost(UnitMovementType.Wheel, + terrain.tileSet.GetWalkability(map.MapTiles[a.X, a.Y])) < double.PositiveInfinity; + } + + public IEnumerable FindUnits(float2 a, float2 b) + { + var min = float2.Min(a, b); + var max = float2.Max(a, b); + + var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y); + + return world.Actors + .Where(x => (x.Owner == LocalPlayer) && (x.Bounds.IntersectsWith(rect))); } } } diff --git a/OpenRa.Game/Graphics/Viewport.cs b/OpenRa.Game/Graphics/Viewport.cs index abf58994f0..deb9fb0bf3 100644 --- a/OpenRa.Game/Graphics/Viewport.cs +++ b/OpenRa.Game/Graphics/Viewport.cs @@ -59,5 +59,10 @@ namespace OpenRa.Game.Graphics if (mi.Event != MouseInputEvent.Down) dragRegion = null; } + + public float2 ViewToWorld(MouseInput mi) + { + return (1 / 24.0f) * (new float2(mi.Location.X, mi.Location.Y) + Location); + } } } diff --git a/OpenRa.Game/Graphics/WorldRenderer.cs b/OpenRa.Game/Graphics/WorldRenderer.cs index dc126d6966..32d9a20d0f 100644 --- a/OpenRa.Game/Graphics/WorldRenderer.cs +++ b/OpenRa.Game/Graphics/WorldRenderer.cs @@ -8,32 +8,31 @@ namespace OpenRa.Game.Graphics { public readonly SpriteRenderer spriteRenderer; public readonly LineRenderer lineRenderer; - public readonly World world; + public readonly Game game; public readonly Region region; public readonly UiOverlay uiOverlay; - public WorldRenderer(Renderer renderer, World world) + public WorldRenderer(Renderer renderer, Game game) { // TODO: this is layout policy. it belongs at a higher level than this. - region = Region.Create(world.game.viewport, DockStyle.Left, - world.game.viewport.Width - 128, Draw, - world.game.controller.HandleMouseInput); + region = Region.Create(game.viewport, DockStyle.Left, + game.viewport.Width - 128, Draw, + game.controller.HandleMouseInput); - world.game.viewport.AddRegion(region); + game.viewport.AddRegion(region); spriteRenderer = new SpriteRenderer(renderer, true); lineRenderer = new LineRenderer(renderer); - uiOverlay = new UiOverlay(spriteRenderer, world.game); - this.world = world; + uiOverlay = new UiOverlay(spriteRenderer, game); } public void Draw() { - var rect = new RectangleF((region.Position + world.game.viewport.Location).ToPointF(), + var rect = new RectangleF((region.Position + game.viewport.Location).ToPointF(), region.Size.ToSizeF()); - foreach (Actor a in world.Actors) + foreach (Actor a in game.world.Actors) { var images = a.Render(); @@ -54,7 +53,7 @@ namespace OpenRa.Game.Graphics spriteRenderer.Flush(); - var selbox = world.game.controller.SelectionBox(); + var selbox = game.controller.SelectionBox; if (selbox != null) { var a = selbox.Value.First; @@ -66,15 +65,14 @@ namespace OpenRa.Game.Graphics lineRenderer.DrawLine(a + b + c, a + c, Color.White, Color.White); lineRenderer.DrawLine(a, a + c, Color.White, Color.White); - foreach (var u in Controller.FindUnits(world.game, selbox.Value.First, selbox.Value.Second)) + foreach (var u in game.FindUnits(selbox.Value.First, selbox.Value.Second)) DrawSelectionBox(u, Color.Yellow); } - var selection = world.game.controller.orderGenerator as UnitOrderGenerator; + var selection = game.controller.orderGenerator as UnitOrderGenerator; if (selection != null) - foreach( var a in world.Actors.Intersect(selection.selection) ) /* make sure we don't grab actors that are dead */ + foreach( var a in game.world.Actors.Intersect(selection.selection) ) /* make sure we don't grab actors that are dead */ DrawSelectionBox(a, Color.White); - lineRenderer.Flush(); } diff --git a/OpenRa.Game/UiOverlay.cs b/OpenRa.Game/UiOverlay.cs index 50b251fb78..b7cbf1ebe5 100644 --- a/OpenRa.Game/UiOverlay.cs +++ b/OpenRa.Game/UiOverlay.cs @@ -20,7 +20,7 @@ namespace OpenRa.Game buildBlocked = SynthesizeTile(0xe6); } - Sprite SynthesizeTile(byte paletteIndex) + static Sprite SynthesizeTile(byte paletteIndex) { byte[] data = new byte[24 * 24]; @@ -36,15 +36,6 @@ namespace OpenRa.Game if (!hasOverlay) return; - Func passableAt = a => - { - a += game.map.Offset; - - return game.map.IsInMap(a.X, a.Y) && - TerrainCosts.Cost(UnitMovementType.Wheel, - game.terrain.tileSet.GetWalkability(game.map.MapTiles[a.X, a.Y])) < double.PositiveInfinity; - }; - var footprint = Rules.Footprint.GetFootprint(name); var j = 0; foreach (var row in footprint) @@ -53,7 +44,9 @@ namespace OpenRa.Game foreach (var c in row) { if (c != '_') - spriteRenderer.DrawSprite(passableAt(position + new int2(i, j)) ? buildOk : buildBlocked, + spriteRenderer.DrawSprite( + game.IsCellBuildable(position + new int2(i, j)) + ? buildOk : buildBlocked, 24 * (position + new int2(i, j)), 0); ++i; }