untangling a few things

This commit is contained in:
Chris Forbes
2009-10-12 21:23:09 +13:00
parent 8a5e84e265
commit 711b419ed0
9 changed files with 92 additions and 241 deletions

View File

@@ -83,5 +83,8 @@ namespace OpenRa
public override string ToString() { return string.Format("({0},{1})", X, Y); } public override string ToString() { return string.Format("({0},{1})", X, Y); }
public int2 ToInt2() { return new int2((int)X, (int)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)); }
} }
} }

View File

@@ -113,7 +113,7 @@ namespace OpenRa.FileFormats
for( int i = 0 ; i < 128 ; i++ ) for( int i = 0 ; i < 128 ; i++ )
for( int j = 0 ; j < 128 ; j++ ) 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 ) if( MapTiles[ j, i ].tile == 0xff || MapTiles[ j, i ].tile == 0xffff )
MapTiles[ j, i ].image = (byte)( i % 4 + ( j % 4 ) * 4 ); MapTiles[ j, i ].image = (byte)( i % 4 + ( j % 4 ) * 4 );
} }

View File

@@ -7,6 +7,7 @@ using IjwFramework.Types;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using OpenRa.Game.GameRules; using OpenRa.Game.GameRules;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using System.Drawing;
namespace OpenRa.Game namespace OpenRa.Game
{ {
@@ -142,6 +143,16 @@ namespace OpenRa.Game
.Where( x => x != null ) .Where( x => x != null )
.FirstOrDefault(); .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);
}
}
} }
namespace Traits namespace Traits

View File

@@ -19,15 +19,11 @@ namespace OpenRa.Game
this.game = 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; float2 dragStart, dragEnd;
public void HandleMouseInput(MouseInput mi) 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 (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Down)
{ {
if (!(orderGenerator is PlaceBuilding)) if (!(orderGenerator is PlaceBuilding))
@@ -35,16 +31,16 @@ namespace OpenRa.Game
} }
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Move) if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Move)
dragEnd = GetWorldPos(mi); dragEnd = xy;
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Up) if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Up)
{ {
if (!(orderGenerator is PlaceBuilding)) if (!(orderGenerator is PlaceBuilding))
{ {
if (dragStart != GetWorldPos(mi)) if (dragStart != xy)
orderGenerator = new UnitOrderGenerator( FindUnits( game, 24 * dragStart, 24 * xy ) ); /* band-box select */ orderGenerator = new UnitOrderGenerator( game.FindUnits( 24 * dragStart, 24 * xy ) ); /* band-box select */
else 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; dragStart = dragEnd;
@@ -58,37 +54,17 @@ namespace OpenRa.Game
if( mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down ) if( mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down )
if( orderGenerator != null ) 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 ); order.Apply( game );
} }
public Actor FindUnit(float2 a, float2 b) public Pair<float2, float2>? SelectionBox
{ {
return FindUnits(game, 24 * a, 24 * b).FirstOrDefault(); get
}
public static IEnumerable<Actor> 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<float2, float2>? SelectionBox()
{ {
if (dragStart == dragEnd) return null; if (dragStart == dragEnd) return null;
return Pair.New(24 * dragStart, 24 * dragEnd); return Pair.New(24 * dragStart, 24 * dragEnd);
} }
} }
} }
}

View File

