Harvesting works better, and other related stuff.
This commit is contained in:
@@ -1,119 +1,119 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using IjwFramework.Types;
|
using IjwFramework.Types;
|
||||||
using OpenRa.FileFormats;
|
using OpenRa.FileFormats;
|
||||||
using OpenRa.Game.GameRules;
|
using OpenRa.Game.GameRules;
|
||||||
using OpenRa.Game.Graphics;
|
using OpenRa.Game.Graphics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using OpenRa.Game.Traits;
|
using OpenRa.Game.Traits;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
class Actor
|
class Actor
|
||||||
{
|
{
|
||||||
public readonly TypeDictionary traits = new TypeDictionary();
|
public readonly TypeDictionary traits = new TypeDictionary();
|
||||||
public readonly UnitInfo unitInfo;
|
public readonly UnitInfo unitInfo;
|
||||||
|
|
||||||
public readonly uint ActorID;
|
public readonly uint ActorID;
|
||||||
public int2 Location;
|
public int2 Location;
|
||||||
public Player Owner;
|
public Player Owner;
|
||||||
public int Health;
|
public int Health;
|
||||||
|
|
||||||
public Actor( string name, int2 location, Player owner )
|
public Actor( string name, int2 location, Player owner )
|
||||||
{
|
{
|
||||||
ActorID = Game.world.NextAID();
|
ActorID = Game.world.NextAID();
|
||||||
unitInfo = Rules.UnitInfo[ name ];
|
unitInfo = Rules.UnitInfo[ name ];
|
||||||
Location = location;
|
Location = location;
|
||||||
CenterLocation = new float2( 12, 12 ) + Game.CellSize * (float2)Location;
|
CenterLocation = new float2( 12, 12 ) + Game.CellSize * (float2)Location;
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
Health = unitInfo.Strength; /* todo: handle cases where this is not true! */
|
Health = unitInfo.Strength; /* todo: handle cases where this is not true! */
|
||||||
|
|
||||||
if( unitInfo.Traits != null )
|
if( unitInfo.Traits != null )
|
||||||
{
|
{
|
||||||
foreach( var traitName in unitInfo.Traits )
|
foreach( var traitName in unitInfo.Traits )
|
||||||
{
|
{
|
||||||
var type = typeof( Traits.Mobile ).Assembly.GetType( typeof( Traits.Mobile ).Namespace + "." + traitName, true, false );
|
var type = typeof( Traits.Mobile ).Assembly.GetType( typeof( Traits.Mobile ).Namespace + "." + traitName, true, false );
|
||||||
var ctor = type.GetConstructor( new[] { typeof( Actor ) } );
|
var ctor = type.GetConstructor( new[] { typeof( Actor ) } );
|
||||||
traits.Add( type, ctor.Invoke( new object[] { this } ) );
|
traits.Add( type, ctor.Invoke( new object[] { this } ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new InvalidOperationException( "No Actor traits for " + unitInfo.Name
|
throw new InvalidOperationException( "No Actor traits for " + unitInfo.Name
|
||||||
+ "; add Traits= to units.ini for appropriate unit" );
|
+ "; add Traits= to units.ini for appropriate unit" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Actor( TreeReference tree, TreeCache treeRenderer )
|
public Actor( TreeReference tree, TreeCache treeRenderer )
|
||||||
{
|
{
|
||||||
Location = new int2( tree.Location );
|
Location = new int2( tree.Location );
|
||||||
traits.Add( new Traits.Tree( treeRenderer.GetImage( tree.Image ) ) );
|
traits.Add( new Traits.Tree( treeRenderer.GetImage( tree.Image ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Tick()
|
public void Tick()
|
||||||
{
|
{
|
||||||
foreach (var tick in traits.WithInterface<Traits.ITick>())
|
foreach (var tick in traits.WithInterface<Traits.ITick>())
|
||||||
tick.Tick(this);
|
tick.Tick(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float2 CenterLocation;
|
public float2 CenterLocation;
|
||||||
public float2 SelectedSize { get { return Render().First().First.size; } }
|
public float2 SelectedSize { get { return Render().First().First.size; } }
|
||||||
|
|
||||||
public IEnumerable<Pair<Sprite, float2>> Render()
|
public IEnumerable<Pair<Sprite, float2>> Render()
|
||||||
{
|
{
|
||||||
return traits.WithInterface<Traits.IRender>().SelectMany( x => x.Render( this ) );
|
return traits.WithInterface<Traits.IRender>().SelectMany( x => x.Render( this ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Order Order( int2 xy, bool lmb )
|
public Order Order( int2 xy, bool lmb )
|
||||||
{
|
{
|
||||||
if (Owner != Game.LocalPlayer)
|
if (Owner != Game.LocalPlayer)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var underCursor = Game.UnitInfluence.GetUnitAt( xy ) ?? Game.BuildingInfluence.GetBuildingAt( xy );
|
var underCursor = Game.UnitInfluence.GetUnitAt( xy ) ?? Game.BuildingInfluence.GetBuildingAt( xy );
|
||||||
|
|
||||||
return traits.WithInterface<Traits.IOrder>()
|
return traits.WithInterface<Traits.IOrder>()
|
||||||
.Select( x => x.Order( this, xy, lmb, underCursor ) )
|
.Select( x => x.Order( this, xy, lmb, underCursor ) )
|
||||||
.FirstOrDefault( x => x != null );
|
.FirstOrDefault( x => x != null );
|
||||||
}
|
}
|
||||||
|
|
||||||
public RectangleF Bounds
|
public RectangleF Bounds
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var size = SelectedSize;
|
var size = SelectedSize;
|
||||||
var loc = CenterLocation - 0.5f * size;
|
var loc = CenterLocation - 0.5f * size;
|
||||||
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
|
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDead { get { return Health <= 0; } }
|
public bool IsDead { get { return Health <= 0; } }
|
||||||
|
|
||||||
public void InflictDamage(Actor attacker, Bullet inflictor, int damage)
|
public void InflictDamage(Actor attacker, Bullet inflictor, int damage)
|
||||||
{
|
{
|
||||||
/* todo: auto-retaliate, etc */
|
/* todo: auto-retaliate, etc */
|
||||||
/* todo: death sequence for infantry based on inflictor */
|
/* todo: death sequence for infantry based on inflictor */
|
||||||
/* todo: start smoking if < conditionYellow and took damage, and not already smoking */
|
/* 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! */
|
if (Health <= 0) return; /* overkill! don't count extra hits as more kills! */
|
||||||
|
|
||||||
Health -= damage;
|
Health -= damage;
|
||||||
if (Health <= 0)
|
if (Health <= 0)
|
||||||
{
|
{
|
||||||
Health = 0;
|
Health = 0;
|
||||||
if (attacker.Owner != null)
|
if (attacker.Owner != null)
|
||||||
attacker.Owner.Kills++;
|
attacker.Owner.Kills++;
|
||||||
|
|
||||||
Game.world.AddFrameEndTask(w => w.Remove(this));
|
Game.world.AddFrameEndTask(w => w.Remove(this));
|
||||||
|
|
||||||
if (Owner == Game.LocalPlayer && !traits.Contains<Building>())
|
if (Owner == Game.LocalPlayer && !traits.Contains<Building>())
|
||||||
Game.PlaySound("unitlst1.aud", false);
|
Game.PlaySound("unitlst1.aud", false);
|
||||||
|
|
||||||
if (traits.Contains<Building>())
|
if (traits.Contains<Building>())
|
||||||
{
|
{
|
||||||
Game.PlaySound("kaboom22.aud", false);
|
Game.PlaySound("kaboom22.aud", false);
|
||||||
// todo: spawn explosion sprites
|
// todo: spawn explosion sprites
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var halfStrength = unitInfo.Strength * Rules.General.ConditionYellow;
|
var halfStrength = unitInfo.Strength * Rules.General.ConditionYellow;
|
||||||
@@ -122,7 +122,7 @@ namespace OpenRa.Game
|
|||||||
/* we just went below half health! */
|
/* we just went below half health! */
|
||||||
foreach (var nd in traits.WithInterface<INotifyDamage>())
|
foreach (var nd in traits.WithInterface<INotifyDamage>())
|
||||||
nd.Damaged(this, DamageState.Half);
|
nd.Damaged(this, DamageState.Half);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,8 +166,8 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
var oresw = new Stopwatch();
|
var oresw = new Stopwatch();
|
||||||
map.GrowOre(SharedRandom);
|
map.GrowOre(SharedRandom);
|
||||||
OreTime = oresw.ElapsedTime();
|
OreTime = oresw.ElapsedTime();
|
||||||
oreTicks = oreFrequency;
|
oreTicks = oreFrequency;
|
||||||
}
|
}
|
||||||
world.Tick();
|
world.Tick();
|
||||||
UnitInfluence.Tick();
|
UnitInfluence.Tick();
|
||||||
@@ -324,7 +324,7 @@ namespace OpenRa.Game
|
|||||||
unit = new Actor(name, (1 / 24f * producer.CenterLocation).ToInt2(), player);
|
unit = new Actor(name, (1 / 24f * producer.CenterLocation).ToInt2(), player);
|
||||||
var mobile = unit.traits.Get<Mobile>();
|
var mobile = unit.traits.Get<Mobile>();
|
||||||
mobile.facing = 128;
|
mobile.facing = 128;
|
||||||
mobile.QueueActivity(new Traits.Activities.Move(unit.Location + new int2(0, 3)));
|
mobile.QueueActivity(new Traits.Activities.Move(unit.Location + new int2(0, 3), 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
world.Add( unit );
|
world.Add( unit );
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ namespace OpenRa.Game
|
|||||||
WorldRenderer.ShowUnitPaths = settings.GetValue("pathdebug", false);
|
WorldRenderer.ShowUnitPaths = settings.GetValue("pathdebug", false);
|
||||||
Game.Replay = settings.GetValue("replay", "");
|
Game.Replay = settings.GetValue("replay", "");
|
||||||
|
|
||||||
Game.Initialize(settings.GetValue("map", "scg11eb.ini"), renderer, new int2(ClientSize),
|
Game.Initialize(settings.GetValue("map", "scm12ea.ini"), renderer, new int2(ClientSize),
|
||||||
settings.GetValue("player", 1));
|
settings.GetValue("player", 1));
|
||||||
|
|
||||||
SequenceProvider.ForcePrecache();
|
SequenceProvider.ForcePrecache();
|
||||||
|
|||||||
@@ -66,12 +66,12 @@ namespace OpenRa.Game
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<int2> FindUnitPath( int2 unitLocation, Func<int2,double> estimator, UnitMovementType umt )
|
public List<int2> FindUnitPath( int2 unitLocation, Func<int2,double> estimator, UnitMovementType umt )
|
||||||
{
|
{
|
||||||
return FindUnitPath( new[] { unitLocation }, estimator, umt );
|
return FindUnitPath( new[] { unitLocation }, estimator, umt );
|
||||||
}
|
}
|
||||||
|
|
||||||
List<int2> FindUnitPath(IEnumerable<int2> startLocations, Func<int2, double> estimator, UnitMovementType umt)
|
public List<int2> FindUnitPath( IEnumerable<int2> startLocations, Func<int2, double> estimator, UnitMovementType umt )
|
||||||
{
|
{
|
||||||
var cellInfo = InitCellInfo();
|
var cellInfo = InitCellInfo();
|
||||||
var queue = new PriorityQueue<PathDistance>();
|
var queue = new PriorityQueue<PathDistance>();
|
||||||
@@ -109,6 +109,9 @@ namespace OpenRa.Game
|
|||||||
continue;
|
continue;
|
||||||
if( checkForBlock && Game.UnitInfluence.GetUnitAt( newHere ) != null )
|
if( checkForBlock && Game.UnitInfluence.GetUnitAt( newHere ) != null )
|
||||||
continue;
|
continue;
|
||||||
|
var est = estimator( newHere );
|
||||||
|
if( est == double.PositiveInfinity )
|
||||||
|
continue;
|
||||||
|
|
||||||
double cellCost = ( ( d.X * d.Y != 0 ) ? 1.414213563 : 1.0 ) * passableCost[(int)umt][ newHere.X, newHere.Y ];
|
double cellCost = ( ( d.X * d.Y != 0 ) ? 1.414213563 : 1.0 ) * passableCost[(int)umt][ newHere.X, newHere.Y ];
|
||||||
double newCost = cellInfo[ here.X, here.Y ].MinCost + cellCost;
|
double newCost = cellInfo[ here.X, here.Y ].MinCost + cellCost;
|
||||||
@@ -119,7 +122,7 @@ namespace OpenRa.Game
|
|||||||
cellInfo[ newHere.X, newHere.Y ].Path = here;
|
cellInfo[ newHere.X, newHere.Y ].Path = here;
|
||||||
cellInfo[ newHere.X, newHere.Y ].MinCost = newCost;
|
cellInfo[ newHere.X, newHere.Y ].MinCost = newCost;
|
||||||
|
|
||||||
queue.Add( new PathDistance( newCost + estimator( newHere ), newHere ) );
|
queue.Add( new PathDistance( newCost + est, newHere ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using OpenRa.Game.Traits.Activities;
|
||||||
|
|
||||||
namespace OpenRa.Game.Traits
|
namespace OpenRa.Game.Traits
|
||||||
{
|
{
|
||||||
@@ -14,7 +14,9 @@ namespace OpenRa.Game.Traits
|
|||||||
w =>
|
w =>
|
||||||
{
|
{
|
||||||
var harvester = new Actor("harv", self.Location + new int2(1, 2), self.Owner);
|
var harvester = new Actor("harv", self.Location + new int2(1, 2), self.Owner);
|
||||||
harvester.traits.Get<Mobile>().facing = 64;
|
var mobile = harvester.traits.Get<Mobile>();
|
||||||
|
mobile.facing = 64;
|
||||||
|
mobile.InternalSetActivity( new Harvest() );
|
||||||
w.Add(harvester);
|
w.Add(harvester);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
harv.gemsCarried = 0;
|
harv.gemsCarried = 0;
|
||||||
harv.oreCarried = 0;
|
harv.oreCarried = 0;
|
||||||
|
|
||||||
|
if( NextActivity == null )
|
||||||
|
NextActivity = new Harvest();
|
||||||
mobile.InternalSetActivity(NextActivity);
|
mobile.InternalSetActivity(NextActivity);
|
||||||
/* todo: return to the ore patch */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,17 +12,27 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
|
|
||||||
public void Tick(Actor self, Mobile mobile)
|
public void Tick(Actor self, Mobile mobile)
|
||||||
{
|
{
|
||||||
|
if( NextActivity != null )
|
||||||
|
{
|
||||||
|
mobile.InternalSetActivity( NextActivity );
|
||||||
|
NextActivity.Tick( self, mobile );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var harv = self.traits.Get<Harvester>();
|
var harv = self.traits.Get<Harvester>();
|
||||||
var isGem = false;
|
var isGem = false;
|
||||||
|
|
||||||
if (!harv.IsFull &&
|
if (!harv.IsFull &&
|
||||||
Game.map.ContainsResource(self.Location) &&
|
Game.map.ContainsResource(self.Location) &&
|
||||||
Game.map.Harvest(self.Location, out isGem))
|
Game.map.Harvest(self.Location, out isGem))
|
||||||
{
|
{
|
||||||
var harvestAnim = "harvest" + Util.QuantizeFacing(mobile.facing, 8);
|
var harvestAnim = "harvest" + Util.QuantizeFacing(mobile.facing, 8);
|
||||||
var renderUnit = self.traits.WithInterface<RenderUnit>().First(); /* better have one of these! */
|
var renderUnit = self.traits.WithInterface<RenderUnit>().First(); /* better have one of these! */
|
||||||
if (harvestAnim != renderUnit.anim.CurrentSequence.Name)
|
if( harvestAnim != renderUnit.anim.CurrentSequence.Name )
|
||||||
renderUnit.PlayCustomAnimation(self, harvestAnim, () => isHarvesting = false);
|
{
|
||||||
|
isHarvesting = true;
|
||||||
|
renderUnit.PlayCustomAnimation( self, harvestAnim, () => isHarvesting = false );
|
||||||
|
}
|
||||||
harv.AcceptResource(isGem);
|
harv.AcceptResource(isGem);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -35,23 +45,19 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
PlanMoreHarvesting(self, mobile);
|
PlanMoreHarvesting(self, mobile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* maybe this doesnt really belong here, since it's the
|
/* maybe this doesnt really belong here, since it's the
|
||||||
* same as what UnitOrders has to do for an explicit return */
|
* same as what UnitOrders has to do for an explicit return */
|
||||||
|
|
||||||
void PlanReturnToBase(Actor self, Mobile mobile)
|
void PlanReturnToBase(Actor self, Mobile mobile)
|
||||||
{
|
{
|
||||||
/* find a proc */
|
/* find a proc */
|
||||||
var proc = ChooseReturnLocation(self);
|
var proc = ChooseReturnLocation(self);
|
||||||
if (proc == null)
|
if( proc != null )
|
||||||
{
|
{
|
||||||
Cancel(self, mobile); /* is this a sane way to cancel? */
|
mobile.QueueActivity( new Move( proc.Location + new int2( 1, 2 ), 0 ) );
|
||||||
return;
|
mobile.QueueActivity( new Turn( 64 ) );
|
||||||
|
mobile.QueueActivity( new DeliverOre() );
|
||||||
}
|
}
|
||||||
|
|
||||||
mobile.QueueActivity(new Move(proc.Location + new int2(1, 2)));
|
|
||||||
mobile.QueueActivity(new Turn(64));
|
|
||||||
mobile.QueueActivity(new DeliverOre());
|
|
||||||
|
|
||||||
mobile.InternalSetActivity(NextActivity);
|
mobile.InternalSetActivity(NextActivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,12 +78,24 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
/* find a nearby patch */
|
/* find a nearby patch */
|
||||||
/* todo: add the queries we need to support this! */
|
/* todo: add the queries we need to support this! */
|
||||||
|
|
||||||
|
var path = Game.PathFinder.FindUnitPath( self.Location, loc =>
|
||||||
|
{
|
||||||
|
if( Game.UnitInfluence.GetUnitAt( loc ) != null ) return double.PositiveInfinity;
|
||||||
|
return Game.map.ContainsResource( loc ) ? 0 : 1;
|
||||||
|
}, UnitMovementType.Wheel )
|
||||||
|
.TakeWhile( a => a != self.Location )
|
||||||
|
.ToList();
|
||||||
|
if( path.Count != 0 )
|
||||||
|
{
|
||||||
|
mobile.QueueActivity( new Move( path ) );
|
||||||
|
mobile.QueueActivity( new Harvest() );
|
||||||
|
}
|
||||||
|
|
||||||
mobile.InternalSetActivity(NextActivity);
|
mobile.InternalSetActivity(NextActivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cancel(Actor self, Mobile mobile)
|
public void Cancel(Actor self, Mobile mobile)
|
||||||
{
|
{
|
||||||
mobile.InternalSetActivity(null); /* bob: anything else required? */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,17 +10,19 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
public Activity NextActivity { get; set; }
|
public Activity NextActivity { get; set; }
|
||||||
|
|
||||||
int2? destination;
|
int2? destination;
|
||||||
|
int nearEnough;
|
||||||
public List<int2> path;
|
public List<int2> path;
|
||||||
Func<Actor, Mobile, List<int2>> getPath;
|
Func<Actor, Mobile, List<int2>> getPath;
|
||||||
|
|
||||||
MovePart move;
|
MovePart move;
|
||||||
|
|
||||||
public Move( int2 destination )
|
public Move( int2 destination, int nearEnough )
|
||||||
{
|
{
|
||||||
this.getPath = ( self, mobile ) => Game.PathFinder.FindUnitPath(
|
this.getPath = ( self, mobile ) => Game.PathFinder.FindUnitPath(
|
||||||
self.Location, destination,
|
self.Location, destination,
|
||||||
mobile.GetMovementType() );
|
mobile.GetMovementType() );
|
||||||
this.destination = destination;
|
this.destination = destination;
|
||||||
|
this.nearEnough = nearEnough;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Move( Actor target, int range )
|
public Move( Actor target, int range )
|
||||||
@@ -29,6 +31,13 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
self.Location, target.Location,
|
self.Location, target.Location,
|
||||||
mobile.GetMovementType(), range );
|
mobile.GetMovementType(), range );
|
||||||
this.destination = null;
|
this.destination = null;
|
||||||
|
this.nearEnough = range;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Move( List<int2> path )
|
||||||
|
{
|
||||||
|
this.path = path;
|
||||||
|
this.destination = path[ 0 ];
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CanEnterCell( int2 c, Actor self )
|
static bool CanEnterCell( int2 c, Actor self )
|
||||||
@@ -98,7 +107,7 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
var nextCell = path[ path.Count - 1 ];
|
var nextCell = path[ path.Count - 1 ];
|
||||||
if( !CanEnterCell( nextCell, self ) )
|
if( !CanEnterCell( nextCell, self ) )
|
||||||
{
|
{
|
||||||
if( ( mobile.toCell - destination.Value ).LengthSquared <= 8 )
|
if( ( mobile.toCell - destination.Value ).LengthSquared <= nearEnough )
|
||||||
{
|
{
|
||||||
path.Clear();
|
path.Clear();
|
||||||
return null;
|
return null;
|
||||||
@@ -120,6 +129,11 @@ namespace OpenRa.Game.Traits.Activities
|
|||||||
if( path.Count == 0 )
|
if( path.Count == 0 )
|
||||||
return null;
|
return null;
|
||||||
nextCell = path[ path.Count - 1 ];
|
nextCell = path[ path.Count - 1 ];
|
||||||
|
if( !CanEnterCell( nextCell, self ) )
|
||||||
|
{
|
||||||
|
path.Clear();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
path.RemoveAt( path.Count - 1 );
|
path.RemoveAt( path.Count - 1 );
|
||||||
return nextCell;
|
return nextCell;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace OpenRa.Game.Traits
|
|||||||
&& underCursor.traits.Contains<AcceptsOre>() && !IsEmpty)
|
&& underCursor.traits.Contains<AcceptsOre>() && !IsEmpty)
|
||||||
return OpenRa.Game.Order.DeliverOre(self, underCursor);
|
return OpenRa.Game.Order.DeliverOre(self, underCursor);
|
||||||
|
|
||||||
if (underCursor == null && Game.map.ContainsResource(xy) && !IsFull)
|
if (underCursor == null && Game.map.ContainsResource(xy))
|
||||||
return OpenRa.Game.Order.Harvest(self, xy);
|
return OpenRa.Game.Order.Harvest(self, xy);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ namespace OpenRa.Game.Traits
|
|||||||
{
|
{
|
||||||
public Actor self;
|
public Actor self;
|
||||||
|
|
||||||
public int2 fromCell;
|
int2 __fromCell;
|
||||||
public int2 toCell { get { return self.Location; } set { self.Location = value; } }
|
public int2 fromCell { get { return __fromCell; } set { Game.UnitInfluence.Remove( this ); __fromCell = value; Game.UnitInfluence.Add( this ); } }
|
||||||
|
public int2 toCell { get { return self.Location; } set { Game.UnitInfluence.Remove( this ); self.Location = value; Game.UnitInfluence.Add( this ); } }
|
||||||
public int facing;
|
public int facing;
|
||||||
|
|
||||||
public int Voice = Game.CosmeticRandom.Next(2);
|
public int Voice = Game.CosmeticRandom.Next(2);
|
||||||
|
|||||||
@@ -47,6 +47,14 @@ namespace OpenRa.Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.Conditional( "SANITY_CHECKS" )]
|
||||||
|
void SanityCheckAdd( Mobile a )
|
||||||
|
{
|
||||||
|
foreach( var c in a.OccupiedCells() )
|
||||||
|
if( influence[c.X, c.Y] != null )
|
||||||
|
throw new InvalidOperationException( "UIM: Sanity check failed (Add)" );
|
||||||
|
}
|
||||||
|
|
||||||
public Actor GetUnitAt( int2 a )
|
public Actor GetUnitAt( int2 a )
|
||||||
{
|
{
|
||||||
return influence[ a.X, a.Y ];
|
return influence[ a.X, a.Y ];
|
||||||
@@ -54,6 +62,7 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
public void Add(Mobile a)
|
public void Add(Mobile a)
|
||||||
{
|
{
|
||||||
|
SanityCheckAdd(a);
|
||||||
foreach (var c in a.OccupiedCells())
|
foreach (var c in a.OccupiedCells())
|
||||||
influence[c.X, c.Y] = a.self;
|
influence[c.X, c.Y] = a.self;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
var mobile = order.Subject.traits.Get<Mobile>();
|
var mobile = order.Subject.traits.Get<Mobile>();
|
||||||
mobile.Cancel( order.Subject );
|
mobile.Cancel( order.Subject );
|
||||||
mobile.QueueActivity( new Traits.Activities.Move( order.TargetLocation ) );
|
mobile.QueueActivity( new Traits.Activities.Move( order.TargetLocation, 8 ) );
|
||||||
|
|
||||||
var attackBase = order.Subject.traits.WithInterface<AttackBase>().FirstOrDefault();
|
var attackBase = order.Subject.traits.WithInterface<AttackBase>().FirstOrDefault();
|
||||||
if( attackBase != null )
|
if( attackBase != null )
|
||||||
@@ -57,7 +57,7 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
var mobile = order.Subject.traits.Get<Mobile>();
|
var mobile = order.Subject.traits.Get<Mobile>();
|
||||||
mobile.Cancel(order.Subject);
|
mobile.Cancel(order.Subject);
|
||||||
mobile.QueueActivity(new Traits.Activities.Move(order.TargetActor.Location + new int2(1, 2)));
|
mobile.QueueActivity(new Traits.Activities.Move(order.TargetActor.Location + new int2(1, 2), 0));
|
||||||
mobile.QueueActivity(new Traits.Activities.Turn(64));
|
mobile.QueueActivity(new Traits.Activities.Turn(64));
|
||||||
mobile.QueueActivity(new Traits.Activities.DeliverOre());
|
mobile.QueueActivity(new Traits.Activities.DeliverOre());
|
||||||
break;
|
break;
|
||||||
@@ -66,7 +66,7 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
var mobile = order.Subject.traits.Get<Mobile>();
|
var mobile = order.Subject.traits.Get<Mobile>();
|
||||||
mobile.Cancel(order.Subject);
|
mobile.Cancel(order.Subject);
|
||||||
mobile.QueueActivity(new Traits.Activities.Move(order.TargetLocation));
|
mobile.QueueActivity(new Traits.Activities.Move(order.TargetLocation, 0));
|
||||||
mobile.QueueActivity(new Traits.Activities.Harvest() );
|
mobile.QueueActivity(new Traits.Activities.Harvest() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user