public override Activity Tick(Actor self) { if (IsCanceled || NextActivity != null) { return(NextActivity); } var deliver = new DeliverResources(self); if (harv.IsFull) { return(Util.SequenceActivities(deliver, NextActivity)); } var closestHarvestablePosition = ClosestHarvestablePos(self); // If no harvestable position could be found, either deliver the remaining resources // or get out of the way and do not disturb. if (!closestHarvestablePosition.HasValue) { if (!harv.IsEmpty) { return(deliver); } var cachedPosition = self.Location; harv.UnblockRefinery(self); // Only do this if UnblockRefinery did nothing. if (self.Location == cachedPosition) { var unblockCell = harv.LastHarvestedCell ?? (self.Location + harvInfo.UnblockCell); var moveTo = mobile.NearestMoveableCell(unblockCell, 2, 5); self.QueueActivity(mobile.MoveTo(moveTo, 1)); self.SetTargetLine(Target.FromCell(self.World, moveTo), Color.Gray, false); } var randFrames = self.World.SharedRandom.Next(100, 175); return(Util.SequenceActivities(NextActivity, new Wait(randFrames), this)); } else { var next = this; // Attempt to claim a resource as ours if (territory != null) { if (!territory.ClaimResource(self, closestHarvestablePosition.Value)) { return(Util.SequenceActivities(new Wait(25), next)); } } // If not given a direct order, assume ordered to the first resource location we find: if (!harv.LastOrderLocation.HasValue) { harv.LastOrderLocation = closestHarvestablePosition; } self.SetTargetLine(Target.FromCell(self.World, closestHarvestablePosition.Value), Color.Red, false); var notify = self.TraitsImplementing <INotifyHarvesterAction>(); foreach (var n in notify) { n.MovingToResources(self, closestHarvestablePosition.Value, next); } return(Util.SequenceActivities(mobile.MoveTo(closestHarvestablePosition.Value, 1), new HarvestResource(self), next)); } }
public override Activity Tick(Actor self) { if (IsCanceled || NextActivity != null) { return(NextActivity); } var deliver = new DeliverResources(self); if (harv.IsFull) { return(ActivityUtils.SequenceActivities(deliver, NextActivity)); } var closestHarvestablePosition = ClosestHarvestablePos(self); // If no harvestable position could be found, either deliver the remaining resources // or get out of the way and do not disturb. if (!closestHarvestablePosition.HasValue) { if (!harv.IsEmpty) { return(deliver); } var unblockCell = harv.LastHarvestedCell ?? (self.Location + harvInfo.UnblockCell); var moveTo = mobile.NearestMoveableCell(unblockCell, 2, 5); self.QueueActivity(mobile.MoveTo(moveTo, 1)); self.SetTargetLine(Target.FromCell(self.World, moveTo), Color.Gray, false); // TODO: The harvest-deliver-return sequence is a horrible mess of duplicated code and edge-cases var notify = self.TraitsImplementing <INotifyHarvesterAction>(); foreach (var n in notify) { n.MovingToResources(self, moveTo, this); } var randFrames = self.World.SharedRandom.Next(100, 175); // Avoid creating an activity cycle var next = NextActivity; NextActivity = null; return(ActivityUtils.SequenceActivities(next, new Wait(randFrames), this)); } else { // Attempt to claim a resource as ours if (territory != null && !territory.ClaimResource(self, closestHarvestablePosition.Value)) { return(ActivityUtils.SequenceActivities(new Wait(25), this)); } // If not given a direct order, assume ordered to the first resource location we find: if (!harv.LastOrderLocation.HasValue) { harv.LastOrderLocation = closestHarvestablePosition; } self.SetTargetLine(Target.FromCell(self.World, closestHarvestablePosition.Value), Color.Red, false); // TODO: The harvest-deliver-return sequence is a horrible mess of duplicated code and edge-cases var notify = self.TraitsImplementing <INotifyHarvesterAction>(); foreach (var n in notify) { n.MovingToResources(self, closestHarvestablePosition.Value, this); } return(ActivityUtils.SequenceActivities(mobile.MoveTo(closestHarvestablePosition.Value, 1), new HarvestResource(self), this)); } }
public override Activity Tick(Actor self) { if (IsCanceled || NextActivity != null) { return(NextActivity); } var deliver = new DeliverResources(self); if (harv.IsFull) { return(Util.SequenceActivities(deliver, NextActivity)); } // Determine where to search from and how far to search: var searchFromLoc = harv.LastOrderLocation ?? (harv.LastLinkedProc ?? harv.LinkedProc ?? self).Location; var searchRadius = harv.LastOrderLocation.HasValue ? harvInfo.SearchFromOrderRadius : harvInfo.SearchFromProcRadius; var searchRadiusSquared = searchRadius * searchRadius; // Find harvestable resources nearby: var path = pathFinder.FindPath( PathSearch.Search(self.World, mobileInfo, self, true) .WithHeuristic(loc => { // Avoid this cell: if (avoidCell.HasValue && loc == avoidCell.Value) { return(EstimateDistance(loc, searchFromLoc) + Constants.CellCost); } // Don't harvest out of range: var distSquared = (loc - searchFromLoc).LengthSquared; if (distSquared > searchRadiusSquared) { return(EstimateDistance(loc, searchFromLoc) + Constants.CellCost * 2); } // Get the resource at this location: var resType = resLayer.GetResource(loc); if (resType == null) { return(EstimateDistance(loc, searchFromLoc) + Constants.CellCost); } // Can the harvester collect this kind of resource? if (!harvInfo.Resources.Contains(resType.Info.Name)) { return(EstimateDistance(loc, searchFromLoc) + Constants.CellCost); } if (territory != null) { // Another harvester has claimed this resource: ResourceClaim claim; if (territory.IsClaimedByAnyoneElse(self, loc, out claim)) { return(EstimateDistance(loc, searchFromLoc) + Constants.CellCost); } } return(0); }) .FromPoint(self.Location)); var next = this; if (path.Count == 0) { if (!harv.IsEmpty) { return(deliver); } else { // Get out of the way if we are: harv.UnblockRefinery(self); var randFrames = self.World.SharedRandom.Next(90, 160); if (NextActivity != null) { return(Util.SequenceActivities(NextActivity, new Wait(randFrames), next)); } else { return(Util.SequenceActivities(new Wait(randFrames), next)); } } } // Attempt to claim a resource as ours: if (territory != null) { if (!territory.ClaimResource(self, path[0])) { return(Util.SequenceActivities(new Wait(25), next)); } } // If not given a direct order, assume ordered to the first resource location we find: if (harv.LastOrderLocation == null) { harv.LastOrderLocation = path[0]; } self.SetTargetLine(Target.FromCell(self.World, path[0]), Color.Red, false); var notify = self.TraitsImplementing <INotifyHarvesterAction>(); foreach (var n in notify) { n.MovingToResources(self, path[0], next); } return(Util.SequenceActivities(mobile.MoveTo(path[0], 1), new HarvestResource(self), next)); }