/// <summary> /// Finds the closest harvestable pos between the current position of the harvester /// and the last order location /// </summary> CPos?ClosestHarvestablePos(Actor self) { // Harvesters should respect an explicit harvest order instead of harvesting the current cell. if (orderLocation == null) { if (harv.CanHarvestCell(self, self.Location) && claimLayer.CanClaimCell(self, self.Location)) { return(self.Location); } } else { if (harv.CanHarvestCell(self, orderLocation.Value) && claimLayer.CanClaimCell(self, orderLocation.Value)) { return(orderLocation); } orderLocation = null; } // Determine where to search from and how far to search: var searchFromLoc = lastHarvestedCell ?? GetSearchFromLocation(self); var searchRadius = 24; var searchRadiusSquared = searchRadius * searchRadius; // Find any harvestable resources: List <CPos> path; using (var search = PathSearch.Search(self.World, locomotorInfo, self, true, loc => domainIndex.IsPassable(self.Location, loc, locomotorInfo) && Math.Abs(self.Location.X - loc.X) > 5 && harv.CanHarvestCell(self, loc) && claimLayer.CanClaimCell(self, loc)) .WithCustomCost(loc => { if ((loc - searchFromLoc).LengthSquared > searchRadiusSquared) { return(int.MaxValue); } return(0); }) .FromPoint(searchFromLoc) .FromPoint(self.Location)) path = pathFinder.FindPath(search); if (path.Count > 0) { return(path[0]); } return(null); }
public override Activity Tick(Actor self) { if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivityTick(self, ChildActivity); if (ChildActivity != null) { return(this); } } //if (IsCanceling || harv.IsFull) // return NextActivity; // Move towards the target cell if (self.Location != targetCell) { //foreach (var n in self.TraitsImplementing<INotifyHarvesterAction>()) // n.MovingToResources(self, targetCell, new FindAndDeliverResources(self)); self.SetTargetLine(Target.FromCell(self.World, targetCell), Color.Red, false); QueueChild(self, move.MoveTo(targetCell, 2), true); return(this); } if (!harv.CanHarvestCell(self, self.Location)) { return(NextActivity); } // Turn to one of the harvestable facings //if (harvInfo.HarvestFacings != 0) //{ // var current = facing.Facing; // var desired = body.QuantizeFacing(current, harvInfo.HarvestFacings); // if (desired != current) // { // QueueChild(self, new Turn(self, desired), true); // return this; // } //} var resource = resLayer.Harvest(self.Location); if (resource == null) { return(NextActivity); } harv.AcceptResource(self, resource); // это событие ловится WithHarverAnimation классом, чтобы 1 раз проиграть анимацию сборки спайса. //foreach (var t in self.TraitsImplementing<INotifyHarvesterAction>()) // t.Harvested(self, resource); foreach (var t in self.TraitsImplementing <INotifyAttack>()) { if (t is OpenRA.Mods.Common.Traits.Render.WithAttackOverlay) //возьмем анимацию для поедания из анимации атаки. { t.PreparingAttack(self, new Target(), null, null); } } //этой Activity делается пауза после одного съедания спайса, чтобы не сосать как пылесосом и подождать анимацию глотания спайса //QueueChild(self, new Wait(500), true); return(this); }