@@ -1,195 +1,40 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ClassDiagram MajorVersion="1" MinorVersion="1"> <ClassDiagram MajorVersion="1" MinorVersion="1">
<Class Name="OpenRa.Game.Actor">
<Position X="1" Y="8.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAEAAAiAAAAAAAAAAQIAAIAAAQAAAAAAABAAAAAAQAA=</HashCode>
<FileName>Actor.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Field Name="Owner" />
</ShowAsAssociation>
</Class>
<Class Name="OpenRa.Game.World">
<Position X="1" Y="1.25" Width="1.5" />
<TypeIdentifier>
<HashCode>AAYAACABABAAgAAAAIAABgAAAAAAAAAIAAAAAAAAAAA=</HashCode>
<FileName>World.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Field Name="game" />
</ShowAsAssociation>
<ShowAsCollectionAssociation>
<Property Name="Actors" />
</ShowAsCollectionAssociation>
</Class>
<Class Name="OpenRa.Game.Game"> <Class Name="OpenRa.Game.Game">
<Position X="5.25" Y="6.75" Width="1.5" /> <Position X="6" Y="2.5" Width="1.5" />
<Members>
<Field Name="localPlayerIndex" Hidden="true" />
<Field Name="treeCache" Hidden="true" />
</Members>
<TypeIdentifier> <TypeIdentifier>
<HashCode>AAAAEAAAAIAAAAEEBAAAIAAQQAAAAAAAJAAAAABAQAA=</HashCode> <HashCode>AAAAEAAAAIAAAAEEBAEAIAAQQAAAAAAAJIAAAABAQAA=</HashCode>
<FileName>Game.cs</FileName> <FileName>Game.cs</FileName>
</TypeIdentifier> </TypeIdentifier>
<ShowAsAssociation> <ShowAsAssociation>
<Field Name="controller" /> <Field Name="controller" />
<Field Name="world" />
<Field Name="worldRenderer" />
<Field Name="viewport" /> <Field Name="viewport" />
<Field Name="pathFinder" />
<Field Name="terrain" />
<Field Name="network" />
<Property Name="LocalPlayer" />
</ShowAsAssociation>
<ShowAsCollectionAssociation>
<Field Name="players" />
</ShowAsCollectionAssociation>
</Class>
<Class Name="OpenRa.Game.PathFinder" Collapsed="true">
<Position X="5.25" Y="4" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAEAAAAAAAABAAAAAAAAAAAAAEEAAAMAAAAAAAAAA=</HashCode>
<FileName>PathFinder.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="OpenRa.Game.Player">
<Position X="9.25" Y="10.25" Width="1.5" />
<TypeIdentifier>
<HashCode>AAEAAAAAAAIAAAAAAAAAACAAAgAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Player.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Field Name="TechTree" />
</ShowAsAssociation>
</Class>
<Class Name="OpenRa.Game.UiOverlay">
<Position X="5.25" Y="10.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAIAAAiAAAAAQIABAAAAkAAAYAAAAAAQAAAA=</HashCode>
<FileName>UiOverlay.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Field Name="game" />
<Field Name="spriteRenderer" />
</ShowAsAssociation> </ShowAsAssociation>
</Class> </Class>
<Class Name="OpenRa.Game.Controller"> <Class Name="OpenRa.Game.Controller">
<Position X="2.25" Y="1.75" Width="1.5" /> <Position X="8.5" Y="3" Width="1.75" />
<Members>
<Field Name="dragEnd" Hidden="true" />
<Field Name="dragStart" Hidden="true" />
</Members>
<TypeIdentifier> <TypeIdentifier>
<HashCode>IAAAAAAIAAAAAAAAAAACAgAAABAAAAAIAIAAAIAABAA=</HashCode> <HashCode>AAAAAAAIAAAAAAAAAAACAgAAABAAAAAIAAAAAIAAAAA=</HashCode>
<FileName>Controller.cs</FileName> <FileName>Controller.cs</FileName>
</TypeIdentifier> </TypeIdentifier>
<ShowAsAssociation> <ShowAsAssociation>
<Field Name="game" /> <Field Name="game" />
<Field Name="orderGenerator" />
</ShowAsAssociation>
</Class>
<Class Name="OpenRa.TechTree.TechTree">
<Position X="11.25" Y="14.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAACAAAAAAAAAAAAAAEAAIgAQAAoyACAAAAAAAAAAA=</HashCode>
<FileName>TechTree\TechTree.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="OpenRa.Game.Graphics.WorldRenderer">
<Position X="1.25" Y="10.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AACAEABAAAAAAmAAAAAAAAAIAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Graphics\WorldRenderer.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Field Name="uiOverlay" />
<Field Name="spriteRenderer" />
<Field Name="lineRenderer" />
<Field Name="world" />
</ShowAsAssociation> </ShowAsAssociation>
</Class> </Class>
<Class Name="OpenRa.Game.Graphics.Viewport"> <Class Name="OpenRa.Game.Graphics.Viewport">
<Position X="10.75" Y="5" Width="1.5" /> <Position X="3.5" Y="2.5" Width="1.5" />
<TypeIdentifier> <TypeIdentifier>
<HashCode>AAAAAAAABAAAiAAAAIYAAEAAAABCAAAAAABgAAAAgBE=</HashCode> <HashCode>AAAAAAAABAAAiABAAIYAAEAAAABCAAAAAABgAAAAgBE=</HashCode>
<FileName>Graphics\Viewport.cs</FileName> <FileName>Graphics\Viewport.cs</FileName>
</TypeIdentifier> </TypeIdentifier>
<ShowAsAssociation>
<Field Name="renderer" />
</ShowAsAssociation>
</Class> </Class>
<Class Name="OpenRa.Game.Graphics.Renderer">
<Position X="13.5" Y="5" Width="1.5" />
<TypeIdentifier>
<HashCode>AACAEAACCAAAAgMAAAAAAEAAAAAAAAAAEAAAAAAAAAA=</HashCode>
<FileName>Graphics\Renderer.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="OpenRa.Game.Graphics.SpriteRenderer">
<Position X="8" Y="13.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAQQAAAAECAAAAAAAAAAAAAABAQABAAAAAAAACIwAQ=</HashCode>
<FileName>Graphics\SpriteRenderer.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Field Name="renderer" />
<Field Name="currentSheet" />
</ShowAsAssociation>
</Class>
<Class Name="OpenRa.Game.Graphics.LineRenderer">
<Position X="2.5" Y="13.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAQQAAAACCAAAAAAAAAAAAAABIQAAAAAEAAAAAIwAA=</HashCode>
<FileName>Graphics\LineRenderer.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Field Name="renderer" />
</ShowAsAssociation>
</Class>
<Class Name="OpenRa.Game.Graphics.Sheet">
<Position X="14.75" Y="9.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAACAgAAACAgAAAAIAAAAAgAAAAIAAAAggAA=</HashCode>
<FileName>Graphics\Sheet.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Field Name="renderer" />
</ShowAsAssociation>
</Class>
<Class Name="OpenRa.Game.Graphics.TerrainRenderer">
<Position X="8.25" Y="6" Width="1.5" />
<TypeIdentifier>
<HashCode>AACQEAAAAAAAAgAABAAACgAAABgAAAAAAAAAAAAAgAA=</HashCode>
<FileName>Graphics\TerrainRenderer.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Field Name="renderer" />
<Field Name="overlayRenderer" />
<Field Name="viewport" />
<Field Name="tileSet" />
</ShowAsAssociation>
</Class>
<Class Name="OpenRa.Game.Graphics.OverlayRenderer">
<Position X="12.25" Y="10.25" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAEAAAABAAAiCAAEAAAAAAAAQAAABAAAAAEAAQAAA=</HashCode>
<FileName>Graphics\OverlayRenderer.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Field Name="spriteRenderer" />
</ShowAsAssociation>
</Class>
<Class Name="OpenRa.FileFormats.TileSet">
<Position X="8.25" Y="2.75" Width="1.5" />
<TypeIdentifier />
</Class>
<Class Name="OpenRa.Game.Network">
<Position X="2.25" Y="5.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAKAAAAAgAAAAAAAAEAAAAAACAAAAABAAAAAJAAAQAA=</HashCode>
<FileName>Network\Network.cs</FileName>
</TypeIdentifier>
</Class>
<Interface Name="OpenRa.Game.IOrderGenerator" Collapsed="true">
<Position X="2.25" Y="0.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAA=</HashCode>
<FileName>IOrderGenerator.cs</FileName>
</TypeIdentifier>
</Interface>
<Font Name="Segoe UI" Size="9" /> <Font Name="Segoe UI" Size="9" />
</ClassDiagram> </ClassDiagram>

