Trait-based units. Any unit/building without sequences will cause a crash when built.
This commit is contained in:
@@ -42,6 +42,7 @@
|
|||||||
<Compile Include="int2.cs" />
|
<Compile Include="int2.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Tuple.cs" />
|
<Compile Include="Tuple.cs" />
|
||||||
|
<Compile Include="TypeDictionary.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
|||||||
38
OpenRa.DataStructures/TypeDictionary.cs
Executable file
38
OpenRa.DataStructures/TypeDictionary.cs
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenRa
|
||||||
|
{
|
||||||
|
public class TypeDictionary
|
||||||
|
{
|
||||||
|
Dictionary<Type, object> inner = new Dictionary<Type, object>();
|
||||||
|
|
||||||
|
public void Add<T>( T val )
|
||||||
|
{
|
||||||
|
inner.Add( typeof( T ), val );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove<T>()
|
||||||
|
{
|
||||||
|
inner.Remove( typeof( T ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains<T>()
|
||||||
|
{
|
||||||
|
return inner.ContainsKey( typeof( T ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Get<T>()
|
||||||
|
{
|
||||||
|
return (T)inner[ typeof( T ) ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<T> WithInterface<T>()
|
||||||
|
{
|
||||||
|
foreach( var i in inner )
|
||||||
|
if( i.Value is T )
|
||||||
|
yield return (T)i.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
468
OpenRa.Game/Actor.cs
Normal file → Executable file
468
OpenRa.Game/Actor.cs
Normal file → Executable file
@@ -1,26 +1,442 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.IO;
|
||||||
using System.Drawing;
|
using System.Linq;
|
||||||
using OpenRa.FileFormats;
|
using System.Text;
|
||||||
|
using IjwFramework.Types;
|
||||||
using System.Windows.Forms;
|
using OpenRa.FileFormats;
|
||||||
using OpenRa.Game.Graphics;
|
using OpenRa.Game.GameRules;
|
||||||
using IjwFramework.Types;
|
using OpenRa.Game.Graphics;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
abstract class Actor
|
class Actor
|
||||||
{
|
{
|
||||||
public readonly Game game;
|
public readonly TypeDictionary traits = new TypeDictionary();
|
||||||
|
public readonly UnitInfo.BaseInfo unitInfo;
|
||||||
public Player owner;
|
|
||||||
public abstract IEnumerable<Pair<Sprite,float2>> CurrentImages { get; }
|
public int2 Location;
|
||||||
public virtual void Tick(Game game, int t) { }
|
public Player Owner;
|
||||||
|
|
||||||
protected Actor(Game game)
|
public Actor( string name, int2 location, Player owner )
|
||||||
{
|
{
|
||||||
this.game = game;
|
unitInfo = Rules.UnitInfo.Get( name );
|
||||||
}
|
Location = location;
|
||||||
}
|
Owner = owner;
|
||||||
}
|
|
||||||
|
switch( name )
|
||||||
|
{
|
||||||
|
///// vehicles /////
|
||||||
|
case "mcv":
|
||||||
|
traits.Add( new Traits.Mobile( this ) );
|
||||||
|
traits.Add( new Traits.RenderUnit( this, name ) );
|
||||||
|
traits.Add( new Traits.McvDeploy( this ) );
|
||||||
|
break;
|
||||||
|
case "mnly":
|
||||||
|
case "apc":
|
||||||
|
case "v2rl":
|
||||||
|
case "arty":
|
||||||
|
traits.Add( new Traits.Mobile( this ) );
|
||||||
|
traits.Add( new Traits.RenderUnit( this, name ) );
|
||||||
|
break;
|
||||||
|
case "jeep":
|
||||||
|
case "1tnk":
|
||||||
|
case "2tnk":
|
||||||
|
case "3tnk":
|
||||||
|
case "4tnk":
|
||||||
|
case "mrj":
|
||||||
|
case "mgg":
|
||||||
|
traits.Add( new Traits.Mobile( this ) );
|
||||||
|
traits.Add( new Traits.Turreted( this ) );
|
||||||
|
traits.Add( new Traits.RenderUnitTurreted( this, name ) );
|
||||||
|
break;
|
||||||
|
case "harv":
|
||||||
|
traits.Add( new Traits.Mobile( this ) );
|
||||||
|
traits.Add( new Traits.RenderUnit( this, name ) );
|
||||||
|
break;
|
||||||
|
///// TODO: infantry /////
|
||||||
|
|
||||||
|
///// TODO: boats /////
|
||||||
|
|
||||||
|
///// TODO: planes /////
|
||||||
|
|
||||||
|
///// buildings /////
|
||||||
|
case "iron":
|
||||||
|
case "pdox":
|
||||||
|
case "mslo":
|
||||||
|
case "atek":
|
||||||
|
case "stek":
|
||||||
|
case "weap":
|
||||||
|
case "fact":
|
||||||
|
case "proc":
|
||||||
|
case "silo":
|
||||||
|
case "hpad":
|
||||||
|
case "afld":
|
||||||
|
case "dome":
|
||||||
|
case "powr":
|
||||||
|
case "apwr":
|
||||||
|
case "barr":
|
||||||
|
case "tent":
|
||||||
|
case "kenn":
|
||||||
|
case "fix":
|
||||||
|
//SYRD, SPEN
|
||||||
|
//GAP
|
||||||
|
//SBAG, BRIK, FENC
|
||||||
|
//FACF, WEAF, SYRF, SPEF, DOMF
|
||||||
|
case "pbox":
|
||||||
|
case "hbox":
|
||||||
|
case "tsla":
|
||||||
|
case "ftur":
|
||||||
|
traits.Add( new Traits.Building( this ) );
|
||||||
|
traits.Add( new Traits.RenderBuilding( this, name ) );
|
||||||
|
break;
|
||||||
|
case "gun":
|
||||||
|
case "agun":
|
||||||
|
case "sam":
|
||||||
|
traits.Add( new Traits.Building( this ) );
|
||||||
|
traits.Add( new Traits.Turreted( this ) );
|
||||||
|
traits.Add( new Traits.RenderBuildingTurreted( this, name ) );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException( "Actor traits for " + name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Actor( TreeReference tree, TreeCache treeRenderer, int2 mapOffset )
|
||||||
|
{
|
||||||
|
Location = new int2( tree.Location ) - mapOffset;
|
||||||
|
traits.Add( new Traits.Tree( treeRenderer.GetImage( tree.Image ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Tick( Game game, int dt )
|
||||||
|
{
|
||||||
|
foreach( var tick in traits.WithInterface<Traits.ITick>() )
|
||||||
|
tick.Tick( this, game, dt );
|
||||||
|
}
|
||||||
|
|
||||||
|
public float2 CenterLocation { get { return new float2( 12, 12 ) + 24 * (float2)Location; } }
|
||||||
|
public float2 SelectedSize { get { return Render().FirstOrDefault().First.size; } }
|
||||||
|
|
||||||
|
public IEnumerable<Pair<Sprite, float2>> Render()
|
||||||
|
{
|
||||||
|
return traits.WithInterface<Traits.IRender>().SelectMany( x => x.Render( this ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Order Order( Game game, int2 xy )
|
||||||
|
{
|
||||||
|
return traits.WithInterface<Traits.IOrder>()
|
||||||
|
.Select( x => x.Order( this, game, xy ) )
|
||||||
|
.Where( x => x != null )
|
||||||
|
.FirstOrDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Traits
|
||||||
|
{
|
||||||
|
interface ITick
|
||||||
|
{
|
||||||
|
void Tick( Actor self, Game game, int dt );
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IRender
|
||||||
|
{
|
||||||
|
IEnumerable<Pair<Sprite, float2>> Render( Actor self );
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IOrder
|
||||||
|
{
|
||||||
|
Order Order( Actor self, Game game, int2 xy );
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class RenderSimple : IRender, ITick
|
||||||
|
{
|
||||||
|
public Animation anim;
|
||||||
|
|
||||||
|
public RenderSimple( Actor self, string unitName )
|
||||||
|
{
|
||||||
|
anim = new Animation( unitName );
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract IEnumerable<Pair<Sprite, float2>> Render( Actor self );
|
||||||
|
|
||||||
|
public virtual void Tick( Actor self, Game game, int dt )
|
||||||
|
{
|
||||||
|
anim.Tick( dt );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderBuilding : RenderSimple
|
||||||
|
{
|
||||||
|
public RenderBuilding( Actor self, string unitName )
|
||||||
|
: base( self, unitName )
|
||||||
|
{
|
||||||
|
anim.PlayThen( "make", () => anim.Play( "idle" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<Pair<Sprite, float2>> Render( Actor self )
|
||||||
|
{
|
||||||
|
yield return Pair.New( anim.Image, 24f * (float2)self.Location );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderBuildingTurreted : RenderBuilding
|
||||||
|
{
|
||||||
|
public RenderBuildingTurreted( Actor self, string unitName )
|
||||||
|
: base( self, unitName )
|
||||||
|
{
|
||||||
|
anim.PlayThen( "make", () => anim.PlayFetchIndex( "idle", () => self.traits.Get<Turreted>().turretFacing ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderUnit : RenderSimple
|
||||||
|
{
|
||||||
|
public RenderUnit( Actor self, string unitName )
|
||||||
|
:base( self, unitName )
|
||||||
|
{
|
||||||
|
anim.PlayFetchIndex( "idle", () => self.traits.Get<Mobile>().facing );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Pair<Sprite, float2> Centered( Sprite s, float2 location )
|
||||||
|
{
|
||||||
|
var loc = location - 0.5f * s.size;
|
||||||
|
return Pair.New( s, loc.Round() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<Pair<Sprite, float2>> Render( Actor self )
|
||||||
|
{
|
||||||
|
var mobile = self.traits.Get<Mobile>();
|
||||||
|
float fraction = ( mobile.moveFraction > 0 ) ? (float)mobile.moveFraction / mobile.moveFractionTotal : 0f;
|
||||||
|
var centerLocation = new float2( 12, 12 ) + 24 * float2.Lerp( mobile.fromCell, mobile.toCell, fraction );
|
||||||
|
yield return Centered( anim.Image, centerLocation );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderUnitTurreted : RenderUnit
|
||||||
|
{
|
||||||
|
public Animation turretAnim;
|
||||||
|
|
||||||
|
public RenderUnitTurreted( Actor self, string unitName )
|
||||||
|
: base( self, unitName )
|
||||||
|
{
|
||||||
|
turretAnim = new Animation( unitName );
|
||||||
|
turretAnim.PlayFetchIndex( "turret", () => self.traits.Get<Turreted>().turretFacing );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<Pair<Sprite, float2>> Render( Actor self )
|
||||||
|
{
|
||||||
|
var mobile = self.traits.Get<Mobile>();
|
||||||
|
float fraction = ( mobile.moveFraction > 0 ) ? (float)mobile.moveFraction / mobile.moveFractionTotal : 0f;
|
||||||
|
var centerLocation = new float2( 12, 12 ) + 24 * float2.Lerp( mobile.fromCell, mobile.toCell, fraction );
|
||||||
|
yield return Centered( anim.Image, centerLocation );
|
||||||
|
yield return Centered( turretAnim.Image, centerLocation );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Tick( Actor self, Game game, int dt )
|
||||||
|
{
|
||||||
|
base.Tick( self, game, dt );
|
||||||
|
turretAnim.Tick( dt );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Mobile : ITick, IOrder
|
||||||
|
{
|
||||||
|
public Actor self;
|
||||||
|
|
||||||
|
public int2 fromCell, destination;
|
||||||
|
public int2 toCell { get { return self.Location; } }
|
||||||
|
public int moveFraction, moveFractionTotal;
|
||||||
|
public int facing;
|
||||||
|
|
||||||
|
public Mobile( Actor self )
|
||||||
|
{
|
||||||
|
this.self = self;
|
||||||
|
fromCell = destination = self.Location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Turn( int desiredFacing )
|
||||||
|
{
|
||||||
|
if( facing == desiredFacing )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int df = ( desiredFacing - facing + 32 ) % 32;
|
||||||
|
facing = ( facing + ( df > 16 ? 31 : 1 ) ) % 32;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float2[] fvecs = Util.MakeArray<float2>( 32,
|
||||||
|
i => -float2.FromAngle( i / 16.0f * (float)Math.PI ) * new float2( 1f, 1.3f ) );
|
||||||
|
|
||||||
|
int GetFacing( float2 d )
|
||||||
|
{
|
||||||
|
if( float2.WithinEpsilon( d, float2.Zero, 0.001f ) )
|
||||||
|
return facing;
|
||||||
|
|
||||||
|
int highest = -1;
|
||||||
|
float highestDot = -1.0f;
|
||||||
|
|
||||||
|
for( int i = 0 ; i < fvecs.Length ; i++ )
|
||||||
|
{
|
||||||
|
float dot = float2.Dot( fvecs[ i ], d );
|
||||||
|
if( dot > highestDot )
|
||||||
|
{
|
||||||
|
highestDot = dot;
|
||||||
|
highest = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return highest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Tick( Actor self, Game game, int dt )
|
||||||
|
{
|
||||||
|
if( fromCell != toCell )
|
||||||
|
{
|
||||||
|
if( Turn( GetFacing( toCell - fromCell ) ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
moveFraction += dt * ( (UnitInfo.MobileInfo)self.unitInfo ).Speed;
|
||||||
|
}
|
||||||
|
if( moveFraction < moveFractionTotal )
|
||||||
|
return;
|
||||||
|
|
||||||
|
moveFraction = 0;
|
||||||
|
moveFractionTotal = 0;
|
||||||
|
fromCell = toCell;
|
||||||
|
|
||||||
|
if( destination == toCell )
|
||||||
|
return;
|
||||||
|
|
||||||
|
List<int2> res = game.pathFinder.FindUnitPath( toCell, PathFinder.DefaultEstimator( destination ) );
|
||||||
|
if( res.Count != 0 )
|
||||||
|
{
|
||||||
|
self.Location = res[ res.Count - 1 ];
|
||||||
|
|
||||||
|
int2 dir = toCell - fromCell;
|
||||||
|
moveFractionTotal = ( dir.X != 0 && dir.Y != 0 ) ? 2500 : 2000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
destination = toCell;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Order Order( Actor self, Game game, int2 xy )
|
||||||
|
{
|
||||||
|
if( xy != toCell )
|
||||||
|
return new MoveOrder( self, xy );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class McvDeploy : IOrder, ITick
|
||||||
|
{
|
||||||
|
public bool Deploying;
|
||||||
|
|
||||||
|
public McvDeploy( Actor self )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Order Order( Actor self, Game game, int2 xy )
|
||||||
|
{
|
||||||
|
// TODO: check that there's enough space at the destination.
|
||||||
|
if( xy == self.Location )
|
||||||
|
return new DeployMcvOrder( self );
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Tick( Actor self, Game game, int dt )
|
||||||
|
{
|
||||||
|
if( !Deploying )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( self.traits.Get<Mobile>().Turn( 12 ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
game.world.AddFrameEndTask( _ =>
|
||||||
|
{
|
||||||
|
game.world.Remove( self );
|
||||||
|
game.world.Add( new Actor( "fact", self.Location - new int2( 1, 1 ), self.Owner ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Turreted
|
||||||
|
: ITick // temporary.
|
||||||
|
{
|
||||||
|
public int turretFacing = 24;
|
||||||
|
|
||||||
|
public Turreted( Actor self )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// temporary.
|
||||||
|
public void Tick( Actor self, Game game, int dt )
|
||||||
|
{
|
||||||
|
turretFacing = ( turretFacing + 1 ) % 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Building : ITick
|
||||||
|
{
|
||||||
|
public Building( Actor self )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
public void Tick( Actor self, Game game, int dt )
|
||||||
|
{
|
||||||
|
if( first && self.Owner == game.LocalPlayer )
|
||||||
|
self.Owner.TechTree.Build( self.unitInfo.Name, true );
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Tree : IRender
|
||||||
|
{
|
||||||
|
Sprite Image;
|
||||||
|
|
||||||
|
public Tree( Sprite treeImage )
|
||||||
|
{
|
||||||
|
Image = treeImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Pair<Sprite, float2>> Render( Actor self )
|
||||||
|
{
|
||||||
|
yield return Pair.New( Image, 24 * (float2)self.Location );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//class WarFactory : Building
|
||||||
|
//{
|
||||||
|
// Animation roof;
|
||||||
|
|
||||||
|
// public WarFactory( int2 location, Player owner, Game game )
|
||||||
|
// : base( "weap", location, owner, game )
|
||||||
|
// {
|
||||||
|
|
||||||
|
// animation.PlayThen( "make", () =>
|
||||||
|
// {
|
||||||
|
// roof = new Animation( "weap" );
|
||||||
|
// animation.PlayRepeating( "idle" );
|
||||||
|
// roof.PlayRepeating( "idle-top" );
|
||||||
|
// } );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override IEnumerable<Pair<Sprite, float2>> CurrentImages
|
||||||
|
// {
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// return ( roof == null )
|
||||||
|
// ? base.CurrentImages
|
||||||
|
// : ( base.CurrentImages.Concat(
|
||||||
|
// new[] { Pair.New( roof.Image, 24 * (float2)location ) } ) );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override void Tick( Game game, int t )
|
||||||
|
// {
|
||||||
|
// base.Tick( game, t );
|
||||||
|
// if( roof != null ) roof.Tick( t );
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace OpenRa.Game
|
|
||||||
{
|
|
||||||
class Building : PlayerOwned
|
|
||||||
{
|
|
||||||
public Building( string name, int2 location, Player owner, Game game )
|
|
||||||
: base( game, name, location )
|
|
||||||
{
|
|
||||||
this.owner = owner;
|
|
||||||
|
|
||||||
animation.PlayThen( "make", () => animation.PlayRepeating( "idle" ) );
|
|
||||||
owner.TechTree.Build( name, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Tick( Game game, int t )
|
|
||||||
{
|
|
||||||
animation.Tick( t );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,90 +1,97 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using IjwFramework.Types;
|
using IjwFramework.Types;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
class Controller
|
class Controller
|
||||||
{
|
{
|
||||||
Game game;
|
Game game;
|
||||||
|
|
||||||
public IOrderGenerator orderGenerator;
|
public IOrderGenerator orderGenerator;
|
||||||
|
|
||||||
public Controller(Game game)
|
public Controller(Game game)
|
||||||
{
|
{
|
||||||
this.game = game;
|
this.game = game;
|
||||||
}
|
}
|
||||||
|
|
||||||
float2 GetWorldPos(MouseInput mi)
|
float2 GetWorldPos(MouseInput mi)
|
||||||
{
|
{
|
||||||
return (1 / 24.0f) * (new float2(mi.Location.X, mi.Location.Y) + game.viewport.Location);
|
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 = GetWorldPos(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))
|
||||||
dragStart = dragEnd = xy;
|
dragStart = dragEnd = xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Move)
|
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Move)
|
||||||
if (dragEnd != null)
|
if (dragEnd != null)
|
||||||
dragEnd = GetWorldPos(mi);
|
dragEnd = GetWorldPos(mi);
|
||||||
|
|
||||||
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.HasValue && !(dragStart.Value == GetWorldPos(mi)))
|
if (dragStart.HasValue && !(dragStart.Value == GetWorldPos(mi)))
|
||||||
orderGenerator = FindUnit(dragStart.Value, xy); /* band-box select */
|
orderGenerator = new UnitOrderGenerator( FindUnits( game, 24 * dragStart.Value, 24 * xy ) ); /* band-box select */
|
||||||
else
|
else
|
||||||
orderGenerator = FindUnit(xy, xy); /* click select */
|
orderGenerator = new UnitOrderGenerator( FindUnits( game, 24 * xy, 24 * xy ) ); /* click select */
|
||||||
}
|
}
|
||||||
|
|
||||||
dragStart = dragEnd = null;
|
dragStart = dragEnd = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mi.Button == MouseButtons.None && mi.Event == MouseInputEvent.Move)
|
if (mi.Button == MouseButtons.None && mi.Event == MouseInputEvent.Move)
|
||||||
{
|
{
|
||||||
/* update the cursor to reflect the thing under us - note this
|
/* update the cursor to reflect the thing under us - note this
|
||||||
* needs to also happen when the *thing* changes, so per-frame hook */
|
* needs to also happen when the *thing* changes, so per-frame hook */
|
||||||
}
|
}
|
||||||
|
|
||||||
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, new int2( (int)xy.X, (int)xy.Y ) ) )
|
||||||
order.Apply( game );
|
order.Apply( game );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Unit FindUnit(float2 a, float2 b)
|
public Actor FindUnit(float2 a, float2 b)
|
||||||
{
|
{
|
||||||
return FindUnits(game, 24 * a, 24 * b).FirstOrDefault();
|
return FindUnits(game, 24 * a, 24 * b).FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<Unit> FindUnits(Game game, float2 a, float2 b)
|
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 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 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);
|
var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y);
|
||||||
|
|
||||||
return game.world.Actors.OfType<Unit>()
|
return game.world.Actors
|
||||||
.Where(x => (x.owner == game.LocalPlayer) && (x.Bounds.IntersectsWith(rect)));
|
.Where(x => (x.Owner == game.LocalPlayer) && (UnitBounds(x).IntersectsWith(rect)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<float2, float2>? SelectionBox()
|
public static RectangleF UnitBounds( Actor actor )
|
||||||
{
|
{
|
||||||
if (dragStart == null || dragEnd == null)
|
var size = actor.SelectedSize;
|
||||||
return null;
|
var loc = actor.CenterLocation - 0.5f * size;
|
||||||
|
return new System.Drawing.RectangleF( loc.X, loc.Y, size.X, size.Y );
|
||||||
return Pair.New(24 * dragStart.Value, 24 * dragEnd.Value);
|
}
|
||||||
}
|
|
||||||
}
|
public Pair<float2, float2>? SelectionBox()
|
||||||
}
|
{
|
||||||
|
if (dragStart == null || dragEnd == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return Pair.New(24 * dragStart.Value, 24 * dragEnd.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,75 +1,63 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using OpenRa.FileFormats;
|
using OpenRa.FileFormats;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using OpenRa.Game.Graphics;
|
using OpenRa.Game.Graphics;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
public readonly World world;
|
public readonly World world;
|
||||||
public readonly Map map;
|
public readonly Map map;
|
||||||
public readonly TreeCache treeCache;
|
public readonly TreeCache treeCache;
|
||||||
public readonly TerrainRenderer terrain;
|
public readonly TerrainRenderer terrain;
|
||||||
public readonly Viewport viewport;
|
public readonly Viewport viewport;
|
||||||
public readonly PathFinder pathFinder;
|
public readonly PathFinder pathFinder;
|
||||||
public readonly Network network;
|
public readonly Network network;
|
||||||
public readonly WorldRenderer worldRenderer;
|
public readonly WorldRenderer worldRenderer;
|
||||||
public readonly Controller controller;
|
public readonly Controller controller;
|
||||||
|
|
||||||
int localPlayerIndex = 2;
|
int localPlayerIndex = 2;
|
||||||
|
|
||||||
public readonly Dictionary<int, Player> players = new Dictionary<int, Player>();
|
public readonly Dictionary<int, Player> players = new Dictionary<int, Player>();
|
||||||
|
|
||||||
// temporary, until we remove all the subclasses of Building
|
public Player LocalPlayer { get { return players[localPlayerIndex]; } }
|
||||||
public Dictionary<string, Func<int2, Player, PlayerOwned>> buildingCreation;
|
|
||||||
|
public Game(string mapName, Renderer renderer, int2 clientSize)
|
||||||
public Player LocalPlayer { get { return players[localPlayerIndex]; } }
|
{
|
||||||
|
Rules.LoadRules();
|
||||||
public Game(string mapName, Renderer renderer, int2 clientSize)
|
|
||||||
{
|
for( int i = 0 ; i < 8 ; i++ )
|
||||||
Rules.LoadRules();
|
players.Add(i, new Player(i, string.Format("Multi{0}", i), OpenRa.TechTree.Race.Soviet));
|
||||||
|
|
||||||
for( int i = 0 ; i < 8 ; i++ )
|
map = new Map(new IniFile(FileSystem.Open(mapName)));
|
||||||
players.Add(i, new Player(i, string.Format("Multi{0}", i), OpenRa.TechTree.Race.Soviet));
|
FileSystem.Mount(new Package(map.Theater + ".mix"));
|
||||||
|
|
||||||
map = new Map(new IniFile(FileSystem.Open(mapName)));
|
viewport = new Viewport(clientSize, map.Size, renderer);
|
||||||
FileSystem.Mount(new Package(map.Theater + ".mix"));
|
|
||||||
|
terrain = new TerrainRenderer(renderer, map, viewport);
|
||||||
viewport = new Viewport(clientSize, map.Size, renderer);
|
world = new World(this);
|
||||||
|
treeCache = new TreeCache(map);
|
||||||
terrain = new TerrainRenderer(renderer, map, viewport);
|
|
||||||
world = new World(this);
|
foreach( TreeReference treeReference in map.Trees )
|
||||||
treeCache = new TreeCache(map);
|
world.Add( new Actor( treeReference, treeCache, map.Offset ) );
|
||||||
|
|
||||||
foreach (TreeReference treeReference in map.Trees)
|
pathFinder = new PathFinder(map, terrain.tileSet);
|
||||||
world.Add(new Tree(treeReference, treeCache, map, this));
|
|
||||||
|
network = new Network();
|
||||||
pathFinder = new PathFinder(map, terrain.tileSet);
|
|
||||||
|
controller = new Controller(this); // CAREFUL THERES AN UGLY HIDDEN DEPENDENCY HERE STILL
|
||||||
network = new Network();
|
worldRenderer = new WorldRenderer(renderer, world);
|
||||||
|
}
|
||||||
var buildings = new[] { "fact", "powr", "apwr", "barr", "atek", "stek", "dome" };
|
|
||||||
buildingCreation = buildings.ToDictionary(s => s,
|
public void Tick()
|
||||||
s => (Func<int2, Player, PlayerOwned>)(
|
{
|
||||||
(l, o) => new Building(s, l, o, this)));
|
var stuffFromOtherPlayers = network.Tick(); // todo: actually use the orders!
|
||||||
|
world.Update();
|
||||||
buildingCreation.Add("proc", (location, owner) => new Refinery(location, owner, this));
|
|
||||||
buildingCreation.Add("weap", (location, owner) => new WarFactory(location, owner, this));
|
viewport.DrawRegions();
|
||||||
buildingCreation.Add("3tnk", (location, owner) => new TurretedUnit("3tnk", location, owner, this));
|
}
|
||||||
|
}
|
||||||
controller = new Controller(this); // CAREFUL THERES AN UGLY HIDDEN DEPENDENCY HERE STILL
|
}
|
||||||
worldRenderer = new WorldRenderer(renderer, world);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Tick()
|
|
||||||
{
|
|
||||||
var stuffFromOtherPlayers = network.Tick(); // todo: actually use the orders!
|
|
||||||
world.Update();
|
|
||||||
|
|
||||||
viewport.DrawRegions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,101 +1,101 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace OpenRa.Game.Graphics
|
namespace OpenRa.Game.Graphics
|
||||||
{
|
{
|
||||||
class WorldRenderer
|
class WorldRenderer
|
||||||
{
|
{
|
||||||
public readonly SpriteRenderer spriteRenderer;
|
public readonly SpriteRenderer spriteRenderer;
|
||||||
public readonly LineRenderer lineRenderer;
|
public readonly LineRenderer lineRenderer;
|
||||||
public readonly World world;
|
public readonly World world;
|
||||||
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, World world)
|
||||||
{
|
{
|
||||||
// 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(world.game.viewport, DockStyle.Left,
|
||||||
world.game.viewport.Width - 128, Draw,
|
world.game.viewport.Width - 128, Draw,
|
||||||
world.game.controller.HandleMouseInput);
|
world.game.controller.HandleMouseInput);
|
||||||
|
|
||||||
world.game.viewport.AddRegion(region);
|
world.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, world.game);
|
||||||
this.world = world;
|
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 + world.game.viewport.Location).ToPointF(),
|
||||||
region.Size.ToSizeF());
|
region.Size.ToSizeF());
|
||||||
|
|
||||||
foreach (Actor a in world.Actors)
|
foreach (Actor a in world.Actors)
|
||||||
{
|
{
|
||||||
var images = a.CurrentImages;
|
var images = a.Render();
|
||||||
|
|
||||||
foreach( var image in images )
|
foreach( var image in images )
|
||||||
{
|
{
|
||||||
var loc = image.Second;
|
var loc = image.Second;
|
||||||
|
|
||||||
if( loc.X > rect.Right || loc.X < rect.Left - image.First.bounds.Width )
|
if( loc.X > rect.Right || loc.X < rect.Left - image.First.bounds.Width )
|
||||||
continue;
|
continue;
|
||||||
if( loc.Y > rect.Bottom || loc.Y < rect.Top - image.First.bounds.Height )
|
if( loc.Y > rect.Bottom || loc.Y < rect.Top - image.First.bounds.Height )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
spriteRenderer.DrawSprite( image.First, loc, ( a.owner != null ) ? a.owner.Palette : 0 );
|
spriteRenderer.DrawSprite( image.First, loc, ( a.Owner != null ) ? a.Owner.Palette : 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uiOverlay.Draw();
|
uiOverlay.Draw();
|
||||||
|
|
||||||
spriteRenderer.Flush();
|
spriteRenderer.Flush();
|
||||||
|
|
||||||
var selbox = world.game.controller.SelectionBox();
|
var selbox = world.game.controller.SelectionBox();
|
||||||
if (selbox != null)
|
if (selbox != null)
|
||||||
{
|
{
|
||||||
var a = selbox.Value.First;
|
var a = selbox.Value.First;
|
||||||
var b = new float2(selbox.Value.Second.X - a.X, 0);
|
var b = new float2(selbox.Value.Second.X - a.X, 0);
|
||||||
var c = new float2(0, selbox.Value.Second.Y - a.Y);
|
var c = new float2(0, selbox.Value.Second.Y - a.Y);
|
||||||
|
|
||||||
lineRenderer.DrawLine(a, a + b, Color.White, Color.White);
|
lineRenderer.DrawLine(a, a + b, Color.White, Color.White);
|
||||||
lineRenderer.DrawLine(a + b, a + b + c, Color.White, Color.White);
|
lineRenderer.DrawLine(a + b, a + b + c, Color.White, Color.White);
|
||||||
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 Controller.FindUnits(world.game, selbox.Value.First, selbox.Value.Second))
|
||||||
DrawSelectionBox(u, Color.Yellow);
|
DrawSelectionBox(u, Color.Yellow);
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedUnit = world.game.controller.orderGenerator as Unit;
|
var selectedUnit = world.game.controller.orderGenerator as Actor;
|
||||||
if (selectedUnit != null)
|
if (selectedUnit != null)
|
||||||
DrawSelectionBox(selectedUnit, Color.White);
|
DrawSelectionBox(selectedUnit, Color.White);
|
||||||
|
|
||||||
|
|
||||||
lineRenderer.Flush();
|
lineRenderer.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawSelectionBox(Unit selectedUnit, Color c)
|
void DrawSelectionBox(Actor selectedUnit, Color c)
|
||||||
{
|
{
|
||||||
var center = selectedUnit.CenterLocation;
|
var center = selectedUnit.CenterLocation;
|
||||||
var size = selectedUnit.SelectedSize;
|
var size = selectedUnit.SelectedSize;
|
||||||
|
|
||||||
var xy = center - 0.5f * size;
|
var xy = center - 0.5f * size;
|
||||||
var XY = center + 0.5f * size;
|
var XY = center + 0.5f * size;
|
||||||
var Xy = new float2(XY.X, xy.Y);
|
var Xy = new float2(XY.X, xy.Y);
|
||||||
var xY = new float2(xy.X, XY.Y);
|
var xY = new float2(xy.X, XY.Y);
|
||||||
|
|
||||||
lineRenderer.DrawLine(xy, xy + new float2(4, 0), c, c);
|
lineRenderer.DrawLine(xy, xy + new float2(4, 0), c, c);
|
||||||
lineRenderer.DrawLine(xy, xy + new float2(0, 4), c, c);
|
lineRenderer.DrawLine(xy, xy + new float2(0, 4), c, c);
|
||||||
lineRenderer.DrawLine(Xy, Xy + new float2(-4, 0), c, c);
|
lineRenderer.DrawLine(Xy, Xy + new float2(-4, 0), c, c);
|
||||||
lineRenderer.DrawLine(Xy, Xy + new float2(0, 4), c, c);
|
lineRenderer.DrawLine(Xy, Xy + new float2(0, 4), c, c);
|
||||||
|
|
||||||
lineRenderer.DrawLine(xY, xY + new float2(4, 0), c, c);
|
lineRenderer.DrawLine(xY, xY + new float2(4, 0), c, c);
|
||||||
lineRenderer.DrawLine(xY, xY + new float2(0, -4), c, c);
|
lineRenderer.DrawLine(xY, xY + new float2(0, -4), c, c);
|
||||||
lineRenderer.DrawLine(XY, XY + new float2(-4, 0), c, c);
|
lineRenderer.DrawLine(XY, XY + new float2(-4, 0), c, c);
|
||||||
lineRenderer.DrawLine(XY, XY + new float2(0, -4), c, c);
|
lineRenderer.DrawLine(XY, XY + new float2(0, -4), c, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,125 +1,125 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using OpenRa.FileFormats;
|
using OpenRa.FileFormats;
|
||||||
using OpenRa.Game.Graphics;
|
using OpenRa.Game.Graphics;
|
||||||
using OpenRa.TechTree;
|
using OpenRa.TechTree;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
using GRegion = OpenRa.Game.Graphics.Region;
|
using GRegion = OpenRa.Game.Graphics.Region;
|
||||||
|
|
||||||
class MainWindow : Form
|
class MainWindow : Form
|
||||||
{
|
{
|
||||||
readonly Renderer renderer;
|
readonly Renderer renderer;
|
||||||
|
|
||||||
Game game;
|
Game game;
|
||||||
public readonly Sidebar sidebar;
|
public readonly Sidebar sidebar;
|
||||||
|
|
||||||
static Size GetResolution(Settings settings)
|
static Size GetResolution(Settings settings)
|
||||||
{
|
{
|
||||||
Size desktopResolution = Screen.PrimaryScreen.Bounds.Size;
|
Size desktopResolution = Screen.PrimaryScreen.Bounds.Size;
|
||||||
|
|
||||||
return new Size(settings.GetValue("width", desktopResolution.Width),
|
return new Size(settings.GetValue("width", desktopResolution.Width),
|
||||||
settings.GetValue("height", desktopResolution.Height));
|
settings.GetValue("height", desktopResolution.Height));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MainWindow(Settings settings)
|
public MainWindow(Settings settings)
|
||||||
{
|
{
|
||||||
FileSystem.Mount(new Folder("../../../../"));
|
FileSystem.Mount(new Folder("../../../../"));
|
||||||
FileSystem.Mount(new Package("redalert.mix"));
|
FileSystem.Mount(new Package("redalert.mix"));
|
||||||
FileSystem.Mount(new Package("conquer.mix"));
|
FileSystem.Mount(new Package("conquer.mix"));
|
||||||
FileSystem.Mount(new Package("hires.mix"));
|
FileSystem.Mount(new Package("hires.mix"));
|
||||||
|
|
||||||
FormBorderStyle = FormBorderStyle.None;
|
FormBorderStyle = FormBorderStyle.None;
|
||||||
BackColor = Color.Black;
|
BackColor = Color.Black;
|
||||||
StartPosition = FormStartPosition.Manual;
|
StartPosition = FormStartPosition.Manual;
|
||||||
Location = Point.Empty;
|
Location = Point.Empty;
|
||||||
Visible = true;
|
Visible = true;
|
||||||
|
|
||||||
bool windowed = !settings.GetValue("fullscreen", false);
|
bool windowed = !settings.GetValue("fullscreen", false);
|
||||||
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 = new Game(settings.GetValue("map", "scg11eb.ini"), renderer, new int2(ClientSize));
|
||||||
|
|
||||||
SequenceProvider.ForcePrecache();
|
SequenceProvider.ForcePrecache();
|
||||||
|
|
||||||
game.world.Add(new Unit("mcv", new int2(5, 5), game.players[3], game));
|
game.world.Add( new Actor( "mcv", new int2( 5, 5 ), game.players[ 3 ]) );
|
||||||
game.world.Add(new Unit("mcv", new int2(7, 5), game.players[2], game));
|
game.world.Add( new Actor( "mcv", new int2( 7, 5 ), game.players[ 2 ] ) );
|
||||||
game.world.Add(new Unit("mcv", new int2(9, 5), game.players[1], game));
|
game.world.Add( new Actor( "mcv", new int2( 9, 5 ), game.players[ 1 ] ) );
|
||||||
game.world.Add(new TurretedUnit("jeep", new int2(9, 7), game.players[1], game));
|
game.world.Add( new Actor( "jeep", new int2( 9, 7 ), game.players[ 1 ] ) );
|
||||||
|
|
||||||
sidebar = new Sidebar(Race.Soviet, renderer, game);
|
sidebar = new Sidebar(Race.Soviet, renderer, game);
|
||||||
|
|
||||||
renderer.SetPalette(new HardwarePalette(renderer, game.map));
|
renderer.SetPalette(new HardwarePalette(renderer, game.map));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Run()
|
internal void Run()
|
||||||
{
|
{
|
||||||
while (Created && Visible)
|
while (Created && Visible)
|
||||||
{
|
{
|
||||||
game.Tick();
|
game.Tick();
|
||||||
Application.DoEvents();
|
Application.DoEvents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int2 lastPos;
|
int2 lastPos;
|
||||||
|
|
||||||
protected override void OnMouseDown(MouseEventArgs e)
|
protected override void OnMouseDown(MouseEventArgs e)
|
||||||
{
|
{
|
||||||
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,
|
||||||
Location = new int2(e.Location)
|
Location = new int2(e.Location)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnMouseMove(MouseEventArgs e)
|
protected override void OnMouseMove(MouseEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnMouseMove(e);
|
base.OnMouseMove(e);
|
||||||
|
|
||||||
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(game,
|
||||||
new int2(e.Location.X / 24, e.Location.Y / 24));
|
new int2(e.Location.X / 24, e.Location.Y / 24));
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
Location = new int2(e.Location)
|
Location = new int2(e.Location)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MouseInput
|
struct MouseInput
|
||||||
{
|
{
|
||||||
public MouseInputEvent Event;
|
public MouseInputEvent Event;
|
||||||
public int2 Location;
|
public int2 Location;
|
||||||
public MouseButtons Button;
|
public MouseButtons Button;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MouseInputEvent { Down, Move, Up };
|
enum MouseInputEvent { Down, Move, Up };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +1,60 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
abstract class Order
|
abstract class Order
|
||||||
{
|
{
|
||||||
public abstract void Apply( Game game );
|
public abstract void Apply( Game game );
|
||||||
}
|
}
|
||||||
|
|
||||||
class MoveOrder : Order
|
class MoveOrder : Order
|
||||||
{
|
{
|
||||||
public readonly Unit Unit;
|
public readonly Actor Unit;
|
||||||
public readonly int2 Destination;
|
public readonly int2 Destination;
|
||||||
|
|
||||||
public MoveOrder(Unit unit, int2 destination)
|
public MoveOrder( Actor unit, int2 destination )
|
||||||
{
|
{
|
||||||
this.Unit = unit;
|
this.Unit = unit;
|
||||||
this.Destination = destination;
|
this.Destination = destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Apply( Game game )
|
public override void Apply( Game game )
|
||||||
{
|
{
|
||||||
Unit.nextOrder = UnitMissions.Move( Unit, Destination );
|
Unit.traits.Get<Traits.Mobile>().destination = Destination;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeployMcvOrder : Order
|
class DeployMcvOrder : Order
|
||||||
{
|
{
|
||||||
Unit unit;
|
Actor Unit;
|
||||||
|
|
||||||
public DeployMcvOrder( Unit unit )
|
public DeployMcvOrder( Actor unit )
|
||||||
{
|
{
|
||||||
this.unit = unit;
|
Unit = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Apply( Game game )
|
public override void Apply( Game game )
|
||||||
{
|
{
|
||||||
unit.nextOrder = UnitMissions.Deploy( unit );
|
Unit.traits.Get<Traits.McvDeploy>().Deploying = true;
|
||||||
}
|
var mobile = Unit.traits.Get<Traits.Mobile>();
|
||||||
}
|
mobile.destination = mobile.toCell;
|
||||||
|
}
|
||||||
class HarvestOrder : Order
|
}
|
||||||
{
|
|
||||||
Unit unit;
|
//class HarvestOrder : Order
|
||||||
|
//{
|
||||||
public HarvestOrder( Unit unit )
|
// Unit unit;
|
||||||
{
|
|
||||||
this.unit = unit;
|
// public HarvestOrder( Unit unit )
|
||||||
}
|
// {
|
||||||
|
// this.unit = unit;
|
||||||
public override void Apply( Game game )
|
// }
|
||||||
{
|
|
||||||
unit.nextOrder = UnitMissions.Harvest( unit );
|
// public override void Apply( Game game )
|
||||||
}
|
// {
|
||||||
}
|
// unit.nextOrder = UnitMissions.Harvest( unit );
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|||||||
@@ -75,7 +75,6 @@
|
|||||||
<Compile Include="GameRules\Rules.cs" />
|
<Compile Include="GameRules\Rules.cs" />
|
||||||
<Compile Include="GameRules\UnitInfo.cs" />
|
<Compile Include="GameRules\UnitInfo.cs" />
|
||||||
<Compile Include="Graphics\Animation.cs" />
|
<Compile Include="Graphics\Animation.cs" />
|
||||||
<Compile Include="Building.cs" />
|
|
||||||
<Compile Include="Game.cs" />
|
<Compile Include="Game.cs" />
|
||||||
<Compile Include="Graphics\LineRenderer.cs" />
|
<Compile Include="Graphics\LineRenderer.cs" />
|
||||||
<Compile Include="Graphics\WorldRenderer.cs" />
|
<Compile Include="Graphics\WorldRenderer.cs" />
|
||||||
@@ -83,7 +82,6 @@
|
|||||||
<Compile Include="TechTree\Item.cs" />
|
<Compile Include="TechTree\Item.cs" />
|
||||||
<Compile Include="Network\Packet.cs" />
|
<Compile Include="Network\Packet.cs" />
|
||||||
<Compile Include="Player.cs" />
|
<Compile Include="Player.cs" />
|
||||||
<Compile Include="PlayerOwned.cs" />
|
|
||||||
<Compile Include="Race.cs" />
|
<Compile Include="Race.cs" />
|
||||||
<Compile Include="Support\SharedResources.cs" />
|
<Compile Include="Support\SharedResources.cs" />
|
||||||
<Compile Include="Graphics\Sheet.cs" />
|
<Compile Include="Graphics\Sheet.cs" />
|
||||||
@@ -101,7 +99,6 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Support\Program.cs" />
|
<Compile Include="Support\Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Refinery.cs" />
|
|
||||||
<Compile Include="Graphics\Renderer.cs" />
|
<Compile Include="Graphics\Renderer.cs" />
|
||||||
<Compile Include="Support\Settings.cs" />
|
<Compile Include="Support\Settings.cs" />
|
||||||
<Compile Include="Sidebar.cs" />
|
<Compile Include="Sidebar.cs" />
|
||||||
@@ -112,15 +109,14 @@
|
|||||||
<Compile Include="TechTree\TechTree.cs" />
|
<Compile Include="TechTree\TechTree.cs" />
|
||||||
<Compile Include="TerrainCosts.cs" />
|
<Compile Include="TerrainCosts.cs" />
|
||||||
<Compile Include="Graphics\TerrainRenderer.cs" />
|
<Compile Include="Graphics\TerrainRenderer.cs" />
|
||||||
<Compile Include="Tree.cs" />
|
|
||||||
<Compile Include="Graphics\TreeCache.cs" />
|
<Compile Include="Graphics\TreeCache.cs" />
|
||||||
<Compile Include="UiOverlay.cs" />
|
<Compile Include="UiOverlay.cs" />
|
||||||
<Compile Include="Unit.cs" />
|
|
||||||
<Compile Include="UnitMissions.cs" />
|
<Compile Include="UnitMissions.cs" />
|
||||||
<Compile Include="Graphics\UnitSheetBuilder.cs" />
|
<Compile Include="Graphics\UnitSheetBuilder.cs" />
|
||||||
<Compile Include="Graphics\Util.cs" />
|
<Compile Include="Graphics\Util.cs" />
|
||||||
<Compile Include="Graphics\Vertex.cs" />
|
<Compile Include="Graphics\Vertex.cs" />
|
||||||
<Compile Include="Graphics\Viewport.cs" />
|
<Compile Include="Graphics\Viewport.cs" />
|
||||||
|
<Compile Include="UnitOrderGenerator.cs" />
|
||||||
<Compile Include="World.cs" />
|
<Compile Include="World.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using OpenRa.Game.Graphics;
|
|
||||||
using IjwFramework.Types;
|
|
||||||
|
|
||||||
namespace OpenRa.Game
|
|
||||||
{
|
|
||||||
abstract class PlayerOwned : Actor
|
|
||||||
{
|
|
||||||
public Animation animation;
|
|
||||||
protected int2 location;
|
|
||||||
|
|
||||||
public UnitMission currentOrder = null;
|
|
||||||
public UnitMission nextOrder = null;
|
|
||||||
|
|
||||||
protected PlayerOwned( Game game, string name, int2 location )
|
|
||||||
: base( game )
|
|
||||||
{
|
|
||||||
animation = new Animation( name );
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<Pair<Sprite, float2>> CurrentImages { get { yield return Pair.New( animation.Image, 24 * (float2)location ); } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
using OpenRa.Game.Graphics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using IjwFramework.Types;
|
|
||||||
|
|
||||||
namespace OpenRa.Game
|
|
||||||
{
|
|
||||||
class Refinery : Building
|
|
||||||
{
|
|
||||||
public Refinery( int2 location, Player owner, Game game )
|
|
||||||
: base( "proc", location, owner, game )
|
|
||||||
{
|
|
||||||
animation.PlayThen("make", () =>
|
|
||||||
{
|
|
||||||
animation.PlayRepeating("idle");
|
|
||||||
|
|
||||||
game.world.AddFrameEndTask( _ =>
|
|
||||||
{
|
|
||||||
Unit harvester = new Unit( "harv", location + new int2( 1, 2 ), owner, game );
|
|
||||||
harvester.facing = 8;
|
|
||||||
game.world.Add(harvester);
|
|
||||||
game.controller.orderGenerator = harvester;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WarFactory : Building
|
|
||||||
{
|
|
||||||
Animation roof;
|
|
||||||
|
|
||||||
public WarFactory(int2 location, Player owner, Game game)
|
|
||||||
: base("weap", location, owner, game)
|
|
||||||
{
|
|
||||||
|
|
||||||
animation.PlayThen("make", () =>
|
|
||||||
{
|
|
||||||
roof = new Animation("weap");
|
|
||||||
animation.PlayRepeating("idle");
|
|
||||||
roof.PlayRepeating("idle-top");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<Pair<Sprite,float2>> CurrentImages
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return (roof == null)
|
|
||||||
? base.CurrentImages
|
|
||||||
: (base.CurrentImages.Concat(
|
|
||||||
new[] { Pair.New(roof.Image, 24 * (float2)location) }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Tick(Game game, int t)
|
|
||||||
{
|
|
||||||
base.Tick(game, t);
|
|
||||||
if (roof != null) roof.Tick(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,225 +1,222 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
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.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
using GRegion = OpenRa.Game.Graphics.Region;
|
using GRegion = OpenRa.Game.Graphics.Region;
|
||||||
|
|
||||||
class Sidebar
|
class Sidebar
|
||||||
{
|
{
|
||||||
TechTree.TechTree techTree;
|
TechTree.TechTree techTree;
|
||||||
|
|
||||||
SpriteRenderer spriteRenderer, clockRenderer;
|
SpriteRenderer spriteRenderer, clockRenderer;
|
||||||
Sprite blank;
|
Sprite blank;
|
||||||
Game game;
|
Game game;
|
||||||
readonly GRegion region;
|
readonly GRegion region;
|
||||||
|
|
||||||
public GRegion Region { get { return region; } }
|
public GRegion Region { get { return region; } }
|
||||||
public float Width { get { return spriteWidth * 2; } }
|
public float Width { get { return spriteWidth * 2; } }
|
||||||
|
|
||||||
Dictionary<string, Sprite> sprites = new Dictionary<string,Sprite>();
|
Dictionary<string, Sprite> sprites = new Dictionary<string,Sprite>();
|
||||||
const int spriteWidth = 64, spriteHeight = 48;
|
const int spriteWidth = 64, spriteHeight = 48;
|
||||||
|
|
||||||
static string[] groups = new string[] { "building", "vehicle", "boat", "infantry", "plane" };
|
static string[] groups = new string[] { "building", "vehicle", "boat", "infantry", "plane" };
|
||||||
|
|
||||||
Dictionary<string, string> itemGroups = new Dictionary<string,string>(); //item->group
|
Dictionary<string, string> itemGroups = new Dictionary<string,string>(); //item->group
|
||||||
Dictionary<string, Animation> clockAnimations = new Dictionary<string,Animation>(); //group->clockAnimation
|
Dictionary<string, Animation> clockAnimations = new Dictionary<string,Animation>(); //group->clockAnimation
|
||||||
Dictionary<string, SidebarItem> selectedItems = new Dictionary<string,SidebarItem>(); //group->selectedItem
|
Dictionary<string, SidebarItem> selectedItems = new Dictionary<string,SidebarItem>(); //group->selectedItem
|
||||||
|
|
||||||
List<SidebarItem> items = new List<SidebarItem>();
|
List<SidebarItem> items = new List<SidebarItem>();
|
||||||
|
|
||||||
public Sidebar( Race race, Renderer renderer, Game game )
|
public Sidebar( Race race, Renderer renderer, Game game )
|
||||||
{
|
{
|
||||||
this.techTree = game.LocalPlayer.TechTree;
|
this.techTree = game.LocalPlayer.TechTree;
|
||||||
this.techTree.BuildableItemsChanged += PopulateItemList;
|
this.techTree.BuildableItemsChanged += PopulateItemList;
|
||||||
this.game = game;
|
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);
|
||||||
|
|
||||||
LoadSprites("buildings.txt");
|
LoadSprites("buildings.txt");
|
||||||
LoadSprites("vehicles.txt");
|
LoadSprites("vehicles.txt");
|
||||||
LoadSprites("infantry.txt");
|
LoadSprites("infantry.txt");
|
||||||
|
|
||||||
foreach (string s in groups)
|
foreach (string s in groups)
|
||||||
{
|
{
|
||||||
clockAnimations.Add(s, new Animation("clock"));
|
clockAnimations.Add(s, new Animation("clock"));
|
||||||
clockAnimations[s].PlayRepeating("idle");
|
clockAnimations[s].PlayRepeating("idle");
|
||||||
selectedItems.Add(s, null);
|
selectedItems.Add(s, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
blank = SheetBuilder.Add(new Size((int)spriteWidth, (int)spriteHeight), 16);
|
blank = SheetBuilder.Add(new Size((int)spriteWidth, (int)spriteHeight), 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 filename)
|
void LoadSprites(string filename)
|
||||||
{
|
{
|
||||||
foreach (string line in Util.ReadAllLines(FileSystem.Open(filename)))
|
foreach (string line in Util.ReadAllLines(FileSystem.Open(filename)))
|
||||||
{
|
{
|
||||||
string key = line.Substring(0, line.IndexOf(','));
|
string key = line.Substring(0, line.IndexOf(','));
|
||||||
int secondComma = line.IndexOf(',', line.IndexOf(',') + 1);
|
int secondComma = line.IndexOf(',', line.IndexOf(',') + 1);
|
||||||
string group = line.Substring(secondComma + 1, line.Length - secondComma - 1);
|
string group = line.Substring(secondComma + 1, line.Length - secondComma - 1);
|
||||||
sprites.Add(key, SpriteSheetBuilder.LoadSprite(key + "icon.shp"));
|
sprites.Add(key, SpriteSheetBuilder.LoadSprite(key + "icon.shp"));
|
||||||
itemGroups.Add(key, group);
|
itemGroups.Add(key, group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawSprite(Sprite s, ref float2 p)
|
void DrawSprite(Sprite s, ref float2 p)
|
||||||
{
|
{
|
||||||
spriteRenderer.DrawSprite(s, p, 0);
|
spriteRenderer.DrawSprite(s, p, 0);
|
||||||
p.Y += spriteHeight;
|
p.Y += spriteHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fill(float height, float2 p)
|
void Fill(float height, float2 p)
|
||||||
{
|
{
|
||||||
while (p.Y < height)
|
while (p.Y < height)
|
||||||
DrawSprite(blank, ref p);
|
DrawSprite(blank, ref p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int buildPos = 0;
|
int buildPos = 0;
|
||||||
int unitPos = 0;
|
int unitPos = 0;
|
||||||
|
|
||||||
void PopulateItemList()
|
void PopulateItemList()
|
||||||
{
|
{
|
||||||
buildPos = 0; unitPos = 0;
|
buildPos = 0; unitPos = 0;
|
||||||
|
|
||||||
items.Clear();
|
items.Clear();
|
||||||
|
|
||||||
foreach (Item i in techTree.BuildableItems)
|
foreach (Item i in techTree.BuildableItems)
|
||||||
{
|
{
|
||||||
Sprite sprite;
|
Sprite sprite;
|
||||||
if (!sprites.TryGetValue(i.tag, out sprite)) continue;
|
if (!sprites.TryGetValue(i.tag, out sprite)) continue;
|
||||||
|
|
||||||
items.Add(new SidebarItem(sprite, i, i.IsStructure ? buildPos : unitPos));
|
items.Add(new SidebarItem(sprite, i, i.IsStructure ? buildPos : unitPos));
|
||||||
|
|
||||||
if (i.IsStructure)
|
if (i.IsStructure)
|
||||||
buildPos += spriteHeight;
|
buildPos += spriteHeight;
|
||||||
else
|
else
|
||||||
unitPos += spriteHeight;
|
unitPos += spriteHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (string g in groups) selectedItems[g] = null;
|
foreach (string g in groups) selectedItems[g] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Paint()
|
void Paint()
|
||||||
{
|
{
|
||||||
foreach (SidebarItem i in items)
|
foreach (SidebarItem i in items)
|
||||||
i.Paint(spriteRenderer, region.Location);
|
i.Paint(spriteRenderer, region.Location);
|
||||||
|
|
||||||
Fill(region.Size.Y + region.Location.Y, new float2(region.Location.X, buildPos + region.Location.Y));
|
Fill(region.Size.Y + region.Location.Y, new float2(region.Location.X, buildPos + region.Location.Y));
|
||||||
Fill(region.Size.Y + region.Location.Y, new float2(region.Location.X + spriteWidth, unitPos + region.Location.Y));
|
Fill(region.Size.Y + region.Location.Y, new float2(region.Location.X + spriteWidth, unitPos + region.Location.Y));
|
||||||
|
|
||||||
spriteRenderer.Flush();
|
spriteRenderer.Flush();
|
||||||
|
|
||||||
foreach (var kvp in selectedItems)
|
foreach (var kvp in selectedItems)
|
||||||
{
|
{
|
||||||
if (kvp.Value != null)
|
if (kvp.Value != null)
|
||||||
{
|
{
|
||||||
clockRenderer.DrawSprite(clockAnimations[kvp.Key].Image, region.Location.ToFloat2() + kvp.Value.location, 0);
|
clockRenderer.DrawSprite(clockAnimations[kvp.Key].Image, region.Location.ToFloat2() + kvp.Value.location, 0);
|
||||||
clockAnimations[kvp.Key].Tick(1);
|
clockAnimations[kvp.Key].Tick(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clockRenderer.Flush();
|
clockRenderer.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SidebarItem GetItem(float2 point)
|
public SidebarItem GetItem(float2 point)
|
||||||
{
|
{
|
||||||
foreach (SidebarItem i in items)
|
foreach (SidebarItem i in items)
|
||||||
if (i.Clicked(point))
|
if (i.Clicked(point))
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseHandler(MouseInput mi)
|
void MouseHandler(MouseInput mi)
|
||||||
{
|
{
|
||||||
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Down)
|
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Down)
|
||||||
{
|
{
|
||||||
var point = new float2(mi.Location.X, mi.Location.Y);
|
var point = new float2(mi.Location.X, mi.Location.Y);
|
||||||
var item = GetItem(point);
|
var item = GetItem(point);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
string group = itemGroups[item.techTreeItem.tag];
|
string group = itemGroups[item.techTreeItem.tag];
|
||||||
if (selectedItems[group] == null)
|
if (selectedItems[group] == null)
|
||||||
{
|
{
|
||||||
selectedItems[group] = item;
|
selectedItems[group] = item;
|
||||||
Build(item);
|
Build(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down )
|
else if( mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down )
|
||||||
{
|
{
|
||||||
var point = new float2(mi.Location.X, mi.Location.Y);
|
var point = new float2(mi.Location.X, mi.Location.Y);
|
||||||
var item = GetItem(point);
|
var item = GetItem(point);
|
||||||
if( item != null )
|
if( item != null )
|
||||||
{
|
{
|
||||||
string group = itemGroups[ item.techTreeItem.tag ];
|
string group = itemGroups[ item.techTreeItem.tag ];
|
||||||
selectedItems[ group ] = null;
|
selectedItems[ group ] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlaceBuilding : IOrderGenerator
|
class PlaceBuilding : IOrderGenerator
|
||||||
{
|
{
|
||||||
public readonly Player Owner;
|
public readonly Player Owner;
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
|
|
||||||
public PlaceBuilding( Player owner, string name )
|
public PlaceBuilding( Player owner, string name )
|
||||||
{
|
{
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
Name = name;
|
Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Order> Order( Game game, int2 xy )
|
public IEnumerable<Order> Order( Game game, 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(Game game, int2 xy)
|
||||||
{
|
{
|
||||||
game.worldRenderer.uiOverlay.SetCurrentOverlay(xy, 2, 3);
|
game.worldRenderer.uiOverlay.SetCurrentOverlay(xy, 2, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlaceBuildingOrder : Order
|
class PlaceBuildingOrder : Order
|
||||||
{
|
{
|
||||||
PlaceBuilding building;
|
PlaceBuilding building;
|
||||||
int2 xy;
|
int2 xy;
|
||||||
|
|
||||||
public PlaceBuildingOrder(PlaceBuilding building, int2 xy)
|
public PlaceBuildingOrder(PlaceBuilding building, int2 xy)
|
||||||
{
|
{
|
||||||
this.building = building;
|
this.building = building;
|
||||||
this.xy = xy;
|
this.xy = xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Apply(Game game)
|
public override void Apply(Game game)
|
||||||
{
|
{
|
||||||
game.world.AddFrameEndTask(_ =>
|
game.world.AddFrameEndTask(_ =>
|
||||||
{
|
{
|
||||||
Func<int2, Player, PlayerOwned> newBuilding;
|
Log.Write( "Player \"{0}\" builds {1}", building.Owner.PlayerName, building.Name );
|
||||||
if (game.buildingCreation.TryGetValue(building.Name, out newBuilding))
|
game.world.Add( new Actor( building.Name, xy, building.Owner ) );
|
||||||
{
|
|
||||||
Log.Write("Player \"{0}\" builds {1}", building.Owner.PlayerName, building.Name);
|
game.controller.orderGenerator = null;
|
||||||
game.world.Add(newBuilding(xy, building.Owner));
|
game.worldRenderer.uiOverlay.KillOverlay();
|
||||||
}
|
});
|
||||||
game.controller.orderGenerator = null;
|
}
|
||||||
game.worldRenderer.uiOverlay.KillOverlay();
|
}
|
||||||
});
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using OpenRa.FileFormats;
|
|
||||||
using System.Drawing;
|
|
||||||
using OpenRa.Game.Graphics;
|
|
||||||
using IjwFramework.Types;
|
|
||||||
|
|
||||||
namespace OpenRa.Game
|
|
||||||
{
|
|
||||||
class Tree : Actor
|
|
||||||
{
|
|
||||||
int2 location;
|
|
||||||
|
|
||||||
public Tree(TreeReference r, TreeCache renderer, Map map, Game game)
|
|
||||||
: base( game )
|
|
||||||
{
|
|
||||||
location = new int2( r.Location ) - map.Offset;
|
|
||||||
currentImages = new Sprite[] { renderer.GetImage(r.Image) };
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite[] currentImages;
|
|
||||||
public override IEnumerable<Pair<Sprite, float2>> CurrentImages
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
foreach( var x in currentImages )
|
|
||||||
yield return Pair.New( x, 24 * (float2)location );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using IjwFramework.Types;
|
|
||||||
using OpenRa.Game.GameRules;
|
|
||||||
using OpenRa.Game.Graphics;
|
|
||||||
|
|
||||||
namespace OpenRa.Game
|
|
||||||
{
|
|
||||||
class Unit : PlayerOwned, IOrderGenerator
|
|
||||||
{
|
|
||||||
public int facing = 0;
|
|
||||||
public int2 fromCell;
|
|
||||||
public int2 toCell
|
|
||||||
{
|
|
||||||
get { return location; }
|
|
||||||
set { location = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int moveFraction, moveFractionTotal;
|
|
||||||
|
|
||||||
readonly float2 renderOffset;
|
|
||||||
public readonly UnitInfo.MobileInfo unitInfo;
|
|
||||||
|
|
||||||
public Unit( string name, int2 cell, Player owner, Game game )
|
|
||||||
: base( game, name, cell )
|
|
||||||
{
|
|
||||||
fromCell = toCell = cell;
|
|
||||||
|
|
||||||
this.owner = owner;
|
|
||||||
this.unitInfo = (UnitInfo.MobileInfo)Rules.UnitInfo.Get( name );
|
|
||||||
|
|
||||||
animation.PlayFetchIndex( "idle", () => facing );
|
|
||||||
renderOffset = animation.Center;
|
|
||||||
}
|
|
||||||
|
|
||||||
static float2[] fvecs = Util.MakeArray<float2>(32,
|
|
||||||
i => -float2.FromAngle(i / 16.0f * (float)Math.PI) * new float2(1f, 1.3f));
|
|
||||||
|
|
||||||
public int GetFacing( float2 d )
|
|
||||||
{
|
|
||||||
if( float2.WithinEpsilon( d, float2.Zero, 0.001f ) )
|
|
||||||
return facing;
|
|
||||||
|
|
||||||
int highest = -1;
|
|
||||||
float highestDot = -1.0f;
|
|
||||||
|
|
||||||
for( int i = 0 ; i < fvecs.Length ; i++ )
|
|
||||||
{
|
|
||||||
float dot = float2.Dot( fvecs[ i ], d );
|
|
||||||
if( dot > highestDot )
|
|
||||||
{
|
|
||||||
highestDot = dot;
|
|
||||||
highest = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return highest;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Tick( Game game, int t )
|
|
||||||
{
|
|
||||||
animation.Tick( t );
|
|
||||||
if( currentOrder == null && nextOrder != null )
|
|
||||||
{
|
|
||||||
currentOrder = nextOrder;
|
|
||||||
nextOrder = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( currentOrder != null )
|
|
||||||
currentOrder( t );
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<Pair<Sprite, float2>> CurrentImages
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
yield return Centered( animation.Image, CenterLocation );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float2 CenterLocation
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
float fraction = ( moveFraction > 0 ) ? (float)moveFraction / moveFractionTotal : 0f;
|
|
||||||
return new float2( 12, 12 ) + 24 * float2.Lerp( fromCell, toCell, fraction );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SupportsMission( SupportedMissions mission )
|
|
||||||
{
|
|
||||||
if( mission == SupportedMissions.Deploy )
|
|
||||||
return this.unitInfo.Name == "MCV";
|
|
||||||
if( mission == SupportedMissions.Harvest )
|
|
||||||
return this.unitInfo.Name == "HARV";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Order> Order( Game game, int2 xy )
|
|
||||||
{
|
|
||||||
if( ( fromCell == toCell || moveFraction == 0 ) && fromCell == xy )
|
|
||||||
{
|
|
||||||
if( SupportsMission( SupportedMissions.Deploy ) )
|
|
||||||
yield return new DeployMcvOrder( this );
|
|
||||||
if( SupportsMission( SupportedMissions.Harvest ) )
|
|
||||||
yield return new HarvestOrder( this );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
yield return new MoveOrder( this, xy );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PrepareOverlay(Game game, int2 xy) { }
|
|
||||||
|
|
||||||
protected static Pair<Sprite, float2> Centered( Sprite s, float2 location )
|
|
||||||
{
|
|
||||||
var loc = location - 0.5f * s.size;
|
|
||||||
return Pair.New( s, loc.Round() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public float2 SelectedSize { get { return this.CurrentImages.First().First.size; } }
|
|
||||||
public System.Drawing.RectangleF Bounds
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var size = SelectedSize;
|
|
||||||
var loc = CenterLocation - 0.5f * size;
|
|
||||||
return new System.Drawing.RectangleF(loc.X, loc.Y, size.X, size.Y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TurretedUnit : Unit
|
|
||||||
{
|
|
||||||
Animation turretAnim;
|
|
||||||
int turretFacing { get { return facing; } }
|
|
||||||
|
|
||||||
public TurretedUnit( string name, int2 cell, Player owner, Game game )
|
|
||||||
: base( name, cell, owner, game )
|
|
||||||
{
|
|
||||||
turretAnim = new Animation( name );
|
|
||||||
turretAnim.PlayFetchIndex( "turret", () => turretFacing );
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<Pair<Sprite, float2>> CurrentImages
|
|
||||||
{
|
|
||||||
get { return base.CurrentImages.Concat(new[] { Centered(turretAnim.Image, CenterLocation) }); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,146 +1,146 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
//Unit Missions:
|
//Unit Missions:
|
||||||
//{
|
//{
|
||||||
//in rules.ini:
|
//in rules.ini:
|
||||||
// Sleep - no-op
|
// Sleep - no-op
|
||||||
// Harmless - no-op, and also not considered a threat
|
// Harmless - no-op, and also not considered a threat
|
||||||
// Sticky
|
// Sticky
|
||||||
// Attack
|
// Attack
|
||||||
// Move
|
// Move
|
||||||
// QMove
|
// QMove
|
||||||
// Retreat
|
// Retreat
|
||||||
// Guard
|
// Guard
|
||||||
// Enter
|
// Enter
|
||||||
// Capture
|
// Capture
|
||||||
// Harvest
|
// Harvest
|
||||||
// Area Guard
|
// Area Guard
|
||||||
// [Return] - unused
|
// [Return] - unused
|
||||||
// Stop
|
// Stop
|
||||||
// [Ambush] - unused
|
// [Ambush] - unused
|
||||||
// Hunt
|
// Hunt
|
||||||
// Unload
|
// Unload
|
||||||
// Sabotage
|
// Sabotage
|
||||||
// Construction
|
// Construction
|
||||||
// Selling
|
// Selling
|
||||||
// Repair
|
// Repair
|
||||||
// Rescue
|
// Rescue
|
||||||
// Missile
|
// Missile
|
||||||
//
|
//
|
||||||
//not in original RA:
|
//not in original RA:
|
||||||
// Deploy (Mcv -> Fact) [should this be construction/unload?]
|
// Deploy (Mcv -> Fact) [should this be construction/unload?]
|
||||||
//}
|
//}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
enum SupportedMissions
|
enum SupportedMissions
|
||||||
{
|
{
|
||||||
Stop = 0,
|
Stop = 0,
|
||||||
Harvest = 1,
|
Harvest = 1,
|
||||||
Deploy = 2,
|
Deploy = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate void UnitMission( int t );
|
//delegate void UnitMission( int t );
|
||||||
static class UnitMissions
|
//static class UnitMissions
|
||||||
{
|
//{
|
||||||
public static UnitMission Sleep()
|
// public static UnitMission Sleep()
|
||||||
{
|
// {
|
||||||
return t => { };
|
// return t => { };
|
||||||
}
|
// }
|
||||||
|
|
||||||
public static UnitMission Move( Unit unit, int2 destination )
|
// public static UnitMission Move( Unit unit, int2 destination )
|
||||||
{
|
// {
|
||||||
return t =>
|
// return t =>
|
||||||
{
|
// {
|
||||||
Game game = unit.game;
|
// Game game = unit.game;
|
||||||
|
|
||||||
if( unit.nextOrder != null )
|
// if( unit.nextOrder != null )
|
||||||
destination = unit.toCell;
|
// destination = unit.toCell;
|
||||||
|
|
||||||
if( Turn( unit, unit.GetFacing( unit.toCell - unit.fromCell ) ) )
|
// if( Turn( unit, unit.GetFacing( unit.toCell - unit.fromCell ) ) )
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
unit.moveFraction += t * unit.unitInfo.Speed;
|
// unit.moveFraction += t * unit.unitInfo.Speed;
|
||||||
if( unit.moveFraction < unit.moveFractionTotal )
|
// if( unit.moveFraction < unit.moveFractionTotal )
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
unit.moveFraction = 0;
|
// unit.moveFraction = 0;
|
||||||
unit.moveFractionTotal = 0;
|
// unit.moveFractionTotal = 0;
|
||||||
unit.fromCell = unit.toCell;
|
// unit.fromCell = unit.toCell;
|
||||||
|
|
||||||
if( unit.toCell == destination )
|
// if( unit.toCell == destination )
|
||||||
{
|
// {
|
||||||
unit.currentOrder = null;
|
// unit.currentOrder = null;
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
List<int2> res = game.pathFinder.FindUnitPath( unit.toCell, PathFinder.DefaultEstimator( destination ) );
|
// List<int2> res = game.pathFinder.FindUnitPath( unit.toCell, PathFinder.DefaultEstimator( destination ) );
|
||||||
if( res.Count != 0 )
|
// if( res.Count != 0 )
|
||||||
{
|
// {
|
||||||
unit.toCell = res[ res.Count - 1 ];
|
// unit.toCell = res[ res.Count - 1 ];
|
||||||
|
|
||||||
int2 dir = unit.toCell - unit.fromCell;
|
// int2 dir = unit.toCell - unit.fromCell;
|
||||||
unit.moveFractionTotal = ( dir.X != 0 && dir.Y != 0 ) ? 2500 : 2000;
|
// unit.moveFractionTotal = ( dir.X != 0 && dir.Y != 0 ) ? 2500 : 2000;
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
destination = unit.toCell;
|
// destination = unit.toCell;
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
public static UnitMission Deploy( Unit unit )
|
// public static UnitMission Deploy( Unit unit )
|
||||||
{
|
// {
|
||||||
return t =>
|
// return t =>
|
||||||
{
|
// {
|
||||||
Game game = unit.game;
|
// Game game = unit.game;
|
||||||
|
|
||||||
if( Turn( unit, 12 ) )
|
// if( Turn( unit, 12 ) )
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
game.world.AddFrameEndTask( _ =>
|
// game.world.AddFrameEndTask( _ =>
|
||||||
{
|
// {
|
||||||
game.world.Remove( unit );
|
// game.world.Remove( unit );
|
||||||
game.world.Add( new Building("fact", unit.fromCell - new int2( 1, 1 ), unit.owner, game ) );
|
// game.world.Add( new Building( "fact", unit.fromCell - new int2( 1, 1 ), unit.Owner, game ) );
|
||||||
} );
|
// } );
|
||||||
unit.currentOrder = null;
|
// unit.currentOrder = null;
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
public static UnitMission Harvest( Unit unit )
|
// public static UnitMission Harvest( Unit unit )
|
||||||
{
|
// {
|
||||||
UnitMission order = null;
|
// UnitMission order = null;
|
||||||
order = t =>
|
// order = t =>
|
||||||
{
|
// {
|
||||||
// TODO: check that there's actually some ore in this cell :)
|
// // TODO: check that there's actually some ore in this cell :)
|
||||||
|
|
||||||
// face in one of the 8 directions
|
// // face in one of the 8 directions
|
||||||
if( Turn( unit, ( unit.facing + 1 ) & ~3 ) )
|
// if( Turn( unit, ( unit.facing + 1 ) & ~3 ) )
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
unit.currentOrder = _ => { };
|
// unit.currentOrder = _ => { };
|
||||||
if( unit.nextOrder == null )
|
// if( unit.nextOrder == null )
|
||||||
unit.nextOrder = order;
|
// unit.nextOrder = order;
|
||||||
|
|
||||||
string sequenceName = string.Format( "harvest{0}", unit.facing / 4 );
|
// string sequenceName = string.Format( "harvest{0}", unit.facing / 4 );
|
||||||
unit.animation.PlayThen( sequenceName, () =>
|
// unit.animation.PlayThen( sequenceName, () =>
|
||||||
{
|
// {
|
||||||
unit.currentOrder = null;
|
// unit.currentOrder = null;
|
||||||
unit.animation.PlayFetchIndex("idle", () => unit.facing);
|
// unit.animation.PlayFetchIndex( "idle", () => unit.facing );
|
||||||
} );
|
// } );
|
||||||
};
|
// };
|
||||||
return order;
|
// return order;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static bool Turn( Unit unit, int desiredFacing )
|
// static bool Turn( Unit unit, int desiredFacing )
|
||||||
{
|
// {
|
||||||
if( unit.facing == desiredFacing )
|
// if( unit.facing == desiredFacing )
|
||||||
return false;
|
// return false;
|
||||||
|
|
||||||
int df = ( desiredFacing - unit.facing + 32 ) % 32;
|
// int df = ( desiredFacing - unit.facing + 32 ) % 32;
|
||||||
unit.facing = ( unit.facing + ( df > 16 ? 31 : 1 ) ) % 32;
|
// unit.facing = ( unit.facing + ( df > 16 ? 31 : 1 ) ) % 32;
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|||||||
39
OpenRa.Game/UnitOrderGenerator.cs
Executable file
39
OpenRa.Game/UnitOrderGenerator.cs
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenRa.Game
|
||||||
|
{
|
||||||
|
class UnitOrderGenerator : IOrderGenerator
|
||||||
|
{
|
||||||
|
public readonly List<Actor> selection;
|
||||||
|
|
||||||
|
public UnitOrderGenerator( IEnumerable<Actor> selected )
|
||||||
|
{
|
||||||
|
selection = selected.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Order> Order( Game game, int2 xy )
|
||||||
|
{
|
||||||
|
foreach( var unit in selection )
|
||||||
|
{
|
||||||
|
var ret = unit.Order( game, xy );
|
||||||
|
if( ret != null )
|
||||||
|
yield return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if( ( fromCell == toCell || moveFraction == 0 ) && fromCell == xy )
|
||||||
|
//{
|
||||||
|
// if( SupportsMission( SupportedMissions.Deploy ) )
|
||||||
|
// return new DeployMcvOrder( this );
|
||||||
|
// if( SupportsMission( SupportedMissions.Harvest ) )
|
||||||
|
// return new HarvestOrder( this );
|
||||||
|
//}
|
||||||
|
|
||||||
|
//return new MoveOrder( this, xy );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrepareOverlay( Game game, int2 xy ) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,39 +1,42 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
class World
|
class World
|
||||||
{
|
{
|
||||||
List<Actor> actors = new List<Actor>();
|
List<Actor> actors = new List<Actor>();
|
||||||
List<Action<World>> frameEndActions = new List<Action<World>>();
|
List<Action<World>> frameEndActions = new List<Action<World>>();
|
||||||
|
|
||||||
public readonly Game game;
|
public readonly Game game;
|
||||||
|
|
||||||
public World(Game game) { this.game = game; }
|
public World(Game game) { this.game = game; }
|
||||||
|
|
||||||
public void Add(Actor a) { actors.Add(a); }
|
public void Add(Actor a) { actors.Add(a); }
|
||||||
public void Remove( Actor a ) { actors.Remove( a ); }
|
public void Remove( Actor a ) { actors.Remove( a ); }
|
||||||
public void AddFrameEndTask( Action<World> a ) { frameEndActions.Add( a ); }
|
public void AddFrameEndTask( Action<World> a ) { frameEndActions.Add( a ); }
|
||||||
|
|
||||||
int lastTime = Environment.TickCount;
|
int lastTime = Environment.TickCount + 2000;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
int t = Environment.TickCount;
|
int t = Environment.TickCount;
|
||||||
int dt = t - lastTime;
|
int dt = t - lastTime;
|
||||||
lastTime = t;
|
if( dt >= 40 )
|
||||||
|
{
|
||||||
foreach (Actor a in actors)
|
lastTime += 40;
|
||||||
a.Tick(game, dt);
|
|
||||||
|
foreach( Actor a in actors )
|
||||||
foreach (Action<World> a in frameEndActions) a(this);
|
a.Tick( game, 40 );
|
||||||
frameEndActions.Clear();
|
}
|
||||||
}
|
|
||||||
|
foreach (Action<World> a in frameEndActions) a(this);
|
||||||
public IEnumerable<Actor> Actors { get { return actors; } }
|
frameEndActions.Clear();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public IEnumerable<Actor> Actors { get { return actors; } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user