Beispiel #1
0
        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));
            }
        }
Beispiel #3
0
        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));
        }