diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 1759394327..a22e85d1b4 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -129,6 +129,7 @@ + diff --git a/OpenRa.Game/Traits/Activities/Harvest.cs b/OpenRa.Game/Traits/Activities/Harvest.cs new file mode 100644 index 0000000000..5e9c05ada6 --- /dev/null +++ b/OpenRa.Game/Traits/Activities/Harvest.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenRa.Game.Traits.Activities +{ + class Harvest : Activity + { + public Activity NextActivity { get; set; } + + public void Tick(Actor self, Mobile mobile) + { + var harv = self.traits.Get(); + var isGem = false; + + if (!harv.IsFull && + Game.map.ContainsResource(self.Location) && + Game.map.Harvest(self.Location, out isGem)) + { + harv.AcceptResource(isGem); + return; + } + + /* nothing to do here, either: + * - return to base, if full, or + * - seek out new ore, schedule a move there, and then this activity */ + + 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 = Game.world.Actors.Where( + a => a.Owner == self.Owner && + a.traits.Contains()) + .FirstOrDefault(); /* todo: *closest* proc, maybe? */ + + if (proc == null) + { + Cancel(self, mobile); /* is this a sane way to cancel? */ + return; + } + + mobile.QueueActivity(new Move(proc.Location + new int2(1, 2))); + mobile.QueueActivity(new Turn(64)); + /* todo: DeliverOre activity */ + + mobile.InternalSetActivity(NextActivity); + } + + void PlanMoreHarvesting(Actor self, Mobile mobile) + { + /* find a nearby patch */ + /* todo: add the queries we need to support this! */ + + mobile.InternalSetActivity(NextActivity); + } + + public void Cancel(Actor self, Mobile mobile) + { + mobile.InternalSetActivity(null); /* bob: anything else required? */ + } + } +} diff --git a/OpenRa.Game/Traits/Harvester.cs b/OpenRa.Game/Traits/Harvester.cs index 4e9ad43f95..a9a2ca89f5 100644 --- a/OpenRa.Game/Traits/Harvester.cs +++ b/OpenRa.Game/Traits/Harvester.cs @@ -11,8 +11,14 @@ namespace OpenRa.Game.Traits int oreCarried = 0; /* sum of these must not exceed capacity */ int gemsCarried = 0; - bool IsFull { get { return oreCarried + gemsCarried == capacity; } } - bool IsEmpty { get { return oreCarried == 0 && gemsCarried == 0; } } + public bool IsFull { get { return oreCarried + gemsCarried == capacity; } } + public bool IsEmpty { get { return oreCarried == 0 && gemsCarried == 0; } } + + public void AcceptResource(bool isGem) + { + if (isGem) gemsCarried++; + else oreCarried++; + } public Order Order(Actor self, int2 xy, bool lmb, Actor underCursor) { diff --git a/OpenRa.Game/UnitOrders.cs b/OpenRa.Game/UnitOrders.cs index 7c77aa7fcf..dd2fb73eec 100755 --- a/OpenRa.Game/UnitOrders.cs +++ b/OpenRa.Game/UnitOrders.cs @@ -63,6 +63,14 @@ namespace OpenRa.Game /* todo: actual deliver activity! [animation + add cash] */ break; } + case "Harvest": + { + var mobile = order.Subject.traits.Get(); + mobile.Cancel(order.Subject); + mobile.QueueActivity(new Traits.Activities.Move(order.TargetLocation)); + mobile.QueueActivity(new Traits.Activities.Harvest() ); + break; + } case "PlaceBuilding": { Game.world.AddFrameEndTask( _ =>