From efb200c16ce707a875a2ec20e8fccd2edd783f6c Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 12 Nov 2009 11:38:28 +1300 Subject: [PATCH] Various harvesting fixes. --- OpenRa.Game/PathFinder.cs | 5 +- OpenRa.Game/PathSearch.cs | 2 +- OpenRa.Game/Traits/Activities/DeliverOre.cs | 59 ++++++++++++++------- OpenRa.Game/Traits/Activities/Harvest.cs | 45 ++++------------ 4 files changed, 56 insertions(+), 55 deletions(-) diff --git a/OpenRa.Game/PathFinder.cs b/OpenRa.Game/PathFinder.cs index 833cae1186..753cfa77b2 100644 --- a/OpenRa.Game/PathFinder.cs +++ b/OpenRa.Game/PathFinder.cs @@ -130,7 +130,10 @@ namespace OpenRa.Game return MakeBidiPath(fromSrc, fromDest, p); /* make some progress on the second search */ - fromDest.Expand( passableCost ); + var q = fromDest.Expand( passableCost ); + + if (fromSrc.cellInfo[q.X, q.Y].Seen && fromSrc.cellInfo[q.X, q.Y].MinCost < float.PositiveInfinity) + return MakeBidiPath(fromSrc, fromDest, q); } return new List(); diff --git a/OpenRa.Game/PathSearch.cs b/OpenRa.Game/PathSearch.cs index dcfee5c826..ce63bde242 100755 --- a/OpenRa.Game/PathSearch.cs +++ b/OpenRa.Game/PathSearch.cs @@ -118,7 +118,7 @@ namespace OpenRa.Game return cellInfo; } - static Func DefaultEstimator( int2 destination ) + public static Func DefaultEstimator( int2 destination ) { return here => { diff --git a/OpenRa.Game/Traits/Activities/DeliverOre.cs b/OpenRa.Game/Traits/Activities/DeliverOre.cs index 9ce9afa2a5..a928fde85a 100644 --- a/OpenRa.Game/Traits/Activities/DeliverOre.cs +++ b/OpenRa.Game/Traits/Activities/DeliverOre.cs @@ -12,6 +12,8 @@ namespace OpenRa.Game.Traits.Activities bool isDone; Actor refinery; + public DeliverOre() { } + public DeliverOre( Actor refinery ) { this.refinery = refinery; @@ -21,14 +23,44 @@ namespace OpenRa.Game.Traits.Activities public void Tick(Actor self, Mobile mobile) { - if( self.Location != refinery.Location + refineryDeliverOffset ) + if( isDone ) { - var move = new Move( refinery.Location + refineryDeliverOffset, 0 ); - mobile.InternalSetActivity( move ); - mobile.QueueActivity( this ); - move.Tick( self, mobile ); + var harv = self.traits.Get(); + + harv.Deliver( self ); + + if( NextActivity == null ) + NextActivity = new Harvest(); + mobile.InternalSetActivity( NextActivity ); return; } + else if( refinery == null || refinery.IsDead ) + { + var search = new PathSearch + { + heuristic = PathSearch.DefaultEstimator( self.Location ), + umt = mobile.GetMovementType(), + checkForBlocked = false, + }; + var refineries = Game.world.Actors.Where( x => x.unitInfo == Rules.UnitInfo[ "proc" ] ).ToList(); + foreach( var r in refineries ) + search.AddInitialCell( r.Location + refineryDeliverOffset ); + + var path = Game.PathFinder.FindPath( search ); + path.Reverse(); + if( path.Count != 0 ) + { + refinery = refineries.FirstOrDefault( x => x.Location + refineryDeliverOffset == path[ 0 ] ); + var move = new Move( () => path ); + mobile.InternalSetActivity( move ); + mobile.QueueActivity( this ); + move.Tick( self, mobile ); + return; + } + else + // no refineries reachable? + return; + } else if( mobile.facing != 64 ) { var turn = new Turn( 64 ); @@ -37,22 +69,11 @@ namespace OpenRa.Game.Traits.Activities turn.Tick( self, mobile ); return; } - else if (isDone) - { - var harv = self.traits.Get(); - - harv.Deliver(self); - - if( NextActivity == null ) - NextActivity = new Harvest(); - mobile.InternalSetActivity(NextActivity); - return; - } var renderUnit = self.traits.WithInterface().First(); - if (renderUnit.anim.CurrentSequence.Name != "empty") - renderUnit.PlayCustomAnimation(self, "empty", - () => isDone = true); + if( renderUnit.anim.CurrentSequence.Name != "empty" ) + renderUnit.PlayCustomAnimation( self, "empty", + () => isDone = true ); } public void Cancel(Actor self, Mobile mobile) diff --git a/OpenRa.Game/Traits/Activities/Harvest.cs b/OpenRa.Game/Traits/Activities/Harvest.cs index ed444d8bfc..925e1949ce 100644 --- a/OpenRa.Game/Traits/Activities/Harvest.cs +++ b/OpenRa.Game/Traits/Activities/Harvest.cs @@ -12,6 +12,8 @@ namespace OpenRa.Game.Traits.Activities public void Tick(Actor self, Mobile mobile) { + if( isHarvesting ) return; + if( NextActivity != null ) { mobile.InternalSetActivity( NextActivity ); @@ -20,10 +22,15 @@ namespace OpenRa.Game.Traits.Activities } var harv = self.traits.Get(); - var isGem = false; - if (!harv.IsFull && - Game.map.ContainsResource(self.Location) && + if( harv.IsFull ) + { + mobile.QueueActivity( new DeliverOre() ); + mobile.InternalSetActivity( NextActivity ); + } + + var isGem = false; + if (Game.map.ContainsResource(self.Location) && Game.map.Harvest(self.Location, out isGem)) { var harvestAnim = "harvest" + Util.QuantizeFacing(mobile.facing, 8); @@ -37,37 +44,7 @@ namespace OpenRa.Game.Traits.Activities return; } - if (isHarvesting) return; - - if (harv.IsFull) - PlanReturnToBase(self, mobile); - else - PlanMoreHarvesting(self, mobile); - } - - /* maybe this doesnt really belong here, since it's the - * same as what UnitOrders has to do for an explicit return */ - - void PlanReturnToBase(Actor self, Mobile mobile) - { - /* find a proc */ - var proc = ChooseReturnLocation(self); - if( proc != null ) - mobile.QueueActivity( new DeliverOre( proc ) ); - - mobile.InternalSetActivity(NextActivity); - } - - static Actor ChooseReturnLocation(Actor self) - { - /* todo: compute paths to possible procs, taking into account enemy presence */ - /* currently, we're good at choosing close, inaccessible procs */ - - return Game.world.Actors.Where( - a => a.Owner == self.Owner && - a.traits.Contains()) - .OrderBy(p => (p.Location - self.Location).LengthSquared) - .FirstOrDefault(); + PlanMoreHarvesting( self, mobile ); } void PlanMoreHarvesting(Actor self, Mobile mobile)