Esempio n. 1
0
        void RescanForTargets(Actor self)
        {
            targetCountdown = WormInfo.TargetRescanInterval;

            // If close enough, we don't care about other actors.
            var target = self.World.FindActorsInCircle(self.CenterPosition, WormInfo.IgnoreNoiseAttackRange)
                         .FirstOrDefault(x => attackTrait.HasAnyValidWeapons(Target.FromActor(x)));

            if (target != null)
            {
                self.CancelActivity();
                attackTrait.ResolveOrder(self, new Order("Attack", target, true)
                {
                    TargetActor = target
                });
                return;
            }

            Func <Actor, bool> isValidTarget = a =>
            {
                if (!a.Info.HasTraitInfo <AttractsWormsInfo>())
                {
                    return(false);
                }

                return(mobile.CanEnterCell(a.Location, null, false));
            };

            var actorsInRange = self.World.FindActorsInCircle(self.CenterPosition, WormInfo.MaxSearchRadius)
                                .Where(isValidTarget).SelectMany(a => a.TraitsImplementing <AttractsWorms>());

            var noiseDirection = actorsInRange.Aggregate(WVec.Zero, (a, b) => a + b.AttractionAtPosition(self.CenterPosition));

            // No target was found
            if (noiseDirection == WVec.Zero)
            {
                return;
            }

            var moveTo = self.World.Map.CellContaining(self.CenterPosition + noiseDirection);

            while (!self.World.Map.Contains(moveTo) || !mobile.CanEnterCell(moveTo, null, false))
            {
                noiseDirection /= 2;
                moveTo          = self.World.Map.CellContaining(self.CenterPosition + noiseDirection);
            }

            // Don't get stuck when the noise is distributed evenly! This will make the worm wander instead of trying to move to where it already is
            if (moveTo == self.Location)
            {
                self.CancelActivity();
                return;
            }

            self.QueueActivity(false, mobile.MoveTo(moveTo, 3));
            IsMovingTowardTarget = true;
        }