Beispiel #1
0
        public virtual void RefreshWaypoints()
        {
            if (TargetUnit == null || TargetUnit.IsDead || GetDistanceTo(TargetUnit) <= Stats.Range.Total && Waypoints.Count == 1)
            {
                return;
            }

            if (GetDistanceTo(TargetUnit) <= Stats.Range.Total - 2f)
            {
                SetWaypoints(new List <Vector2> {
                    new Vector2(X, Y)
                });
            }
            else
            {
                SetWaypoints(new List <Vector2>()
                {
                    GetPosition(), TargetUnit.GetPosition()
                });

                /* TODO: Soon we will use path finding for this.
                 * if(CurWaypoint >= Waypoints.Count)
                 * {
                 *  var newWaypoints = _game.Map.NavGrid.GetPath(GetPosition(), TargetUnit.GetPosition());
                 *  if (newWaypoints.Count > 1)
                 *  {
                 *      SetWaypoints(newWaypoints);
                 *  }
                 * }*/
            }
        }
Beispiel #2
0
        // AI tasks
        protected bool ScanForTargets()
        {
            if (TargetUnit != null && !TargetUnit.IsDead && Vector2.Distance(TargetUnit.GetPosition(), this.GetPosition()) < DETECT_RANGE)
            {
                return(true);
            }
            IAttackableUnit nextTarget         = null;
            var             nextTargetPriority = 14;
            var             objects            = _game.ObjectManager.GetObjects();

            //Find target closest to max attack range.
            foreach (var it in objects.OrderBy(x => GetDistanceTo(x.Value) - Stats.Range.Total))
            {
                if (!(it.Value is IAttackableUnit u) ||
                    u.IsDead ||
                    u.Team == Team ||
                    GetDistanceTo(u) > DETECT_RANGE ||
                    !_game.ObjectManager.TeamHasVisionOn(Team, u))
                {
                    continue;
                }
                var priority = (int)ClassifyTarget(u); // get the priority.
                if (priority < nextTargetPriority)     // if the priority is lower than the target we checked previously
                {
                    nextTarget         = u;            // make him a potential target.
                    nextTargetPriority = priority;
                }
            }
            if (nextTarget != null)      // If we have a target
            {
                TargetUnit = nextTarget; // Set the new target and refresh waypoints
                _game.PacketNotifier.NotifySetTarget(this, nextTarget);
                return(true);
            }
            _game.PacketNotifier.NotifyNPC_InstantStopAttack(this, false);
            IsAttacking = false;
            return(false);
        }
Beispiel #3
0
        public bool RecalculateAttackPosition()
        {
            if (Target != null && TargetUnit != null && !TargetUnit.IsDead && GetDistanceTo(Target) < CollisionRadius && GetDistanceTo(TargetUnit.X, TargetUnit.Y) <= Stats.Range.Total)//If we are already where we should be, do not move.
            {
                return(false);
            }
            var objects = _game.ObjectManager.GetObjects();
            List <CirclePoly> UsedPositions = new List <CirclePoly>();
            var isCurrentlyOverlapping      = false;

            var thisCollisionCircle = new CirclePoly(((Target)Target)?.GetPosition() ?? GetPosition(), CollisionRadius + 10);

            foreach (var gameObject in objects)
            {
                var unit = gameObject.Value as AttackableUnit;
                if (unit == null ||
                    unit.NetId == NetId ||
                    unit.IsDead ||
                    unit.Team != Team ||
                    unit.GetDistanceTo(TargetUnit) > DETECT_RANGE
                    )
                {
                    continue;
                }
                var targetCollisionCircle = new CirclePoly(((Target)unit.Target)?.GetPosition() ?? unit.GetPosition(), unit.CollisionRadius + 10);
                if (targetCollisionCircle.CheckForOverLaps(thisCollisionCircle))
                {
                    isCurrentlyOverlapping = true;
                }
                UsedPositions.Add(targetCollisionCircle);
            }
            if (isCurrentlyOverlapping)
            {
                var targetCircle = new CirclePoly(((Target)TargetUnit.Target)?.GetPosition() ?? TargetUnit.GetPosition(), Stats.Range.Total, 72);
                //Find optimal position...
                foreach (var point in targetCircle.Points.OrderBy(x => GetDistanceTo(X, Y)))
                {
                    if (_game.Map.NavGrid.IsWalkable(point))
                    {
                        var positionUsed = false;
                        foreach (var circlePoly in UsedPositions)
                        {
                            if (circlePoly.CheckForOverLaps(new CirclePoly(point, CollisionRadius + 10, 20)))
                            {
                                positionUsed = true;
                            }
                        }
                        if (!positionUsed)
                        {
                            SetWaypoints(new List <Vector2> {
                                GetPosition(), point
                            });
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }