diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index e91f977190..3ceeca8b09 100755 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -48,17 +48,23 @@ namespace OpenRa.Game public void Tick() { - var nextActivity = currentActivity; - while( nextActivity != null ) + + while (currentActivity != null) { - currentActivity = nextActivity; - nextActivity = nextActivity.Tick( this ); + var a = currentActivity; + currentActivity = a.Tick(this) ?? new Idle(); + if (a == currentActivity) break; } foreach (var tick in traits.WithInterface()) tick.Tick(this); } + public bool IsIdle + { + get { return currentActivity == null || currentActivity is Idle; } + } + public float2 CenterLocation; public float2 SelectedSize { diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 818cbb205c..74d85740c5 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -132,6 +132,7 @@ + diff --git a/OpenRa.Game/Traits/Activities/Attack.cs b/OpenRa.Game/Traits/Activities/Attack.cs index 5160223cb9..edb64ea905 100644 --- a/OpenRa.Game/Traits/Activities/Attack.cs +++ b/OpenRa.Game/Traits/Activities/Attack.cs @@ -40,7 +40,7 @@ namespace OpenRa.Game.Traits.Activities var attack = self.traits.WithInterface().First(); attack.target = Target; attack.DoAttack(self); - return null; + return this; } public void Cancel(Actor self) diff --git a/OpenRa.Game/Traits/Activities/DeliverOre.cs b/OpenRa.Game/Traits/Activities/DeliverOre.cs index c93d7dc817..c41c69c6c5 100644 --- a/OpenRa.Game/Traits/Activities/DeliverOre.cs +++ b/OpenRa.Game/Traits/Activities/DeliverOre.cs @@ -59,7 +59,7 @@ namespace OpenRa.Game.Traits.Activities } else // no refineries reachable? - return null; + return this; } else if( unit.Facing != 64 ) return new Turn( 64 ) { NextActivity = this }; @@ -69,7 +69,7 @@ namespace OpenRa.Game.Traits.Activities renderUnit.PlayCustomAnimation( self, "empty", () => isDone = true ); - return null; + return this; } public void Cancel(Actor self) diff --git a/OpenRa.Game/Traits/Activities/DeployMcv.cs b/OpenRa.Game/Traits/Activities/DeployMcv.cs index d452b9a0c9..74354ee6af 100755 --- a/OpenRa.Game/Traits/Activities/DeployMcv.cs +++ b/OpenRa.Game/Traits/Activities/DeployMcv.cs @@ -15,7 +15,7 @@ namespace OpenRa.Game.Traits.Activities Sound.Play("build5.aud"); Game.world.Add( new Actor( Rules.UnitInfo["fact"], self.Location - new int2( 1, 1 ), self.Owner ) ); } ); - return null; + return this; } public void Cancel( Actor self ) diff --git a/OpenRa.Game/Traits/Activities/Fly.cs b/OpenRa.Game/Traits/Activities/Fly.cs index b2718a88c5..ca4a631ad6 100644 --- a/OpenRa.Game/Traits/Activities/Fly.cs +++ b/OpenRa.Game/Traits/Activities/Fly.cs @@ -38,7 +38,7 @@ namespace OpenRa.Game.Traits.Activities self.CenterLocation += speed * -float2.FromAngle((float)angle); self.Location = ((1 / 24f) * self.CenterLocation).ToInt2(); - return null; + return this; } public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } @@ -74,7 +74,7 @@ namespace OpenRa.Game.Traits.Activities self.CenterLocation += speed * -float2.FromAngle((float)angle); self.Location = ((1 / 24f) * self.CenterLocation).ToInt2(); - return null; + return this; } public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } @@ -103,7 +103,7 @@ namespace OpenRa.Game.Traits.Activities self.Location = ((1 / 24f) * self.CenterLocation).ToInt2(); unit.Altitude += Math.Sign(targetAltitude - unit.Altitude); - return null; + return this; } public void Cancel(Actor self) { remainingTicks = 0; NextActivity = null; } diff --git a/OpenRa.Game/Traits/Activities/Follow.cs b/OpenRa.Game/Traits/Activities/Follow.cs index fc4877ba8c..e53ec7e22d 100644 --- a/OpenRa.Game/Traits/Activities/Follow.cs +++ b/OpenRa.Game/Traits/Activities/Follow.cs @@ -24,7 +24,7 @@ namespace OpenRa.Game.Traits.Activities if( !inRange ) return new Move( Target, Range ) { NextActivity = this }; - return null; + return this; } public void Cancel(Actor self) diff --git a/OpenRa.Game/Traits/Activities/Harvest.cs b/OpenRa.Game/Traits/Activities/Harvest.cs index dfbc2023ff..677c34e953 100644 --- a/OpenRa.Game/Traits/Activities/Harvest.cs +++ b/OpenRa.Game/Traits/Activities/Harvest.cs @@ -12,49 +12,62 @@ namespace OpenRa.Game.Traits.Activities var unit = self.traits.Get(); var mobile = self.traits.Get(); - if( isHarvesting ) return null; - - if( NextActivity != null ) - return NextActivity; + if( isHarvesting ) return this; + if( NextActivity != null ) return NextActivity; var harv = self.traits.Get(); if( harv.IsFull ) return new DeliverOre { NextActivity = NextActivity }; - var isGem = false; - if( Rules.Map.ContainsResource( self.Location ) && - Rules.Map.Harvest( self.Location, out isGem ) ) - { - var harvestAnim = "harvest" + Util.QuantizeFacing( unit.Facing, 8 ); - var renderUnit = self.traits.WithInterface().First(); /* better have one of these! */ - if( harvestAnim != renderUnit.anim.CurrentSequence.Name ) - { - isHarvesting = true; - renderUnit.PlayCustomAnimation( self, harvestAnim, () => isHarvesting = false ); - } - harv.AcceptResource( isGem ); - return null; - } + if (HarvestThisTile(self)) + return this; else { - self.QueueActivity( new Move( - () => - { - var search = new PathSearch - { - heuristic = loc => ( Rules.Map.ContainsResource( loc ) ? 0 : 1 ), - umt = UnitMovementType.Wheel, - checkForBlocked = true - }; - search.AddInitialCell( self.Location ); - return Game.PathFinder.FindPath( search ); - } ) ); - self.QueueActivity( new Harvest() ); + FindMoreOre(self); return NextActivity; } } + bool HarvestThisTile(Actor self) + { + var unit = self.traits.Get(); + var harv = self.traits.Get(); + var renderUnit = self.traits.WithInterface().First(); /* better have one of these! */ + + var isGem = false; + if (!Rules.Map.ContainsResource(self.Location) || + !Rules.Map.Harvest(self.Location, out isGem)) + return false; + + var harvestAnim = "harvest" + Util.QuantizeFacing(unit.Facing, 8); + + if (harvestAnim != renderUnit.anim.CurrentSequence.Name) + { + isHarvesting = true; + renderUnit.PlayCustomAnimation(self, harvestAnim, () => isHarvesting = false); + } + harv.AcceptResource(isGem); + return true; + } + + void FindMoreOre(Actor self) + { + self.QueueActivity(new Move( + () => + { + var search = new PathSearch + { + heuristic = loc => (Rules.Map.ContainsResource(loc) ? 0 : 1), + umt = UnitMovementType.Wheel, + checkForBlocked = true + }; + search.AddInitialCell(self.Location); + return Game.PathFinder.FindPath(search); + })); + self.QueueActivity(new Harvest()); + } + public void Cancel(Actor self) { } } } diff --git a/OpenRa.Game/Traits/Activities/Idle.cs b/OpenRa.Game/Traits/Activities/Idle.cs new file mode 100644 index 0000000000..129bd7f6ec --- /dev/null +++ b/OpenRa.Game/Traits/Activities/Idle.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenRa.Game.Traits.Activities +{ + class Idle : IActivity + { + public IActivity NextActivity { get; set; } + + public IActivity Tick(Actor self) { return NextActivity; } + public void Cancel(Actor self) {} + } +} diff --git a/OpenRa.Game/Traits/Activities/Move.cs b/OpenRa.Game/Traits/Activities/Move.cs index 9a655495a1..a1cfb0655c 100755 --- a/OpenRa.Game/Traits/Activities/Move.cs +++ b/OpenRa.Game/Traits/Activities/Move.cs @@ -59,7 +59,7 @@ namespace OpenRa.Game.Traits.Activities if( move != null ) { move.TickMove( self, mobile, this ); - return null; + return this; } if( destination == self.Location ) @@ -74,14 +74,14 @@ namespace OpenRa.Game.Traits.Activities if( path.Count == 0 ) { destination = mobile.toCell; - return null; + return this; } destination = path[ 0 ]; var nextCell = PopPath( self, mobile ); if( nextCell == null ) - return null; + return NextActivity; int2 dir = nextCell.Value - mobile.fromCell; var firstFacing = Util.GetFacing( dir, unit.Facing ); @@ -103,7 +103,7 @@ namespace OpenRa.Game.Traits.Activities move.TickMove( self, mobile, this ); - return null; + return this; } } diff --git a/OpenRa.Game/Traits/Activities/Turn.cs b/OpenRa.Game/Traits/Activities/Turn.cs index 53d22b822b..f07033d93e 100755 --- a/OpenRa.Game/Traits/Activities/Turn.cs +++ b/OpenRa.Game/Traits/Activities/Turn.cs @@ -20,7 +20,7 @@ namespace OpenRa.Game.Traits.Activities return NextActivity; Util.TickFacing( ref unit.Facing, desiredFacing, self.Info.ROT ); - return null; + return this; } public void Cancel( Actor self )