View File

@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using System.Linq;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using OpenRa.TechTree;
using System.Drawing;
using System.Linq;
namespace OpenRa.Game namespace OpenRa.Game
{ {
@@ -30,7 +30,7 @@ namespace OpenRa.Game
Rules.LoadRules(); Rules.LoadRules();
for( int i = 0 ; i < 8 ; i++ ) 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))); map = new Map(new IniFile(FileSystem.Open(mapName)));
FileSystem.Mount(new Package(map.Theater + ".mix")); FileSystem.Mount(new Package(map.Theater + ".mix"));
@@ -49,7 +49,7 @@ namespace OpenRa.Game
network = new Network(); network = new Network();
controller = new Controller(this); // CAREFUL THERES AN UGLY HIDDEN DEPENDENCY HERE STILL 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() public void Tick()
@@ -59,5 +59,25 @@ namespace OpenRa.Game
viewport.DrawRegions(); 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<Actor> 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)));
}
} }
} }

View File

@@ -59,5 +59,10 @@ namespace OpenRa.Game.Graphics
if (mi.Event != MouseInputEvent.Down) if (mi.Event != MouseInputEvent.Down)
dragRegion = null; dragRegion = null;
} }
public float2 ViewToWorld(MouseInput mi)
{
return (1 / 24.0f) * (new float2(mi.Location.X, mi.Location.Y) + Location);
}
} }
} }

