/// <summary>
 /// Fired by the agents died event or when the current target moves out of range,
 /// Fires the lostTarget event.
 /// </summary>
 void OnTargetRemoved(EntityTargetable target)
 {
     //target.removed -= OnTargetRemoved;
     target.OnHidden += OnTargetRemoved;
     target.OnDead   += OnTargetRemoved;
     if (m_CurrrentTargetable != null && target.Id == m_CurrrentTargetable.Id)
     {
         if (lostTarget != null)
         {
             lostTarget();
         }
         m_HadTarget = false;
         m_TargetsInRange.Remove(m_CurrrentTargetable);
         m_CurrrentTargetable      = null;
         m_XRotationCorrectionTime = 0.0f;
     }
     else //wasnt the current target, find and remove from targets list
     {
         for (int i = 0; i < m_TargetsInRange.Count; i++)
         {
             if (m_TargetsInRange[i].Id == target.Id)
             {
                 m_TargetsInRange.RemoveAt(i);
                 break;
             }
         }
     }
 }
        public override void Launch(List <EntityTargetable> targets, AttackerData attackerData, ProjectileData projectileData, Vector3 origin, Transform[] firingPoints)
        {
            EntityTargetable target      = targets[UnityEngine.Random.Range(0, targets.Count)];
            Transform        firingPoint = GetRandomTransform(firingPoints);

            Launch(target, attackerData, projectileData, origin, firingPoint);
        }
        /// <summary>
        /// Returns the nearest targetable within the currently tracked targetables
        /// </summary>
        /// <returns>The nearest targetable if there is one, null otherwise</returns>
        protected virtual EntityTargetable GetNearestTargetable()
        {
            int length = m_TargetsInRange.Count;

            if (length == 0)
            {
                return(null);
            }

            EntityTargetable nearest  = null;
            float            distance = float.MaxValue;

            for (int i = length - 1; i >= 0; i--)
            {
                EntityTargetable targetable = m_TargetsInRange[i];
                if (targetable == null || !targetable.Available || targetable.IsDead)
                {
                    m_TargetsInRange.RemoveAt(i);
                    continue;
                }
                float currentDistance = Vector3.Distance(transform.position, targetable.transform.position);
                if (currentDistance < distance)
                {
                    distance = currentDistance;
                    nearest  = targetable;
                }
            }

            return(nearest);
        }
 protected override void OnLeave(ProcedureOwner procedureOwner, bool isShutdown)
 {
     base.OnLeave(procedureOwner, isShutdown);
     owner.Targetter.transform.position = owner.transform.position;
     owner         = null;
     m_TargetTower = null;
 }
        protected virtual int ByDistance(EntityTargetable first, EntityTargetable second)
        {
            float firstSqrMagnitude  = Vector3.SqrMagnitude(first.transform.position - epicenter.position);
            float secondSqrMagnitude = Vector3.SqrMagnitude(second.transform.position - epicenter.position);

            return(firstSqrMagnitude.CompareTo(secondSqrMagnitude));
        }
 private void OnTargetTowerDestroyed(EntityTargetable target)
 {
     if (m_TargetTower == target)
     {
         m_TargetTower.OnHidden -= OnTargetTowerDestroyed;
         m_TargetTower           = null;
     }
 }
        /// <summary>
        /// Checks if the targetable is a valid target
        /// </summary>
        /// <param name="targetable"></param>
        /// <returns>true if targetable is vaild, false if not</returns>
        protected virtual bool IsTargetableValid(EntityTargetable targetable)
        {
            if (targetable == null || alignment == EnumAlignment.None || targetable.Alignment == EnumAlignment.None)
            {
                return(false);
            }

            return(targetable.Available && !targetable.IsDead && alignment != targetable.Alignment);
        }
        public override void Launch(EntityTargetable target, AttackerData attackerData, ProjectileData projectileData, Vector3 origin, Transform firingPoint)
        {
            GameEntry.Event.Fire(this, ShowEntityInLevelEventArgs.Create(
                                     attackerData.ProjectileEntityId,
                                     TypeUtility.GetEntityType(attackerData.ProjectileType),
                                     null,
                                     EntityDataProjectile.Create(target, projectileData, origin, firingPoint, firingPoint.position, firingPoint.rotation)));

            PlayParticles(fireParticleSystem, firingPoint.position, target.transform.position);
        }
        public static EntityDataProjectile Create(EntityTargetable entityTargetable, ProjectileData projectileData, Vector3 origin, Transform firingPoint, object userData = null)
        {
            EntityDataProjectile entityData = ReferencePool.Acquire <EntityDataProjectile>();

            entityData.EntityTargetable = entityTargetable;
            entityData.ProjectileData   = projectileData;
            entityData.Origin           = origin;
            entityData.FiringPoint      = firingPoint;
            entityData.UserData         = userData;
            return(entityData);
        }
        private void OnTargetEntersRange(EntityTargetable target)
        {
            EntityEnemy enemy = target as EntityEnemy;

            if (enemy == null)
            {
                return;
            }
            enemy.ApplySlow(entityDataTower.Tower.SerialId, entityDataTower.Tower.SpeedDownRate);
            slowList.Add(enemy);
            enemy.OnDead   += RemoveSlowTarget;
            enemy.OnHidden += RemoveSlowTarget;
        }
        public virtual void Launch(List <EntityTargetable> targets, AttackerData attackerData, ProjectileData projectileData, Vector3 origin, Transform[] firingPoints)
        {
            int count = targets.Count;
            int currentFiringPointIndex = 0;
            int firingPointLength       = firingPoints.Length;

            for (int i = 0; i < count; i++)
            {
                EntityTargetable target      = targets[i];
                Transform        firingPoint = firingPoints[currentFiringPointIndex];
                currentFiringPointIndex = (currentFiringPointIndex + 1) % firingPointLength;
                Launch(target, attackerData, projectileData, origin, firingPoint);
            }
        }
        private void RemoveSlowTarget(EntityTargetable target)
        {
            EntityEnemy enemy = target as EntityEnemy;

            if (enemy == null)
            {
                return;
            }

            enemy.RemoveSlow(entityDataTower.Tower.SerialId);

            enemy.OnDead   -= RemoveSlowTarget;
            enemy.OnHidden -= RemoveSlowTarget;

            slowList.Remove(enemy);
        }
        /// <summary>
        /// Clears the list of current targets and clears all events
        /// </summary>
        public void ResetTargetter()
        {
            m_SearchTimer = searchRate;
            m_WaitTimer   = idleWaitTime;

            m_TargetsInRange.Clear();
            m_CurrrentTargetable = null;

            targetEntersRange = null;
            targetExitsRange  = null;
            acquiredTarget    = null;
            lostTarget        = null;

            // Reset turret facing
            if (turret != null)
            {
                turret.localRotation = Quaternion.identity;
            }
        }
        protected override void OnUpdate(ProcedureOwner procedureOwner, float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);

            if (owner.IsPause)
            {
                return;
            }

            owner.Attacker.OnUpdate(elapseSeconds, realElapseSeconds);

            if (!owner.isPathBlocked)
            {
                ChangeState <EnemyMoveState>(procedureOwner);
                return;
            }

            EntityTargetable tower = owner.Targetter.GetTarget();

            if (tower != m_TargetTower)
            {
                // if the current target is to be replaced, unsubscribe from removed event
                if (m_TargetTower != null)
                {
                    m_TargetTower.OnHidden -= OnTargetTowerDestroyed;
                }

                // assign target, can be null
                m_TargetTower = tower;

                // if new target found subscribe to removed event
                if (m_TargetTower != null)
                {
                    m_TargetTower.OnHidden += OnTargetTowerDestroyed;
                }
            }
            if (m_TargetTower == null)
            {
                ChangeState <EnemyMoveState>(procedureOwner);
            }
        }
        public void OnUpdate(float elapseSeconds, float realElapseSeconds)
        {
            m_SearchTimer -= elapseSeconds;

            if (m_SearchTimer <= 0.0f && m_CurrrentTargetable == null && m_TargetsInRange.Count > 0)
            {
                m_CurrrentTargetable = GetNearestTargetable();
                if (m_CurrrentTargetable != null)
                {
                    if (acquiredTarget != null)
                    {
                        acquiredTarget(m_CurrrentTargetable);
                    }
                    m_SearchTimer = searchRate;
                }
            }

            AimTurret();

            m_HadTarget = m_CurrrentTargetable != null;
        }
        protected override void OnShow(object userData)
        {
            base.OnShow(userData);

            enemy = entityDataProjectile.EntityTargetable;

            Vector3 startingPoint = entityDataProjectile.FiringPoint.position;
            Vector3 targetPoint   = Ballistics.CalculateLinearLeadingTargetPoint(
                startingPoint, enemy.transform.position,
                enemy.Velocity, startSpeed,
                acceleration);


            Vector3 direction = entityDataProjectile.FiringPoint.forward;

            Vector3    binormal = Vector3.Cross(direction, Vector3.up);
            Quaternion rotation = Quaternion.AngleAxis(fireVectorXRotationAdjustment, binormal);

            Vector3 adjustedFireVector = rotation * direction;

            FireInDirection(startingPoint, adjustedFireVector);
        }
 void OnTargetLost(EntityTargetable enemy)
 {
     enemy.OnHidden -= OnTargetLost;
     enemy.OnDead   -= OnTargetLost;
     this.enemy      = null;
 }
 public void Clear()
 {
     owner         = null;
     m_TargetTower = null;
 }
        protected override void OnUpdate(ProcedureOwner procedureOwner, float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);

            if (owner.IsPause)
            {
                return;
            }

            owner.Targetter.OnUpdate(elapseSeconds, realElapseSeconds);

            if (owner.TargetPlayer != null)
            {
                ChangeState <EnemyAttackHomeBaseState>(procedureOwner);
                return;
            }


            if (owner.LevelPath == null || owner.LevelPath.PathNodes == null || owner.LevelPath.PathNodes.Length == 0)
            {
                return;
            }

            if (owner.LevelPath.PathNodes.Length > targetPathNodeIndex && owner.isAtDestination)
            {
                if (owner.LevelPath.PathNodes.Length - 1 != targetPathNodeIndex)
                {
                    owner.Agent.SetDestination(owner.LevelPath.PathNodes[++targetPathNodeIndex].position);
                }
            }

            owner.Agent.speed = owner.EntityDataEnemy.EnemyData.Speed * owner.CurrentSlowRate;

            if (owner.isPathBlocked)
            {
                owner.Targetter.transform.position = owner.Agent.pathEndPosition;
                EntityTargetable tower = owner.Targetter.GetTarget();
                if (tower != m_TargetTower)
                {
                    // if the current target is to be replaced, unsubscribe from removed event
                    if (m_TargetTower != null)
                    {
                        m_TargetTower.OnHidden -= OnTargetTowerDestroyed;
                    }

                    // assign target, can be null
                    m_TargetTower = tower;

                    // if new target found subscribe to removed event
                    if (m_TargetTower != null)
                    {
                        m_TargetTower.OnHidden += OnTargetTowerDestroyed;
                    }
                }
                if (m_TargetTower == null)
                {
                    return;
                }
                float distanceToTower = Vector3.Distance(owner.transform.position, m_TargetTower.transform.position);
                if (distanceToTower > owner.EntityDataEnemy.EnemyData.Range)
                {
                    return;
                }

                ChangeState <EnemyAttackTowerState>(procedureOwner);
            }
        }
 protected override void OnLeave(ProcedureOwner procedureOwner, bool isShutdown)
 {
     base.OnLeave(procedureOwner, isShutdown);
     owner         = null;
     m_TargetTower = null;
 }
 private void OnTargetExitsRange(EntityTargetable enmey)
 {
     RemoveSlowTarget(enmey);
 }
 public abstract void Launch(EntityTargetable target, AttackerData attackerData, ProjectileData projectileData, Vector3 origin, Transform firingPoint);
 public virtual void Launch(EntityTargetable target, AttackerData attackerData, ProjectileData projectileData, Vector3 origin, Transform[] firingPoints)
 {
     Launch(target, attackerData, projectileData, origin, GetRandomTransform(firingPoints));
 }
 public void ResetAttack()
 {
     m_TrackingTarget = null;
     m_FireTimer      = 0;
 }
 void OnLostTarget()
 {
     m_TrackingTarget = null;
 }
 void OnAcquiredTarget(EntityTargetable acquiredTarget)
 {
     m_TrackingTarget = acquiredTarget;
 }
 public void Clear()
 {
     targetPathNodeIndex = 0;
     owner         = null;
     m_TargetTower = null;
 }