pushed bibs down into the smudge layer; made Game static

This commit is contained in:
Chris Forbes
2009-10-20 20:47:04 +13:00
parent e41e74e609
commit a4c344523f
26 changed files with 201 additions and 202 deletions

View File

@@ -31,6 +31,10 @@ namespace OpenRa.FileFormats
public Map(IniFile file) public Map(IniFile file)
{ {
for (int j = 0; j < 128; j++)
for (int i = 0; i < 128; i++)
MapTiles[i, j] = new TileReference();
IniSection basic = file.GetSection("Basic"); IniSection basic = file.GetSection("Basic");
Title = basic.GetValue("Name", "(null)"); Title = basic.GetValue("Name", "(null)");

View File

@@ -4,11 +4,12 @@ using System.Text;
namespace OpenRa.FileFormats namespace OpenRa.FileFormats
{ {
public struct TileReference public class TileReference
{ {
public ushort tile; public ushort tile;
public byte image; public byte image;
public byte overlay; public byte overlay;
public byte smudge;
public override int GetHashCode() { return tile.GetHashCode() ^ image.GetHashCode(); } public override int GetHashCode() { return tile.GetHashCode() ^ image.GetHashCode(); }

View File

@@ -45,10 +45,10 @@ namespace OpenRa.Game
traits.Add( new Traits.Tree( treeRenderer.GetImage( tree.Image ) ) ); traits.Add( new Traits.Tree( treeRenderer.GetImage( tree.Image ) ) );
} }
public void Tick( Game game ) public void Tick()
{ {
foreach( var tick in traits.WithInterface<Traits.ITick>() ) foreach (var tick in traits.WithInterface<Traits.ITick>())
tick.Tick( this, game ); tick.Tick(this);
} }
public float2 CenterLocation; public float2 CenterLocation;
@@ -59,10 +59,10 @@ namespace OpenRa.Game
return traits.WithInterface<Traits.IRender>().SelectMany( x => x.Render( this ) ); return traits.WithInterface<Traits.IRender>().SelectMany( x => x.Render( this ) );
} }
public Order Order( Game game, int2 xy ) public Order Order( int2 xy )
{ {
return traits.WithInterface<Traits.IOrder>() return traits.WithInterface<Traits.IOrder>()
.Select( x => x.Order( this, game, xy ) ) .Select( x => x.Order( this, xy ) )
.Where( x => x != null ) .Where( x => x != null )
.FirstOrDefault(); .FirstOrDefault();
} }

View File

@@ -10,7 +10,7 @@ namespace OpenRa.Game
{ {
interface IEffect interface IEffect
{ {
void Tick(Game g); void Tick();
IEnumerable<Pair<Sprite, float2>> Render(); IEnumerable<Pair<Sprite, float2>> Render();
Player Owner { get; } Player Owner { get; }
} }
@@ -32,7 +32,7 @@ namespace OpenRa.Game
/* src, dest are *pixel* coords */ /* src, dest are *pixel* coords */
public Bullet(string weapon, Player owner, Actor firedBy, public Bullet(string weapon, Player owner, Actor firedBy,
int2 src, int2 dest, Game game) int2 src, int2 dest)
{ {
Owner = owner; Owner = owner;
FiredBy = firedBy; FiredBy = firedBy;
@@ -48,18 +48,17 @@ namespace OpenRa.Game
int TotalTime() { return (Dest - Src).Length * BaseBulletSpeed / Weapon.Speed; } int TotalTime() { return (Dest - Src).Length * BaseBulletSpeed / Weapon.Speed; }
public void Tick(Game game) public void Tick()
{ {
if (t == 0) if (t == 0)
game.PlaySound(Weapon.Report + ".aud", false); Game.PlaySound(Weapon.Report + ".aud", false);
t += 40; t += 40;
if (t > TotalTime()) /* remove finished bullets */ if (t > TotalTime()) /* remove finished bullets */
{ {
game.world.AddFrameEndTask(w => w.Remove(this)); Game.world.AddFrameEndTask(w => w.Remove(this));
game.PlaySound("kaboom25.aud", false); Game.world.AddFrameEndTask(w => w.Add(new Explosion(Dest)));
game.world.AddFrameEndTask(w => w.Add(new Explosion(Dest, game)));
} }
} }

View File

@@ -10,19 +10,12 @@ namespace OpenRa.Game
{ {
class Controller class Controller
{ {
Game game;
public IOrderGenerator orderGenerator; public IOrderGenerator orderGenerator;
public Controller(Game game)
{
this.game = game;
}
float2 dragStart, dragEnd; float2 dragStart, dragEnd;
public void HandleMouseInput(MouseInput mi) public void HandleMouseInput(MouseInput mi)
{ {
var xy = game.viewport.ViewToWorld(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)
{ {
@@ -30,8 +23,8 @@ namespace OpenRa.Game
dragStart = dragEnd = xy; dragStart = dragEnd = xy;
if (orderGenerator != null) if (orderGenerator != null)
foreach (var order in orderGenerator.Order(game, xy.ToInt2())) foreach (var order in orderGenerator.Order(xy.ToInt2()))
order.Apply(game, true); order.Apply(true);
} }
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Move) if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Move)
@@ -43,10 +36,10 @@ namespace OpenRa.Game
{ {
if (dragStart != xy) if (dragStart != xy)
orderGenerator = new UnitOrderGenerator( orderGenerator = new UnitOrderGenerator(
game.SelectUnitsInBox( Game.CellSize * dragStart, Game.CellSize * xy ) ); Game.SelectUnitsInBox( Game.CellSize * dragStart, Game.CellSize * xy ) );
else else
orderGenerator = new UnitOrderGenerator( orderGenerator = new UnitOrderGenerator(
game.SelectUnitOrBuilding( Game.CellSize * xy ) ); Game.SelectUnitOrBuilding( Game.CellSize * xy ) );
} }
dragStart = dragEnd = xy; dragStart = dragEnd = xy;
@@ -61,8 +54,8 @@ 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, xy.ToInt2() ) ) foreach( var order in orderGenerator.Order( xy.ToInt2() ) )
order.Apply( game, false ); order.Apply( false );
} }
public Pair<float2, float2>? SelectionBox public Pair<float2, float2>? SelectionBox
@@ -81,7 +74,7 @@ namespace OpenRa.Game
if (uog != null && uog.selection.Count > 0 && uog.selection.Any(a => a.traits.Contains<Traits.Mobile>())) if (uog != null && uog.selection.Count > 0 && uog.selection.Any(a => a.traits.Contains<Traits.Mobile>()))
return Cursor.Move; return Cursor.Move;
if (game.SelectUnitOrBuilding(Game.CellSize * dragEnd).Any()) if (Game.SelectUnitOrBuilding(Game.CellSize * dragEnd).Any())
return Cursor.Select; return Cursor.Select;
return Cursor.Default; return Cursor.Default;

View File

@@ -13,15 +13,16 @@ namespace OpenRa.Game
Animation anim; Animation anim;
int2 pos; int2 pos;
public Explosion(int2 pixelPos, Game g) public Explosion(int2 pixelPos)
{ {
this.pos = pixelPos; this.pos = pixelPos;
anim = new Animation("veh-hit3"); anim = new Animation("veh-hit3");
anim.PlayThen("idle", () => g.world.AddFrameEndTask(w => w.Remove(this))); anim.PlayThen("idle", () => Game.world.AddFrameEndTask(w => w.Remove(this)));
Game.PlaySound("kaboom25.aud", false);
} }
public void Tick(Game g) { anim.Tick(); } public void Tick() { anim.Tick(); }
public IEnumerable<Pair<Sprite, float2>> Render() public IEnumerable<Pair<Sprite, float2>> Render()
{ {

View File

@@ -9,30 +9,30 @@ using IjwFramework.Collections;
namespace OpenRa.Game namespace OpenRa.Game
{ {
class Game static class Game
{ {
public static readonly int CellSize = 24; public static readonly int CellSize = 24;
public readonly World world; public static World world;
public readonly Map map; public static Map map;
readonly TreeCache treeCache; static TreeCache treeCache;
public readonly TerrainRenderer terrain; public static TerrainRenderer terrain;
public readonly Viewport viewport; public static Viewport viewport;
public readonly PathFinder pathFinder; public static PathFinder pathFinder;
public readonly Network network; public static Network network;
public readonly WorldRenderer worldRenderer; public static WorldRenderer worldRenderer;
public readonly Controller controller; public static Controller controller;
int localPlayerIndex = 0; static int localPlayerIndex = 0;
public readonly Dictionary<int, Player> players = new Dictionary<int, Player>(); public static Dictionary<int, Player> players = new Dictionary<int, Player>();
public Player LocalPlayer { get { return players[localPlayerIndex]; } } public static Player LocalPlayer { get { return players[localPlayerIndex]; } }
public BuildingInfluenceMap LocalPlayerBuildings; public static BuildingInfluenceMap LocalPlayerBuildings;
ISoundEngine soundEngine; static ISoundEngine soundEngine;
public Game(string mapName, Renderer renderer, int2 clientSize) public static void Initialize(string mapName, Renderer renderer, int2 clientSize)
{ {
Rules.LoadRules( mapName ); Rules.LoadRules( mapName );
@@ -46,7 +46,7 @@ namespace OpenRa.Game
viewport = new Viewport(clientSize, map.Size, renderer); viewport = new Viewport(clientSize, map.Size, renderer);
terrain = new TerrainRenderer(renderer, map, viewport); terrain = new TerrainRenderer(renderer, map, viewport);
world = new World(this); world = new World();
treeCache = new TreeCache(map); treeCache = new TreeCache(map);
foreach( TreeReference treeReference in map.Trees ) foreach( TreeReference treeReference in map.Trees )
@@ -61,8 +61,8 @@ namespace OpenRa.Game
network = new Network(); network = new Network();
controller = new Controller(this); // CAREFUL THERES AN UGLY HIDDEN DEPENDENCY HERE STILL controller = new Controller();
worldRenderer = new WorldRenderer(renderer, this); worldRenderer = new WorldRenderer(renderer);
soundEngine = new ISoundEngine(); soundEngine = new ISoundEngine();
sounds = new Cache<string, ISoundSource>(LoadSound); sounds = new Cache<string, ISoundSource>(LoadSound);
@@ -70,7 +70,7 @@ namespace OpenRa.Game
PlaySound("intro.aud", false); PlaySound("intro.aud", false);
} }
void LoadMapBuildings( IniFile mapfile ) static void LoadMapBuildings( IniFile mapfile )
{ {
foreach( var s in mapfile.GetSection( "STRUCTURES", true ) ) foreach( var s in mapfile.GetSection( "STRUCTURES", true ) )
{ {
@@ -81,7 +81,7 @@ namespace OpenRa.Game
} }
} }
void LoadMapUnits( IniFile mapfile ) static void LoadMapUnits( IniFile mapfile )
{ {
foreach( var s in mapfile.GetSection( "UNITS", true ) ) foreach( var s in mapfile.GetSection( "UNITS", true ) )
{ {
@@ -92,9 +92,9 @@ namespace OpenRa.Game
} }
} }
readonly Cache<string, ISoundSource> sounds; static Cache<string, ISoundSource> sounds;
ISoundSource LoadSound(string filename) static ISoundSource LoadSound(string filename)
{ {
var data = AudLoader.LoadSound(FileSystem.Open(filename)); var data = AudLoader.LoadSound(FileSystem.Open(filename));
return soundEngine.AddSoundSourceFromPCMData(data, filename, return soundEngine.AddSoundSourceFromPCMData(data, filename,
@@ -107,14 +107,14 @@ namespace OpenRa.Game
}); });
} }
public void PlaySound(string name, bool loop) public static void PlaySound(string name, bool loop)
{ {
var sound = sounds[name]; var sound = sounds[name];
// todo: positioning // todo: positioning
soundEngine.Play2D(sound, loop, false, false); soundEngine.Play2D(sound, loop, false, false);
} }
public void Tick() public static void Tick()
{ {
var stuffFromOtherPlayers = network.Tick(); // todo: actually use the orders! var stuffFromOtherPlayers = network.Tick(); // todo: actually use the orders!
world.Update(); world.Update();
@@ -122,7 +122,7 @@ namespace OpenRa.Game
viewport.DrawRegions(); viewport.DrawRegions();
} }
public bool IsCellBuildable(int2 a) public static bool IsCellBuildable(int2 a)
{ {
if (LocalPlayerBuildings[a] != null) return false; if (LocalPlayerBuildings[a] != null) return false;
@@ -133,7 +133,7 @@ namespace OpenRa.Game
terrain.tileSet.GetWalkability(map.MapTiles[a.X, a.Y])) < double.PositiveInfinity; terrain.tileSet.GetWalkability(map.MapTiles[a.X, a.Y])) < double.PositiveInfinity;
} }
IEnumerable<Actor> FindUnits(float2 a, float2 b) static IEnumerable<Actor> FindUnits(float2 a, float2 b)
{ {
var min = float2.Min(a, b); var min = float2.Min(a, b);
var max = float2.Max(a, b); var max = float2.Max(a, b);
@@ -144,12 +144,12 @@ namespace OpenRa.Game
.Where(x => x.Bounds.IntersectsWith(rect)); .Where(x => x.Bounds.IntersectsWith(rect));
} }
public IEnumerable<Actor> SelectUnitsInBox(float2 a, float2 b) public static IEnumerable<Actor> SelectUnitsInBox(float2 a, float2 b)
{ {
return FindUnits(a, b).Where(x => x.Owner == LocalPlayer && x.traits.Contains<Traits.Mobile>()); return FindUnits(a, b).Where(x => x.Owner == LocalPlayer && x.traits.Contains<Traits.Mobile>());
} }
public IEnumerable<Actor> SelectUnitOrBuilding(float2 a) public static IEnumerable<Actor> SelectUnitOrBuilding(float2 a)
{ {
var q = FindUnits(a, a); var q = FindUnits(a, a);
return q.Where(x => x.traits.Contains<Traits.Mobile>()).Concat(q).Take(1); return q.Where(x => x.traits.Contains<Traits.Mobile>()).Concat(q).Take(1);

View File

@@ -44,6 +44,8 @@ namespace OpenRa.Game.Graphics
}; };
Sprite[][] overlaySprites; Sprite[][] overlaySprites;
Sprite[] smudgeSprites;
SpriteRenderer spriteRenderer; SpriteRenderer spriteRenderer;
Map map; Map map;
@@ -53,8 +55,12 @@ namespace OpenRa.Game.Graphics
this.map = map; this.map = map;
overlaySprites = new Sprite[ overlaySpriteNames.Length ][]; overlaySprites = new Sprite[ overlaySpriteNames.Length ][];
for( int i = 0 ; i < overlaySpriteNames.Length ; i++ ) for (int i = 0; i < overlaySpriteNames.Length; i++)
overlaySprites[ i ] = SpriteSheetBuilder.LoadAllSprites( overlaySpriteNames[ i ], ".shp", ".tem", ".sno" ); overlaySprites[i] = SpriteSheetBuilder.LoadAllSprites(overlaySpriteNames[i], ".shp", ".tem", ".sno");
/* todo: add the rest of the smudge sprites */
smudgeSprites = new[] { "bib3", "bib2" }.SelectMany(
f => SpriteSheetBuilder.LoadAllSprites(f, ".shp", ".tem", ".sno")).ToArray();
} }
public void Draw() public void Draw()
@@ -62,7 +68,15 @@ namespace OpenRa.Game.Graphics
for( int y = 0 ; y < 128 ; y++ ) for( int y = 0 ; y < 128 ; y++ )
for (int x = 0; x < 128; x++) for (int x = 0; x < 128; x++)
{ {
var o = map.MapTiles[x, y].overlay; var tr = map.MapTiles[x,y];
if (tr.smudge != 0 && tr.smudge <= smudgeSprites.Length)
{
var location = new int2(x, y);
spriteRenderer.DrawSprite(smudgeSprites[tr.smudge - 1],
Game.CellSize * (float2)(location - map.Offset), 0);
}
var o = tr.overlay;
if (o < overlaySprites.Length) if (o < overlaySprites.Length)
{ {
var location = new int2(x, y); var location = new int2(x, y);

View File

@@ -10,23 +10,21 @@ namespace OpenRa.Game.Graphics
{ {
public readonly SpriteRenderer spriteRenderer; public readonly SpriteRenderer spriteRenderer;
public readonly LineRenderer lineRenderer; public readonly LineRenderer lineRenderer;
public readonly Game game;
public readonly Region region; public readonly Region region;
public readonly UiOverlay uiOverlay; public readonly UiOverlay uiOverlay;
public WorldRenderer(Renderer renderer, Game game) public WorldRenderer(Renderer renderer)
{ {
// 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.
this.game = game; region = Region.Create(Game.viewport, DockStyle.Left,
region = Region.Create(game.viewport, DockStyle.Left, Game.viewport.Width - 128, Draw,
game.viewport.Width - 128, Draw, Game.controller.HandleMouseInput);
game.controller.HandleMouseInput);
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, game); uiOverlay = new UiOverlay(spriteRenderer);
} }
void DrawSpriteList(Player owner, RectangleF rect, void DrawSpriteList(Player owner, RectangleF rect,
@@ -50,20 +48,20 @@ namespace OpenRa.Game.Graphics
public void Draw() public void Draw()
{ {
var rect = new RectangleF((region.Position + game.viewport.Location).ToPointF(), var rect = new RectangleF((region.Position + Game.viewport.Location).ToPointF(),
region.Size.ToSizeF()); region.Size.ToSizeF());
foreach (Actor a in game.world.Actors) foreach (Actor a in Game.world.Actors)
DrawSpriteList(a.Owner, rect, a.Render()); DrawSpriteList(a.Owner, rect, a.Render());
foreach (IEffect e in game.world.Effects) foreach (IEffect e in Game.world.Effects)
DrawSpriteList(e.Owner, rect, e.Render()); DrawSpriteList(e.Owner, rect, e.Render());
uiOverlay.Draw(); uiOverlay.Draw();
spriteRenderer.Flush(); spriteRenderer.Flush();
var selbox = game.controller.SelectionBox; var selbox = Game.controller.SelectionBox;
if (selbox != null) if (selbox != null)
{ {
var a = selbox.Value.First; var a = selbox.Value.First;
@@ -75,13 +73,13 @@ 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 game.SelectUnitsInBox(selbox.Value.First, selbox.Value.Second)) foreach (var u in Game.SelectUnitsInBox(selbox.Value.First, selbox.Value.Second))
DrawSelectionBox(u, Color.Yellow, false); DrawSelectionBox(u, Color.Yellow, false);
} }
var selection = game.controller.orderGenerator as UnitOrderGenerator; var selection = Game.controller.orderGenerator as UnitOrderGenerator;
if (selection != null) if (selection != null)
foreach( var a in game.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, true); DrawSelectionBox(a, Color.White, true);
lineRenderer.Flush(); lineRenderer.Flush();

View File

@@ -6,7 +6,7 @@ namespace OpenRa.Game
{ {
interface IOrderGenerator interface IOrderGenerator
{ {
IEnumerable<Order> Order( Game game, int2 xy ); IEnumerable<Order> Order( int2 xy );
void PrepareOverlay( Game game, int2 xy ); void PrepareOverlay( int2 xy );
} }
} }

View File

@@ -3,17 +3,17 @@ using System.Windows.Forms;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using OpenRa.TechTree; using OpenRa.TechTree;
using System.Runtime.InteropServices;
namespace OpenRa.Game namespace OpenRa.Game
{ {
using GRegion = OpenRa.Game.Graphics.Region; using GRegion = OpenRa.Game.Graphics.Region;
using System.Runtime.InteropServices;
class MainWindow : Form class MainWindow : Form
{ {
readonly Renderer renderer; readonly Renderer renderer;
Game game;
public readonly Sidebar sidebar; public readonly Sidebar sidebar;
static Size GetResolution(Settings settings) static Size GetResolution(Settings settings)
@@ -50,37 +50,36 @@ using System.Runtime.InteropServices;
renderer = new Renderer(this, GetResolution(settings), windowed); renderer = new Renderer(this, GetResolution(settings), windowed);
SheetBuilder.Initialize(renderer); SheetBuilder.Initialize(renderer);
game = new Game(settings.GetValue("map", "scg11eb.ini"), renderer, new int2(ClientSize)); Game.Initialize(settings.GetValue("map", "scg11eb.ini"), renderer, new int2(ClientSize));
SequenceProvider.ForcePrecache(); SequenceProvider.ForcePrecache();
Traits.RenderBuilding.Prefetch();
game.world.Add( new Actor( "mcv", new int2( 5, 5 ), game.players[ 3 ]) ); Game.world.Add( new Actor( "mcv", new int2( 5, 5 ), Game.players[ 3 ]) );
game.world.Add( new Actor( "mcv", new int2( 7, 5 ), game.players[ 2 ] ) ); Game.world.Add( new Actor( "mcv", new int2( 7, 5 ), Game.players[ 2 ] ) );
game.world.Add( new Actor( "mcv", new int2( 9, 5 ), game.players[ 0 ] ) ); Game.world.Add( new Actor( "mcv", new int2( 9, 5 ), Game.players[ 0 ] ) );
var jeep = new Actor( "jeep", new int2( 9, 7 ), game.players[ 1 ] ); var jeep = new Actor( "jeep", new int2( 9, 7 ), Game.players[ 1 ] );
game.world.Add( jeep ); Game.world.Add( jeep );
var tank = new Actor( "3tnk", new int2( 12, 7 ), game.players[ 1 ] ); var tank = new Actor( "3tnk", new int2( 12, 7 ), Game.players[ 1 ] );
game.world.Add( tank ); Game.world.Add( tank );
tank.traits.Get<Traits.AttackTurreted>().target = jeep; tank.traits.Get<Traits.AttackTurreted>().target = jeep;
sidebar = new Sidebar(renderer, game); sidebar = new Sidebar(renderer);
renderer.BuildPalette(game.map); renderer.BuildPalette(Game.map);
ShowCursor(false); ShowCursor(false);
game.world.ResetTimer(); Game.world.ResetTimer();
} }
internal void Run() internal void Run()
{ {
while (Created && Visible) while (Created && Visible)
{ {
game.Tick(); Game.Tick();
// rude hack // rude hack
game.viewport.cursor = game.controller.ChooseCursor(); Game.viewport.cursor = Game.controller.ChooseCursor();
Application.DoEvents(); Application.DoEvents();
} }
@@ -93,7 +92,7 @@ using System.Runtime.InteropServices;
base.OnMouseDown(e); base.OnMouseDown(e);
lastPos = new int2(e.Location); lastPos = new int2(e.Location);
game.viewport.DispatchMouseInput(new MouseInput Game.viewport.DispatchMouseInput(new MouseInput
{ {
Button = e.Button, Button = e.Button,
Event = MouseInputEvent.Down, Event = MouseInputEvent.Down,
@@ -108,27 +107,27 @@ using System.Runtime.InteropServices;
if (e.Button == MouseButtons.Middle) if (e.Button == MouseButtons.Middle)
{ {
int2 p = new int2(e.Location); int2 p = new int2(e.Location);
game.viewport.Scroll(lastPos - p); Game.viewport.Scroll(lastPos - p);
lastPos = p; lastPos = p;
} }
game.viewport.DispatchMouseInput(new MouseInput Game.viewport.DispatchMouseInput(new MouseInput
{ {
Button = e.Button, Button = e.Button,
Event = MouseInputEvent.Move, Event = MouseInputEvent.Move,
Location = new int2(e.Location) Location = new int2(e.Location)
}); });
if (game.controller.orderGenerator != null) if (Game.controller.orderGenerator != null)
game.controller.orderGenerator.PrepareOverlay(game, Game.controller.orderGenerator.PrepareOverlay(
((1 / 24f) * (new float2(e.Location) + game.viewport.Location)).ToInt2()); ((1 / 24f) * (new float2(e.Location) + Game.viewport.Location)).ToInt2());
} }
protected override void OnMouseUp(MouseEventArgs e) protected override void OnMouseUp(MouseEventArgs e)
{ {
base.OnMouseUp(e); base.OnMouseUp(e);
game.viewport.DispatchMouseInput(new MouseInput Game.viewport.DispatchMouseInput(new MouseInput
{ {
Button = e.Button, Button = e.Button,
Event = MouseInputEvent.Up, Event = MouseInputEvent.Up,

View File

@@ -6,7 +6,7 @@ namespace OpenRa.Game
{ {
abstract class Order abstract class Order
{ {
public abstract void Apply( Game game, bool leftMButton ); public abstract void Apply( bool leftMButton );
} }
class MoveOrder : Order class MoveOrder : Order
@@ -20,11 +20,11 @@ namespace OpenRa.Game
this.Destination = destination; this.Destination = destination;
} }
public override void Apply( Game game, bool leftMouseButton ) public override void Apply( bool leftMouseButton )
{ {
if (leftMouseButton) return; if (leftMouseButton) return;
if (game.LocalPlayer == Unit.Owner) if (Game.LocalPlayer == Unit.Owner)
game.PlaySound("ackno.r00", false); Game.PlaySound("ackno.r00", false);
var mobile = Unit.traits.Get<Traits.Mobile>(); var mobile = Unit.traits.Get<Traits.Mobile>();
mobile.destination = Destination; mobile.destination = Destination;
mobile.desiredFacing = null; mobile.desiredFacing = null;
@@ -42,7 +42,7 @@ namespace OpenRa.Game
Location = location; Location = location;
} }
public override void Apply( Game game, bool leftMouseButton ) public override void Apply( bool leftMouseButton )
{ {
if (leftMouseButton) return; if (leftMouseButton) return;
Unit.traits.Get<Traits.McvDeploy>().DeployLocation = Location; Unit.traits.Get<Traits.McvDeploy>().DeployLocation = Location;

View File

@@ -17,7 +17,6 @@ namespace OpenRa.Game
SpriteRenderer spriteRenderer, clockRenderer; SpriteRenderer spriteRenderer, clockRenderer;
Sprite blank; Sprite blank;
Game game;
readonly GRegion region; readonly GRegion region;
public GRegion Region { get { return region; } } public GRegion Region { get { return region; } }
@@ -34,13 +33,12 @@ namespace OpenRa.Game
List<SidebarItem> items = new List<SidebarItem>(); List<SidebarItem> items = new List<SidebarItem>();
public Sidebar( Renderer renderer, Game game ) public Sidebar( Renderer renderer )
{ {
this.techTree = game.LocalPlayer.TechTree; this.techTree = Game.LocalPlayer.TechTree;
this.techTree.BuildableItemsChanged += PopulateItemList; this.techTree.BuildableItemsChanged += PopulateItemList;
this.game = game; region = GRegion.Create(Game.viewport, DockStyle.Right, 128, Paint, MouseHandler);
region = GRegion.Create(game.viewport, DockStyle.Right, 128, Paint, MouseHandler); Game.viewport.AddRegion( region );
game.viewport.AddRegion( region );
spriteRenderer = new SpriteRenderer(renderer, false); spriteRenderer = new SpriteRenderer(renderer, false);
clockRenderer = new SpriteRenderer(renderer, true); clockRenderer = new SpriteRenderer(renderer, true);
@@ -63,7 +61,8 @@ namespace OpenRa.Game
public void Build(SidebarItem item) public void Build(SidebarItem item)
{ {
if (item != null) if (item != null)
game.controller.orderGenerator = new PlaceBuilding(game.LocalPlayer, item.techTreeItem.tag.ToLowerInvariant()); Game.controller.orderGenerator = new PlaceBuilding(Game.LocalPlayer,
item.techTreeItem.tag.ToLowerInvariant());
} }
void LoadSprites( string category, string group ) void LoadSprites( string category, string group )
@@ -186,15 +185,15 @@ namespace OpenRa.Game
Name = name; Name = name;
} }
public IEnumerable<Order> Order( Game game, int2 xy ) public IEnumerable<Order> Order( int2 xy )
{ {
// todo: check that space is free // todo: check that space is free
yield return new PlaceBuildingOrder( this, xy ); yield return new PlaceBuildingOrder( this, xy );
} }
public void PrepareOverlay(Game game, int2 xy) public void PrepareOverlay(int2 xy)
{ {
game.worldRenderer.uiOverlay.SetCurrentOverlay(xy, Name); Game.worldRenderer.uiOverlay.SetCurrentOverlay(xy, Name);
} }
} }
@@ -209,11 +208,11 @@ namespace OpenRa.Game
this.xy = xy; this.xy = xy;
} }
public override void Apply(Game game, bool leftMouseButton) public override void Apply(bool leftMouseButton)
{ {
if (leftMouseButton) if (leftMouseButton)
{ {
game.world.AddFrameEndTask(_ => Game.world.AddFrameEndTask(_ =>
{ {
Log.Write("Player \"{0}\" builds {1}", building.Owner.PlayerName, building.Name); Log.Write("Player \"{0}\" builds {1}", building.Owner.PlayerName, building.Name);
@@ -224,18 +223,18 @@ namespace OpenRa.Game
if (row.Length > maxWidth) if (row.Length > maxWidth)
maxWidth = row.Length; maxWidth = row.Length;
game.world.Add(new Actor(building.Name, xy - new int2(maxWidth / 2, footprint.Length / 2), building.Owner)); Game.world.Add(new Actor(building.Name, xy - new int2(maxWidth / 2, footprint.Length / 2), building.Owner));
game.controller.orderGenerator = null; Game.controller.orderGenerator = null;
game.worldRenderer.uiOverlay.KillOverlay(); Game.worldRenderer.uiOverlay.KillOverlay();
}); });
} }
else else
{ {
game.world.AddFrameEndTask(_ => Game.world.AddFrameEndTask(_ =>
{ {
game.controller.orderGenerator = null; Game.controller.orderGenerator = null;
game.worldRenderer.uiOverlay.KillOverlay(); Game.worldRenderer.uiOverlay.KillOverlay();
}); });
} }
} }

View File

@@ -18,7 +18,7 @@ namespace OpenRa.Game.Traits
self.traits.Get<Turreted>(); self.traits.Get<Turreted>();
} }
public void Tick( Actor self, Game game ) public void Tick( Actor self )
{ {
if( primaryFireDelay > 0 ) if( primaryFireDelay > 0 )
--primaryFireDelay; --primaryFireDelay;
@@ -33,16 +33,16 @@ namespace OpenRa.Game.Traits
if( turreted.desiredFacing != turreted.turretFacing ) if( turreted.desiredFacing != turreted.turretFacing )
return; return;
if( self.unitInfo.Primary != null && CheckFire( self, game, self.unitInfo.Primary, ref primaryFireDelay ) ) if( self.unitInfo.Primary != null && CheckFire( self, self.unitInfo.Primary, ref primaryFireDelay ) )
{ {
secondaryFireDelay = Math.Max( 4, secondaryFireDelay ); secondaryFireDelay = Math.Max( 4, secondaryFireDelay );
return; return;
} }
if( self.unitInfo.Secondary != null && CheckFire( self, game, self.unitInfo.Secondary, ref secondaryFireDelay ) ) if( self.unitInfo.Secondary != null && CheckFire( self, self.unitInfo.Secondary, ref secondaryFireDelay ) )
return; return;
} }
bool CheckFire( Actor self, Game game, string weaponName, ref int fireDelay ) bool CheckFire( Actor self, string weaponName, ref int fireDelay )
{ {
if( fireDelay > 0 ) if( fireDelay > 0 )
return false; return false;
@@ -54,7 +54,10 @@ namespace OpenRa.Game.Traits
// FIXME: rules specifies ROF in 1/15 sec units; ticks are 1/25 sec // FIXME: rules specifies ROF in 1/15 sec units; ticks are 1/25 sec
fireDelay = weapon.ROF; fireDelay = weapon.ROF;
game.world.Add( new Bullet( weaponName, self.Owner, self, self.CenterLocation.ToInt2(), target.CenterLocation.ToInt2(), game ) ); Game.world.Add( new Bullet( weaponName, self.Owner, self,
self.CenterLocation.ToInt2(),
target.CenterLocation.ToInt2() ) );
return true; return true;
} }
} }

View File

@@ -12,9 +12,9 @@ namespace OpenRa.Game.Traits
} }
bool first = true; bool first = true;
public void Tick(Actor self, Game game) public void Tick(Actor self)
{ {
if (first && self.Owner == game.LocalPlayer) if (first && self.Owner == Game.LocalPlayer)
{ {
self.Owner.TechTree.Build(self.unitInfo.Name, true); self.Owner.TechTree.Build(self.unitInfo.Name, true);
self.CenterLocation = Game.CellSize * (float2)self.Location + 0.5f * self.SelectedSize; self.CenterLocation = Game.CellSize * (float2)self.Location + 0.5f * self.SelectedSize;

View File

@@ -13,7 +13,7 @@ namespace OpenRa.Game.Traits
{ {
} }
public Order Order(Actor self, Game game, int2 xy) public Order Order(Actor self, int2 xy)
{ {
DeployLocation = null; DeployLocation = null;
// TODO: check that there's enough space at the destination. // TODO: check that there's enough space at the destination.
@@ -23,7 +23,7 @@ namespace OpenRa.Game.Traits
return null; return null;
} }
public void Tick(Actor self, Game game) public void Tick(Actor self)
{ {
if( self.Location != DeployLocation ) if( self.Location != DeployLocation )
return; return;
@@ -36,10 +36,10 @@ namespace OpenRa.Game.Traits
if( mobile.facing != mobile.desiredFacing ) if( mobile.facing != mobile.desiredFacing )
return; return;
game.world.AddFrameEndTask(_ => Game.world.AddFrameEndTask(_ =>
{ {
game.world.Remove(self); Game.world.Remove(self);
game.world.Add(new Actor("fact", self.Location - new int2(1, 1), self.Owner)); Game.world.Add(new Actor("fact", self.Location - new int2(1, 1), self.Owner));
}); });
} }
} }

View File

@@ -29,13 +29,13 @@ namespace OpenRa.Game.Traits
self.CenterLocation = new float2(12, 12) + Game.CellSize * float2.Lerp(fromCell, toCell, fraction); self.CenterLocation = new float2(12, 12) + Game.CellSize * float2.Lerp(fromCell, toCell, fraction);
} }
public void Tick(Actor self, Game game) public void Tick(Actor self)
{ {
Move(self, game); Move(self);
UpdateCenterLocation(); UpdateCenterLocation();
} }
void Move(Actor self, Game game) void Move(Actor self)
{ {
if( fromCell != toCell ) if( fromCell != toCell )
desiredFacing = Util.GetFacing( toCell - fromCell, facing ); desiredFacing = Util.GetFacing( toCell - fromCell, facing );
@@ -60,7 +60,7 @@ namespace OpenRa.Game.Traits
if (destination == toCell) if (destination == toCell)
return; return;
List<int2> res = game.pathFinder.FindUnitPath(toCell, PathFinder.DefaultEstimator(destination)); List<int2> res = Game.pathFinder.FindUnitPath(toCell, PathFinder.DefaultEstimator(destination));
if (res.Count != 0) if (res.Count != 0)
{ {
self.Location = res[res.Count - 1]; self.Location = res[res.Count - 1];
@@ -72,12 +72,11 @@ namespace OpenRa.Game.Traits
destination = toCell; destination = toCell;
} }
public Order Order(Actor self, Game game, int2 xy) public Order Order(Actor self, int2 xy)
{ {
if (xy != toCell) if (xy != toCell)
{
return new MoveOrder(self, xy); return new MoveOrder(self, xy);
}
return null; return null;
} }
} }

View File

@@ -5,47 +5,43 @@ using System.Text;
using IjwFramework.Types; using IjwFramework.Types;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using OpenRa.Game.GameRules; using OpenRa.Game.GameRules;
using OpenRa.FileFormats;
using OpenRa.Game;
namespace OpenRa.Game.Traits namespace OpenRa.Game.Traits
{ {
class RenderBuilding : RenderSimple class RenderBuilding : RenderSimple
{ {
static Sprite[] largeBib; const int SmallBibStart = 1;
static Sprite[] smallBib; const int LargeBibStart = 5;
static int2[] largeBibPos = new[] { new int2(0,0), new int2(1,0), new int2(2,0),
new int2(0,1), new int2(1,1), new int2(2,1) };
static int2[] smallBibPos = new[] { new int2(0,0), new int2(1,0),
new int2(0,1), new int2(1,1)};
public RenderBuilding(Actor self) public RenderBuilding(Actor self)
: base(self) : base(self)
{ {
anim.PlayThen("make", () => anim.PlayRepeating("idle")); anim.PlayThen("make", () => anim.PlayRepeating("idle"));
}
public static void Prefetch() // at this point, we already know where we are, so we can safely place the bib in the smudge
{ if (((UnitInfo.BuildingInfo)self.unitInfo).Bib)
largeBib = SpriteSheetBuilder.LoadAllSprites("bib2.", "tem", "sno", "int"); {
smallBib = SpriteSheetBuilder.LoadAllSprites("bib3.", "tem", "sno", "int"); var fp = Rules.Footprint.GetFootprint(self.unitInfo.Name);
var bibOffset = fp.Length - 2;
var hasSmallBib = fp.First().Length == 2;
if (hasSmallBib)
for (int i = 0; i < 4; i++)
Game.map.MapTiles[
self.Location.X + i % 2 + Game.map.Offset.X,
self.Location.Y + i / 2 + Game.map.Offset.Y + bibOffset].smudge = (byte)(i + SmallBibStart);
else
for (int i = 0; i < 6; i++)
Game.map.MapTiles[
self.Location.X + i % 3 + Game.map.Offset.X,
self.Location.Y + i / 3 + Game.map.Offset.Y + bibOffset].smudge = (byte)(i + LargeBibStart);
}
} }
public override IEnumerable<Pair<Sprite, float2>> Render(Actor self) public override IEnumerable<Pair<Sprite, float2>> Render(Actor self)
{ {
if (((UnitInfo.BuildingInfo)self.unitInfo).Bib)
{
var fp = Rules.Footprint.GetFootprint(self.unitInfo.Name );
var bibOffset = new int2(0, fp.Length - 2);
var hasSmallBib = fp.First().Length == 2;
var bib = hasSmallBib ? smallBib : largeBib;
var bibPos = hasSmallBib ? smallBibPos : largeBibPos;
for (int i = 0; i < bib.Length; i++)
yield return Pair.New(bib[i], 24f * (float2)(self.Location + bibOffset + bibPos[i]));
}
yield return Pair.New(anim.Image, 24f * (float2)self.Location); yield return Pair.New(anim.Image, 24f * (float2)self.Location);
} }
} }

View File

@@ -33,9 +33,9 @@ namespace OpenRa.Game.Traits
return base.Render(self); return base.Render(self);
} }
public override void Tick(Actor self, Game game) public override void Tick(Actor self)
{ {
base.Tick(self, game); base.Tick(self);
roof.Tick(); roof.Tick();
} }
} }

View File

@@ -18,7 +18,7 @@ namespace OpenRa.Game.Traits
public abstract IEnumerable<Pair<Sprite, float2>> Render(Actor self); public abstract IEnumerable<Pair<Sprite, float2>> Render(Actor self);
public virtual void Tick(Actor self, Game game) public virtual void Tick(Actor self)
{ {
anim.Tick(); anim.Tick();
} }

View File

@@ -25,9 +25,9 @@ namespace OpenRa.Game.Traits
yield return Centered(turretAnim.Image, self.CenterLocation); yield return Centered(turretAnim.Image, self.CenterLocation);
} }
public override void Tick(Actor self, Game game) public override void Tick(Actor self)
{ {
base.Tick(self, game); base.Tick(self);
turretAnim.Tick(); turretAnim.Tick();
} }
} }

View File

@@ -7,7 +7,7 @@ using IjwFramework.Types;
namespace OpenRa.Game.Traits namespace OpenRa.Game.Traits
{ {
interface ITick { void Tick(Actor self, Game game); } interface ITick { void Tick(Actor self); }
interface IRender { IEnumerable<Pair<Sprite, float2>> Render(Actor self); } interface IRender { IEnumerable<Pair<Sprite, float2>> Render(Actor self); }
interface IOrder { Order Order(Actor self, Game game, int2 xy); } interface IOrder { Order Order(Actor self, int2 xy); }
} }

View File

@@ -14,7 +14,7 @@ namespace OpenRa.Game.Traits
{ {
} }
public void Tick( Actor self, Game game ) public void Tick( Actor self )
{ {
var df = desiredFacing ?? ( self.traits.Contains<Mobile>() ? self.traits.Get<Mobile>().facing : turretFacing ); var df = desiredFacing ?? ( self.traits.Contains<Mobile>() ? self.traits.Get<Mobile>().facing : turretFacing );
Util.TickFacing( ref turretFacing, df, self.unitInfo.ROT ); Util.TickFacing( ref turretFacing, df, self.unitInfo.ROT );

View File

@@ -10,12 +10,10 @@ namespace OpenRa.Game
SpriteRenderer spriteRenderer; SpriteRenderer spriteRenderer;
Sprite buildOk; Sprite buildOk;
Sprite buildBlocked; Sprite buildBlocked;
Game game;
public UiOverlay(SpriteRenderer spriteRenderer, Game game) public UiOverlay(SpriteRenderer spriteRenderer)
{ {
this.spriteRenderer = spriteRenderer; this.spriteRenderer = spriteRenderer;
this.game = game;
buildOk = SynthesizeTile(0x80); buildOk = SynthesizeTile(0x80);
buildBlocked = SynthesizeTile(0xe6); buildBlocked = SynthesizeTile(0xe6);
@@ -38,7 +36,7 @@ namespace OpenRa.Game
return; return;
foreach (var t in Footprint.Tiles(name,position)) foreach (var t in Footprint.Tiles(name,position))
spriteRenderer.DrawSprite(game.IsCellBuildable(t) ? buildOk : buildBlocked, Game.CellSize * t, 0); spriteRenderer.DrawSprite(Game.IsCellBuildable(t) ? buildOk : buildBlocked, Game.CellSize * t, 0);
spriteRenderer.Flush(); spriteRenderer.Flush();
} }

View File

@@ -14,16 +14,16 @@ namespace OpenRa.Game
selection = selected.ToList(); selection = selected.ToList();
} }
public IEnumerable<Order> Order( Game game, int2 xy ) public IEnumerable<Order> Order( int2 xy )
{ {
foreach( var unit in selection ) foreach( var unit in selection )
{ {
var ret = unit.Order( game, xy ); var ret = unit.Order( xy );
if( ret != null ) if( ret != null )
yield return ret; yield return ret;
} }
} }
public void PrepareOverlay( Game game, int2 xy ) { } public void PrepareOverlay( int2 xy ) { }
} }
} }

View File

@@ -10,12 +10,9 @@ namespace OpenRa.Game
List<Actor> actors = new List<Actor>(); List<Actor> actors = new List<Actor>();
List<IEffect> effects = new List<IEffect>(); List<IEffect> effects = new List<IEffect>();
List<Action<World>> frameEndActions = new List<Action<World>>(); List<Action<World>> frameEndActions = new List<Action<World>>();
readonly Game game;
int lastTime = Environment.TickCount; int lastTime = Environment.TickCount;
const int timestep = 40; const int timestep = 40;
public World(Game game) { this.game = game; }
public void Add(Actor a) { actors.Add(a); ActorAdded(a); } public void Add(Actor a) { actors.Add(a); ActorAdded(a); }
public void Remove(Actor a) { actors.Remove(a); ActorRemoved(a); } public void Remove(Actor a) { actors.Remove(a); ActorRemoved(a); }
@@ -36,14 +33,12 @@ namespace OpenRa.Game
{ {
int t = Environment.TickCount; int t = Environment.TickCount;
int dt = t - lastTime; int dt = t - lastTime;
if( dt >= timestep ) if (dt >= timestep)
{ {
lastTime += timestep; lastTime += timestep;
foreach( var a in actors ) foreach (var a in actors) a.Tick();
a.Tick(game); foreach (var e in effects) e.Tick();
foreach (var b in effects)
b.Tick(game);
Renderer.waterFrame += 0.00125f * timestep; Renderer.waterFrame += 0.00125f * timestep;
} }