diff --git a/OpenRa.DataStructures/float2.cs b/OpenRa.DataStructures/float2.cs index 6b57223279..8c6f3ef20d 100644 --- a/OpenRa.DataStructures/float2.cs +++ b/OpenRa.DataStructures/float2.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.InteropServices; using System.Drawing; +using System.Runtime.InteropServices; namespace OpenRa { @@ -18,6 +16,7 @@ namespace OpenRa public float2(SizeF p) { X = p.Width; Y = p.Height; } public PointF ToPointF() { return new PointF(X, Y); } + public SizeF ToSizeF() { return new SizeF(X, Y); } public static implicit operator float2(int2 src) { return new float2(src.X, src.Y); } diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs new file mode 100644 index 0000000000..7a3a8b31f4 --- /dev/null +++ b/OpenRa.Game/Controller.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace OpenRa.Game +{ + class Controller + { + Game game; + + public IOrderGenerator orderGenerator; + + public Controller(Game game) + { + this.game = game; + } + + public void WorldClicked(object sender, MouseEventArgs e) + { + var xy = (1 / 24.0f) * (new float2(e.Location) + game.viewport.Location); + if (orderGenerator != null) + orderGenerator.Order(game, new int2((int)xy.X, (int)xy.Y)).Apply(game); + // todo: route all orders through netcode + } + } +} diff --git a/OpenRa.Game/Game Code.cd b/OpenRa.Game/Game Code.cd new file mode 100644 index 0000000000..cef986620c --- /dev/null +++ b/OpenRa.Game/Game Code.cd @@ -0,0 +1,234 @@ + + + + + + AAAAgAAAAAAAgAAAAAAAAAAAAAAAAAAIAAAAAIAAQAA= + Actor.cs + + + + + + AAaAACBBAAAAAiAAAIACBgAAAAAAAAAIAAAAAAgAAAA= + World.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA= + Building.cs + + + + + + AAEAEAAAAIAAAgAABAAAIAAQAAAAAQAAJAAAAABAQAA= + Game.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAAAAABAAAAAKIEAACAAAgAI= + MainWindow.cs + + + + + + AAAAAAAAABAAAAAAIAAAAAAAAAAAAAAEAAAAAAAAAAA= + MoveOrder.cs + + + + + + AAAAAAAAABAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + MoveOrder.cs + + + + + + AAAAAAAAABAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + MoveOrder.cs + + + + + + AAAAEAAAAAAAABAAAAAAAAAAAAAEEAAAMAAAAAAAAAA= + PathFinder.cs + + + + + + AAEAAAAAAAAAAAAAAAAAACAAAgAAAAAAAAAAAAAAAAA= + Player.cs + + + + + + AAAAgAAAAAAAIAAAAAAAAIACAAAAAAAAAgAAAIAAAAA= + PlayerOwned.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + Refinery.cs + + + + + + AAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + Rules.cs + + + + + + AACAAAQAgECAAGAAEAgCAEAACABAiIAIAAAAIAC8AAA= + Sidebar.cs + + + + + + AAEAAACAAAAAAAAAAAAAAAQAAAAAAAAAAAAAQAAAAAA= + Sidebar.cs + + + + + + + AAAAAAAAAAAAAAAAAAAAAAACEBAAACAAAAAAAAAIAAA= + SidebarItem.cs + + + + + + AAAAAAAAAAAAAAIAAAAAABAAAAAAAAAAAAAAAAAAAAA= + TerrainCosts.cs + + + + + + gAAAgAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAIAAAAA= + Tree.cs + + + + + + AAAAAAAAAIAAAiQAQAAQIABAQAAgAAAYAAAAAAQAAAA= + UiOverlay.cs + + + + + + AAEAgDgAAAAAAAAAAAAAAAEAAAEGAAgAAAAERAAAQAA= + Unit.cs + + + + + + + AIAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAA= + UnitInfo.cs + + + + + + + + AAAAAAAAAYAAAAAAAAACAAABAAAAAAAAABAAAAAAAAA= + UnitMissions.cs + + + + + + AAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + MoveOrder.cs + + + + + + EAAAAAAAABAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + Sidebar.cs + + + + + + AAAAAAAAAAAAAAIAAAEAAAAAAAAAAAQAAAAAAAAAAAA= + PathFinder.cs + + + + + + AAAAAAAAAAAAAAQAAAIAQAAAAAAAAAAAAAAAAAAAAAA= + PathFinder.cs + + + + + + + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAA= + IOrderGenerator.cs + + + + + + AAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAQAAAAAAAiAAA= + TerrainCosts.cs + + + + + + AAAAAAABAAAAAAAAIEAAAAAAAABgAAQgAAAAAABQAAA= + TerrainCosts.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAIBAAAAAAAAA= + UnitMissions.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAEAAAA= + Race.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAA= + UnitMissions.cs + + + + \ No newline at end of file diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index e23b35d36f..fb91c4947c 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -15,14 +15,18 @@ namespace OpenRa.Game public readonly Viewport viewport; public readonly PathFinder pathFinder; public readonly Network network; + public readonly WorldRenderer worldRenderer; + public readonly Controller controller; - public int localPlayerIndex = 1; + int localPlayerIndex = 1; public readonly Dictionary players = new Dictionary(); // temporary, until we remove all the subclasses of Building public Dictionary> buildingCreation = new Dictionary>(); + public Player LocalPlayer { get { return players[localPlayerIndex]; } } + public Game(string mapName, Renderer renderer, int2 clientSize) { for (int i = 0; i < 8; i++) @@ -34,7 +38,7 @@ namespace OpenRa.Game viewport = new Viewport(clientSize, map.Size, renderer); terrain = new TerrainRenderer(renderer, map, viewport); - world = new World(renderer, this); + world = new World(this); treeCache = new TreeCache(map); foreach (TreeReference treeReference in map.Trees) @@ -48,20 +52,18 @@ namespace OpenRa.Game string[] buildings = { "fact", "powr", "apwr", "weap", "barr", "atek", "stek", "dome" }; foreach (string s in buildings) - AddBuilding(s); - } + buildingCreation.Add(s, (location, owner) => new Building(s, location, owner, this)); - void AddBuilding(string name) - { - buildingCreation.Add(name, (location, owner) => new Building(name, location, owner, this)); + controller = new Controller(this); // CAREFUL THERES AN UGLY HIDDEN DEPENDENCY HERE STILL + worldRenderer = new WorldRenderer(renderer, world); } public void Tick() { - viewport.DrawRegions(this); - Queue stuffFromOtherPlayers = network.Tick(); // todo: actually use the orders! - } + var stuffFromOtherPlayers = network.Tick(); // todo: actually use the orders! + world.Update(); - public void Issue(IOrder order) { order.Apply(this); } + viewport.DrawRegions(this); + } } } diff --git a/OpenRa.Game/Graphics/Viewport.cs b/OpenRa.Game/Graphics/Viewport.cs index 9ba0db84db..1bc83e6b78 100644 --- a/OpenRa.Game/Graphics/Viewport.cs +++ b/OpenRa.Game/Graphics/Viewport.cs @@ -28,10 +28,8 @@ namespace OpenRa.Game.Graphics } List regions = new List(); - public void AddRegion(Region r) - { - regions.Add(r); - } + + public void AddRegion(Region r) { regions.Add(r); } public void DrawRegions(Game game) { @@ -46,9 +44,6 @@ namespace OpenRa.Game.Graphics renderer.EndFrame(); } - public IEnumerable Regions - { - get { return regions; } - } + public IEnumerable Regions { get { return regions; } } } } diff --git a/OpenRa.Game/Graphics/WorldRenderer.cs b/OpenRa.Game/Graphics/WorldRenderer.cs new file mode 100644 index 0000000000..d060b4bbae --- /dev/null +++ b/OpenRa.Game/Graphics/WorldRenderer.cs @@ -0,0 +1,48 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace OpenRa.Game.Graphics +{ + class WorldRenderer + { + public readonly SpriteRenderer spriteRenderer; + public readonly World world; + public readonly Region region; + public readonly UiOverlay uiOverlay; + + public WorldRenderer(Renderer renderer, World world) + { + // 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.WorldClicked); // TODO: world.WorldClicked is part of the CONTROLLER + world.game.viewport.AddRegion(region); + + spriteRenderer = new SpriteRenderer(renderer, true); + uiOverlay = new UiOverlay(spriteRenderer, world.game); + this.world = world; + } + + public void Draw() + { + var rect = new RectangleF(region.Location.ToPointF(), region.Size.ToSizeF()); + + foreach (Actor a in world.Actors) + { + Sprite[] images = a.CurrentImages; + float2 loc = a.RenderLocation; + + if (loc.X > rect.Right || loc.X < rect.Left - images[0].bounds.Width) + continue; + + if (loc.Y > rect.Bottom || loc.Y < rect.Top - images[0].bounds.Height) + continue; + + foreach (Sprite image in images) + spriteRenderer.DrawSprite(image, loc, (a.owner != null) ? a.owner.Palette : 0); + } + + spriteRenderer.Flush(); + } + } +} diff --git a/OpenRa.Game/IOrderGenerator.cs b/OpenRa.Game/IOrderGenerator.cs index 74ec7ca9c6..cf605dc73a 100644 --- a/OpenRa.Game/IOrderGenerator.cs +++ b/OpenRa.Game/IOrderGenerator.cs @@ -6,7 +6,7 @@ namespace OpenRa.Game { interface IOrderGenerator { - IOrder Order( Game game, int2 xy ); + Order Order( Game game, int2 xy ); void PrepareOverlay( Game game, int2 xy ); } } diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs index d541db0fae..10f1c22715 100644 --- a/OpenRa.Game/MainWindow.cs +++ b/OpenRa.Game/MainWindow.cs @@ -47,7 +47,7 @@ namespace OpenRa.Game game.world.Add( new Unit( "mcv", new int2( 5, 5 ), game.players[ 3 ], game ) ); game.world.Add( new Unit( "mcv", new int2( 7, 5 ), game.players[ 2 ], game ) ); Unit mcv = new Unit( "mcv", new int2( 9, 5 ), game.players[ 1 ], game ); - game.world.orderGenerator = mcv; + game.controller.orderGenerator = mcv; game.world.Add( mcv ); sidebar = new Sidebar(Race.Soviet, renderer, game); @@ -72,7 +72,7 @@ namespace OpenRa.Game lastPos = new int2(e.Location); if (e.Button == MouseButtons.Left) - foreach (GRegion region in game.viewport.Regions) + foreach (var region in game.viewport.Regions) if (region.Contains(lastPos)) region.Clicked(e); } @@ -88,8 +88,8 @@ namespace OpenRa.Game lastPos = p; } - if (game.world.orderGenerator != null) - game.world.orderGenerator.PrepareOverlay(game, + if (game.controller.orderGenerator != null) + game.controller.orderGenerator.PrepareOverlay(game, new int2(e.Location.X / 24, e.Location.Y / 24)); } } diff --git a/OpenRa.Game/MoveOrder.cs b/OpenRa.Game/MoveOrder.cs index 87aeebb36f..80cbf96671 100644 --- a/OpenRa.Game/MoveOrder.cs +++ b/OpenRa.Game/MoveOrder.cs @@ -4,12 +4,12 @@ using System.Text; namespace OpenRa.Game { - interface IOrder + abstract class Order { - void Apply( Game game ); + public abstract void Apply( Game game ); } - class MoveOrder : IOrder + class MoveOrder : Order { public readonly Unit Unit; public readonly int2 Destination; @@ -20,13 +20,13 @@ namespace OpenRa.Game this.Destination = destination; } - public void Apply( Game game ) + public override void Apply( Game game ) { Unit.nextOrder = UnitMissions.Move( Unit, Destination ); } } - class DeployMcvOrder : IOrder + class DeployMcvOrder : Order { Unit unit; @@ -35,13 +35,13 @@ namespace OpenRa.Game this.unit = unit; } - public void Apply( Game game ) + public override void Apply( Game game ) { unit.nextOrder = UnitMissions.Deploy( unit ); } } - class HarvestOrder : IOrder + class HarvestOrder : Order { Unit unit; @@ -50,7 +50,7 @@ namespace OpenRa.Game this.unit = unit; } - public void Apply( Game game ) + public override void Apply( Game game ) { unit.nextOrder = UnitMissions.Harvest( unit ); } diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 4fb47ae327..af776e909b 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -71,9 +71,11 @@ + + @@ -81,7 +83,7 @@ - + @@ -148,6 +150,7 @@ + diff --git a/OpenRa.Game/Refinery.cs b/OpenRa.Game/Refinery.cs index 5f03dd087f..38721123a9 100644 --- a/OpenRa.Game/Refinery.cs +++ b/OpenRa.Game/Refinery.cs @@ -15,7 +15,7 @@ namespace OpenRa.Game Unit harvester = new Unit( "harv", location + new int2( 1, 2 ), owner, game ); harvester.facing = 8; game.world.Add(harvester); - game.world.orderGenerator = harvester; + game.controller.orderGenerator = harvester; }); }); } diff --git a/OpenRa.Game/Sidebar.cs b/OpenRa.Game/Sidebar.cs index 888ac68a60..465776a8e2 100644 --- a/OpenRa.Game/Sidebar.cs +++ b/OpenRa.Game/Sidebar.cs @@ -31,7 +31,7 @@ namespace OpenRa.Game public Sidebar( Race race, Renderer renderer, Game game ) { - this.techTree = game.players[ game.localPlayerIndex ].TechTree; + this.techTree = game.LocalPlayer.TechTree; this.game = game; region = GRegion.Create(game.viewport, DockStyle.Right, 128, Paint, MouseHandler); game.viewport.AddRegion( region ); @@ -49,7 +49,7 @@ namespace OpenRa.Game public void Build(SidebarItem item) { if (item != null) - game.world.orderGenerator = new PlaceBuilding(game.players[1], item.techTreeItem.tag.ToLowerInvariant()); + game.controller.orderGenerator = new PlaceBuilding(game.players[1], item.techTreeItem.tag.ToLowerInvariant()); } void LoadSprites(string filename) @@ -132,16 +132,16 @@ namespace OpenRa.Game class PlaceBuilding : IOrderGenerator { - Player owner; - string buildingName; + public readonly Player Owner; + public readonly string Name; - public PlaceBuilding( Player owner, string buildingName ) + public PlaceBuilding( Player owner, string name ) { - this.owner = owner; - this.buildingName = buildingName; + Owner = owner; + Name = name; } - public IOrder Order( Game game, int2 xy ) + public Order Order( Game game, int2 xy ) { // todo: check that space is free return new PlaceBuildingOrder( this, xy ); @@ -149,34 +149,34 @@ namespace OpenRa.Game public void PrepareOverlay(Game game, int2 xy) { - game.world.uiOverlay.SetCurrentOverlay(false, xy, 2, 3); + game.worldRenderer.uiOverlay.SetCurrentOverlay(false, xy, 2, 3); + } + } + + class PlaceBuildingOrder : Order + { + PlaceBuilding building; + int2 xy; + + public PlaceBuildingOrder(PlaceBuilding building, int2 xy) + { + this.building = building; + this.xy = xy; } - class PlaceBuildingOrder : IOrder + public override void Apply(Game game) { - PlaceBuilding building; - int2 xy; - - public PlaceBuildingOrder( PlaceBuilding building, int2 xy ) + game.world.AddFrameEndTask(_ => { - this.building = building; - this.xy = xy; - } - - public void Apply( Game game ) - { - game.world.AddFrameEndTask( _ => + Func newBuilding; + if (game.buildingCreation.TryGetValue(building.Name, out newBuilding)) { - Func newBuilding; - if( game.buildingCreation.TryGetValue( building.buildingName, out newBuilding ) ) - { - Log.Write( "Player \"{0}\" builds {1}", building.owner.PlayerName, building.buildingName ); - game.world.Add( newBuilding( xy, building.owner ) ); - } - game.world.orderGenerator = null; - game.world.uiOverlay.KillOverlay(); - } ); - } + Log.Write("Player \"{0}\" builds {1}", building.Owner.PlayerName, building.Name); + game.world.Add(newBuilding(xy, building.Owner)); + } + game.controller.orderGenerator = null; + game.worldRenderer.uiOverlay.KillOverlay(); + }); } } } diff --git a/OpenRa.Game/Support/SharedResources.cs b/OpenRa.Game/Support/SharedResources.cs new file mode 100644 index 0000000000..efc22425dd --- /dev/null +++ b/OpenRa.Game/Support/SharedResources.cs @@ -0,0 +1,13 @@ +using IjwFramework.Types; +using OpenRa.FileFormats; + +namespace OpenRa.Game +{ + class SharedResources + { + static Lazy rules = new Lazy( + () => new IniFile( FileSystem.Open( "rules.ini" ))); + + public static IniFile Rules { get { return rules.Value; } } + } +} diff --git a/OpenRa.Game/UiOverlay.cs b/OpenRa.Game/UiOverlay.cs index 037b18ccb1..3e8d370293 100644 --- a/OpenRa.Game/UiOverlay.cs +++ b/OpenRa.Game/UiOverlay.cs @@ -39,6 +39,8 @@ namespace OpenRa.Game for (int j = 0; j < height; j++) spriteRenderer.DrawSprite(blocked ? buildBlocked : buildOk, 24 * (position + new int2(i, j)) + game.viewport.Location, 0); + + spriteRenderer.Flush(); } bool blocked, hasOverlay; diff --git a/OpenRa.Game/Unit.cs b/OpenRa.Game/Unit.cs index 34651138d7..4b9bd67528 100644 --- a/OpenRa.Game/Unit.cs +++ b/OpenRa.Game/Unit.cs @@ -83,7 +83,7 @@ namespace OpenRa.Game return mission == ( unitInfo.supportedMissions & mission ); } - public IOrder Order( Game game, int2 xy ) + public Order Order( Game game, int2 xy ) { if( ( fromCell == toCell || moveFraction == 0 ) && fromCell == xy ) { diff --git a/OpenRa.Game/World.cs b/OpenRa.Game/World.cs index d07f81c5e8..3a14768b2b 100644 --- a/OpenRa.Game/World.cs +++ b/OpenRa.Game/World.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.Windows.Forms; -using Ijw.DirectX; -using OpenRa.Game.Graphics; namespace OpenRa.Game { @@ -10,22 +8,10 @@ namespace OpenRa.Game { List actors = new List(); List> frameEndActions = new List>(); - SpriteRenderer spriteRenderer; - Game game; - Region region; - public IOrderGenerator orderGenerator; - public UiOverlay uiOverlay; - public World(Renderer renderer, Game game) - { - region = Region.Create(game.viewport, DockStyle.Left, game.viewport.Width - 128, Draw, WorldClicked); - this.game = game; - game.viewport.AddRegion(region); - - spriteRenderer = new SpriteRenderer(renderer, true); + public readonly Game game; - uiOverlay = new UiOverlay(spriteRenderer, game); - } + public World(Game game) { this.game = game; } public void Add(Actor a) { actors.Add(a); } public void Remove( Actor a ) { actors.Remove( a ); } @@ -33,46 +19,21 @@ namespace OpenRa.Game int lastTime = Environment.TickCount; - void WorldClicked(object sender, MouseEventArgs e) - { - float2 xy = (1 / 24.0f) * (new float2(e.Location) + game.viewport.Location); - if (orderGenerator != null) - { - IOrder order = orderGenerator.Order(game, new int2((int)xy.X, (int)xy.Y)); - game.Issue(order); - } - } - void Draw() + + public void Update() { int t = Environment.TickCount; int dt = t - lastTime; lastTime = t; - var range = new Range(region.Location, region.Location + region.Size); - foreach (Actor a in actors) - { - a.Tick( game, dt ); - - Sprite[] images = a.CurrentImages; - float2 loc = a.RenderLocation; - - if( loc.X > range.End.X || loc.X < range.Start.X - images[ 0 ].bounds.Width ) - continue; - - if( loc.Y > range.End.Y || loc.Y < range.Start.Y - images[ 0 ].bounds.Height ) - continue; - - foreach( Sprite image in images ) - spriteRenderer.DrawSprite(image, loc, (a.owner != null) ? a.owner.Palette : 0); - } + a.Tick(game, dt); foreach (Action a in frameEndActions) a(this); frameEndActions.Clear(); - - uiOverlay.Draw(); - spriteRenderer.Flush(); } + + public IEnumerable Actors { get { return actors; } } } }