View File

@@ -8,32 +8,31 @@ namespace OpenRa.Game.Graphics
{ {
public readonly SpriteRenderer spriteRenderer; public readonly SpriteRenderer spriteRenderer;
public readonly LineRenderer lineRenderer; public readonly LineRenderer lineRenderer;
public readonly World world; public readonly Game game;
public readonly Region region; public readonly Region region;
public readonly UiOverlay uiOverlay; 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. // TODO: this is layout policy. it belongs at a higher level than this.
region = Region.Create(world.game.viewport, DockStyle.Left, region = Region.Create(game.viewport, DockStyle.Left,
world.game.viewport.Width - 128, Draw, game.viewport.Width - 128, Draw,
world.game.controller.HandleMouseInput); game.controller.HandleMouseInput);
world.game.viewport.AddRegion(region); game.viewport.AddRegion(region);
spriteRenderer = new SpriteRenderer(renderer, true); spriteRenderer = new SpriteRenderer(renderer, true);
lineRenderer = new LineRenderer(renderer); lineRenderer = new LineRenderer(renderer);
uiOverlay = new UiOverlay(spriteRenderer, world.game); uiOverlay = new UiOverlay(spriteRenderer, game);
this.world = world;
} }
public void Draw() 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()); region.Size.ToSizeF());
foreach (Actor a in world.Actors) foreach (Actor a in game.world.Actors)
{ {
var images = a.Render(); var images = a.Render();
@@ -54,7 +53,7 @@ namespace OpenRa.Game.Graphics
spriteRenderer.Flush(); spriteRenderer.Flush();
var selbox = world.game.controller.SelectionBox(); var selbox = game.controller.SelectionBox;
if (selbox != null) if (selbox != null)
{ {
var a = selbox.Value.First; var a = selbox.Value.First;
@@ -66,16 +65,15 @@ namespace OpenRa.Game.Graphics
lineRenderer.DrawLine(a + b + c, a + c, Color.White, Color.White); lineRenderer.DrawLine(a + b + c, a + c, Color.White, Color.White);
lineRenderer.DrawLine(a, 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); DrawSelectionBox(u, Color.Yellow);
} }
var selection = world.game.controller.orderGenerator as UnitOrderGenerator; var selection = game.controller.orderGenerator as UnitOrderGenerator;
if (selection != null) 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); DrawSelectionBox(a, Color.White);
lineRenderer.Flush(); lineRenderer.Flush();
} }

View File

@@ -20,7 +20,7 @@ namespace OpenRa.Game
buildBlocked = SynthesizeTile(0xe6); buildBlocked = SynthesizeTile(0xe6);
} }
Sprite SynthesizeTile(byte paletteIndex) static Sprite SynthesizeTile(byte paletteIndex)
{ {
byte[] data = new byte[24 * 24]; byte[] data = new byte[24 * 24];
@@ -36,15 +36,6 @@ namespace OpenRa.Game
if (!hasOverlay) if (!hasOverlay)
return; return;
Func<int2, bool> 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 footprint = Rules.Footprint.GetFootprint(name);
var j = 0; var j = 0;
foreach (var row in footprint) foreach (var row in footprint)
@@ -53,7 +44,9 @@ namespace OpenRa.Game
foreach (var c in row) foreach (var c in row)
{ {
if (c != '_') 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); 24 * (position + new int2(i, j)), 0);
++i; ++i;
} }