Harvesting works better, and other related stuff.
This commit is contained in:
@@ -1,119 +1,119 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using IjwFramework.Types;
|
||||
using OpenRa.FileFormats;
|
||||
using OpenRa.Game.GameRules;
|
||||
using OpenRa.Game.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using IjwFramework.Types;
|
||||
using OpenRa.FileFormats;
|
||||
using OpenRa.Game.GameRules;
|
||||
using OpenRa.Game.Graphics;
|
||||
using System.Drawing;
|
||||
using OpenRa.Game.Traits;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
class Actor
|
||||
{
|
||||
public readonly TypeDictionary traits = new TypeDictionary();
|
||||
public readonly UnitInfo unitInfo;
|
||||
|
||||
public readonly uint ActorID;
|
||||
public int2 Location;
|
||||
public Player Owner;
|
||||
using OpenRa.Game.Traits;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
class Actor
|
||||
{
|
||||
public readonly TypeDictionary traits = new TypeDictionary();
|
||||
public readonly UnitInfo unitInfo;
|
||||
|
||||
public readonly uint ActorID;
|
||||
public int2 Location;
|
||||
public Player Owner;
|
||||
public int Health;
|
||||
|
||||
public Actor( string name, int2 location, Player owner )
|
||||
{
|
||||
ActorID = Game.world.NextAID();
|
||||
unitInfo = Rules.UnitInfo[ name ];
|
||||
Location = location;
|
||||
CenterLocation = new float2( 12, 12 ) + Game.CellSize * (float2)Location;
|
||||
Owner = owner;
|
||||
public Actor( string name, int2 location, Player owner )
|
||||
{
|
||||
ActorID = Game.world.NextAID();
|
||||
unitInfo = Rules.UnitInfo[ name ];
|
||||
Location = location;
|
||||
CenterLocation = new float2( 12, 12 ) + Game.CellSize * (float2)Location;
|
||||
Owner = owner;
|
||||
Health = unitInfo.Strength; /* todo: handle cases where this is not true! */
|
||||
|
||||
if( unitInfo.Traits != null )
|
||||
{
|
||||
foreach( var traitName in unitInfo.Traits )
|
||||
{
|
||||
var type = typeof( Traits.Mobile ).Assembly.GetType( typeof( Traits.Mobile ).Namespace + "." + traitName, true, false );
|
||||
var ctor = type.GetConstructor( new[] { typeof( Actor ) } );
|
||||
traits.Add( type, ctor.Invoke( new object[] { this } ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new InvalidOperationException( "No Actor traits for " + unitInfo.Name
|
||||
+ "; add Traits= to units.ini for appropriate unit" );
|
||||
}
|
||||
|
||||
public Actor( TreeReference tree, TreeCache treeRenderer )
|
||||
{
|
||||
Location = new int2( tree.Location );
|
||||
traits.Add( new Traits.Tree( treeRenderer.GetImage( tree.Image ) ) );
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
foreach (var tick in traits.WithInterface<Traits.ITick>())
|
||||
tick.Tick(this);
|
||||
}
|
||||
|
||||
public float2 CenterLocation;
|
||||
public float2 SelectedSize { get { return Render().First().First.size; } }
|
||||
|
||||
public IEnumerable<Pair<Sprite, float2>> Render()
|
||||
{
|
||||
return traits.WithInterface<Traits.IRender>().SelectMany( x => x.Render( this ) );
|
||||
}
|
||||
|
||||
public Order Order( int2 xy, bool lmb )
|
||||
{
|
||||
if (Owner != Game.LocalPlayer)
|
||||
return null;
|
||||
|
||||
var underCursor = Game.UnitInfluence.GetUnitAt( xy ) ?? Game.BuildingInfluence.GetBuildingAt( xy );
|
||||
|
||||
return traits.WithInterface<Traits.IOrder>()
|
||||
.Select( x => x.Order( this, xy, lmb, underCursor ) )
|
||||
.FirstOrDefault( x => x != null );
|
||||
}
|
||||
|
||||
public RectangleF Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
var size = SelectedSize;
|
||||
var loc = CenterLocation - 0.5f * size;
|
||||
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDead { get { return Health <= 0; } }
|
||||
|
||||
public void InflictDamage(Actor attacker, Bullet inflictor, int damage)
|
||||
{
|
||||
/* todo: auto-retaliate, etc */
|
||||
/* todo: death sequence for infantry based on inflictor */
|
||||
/* todo: start smoking if < conditionYellow and took damage, and not already smoking */
|
||||
|
||||
if (Health <= 0) return; /* overkill! don't count extra hits as more kills! */
|
||||
|
||||
Health -= damage;
|
||||
if (Health <= 0)
|
||||
{
|
||||
Health = 0;
|
||||
if (attacker.Owner != null)
|
||||
attacker.Owner.Kills++;
|
||||
|
||||
Game.world.AddFrameEndTask(w => w.Remove(this));
|
||||
|
||||
if (Owner == Game.LocalPlayer && !traits.Contains<Building>())
|
||||
|
||||
if( unitInfo.Traits != null )
|
||||
{
|
||||
foreach( var traitName in unitInfo.Traits )
|
||||
{
|
||||
var type = typeof( Traits.Mobile ).Assembly.GetType( typeof( Traits.Mobile ).Namespace + "." + traitName, true, false );
|
||||
var ctor = type.GetConstructor( new[] { typeof( Actor ) } );
|
||||
traits.Add( type, ctor.Invoke( new object[] { this } ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new InvalidOperationException( "No Actor traits for " + unitInfo.Name
|
||||
+ "; add Traits= to units.ini for appropriate unit" );
|
||||
}
|
||||
|
||||
public Actor( TreeReference tree, TreeCache treeRenderer )
|
||||
{
|
||||
Location = new int2( tree.Location );
|
||||
traits.Add( new Traits.Tree( treeRenderer.GetImage( tree.Image ) ) );
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
foreach (var tick in traits.WithInterface<Traits.ITick>())
|
||||
tick.Tick(this);
|
||||
}
|
||||
|
||||
public float2 CenterLocation;
|
||||
public float2 SelectedSize { get { return Render().First().First.size; } }
|
||||
|
||||
public IEnumerable<Pair<Sprite, float2>> Render()
|
||||
{
|
||||
return traits.WithInterface<Traits.IRender>().SelectMany( x => x.Render( this ) );
|
||||
}
|
||||
|
||||
public Order Order( int2 xy, bool lmb )
|
||||
{
|
||||
if (Owner != Game.LocalPlayer)
|
||||
return null;
|
||||
|
||||
var underCursor = Game.UnitInfluence.GetUnitAt( xy ) ?? Game.BuildingInfluence.GetBuildingAt( xy );
|
||||
|
||||
return traits.WithInterface<Traits.IOrder>()
|
||||
.Select( x => x.Order( this, xy, lmb, underCursor ) )
|
||||
.FirstOrDefault( x => x != null );
|
||||
}
|
||||
|
||||
public RectangleF Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
var size = SelectedSize;
|
||||
var loc = CenterLocation - 0.5f * size;
|
||||
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDead { get { return Health <= 0; } }
|
||||
|
||||
public void InflictDamage(Actor attacker, Bullet inflictor, int damage)
|
||||
{
|
||||
/* todo: auto-retaliate, etc */
|
||||
/* todo: death sequence for infantry based on inflictor */
|
||||
/* todo: start smoking if < conditionYellow and took damage, and not already smoking */
|
||||
|
||||
if (Health <= 0) return; /* overkill! don't count extra hits as more kills! */
|
||||
|
||||
Health -= damage;
|
||||
if (Health <= 0)
|
||||
{
|
||||
Health = 0;
|
||||
if (attacker.Owner != null)
|
||||
attacker.Owner.Kills++;
|
||||
|
||||
Game.world.AddFrameEndTask(w => w.Remove(this));
|
||||
|
||||
if (Owner == Game.LocalPlayer && !traits.Contains<Building>())
|
||||
Game.PlaySound("unitlst1.aud", false);
|
||||
|
||||
if (traits.Contains<Building>())
|
||||
{
|
||||
Game.PlaySound("kaboom22.aud", false);
|
||||
// todo: spawn explosion sprites
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var halfStrength = unitInfo.Strength * Rules.General.ConditionYellow;
|
||||
@@ -122,7 +122,7 @@ namespace OpenRa.Game
|
||||
/* we just went below half health! */
|
||||
foreach (var nd in traits.WithInterface<INotifyDamage>())
|
||||
nd.Damaged(this, DamageState.Half);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user