Ejemplo n.º 1
0
        /// <summary>Finds the closest friendly station and moves to it, if we're close enough we dock (delete the instance).</summary>
        /// <returns>Whether to do the rest of the update.</returns>
        protected override bool UpdateInternal()
        {
            // See if there are any stations nearby.
            var faction  = ((Faction)AI.Manager.GetComponent(AI.Entity, Faction.TypeId)).Value;
            var position = ((ITransform)AI.Manager.GetComponent(AI.Entity, TransformTypeId)).Position;
            var index    = (IndexSystem)AI.Manager.GetSystem(IndexSystem.TypeId);

            // The closest station we were able to find and how far it is away.
            var closestStation  = 0;
            var distanceSquared = float.MaxValue;

            ISet <int> neighbors = new HashSet <int>();

            index[Detectable.IndexId].Find(position, ScanRange, neighbors);
            foreach (IIndexable neighbor in neighbors.Select(AI.Manager.GetComponentById))
            {
                // See if it's a station.
                // TODO...

                // Friend or foe?
                var neighborFaction = ((Faction)AI.Manager.GetComponent(neighbor.Entity, Faction.TypeId));
                if (neighborFaction != null && (neighborFaction.Value & faction) != 0)
                {
                    // Friend. Closer than any other?
                    var neighborPosition        = ((ITransform)AI.Manager.GetComponent(neighbor.Entity, TransformTypeId)).Position;
                    var neighborDistanceSquared = FarPosition.DistanceSquared(position, neighborPosition);
                    if (neighborDistanceSquared < distanceSquared)
                    {
                        distanceSquared = neighborDistanceSquared;
                        closestStation  = neighbor.Entity;
                    }
                }
            }

            // Do we have a closest station?
            if (closestStation > 0)
            {
                var neighborPosition =
                    ((ITransform)AI.Manager.GetComponent(closestStation, TransformTypeId)).Position;
                // Close enough to dock?
                if (FarPosition.DistanceSquared(position, neighborPosition) < DockingRange * DockingRange)
                {
                    // Yes! Kill ourselves.
                    // TODO: display some particle effects to hint we're docking.
                    AI.Manager.RemoveEntity(AI.Entity);
                }
                else
                {
                    // No. Let's try to get there.
                    AI.AttackMove(ref neighborPosition);
                }
            }

            // We never have anything else to do anyway.
            return(false);
        }
Ejemplo n.º 2
0
        /// <summary>Check if we reached our target.</summary>
        /// <returns>Whether to do the rest of the update.</returns>
        protected override bool UpdateInternal()
        {
            var position = ((ITransform)AI.Manager.GetComponent(AI.Entity, TransformTypeId)).Position;

            if (FarPosition.DistanceSquared(position, Target) < ReachedEpsilon * ReachedEpsilon)
            {
                // We have reached our target, pop self.
                AI.PopBehavior();
                return(false);
            }

            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>Behavior specific update logic, e.g. checking for nearby enemies.</summary>
        /// <returns>Whether to do the rest of the update.</returns>
        protected override bool UpdateInternal()
        {
            // Get our ship control.
            var control = ((ShipControl)AI.Manager.GetComponent(AI.Entity, ShipControl.TypeId));

            // If our target died, we're done here.
            if (!AI.Manager.HasEntity(Target))
            {
                control.Shooting = false;
                _start           = null;
                AI.PopBehavior();
                return(false);
            }

            // Get our position.
            var position = ((ITransform)AI.Manager.GetComponent(AI.Entity, TransformTypeId)).Position;

            // Check if we've traveled too far.
            if (_start.HasValue)
            {
                if (FarPosition.DistanceSquared(_start.Value, position) >
                    AI.Configuration.ChaseDistance * AI.Configuration.ChaseDistance)
                {
                    // Yeah, that's it, let's give up and return to what we
                    // were doing before.
                    control.Shooting = false;
                    _start           = null;
                    AI.PopBehavior();
                    return(false);
                }
            }
            else
            {
                // Not set yet, do it now.
                _start = position;
            }

            // Get our ship info.
            var info = (ShipInfo)AI.Manager.GetComponent(AI.Entity, ShipInfo.TypeId);

            // Target still lives, see how far away it is.
            var targetPosition = ((ITransform)AI.Manager.GetComponent(Target, TransformTypeId)).Position;
            var toTarget       = (Vector2)(targetPosition - position);
            var targetAngle    = (float)Math.Atan2(toTarget.Y, toTarget.X);
            var weaponRange    = info.WeaponRange + AI.Configuration.WeaponRangeEpsilon;

            // If we're close enough and the target is somewhat in front of us, open fire.
            control.Shooting = (toTarget.LengthSquared() < weaponRange * weaponRange) &&
                               Math.Abs(Angle.MinAngle(targetAngle, info.Rotation)) <
                               AI.Configuration.WeaponFiringAngle * 0.5f;

            // If we're in a squad we want the other members to help us.
            var squad = (Squad)AI.Manager.GetComponent(AI.Entity, Squad.TypeId);

            if (squad != null)
            {
                foreach (var member in squad.Members)
                {
                    // Skip self, we're already busy.
                    if (member == AI.Entity)
                    {
                        continue;
                    }
                    var ai = (ArtificialIntelligence)AI.Manager.GetComponent(member, ArtificialIntelligence.TypeId);
                    if (ai != null && ai.CurrentBehavior != ArtificialIntelligence.BehaviorType.Attack)
                    {
                        ai.Attack(Target);
                    }
                }
            }

            // All OK.
            return(true);
        }