/// <summary>
	/// TargetCoords is used when a ship has been hit and it will try and destroy
	/// this ship
	/// </summary>
	/// <param name="row">row generated around the hit tile</param>
	/// <param name="column">column generated around the hit tile</param>
	private void TargetCoords(ref int row, ref int column)
	{
		Location l = _Targets.Pop();

		if ((_Targets.Count == 0))
			_CurrentState = AIStates.Searching;
		row = l.Row;
		column = l.Column;
	}
示例#2
0
    /// <summary>
    /// ProcessShot will be called uppon when a ship is found.
    /// It will create a stack with targets it will try to hit. These targets
    /// will be around the tile that has been hit.
    /// </summary>
    /// <param name="row">the row it needs to process</param>
    /// <param name="col">the column it needs to process</param>
    /// <param name="result">the result og the last shot (should be hit)</param>
    protected override void ProcessShot(int row, int col, AttackResult result)
    {
        if (result.Value == ResultOfAttack.Hit) {
            _CurrentState = AIStates.Searching;

        } else if (result.Value == ResultOfAttack.ShotAlready) {
            throw new ApplicationException("Error in AI");
        }
    }
示例#3
0
 public override AIStates OnGetHit( Mobile by, AIStates AIState, int dmg )
 {
     if ( AIState != AIStates.Attack && AIState != AIStates.Fighting )
     {
         OnBeginFight( by );
         return AIStates.BeingAttacked;
     }
     return AIState;
 }
示例#4
0
 /// <summary>
 /// ProcessShot will be called uppon when a ship is found.
 /// It will create a stack with targets it will try to hit. These targets
 /// will be around the tile that has been hit.
 /// </summary>
 /// <param name="row">the row it needs to process</param>
 /// <param name="col">the column it needs to process</param>
 /// <param name="result">the result og the last shot (should be hit)</param>
 protected override void ProcessShot(int row, int col, AttackResult result)
 {
     if (result.Value == ResultOfAttack.Hit) {
         _CurrentState = AIStates.TargetingShip;
         AddTarget(row - 1, col);
         AddTarget(row, col - 1);
         AddTarget(row + 1, col);
         AddTarget(row, col + 1);
     } else if (result.Value == ResultOfAttack.ShotAlready) {
         throw new ApplicationException("Error in AI");
     }
 }
示例#5
0
 public override AIStates OnGetHit( Mobile by, AIStates AIState, int dmg )
 {
     if ( AIState != AIStates.Attack && AIState != AIStates.Fighting )
     {
         OnBeginFight( by );
         if ( by == From )
             From.AttackTarget = From.LastOffender;
         else
             From.AttackTarget = by;
         return AIStates.BeingAttacked;
     }
     return AIState;
 }
 /// <summary>
 /// ProcessShot will be called uppon when a ship is found.
 /// It will create a stack with targets it will try to hit. These targets
 /// will be randomly assigned.
 /// </summary>
 /// <param name="row">the row it needs to process</param>
 /// <param name="rowOld">the row it contained before hit</param>
 /// <param name="col">the column it needs to process</param>
 /// <param name="colOld">the column it contained before hit</param>
 /// <param name="result">the result of the last shot (should be hit)</param>
 protected override void ProcessShot(int row, int col, AttackResult result)
 {
     if (result.Value == ResultOfAttack.Hit) {
         _CurrentState = AIStates.Searching;
         int rowOld = row;
         int colOld = col;
         SearchCoords(ref row, ref col);
         AddTarget(row, colOld);
         AddTarget(rowOld, col);
     } else if (result.Value == ResultOfAttack.ShotAlready) {
         throw new ApplicationException("Error in AI");
     }
 }
示例#7
0
    /// <summary>
    /// ProcessShot will be called uppon when a ship is found.
    /// It will create a stack with targets it will try to hit. These targets
    /// will be around the tile that has been hit.
    /// </summary>
    /// <param name="row">the row it needs to process</param>
    /// <param name="col">the column it needs to process</param>
    /// <param name="result">the result og the last shot (should be hit)</param>

    protected override void ProcessShot(int row, int col, AttackResult result)
    {
        /// no next targets will be added if AI hits a target
        /// everytime AI hits the target, next target will be set randomly
        Console.WriteLine(row + " " + col);
        if (result.Value == ResultOfAttack.Hit)
        {
            _CurrentState = AIStates.TargetingShip;
            AddTarget(_Random.Next(0, EnemyGrid.Width), _Random.Next(0, EnemyGrid.Height));
        }
        else if (result.Value == ResultOfAttack.ShotAlready)
        {
            throw new ApplicationException("Error in AI");
        }
    }
示例#8
0
    /// <summary>
    /// ProcessShot will be called uppon when a ship is found.
    /// It will create a stack with targets it will try to hit. These targets
    /// will be around the tile that has been hit.
    /// </summary>
    /// <param name="row">the row it needs to process</param>
    /// <param name="col">the column it needs to process</param>
    /// <param name="result">the result og the last shot (should be hit)</param>

    protected override void ProcessShot(int row, int col, AttackResult result)
    {
        if (result.Value == ResultOfAttack.Hit)
        {
            _CurrentState = AIStates.TargetingShip;
            AddTarget(row - 1, col);
            AddTarget(row, col - 1);
            AddTarget(row + 1, col);
            AddTarget(row, col + 1);
        }
        else if (result.Value == ResultOfAttack.ShotAlready)
        {
            throw new ApplicationException("Error in AI");
        }
    }
示例#9
0
    public void MoveTo(Vector3 start, Vector3 target)
    {
        if (Active)
        {
            if (start.x >= target.x)
            {
                transform.position = transform.position;
            }

            CurrentState = AIStates.MOVING;
            DrawLine(start, target, new Color(255, 0, 0), 0.5f);
            float step = speed * Time.deltaTime;
            transform.position = Vector3.MoveTowards(start, target, step);
        }
    }
示例#10
0
    private void Start()
    {
        movement           = GetComponent <CarMovement>();
        driftLine          = GetComponent <CarDriftLine>();
        carDriftDust       = GetComponent <CarDriftDust>();
        carColliderCommon  = GetComponent <ColliderCommon>();
        ballColliderCommon = ball.GetComponent <ColliderCommon>();
        carPowerUpControl  = GetComponent <CarPowerUpControl>();

        InitializeTempDistance();

        aIState = AIStates.None;

        FindAllCarsExceptThis();
    }
示例#11
0
 protected override void ProcessShot(int row, int col, AttackResult result)
 {
     if (result.Value == ResultOfAttack.Hit)
     {
         _CurrentState = AIStates.RandomTarget;
         AddTarget(row - _Random.Next(0, EnemyGrid.Height), col);
         AddTarget(row, col - _Random.Next(0, EnemyGrid.Width));
         AddTarget(row + _Random.Next(0, EnemyGrid.Height), col);
         AddTarget(row, col + _Random.Next(0, EnemyGrid.Width));
     }
     else if (result.Value == ResultOfAttack.ShotAlready)
     {
         throw new ApplicationException("Error in AI");
     }
 }
示例#12
0
    /// <summary>
    /// TargetCoords is used when a ship has been hit and it will try and destroy
    /// this ship
    /// </summary>
    /// <param name="row">row generated around the hit tile</param>
    /// <param name="column">column generated around the hit tile</param>
    private void TargetCoords(ref int row, ref int column)
    {
        Location l = _Targets.Pop();

        if ((_Targets.Count == 0))
        {
            _CurrentState = AIStates.Searching;
        }
        else if ((_Targets.Count == 1))
        {
            _CurrentState = AIStates.Searching;
        }
        row    = l.Row;
        column = l.Column;
    }
示例#13
0
    private void OnStateExit(AIStates state, AIStates toState)
    {
        switch (state)
        {
        case AIStates.Idling:
        {
            break;
        }

        case AIStates.Chasing:
        {
            break;
        }
        }
    }
示例#14
0
 /// <summary>
 /// ProcessShot will be called uppon when a ship is found.
 /// It will create a stack with targets it will try to hit. These targets
 /// will be randomly assigned.
 /// </summary>
 /// <param name="row">the row it needs to process</param>
 /// <param name="rowOld">the row it contained before hit</param>
 /// <param name="col">the column it needs to process</param>
 /// <param name="colOld">the column it contained before hit</param>
 /// <param name="result">the result of the last shot (should be hit)</param>
 protected override void ProcessShot(int row, int col, AttackResult result)
 {
     if (result.Value == ResultOfAttack.Hit)
     {
         _CurrentState = AIStates.Searching;
         int rowOld = row;
         int colOld = col;
         SearchCoords(ref row, ref col);
         AddTarget(row, colOld);
         AddTarget(rowOld, col);
     }
     else if (result.Value == ResultOfAttack.ShotAlready)
     {
         throw new ApplicationException("Error in AI");
     }
 }
示例#15
0
    //Patrol method for rotating
    void Patrol(Text text, AISense sense)
    {
        isSpotted = false;
        // Do Patrol
        transform.Rotate(0, 0, -Time.deltaTime * rotationSpeed);

        // Check for Transitions
        if (sense.CanSee(GameManager.instance.player) || sense.CanHear(GameManager.instance.player, GameManager.instance.noiseMaker.volume))
        {
            //Since spotted, increase the counter
            text.text = "Times Spotted: " + ++timesSpotted;

            //currentstate is now Chasing
            currentState = AIStates.ChaseAndFire;
        }
    }
示例#16
0
        public void OnAction(Entity entity)
        {
            if (entity.Name == "Player")
            {
                //Delete(entity);
            }

            if ((entity.Mask & MASK) == MASK)
            {
                List <IComponent> components = entity.Components;

                IComponent healthComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_HEALTH);
                });

                IComponent ammoComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_AMMO);
                });

                ComponentAI aiComponent = (ComponentAI)components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_AI);
                });
                AIStates state = aiComponent.CurrentState;


                IComponent pickupComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_PICK_UP);
                });

                IComponent aliveComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_ALIVE);
                });

                PowerUp((ComponentHealth)healthComponent, (ComponentAmmo)ammoComponent, (ComponentPickUp)pickupComponent, (ComponentAlive)(aliveComponent));


                if (pickupComponent == null && aliveComponent == null)
                {
                    Delete(entity);
                }
            }
        }
示例#17
0
    private void IdentifyDriftTimeAndRotation()
    {
        int direction = Random.Range(0, 2);

        if (direction == 0)
        {
            carDirection = CarDirection.Right;
        }
        else
        {
            carDirection = CarDirection.Left;
        }

        StartCoroutine(Drifting(RandomDriftingTime()));

        aIState = AIStates.Drift;
    }
        protected void checkStateBehaviour()
        {
            switch (currentState)
            {
            case AIStates.Patrol:
                if (agent.remainingDistance < 0.3f && !nextPathCalculated)
                {
                    nextPathCalculated = true;
                    setAgentParameters(0, 0);
                    setAnimatorParameters("Speed", 0);
                    co = StartCoroutine(loadAnimationSeek());
                }
                break;

            case AIStates.Peace:
                if (agent.remainingDistance < 0.3f && !nextPathCalculated)
                {
                    nextPathCalculated = true;
                    setAgentParameters(0, 0);
                    setAnimatorParameters("Speed", 0);
                    co = StartCoroutine(loadAnimationSeek());
                }
                break;

            case AIStates.Feeding:
                if (!seeking_food)
                {
                    setFoodPoint();
                }
                break;

            case AIStates.Alerted:
                //nada
                setAnimatorParameters("Speed", 3);
                break;

            case AIStates.Attack:
                //nada
                break;

            default:
                currentState = AIStates.Patrol;
                setNextRandomPoint();
                break;
            }
        }
示例#19
0
 /// <summary>
 /// ProcessShot will be called uppon when a ship is found.
 /// It will create a stack with targets it will try to hit. These targets
 /// will be around the tile that has been hit.
 /// </summary>
 /// <param name="row">The row it needs to process.</param>
 /// <param name="col">The column it needs to process.</param>
 /// <param name="result">The result og the last shot (should be hit).</param>
 protected override void ProcessShot(int row, int col, AttackResult result)
 {
     // If the attack hits.
     if (result.Value == ResultOfAttack.Hit)
     {
         _CurrentState = AIStates.TargetingShip;
         AddTarget(row - 1, col);
         AddTarget(row, col - 1);
         AddTarget(row + 1, col);
         AddTarget(row, col + 1);
     }
     // If the attack is at a place that is already attacked.
     else if (result.Value == ResultOfAttack.ShotAlready)
     {
         throw (new ApplicationException("Error in AI"));
     }
 }
示例#20
0
        /// <summary>
        /// TargetCoords is used when a ship has been hit and it will try to avoid
        /// the ship
        /// </summary>
        /// <param name="row">row generated around the hit tile</param>
        /// <param name="column">column generated around the hit tile</param>
        private void FindTargetCoords(ref int row, ref int column)
        {
            Location l = _Targets.Pop();


            if ((_Targets.Count == 0))
            {
                _CurrentState = AIStates.Searching;
            }

            row    = l.Row;
            column = l.Column;
            while (row == l.Row && column == l.Column)
            {
                SearchCoords(ref row, ref column);
            }
        }
示例#21
0
 public override AIStates OnGetHit(Mobile by, AIStates AIState, int dmg)
 {
     if (AIState != AIStates.Attack && AIState != AIStates.Fighting)
     {
         OnBeginFight(by);
         if (by == From)
         {
             From.AttackTarget = From.LastOffender;
         }
         else
         {
             From.AttackTarget = by;
         }
         return(AIStates.BeingAttacked);
     }
     return(AIState);
 }
        // Update is called once per frame
        public void FixedUpdate()
        {
            if (currentState == AIStates.Dead)
            {
                return;
            }

            //Si no está en alerta o attaque accede aquí así restamos si tiene hambre
            if (!currentState.Equals(AIStates.Alerted) && !currentState.Equals(AIStates.Attack) && !currentState.Equals(AIStates.Peace))
            {
                //coroutinePatrolEnded indica si las coroutines han terminado así no mezclamos animaciones ni estados durante las animaciones
                if (!currentState.Equals(AIStates.Feeding) && !feeding && coroutinePatrolEnded)
                {
                    hungry -= hungry_time;
                    if (hungry < 0)
                    {
                        hungry = 0;
                    }
                    if (hungry < min_hungry)
                    {
                        currentState = AIStates.Feeding;
                    }
                }
                //si está comiendo restauramos el hambre a 100 y volvemos al estado Patrol
                else if (feeding && coroutinePatrolEnded)
                {
                    hungry += hungry_time * 50;
                    if (hungry >= 90f && !currentState.Equals(AIStates.Alerted) && !currentState.Equals(AIStates.Attack))
                    {
                        Debug.Log("ENTRO IF FEEDING UPDATE");
                        setAnimatorParameters("Feeding_bool", false);
                        hungry       = 100;
                        currentState = AIStates.Patrol;
                        seeking_food = false;
                        feeding      = false;

                        StartCoroutine(wait());
                    }
                }
            }

            //chequeamos los estados aunque en realidad solo dos estados aquí los demás estados se activan por eventos
            // de los colliders VISION Y ATTACK_COLLIDER
            checkStateBehaviour();
        }
示例#23
0
    /// <summary>
    /// ProcessShot will be called uppon when a ship is found.
    /// It will create a stack with targets it will try to hit. These targets
    /// will be around the tile that has been hit.
    /// </summary>
    /// <param name="row">the row it needs to process</param>
    /// <param name="col">the column it needs to process</param>
    /// <param name="result">the result og the last shot (should be hit)</param>

    protected override void ProcessShot(int row, int col, AttackResult result)
    {
        if (result.Value == ResultOfAttack.Hit)
        {
            _CurrentState = AIStates.TargetingShip;
            Random rnd         = new Random();
            int    row_rand    = rnd.Next(-1, 1);
            int    column_rand = rnd.Next(-1, 1);
            AddTarget(row - 1 + row_rand, col + column_rand);
            AddTarget(row + row_rand, col - 1 + column_rand);
            AddTarget(row + 1 + row_rand, col + column_rand);
            AddTarget(row + row_rand, col + 1 + column_rand);
        }
        else if (result.Value == ResultOfAttack.ShotAlready)
        {
            throw new ApplicationException("Error in AI");
        }
    }
示例#24
0
        // '' <summary>
        // '' ProcessHit gets the last hit location coordinates and will ask AddTarget to
        // '' create targets around that location by calling the method four times each time with
        // '' a new location around the last hit location.
        // '' It will then set the state of the AI and if it's not Searching or targetingShip then
        // '' start ReOrderTargets.
        // '' </summary>
        // '' <param name="row"></param>
        // '' <param name="col"></param>

        public void ProcessHit(int row, int col)
        {
            _LastHit.Add(_CurrentTarget);
            AddTarget((row - 1), col);
            AddTarget(row, (col - 1));
            AddTarget((row + 1), col);
            AddTarget(row, (col + 1));
            if ((_CurrentState == AIStates.Searching))
            {
                _CurrentState = AIStates.TargetingShip;
            }
            else
            {
                // either targetting or hitting ... both are the same here
                _CurrentState = AIStates.HittingShip;
                ReOrderTargets();
            }
        }
示例#25
0
 // Use this for initialization
 void Start()
 {
     if (patrolPoints.Length == 0 || patrolPoints[0] == null)
     {
         state = AIStates.Idle;
     }
     else
     {
         state = AIStates.Patroling;
     }
     if (patrolPoints.Length > 0 && patrolPoints[0] != null)
     {
         agent.SetDestination(patrolPoints[Random.Range(0, patrolPoints.Length)].position);
     }
     animation = GetComponentInChildren <Animator>();
     player    = GameObject.FindGameObjectWithTag("Player");
     alarm     = GameObject.FindGameObjectWithTag("alertbar").GetComponent <Alarm>();
 }
示例#26
0
 private void AIDecisions()
 {
     if (null == currentTarget)
     {
         state = AIStates.patrol;
     }
     else if (null != currentTarget && previouslyAttackedTarget != currentTarget)
     {
         if (navMeshAgent.remainingDistance > navMeshAgent.stoppingDistance)
         {
             state = AIStates.chase;
         }
         else //if (navMeshAgent.remainingDistance < navMeshAgent.stoppingDistance)
         {
             state = AIStates.attack;
         }
     }
 }
示例#27
0
            void PlayStateTransitionVoice(AIStates overrideVoice = AIStates.None)
            {
                overrideVoice = (overrideVoice == AIStates.None) ? currentState : overrideVoice;
                switch (overrideVoice)
                {
                case AIStates.Hostile:
                    break;

                case AIStates.Suspicious:
                    break;

                case AIStates.Calm:
                    break;

                default:
                    break;
                }
            }
示例#28
0
    private void OnStateEnter(AIStates state, AIStates fromState)
    {
        switch (state)
        {
        case AIStates.Idling:
        {
            MaxStableMoveSpeed = 0f;

            break;
        }

        case AIStates.Chasing:
        {
            MaxStableMoveSpeed = settings.MaxStableMoveSpeed;
            break;
        }
        }
    }
示例#29
0
    protected IEnumerator Patrol()
    {
        while (this.enabled && currentState == AIStates.Patrol)
        {
            agent.speed = Mathf.Lerp(agent.speed, walkSpeed, 2f * Time.deltaTime);
            Transform waypoint = null;

            this.UpdatePath(waypoint);

            // check transitions
            if (!HasTarget())
            {
                currentState = AIStates.Patrol;
                break;
            }

            yield return(null);
        }
    }
示例#30
0
    // Use this for initialization
    void Start()
    {
        // Get Starting Position
        InitialPoint = this.transform.position;
        // Set Dying to false
        Dying = false;
        // Set Manipulated to false
        Manipulated = false;
        // Set Default state to IDLE
        ThisAIState = AIStates.IDLE;
        // Get NavMeshAgent component
        ThisNavAgent = this.GetComponent <NavMeshAgent>();
        // Get reference to Player
        PlayerReference = GameObject.FindGameObjectWithTag("Player");
        // First Random Position
        ThisNavAgent.destination = NewRandomPosition();

        anim = GetComponentInChildren <Animator>();
    }
示例#31
0
        private void PlayerDetection(ComponentPosition pos, ComponentVelocity vel, AIStates state)
        {
            if (state == AIStates.Wandering)
            {
                Vector2 AIpos = new Vector2(pos.Position.X, pos.Position.Z);
                Vector2 v     = MyGame.NewCameraPosition - AIpos;

                float dot = MyGame.DotProduct(v.Normalized(), AIpos.Normalized());

                if (dot > 0.7)
                {
                    droneSpeed = 0.8f;
                }
                else
                {
                    droneSpeed = 0.5f;
                }
            }
        }
示例#32
0
 private void MoveTo()
 {
     //If the target is in position we switch tto the attack state
     if (Position.DistanceTo(target.Position) < 300)
     {
         //Change the state to the attack state
         myState = AIStates.Attack;
     }
     else
     {
         //Get the direction to move in
         Vector2 dir = target.Position - Position;
         //Normalizing direction for movement
         dir = dir.Normalized();
         //Move and slide has the phsics delta already worked in and using it helps the objects slide past each other
         MoveAndSlide(dir * speed);
         //Rotate to target
         Rotation = Mathf.LerpAngle(Rotation, dir.Angle(), 0.2f);
     }
 }
示例#33
0
        /// <summary>
        /// ProcessHit gets the last hit location coordinates and will ask AddTarget to
        /// create targets around that location by calling the method four times each time with
        /// a new location around the last hit location.
        /// It will then set the state of the AI and if it's not Searching or targetingShip then
        /// start ReOrderTargets.
        /// </summary>
        /// <param name="row"></param>
        /// <param name="col"></param>
        private void ProcessHit(int row, int col)
        {
            _LastHit.Add(_CurrentTarget);

            // Uses _CurrentTarget as the source
            AddTarget(row - 1, col);
            AddTarget(row, col - 1);
            AddTarget(row + 1, col);
            AddTarget(row, col + 1);
            if (_CurrentState == AIStates.Searching)
            {
                _CurrentState = AIStates.TargetingShip;
            }
            else
            {
                // either targetting or hitting... both are the same here
                _CurrentState = AIStates.HittingShip;
                ReOrderTargets();
            }
        }
示例#34
0
        public void SetAnimVars(AIStates state)
        {
            switch (state)
            {
            case AIStates.Calm:
                animator.anim.SetBool(animator.hostile, false);
                animator.anim.SetBool(animator.suspicious, false);
                break;

            case AIStates.Suspicious:
                animator.anim.SetBool(animator.hostile, false);
                animator.anim.SetBool(animator.suspicious, true);
                break;

            case AIStates.Hostile:
                animator.anim.SetBool(animator.hostile, true);
                animator.anim.SetBool(animator.suspicious, true);
                break;
            }
        }
示例#35
0
 private void HandleMelee()
 {
     if (AIState == AIStates.Melee)
     {
         if (currentAttackLoadTime <= 0)
         {
             character.Attack();
             currentTimeBetweenAttacks = timeBetweenAttacks;
             AIState        = AIStates.Wait;
             targetPosition = target.targetObject.transform.position;
             movementController.lastInputMove = (targetPosition - this.transform.position).normalized;
             SetToIdleAfter(attackLoadTime);
             character.immune = false;
         }
         else
         {
             currentAttackLoadTime -= Time.deltaTime;
         }
     }
 }
示例#36
0
    // <summary>
    // ProcessShot will be called uppon when a ship is found.
    // It will create a stack with targets it will try to hit. These targets
    // will be around the tile that has been hit.
    // </summary>
    // <param name="row">the row it needs to process</param>
    // <param name="col">the column it needs to process</param>
    // <param name="result">the result og the last shot (should be hit)</param>

    protected override void ProcessShot(int row, int col, AttackResult result)
    {
        Random random = new Random();

        if (result.Value == ResultOfAttack.Hit)
        {
            _CurrentState = AIStates.TargetingShip;

            AddTarget(row - 1, col);
            int num = random.Next(5);
            if (num == 1)
            {
                AddTarget(row - 1, col - 1);
            }

            AddTarget(row, col - 1);
            num = random.Next(5);
            if (num == 1)
            {
                AddTarget(row + 1, col - 1);
            }

            AddTarget(row + 1, col);
            num = random.Next(5);
            if (num == 1)
            {
                AddTarget(row + 1, col + 1);
            }

            AddTarget(row, col + 1);
            num = random.Next(5);
            if (num == 1)
            {
                AddTarget(row - 1, col + 1);
            }
        }
        else if (result.Value == ResultOfAttack.ShotAlready)
        {
            throw new ApplicationException("Error in AI");
        }
    }
示例#37
0
	// Find our nearest target, whether it be a player, enemy, or item, based
	// on what state we are currently in and what is available.
	Transform FindNearestTarget()
	{
		Transform nearestTarget = null;
		if( (aiState != AIStates.Pursue_Item && ( (!IsEnemy && Manager_Targeting.instance.enemyTargets.Count == 0)
		     || (IsEnemy && Manager_Targeting.instance.playerTargets.Count == 0) ) )
		   || (aiState == AIStates.Pursue_Item && (detectionRadius == null
		   || detectionRadius.inRangeItems.Count == 0 && detectionRadius.itemStorersInRange.Count == 0)))
		{
			if(aiState == AIStates.Pursue_Item)
				aiState = AIStates.Pursue; // If we were pursuing an item, there were none nearby so pursue again.
			return null;
		}
		// Setup our correct target list to check from.
		float shortestSoFar = 100;
		List<Transform> targets = Manager_Targeting.instance.playerTargets;
		if(aiState == AIStates.Pursue_Item)
		{
			// Put the names of all of your healing items in that Any() and All() parts I have
			// since that checks for healing items. You can just put a part of
			// their name. They will only attempt to go after those if their
			// health isn't maxed. If any are not healing, they will go after any of the
			// ones that aren't healing then using All to make sure the item's name is not in _healingItemNames.
			// You can check below in the foreach loop where we check for dist < shortestSoFar
			if(detectionRadius.inRangeItems.Count > 0 && ( (_charStatus.Stats[0] < _charStatus.Stats[1]
				&& detectionRadius.inRangeItems.Any(item => item != null && _healingItemNames.Any(itemName => item.name.Contains(itemName)) ) )
				|| (detectionRadius.inRangeItems.Any(item => item != null && _healingItemNames.All(itemName => !item.name.Contains(itemName)) ) )) )
				targets = detectionRadius.inRangeItems;
			else if(detectionRadius.itemStorersInRange.Count > 0)
				targets = detectionRadius.itemStorersInRange;
			else
			{
				// No need to pursue item then. This stuff is here just in case we
				// reach here.
				aiState = AIStates.Wander;
				targetForNavMesh = null;
				return null;
			}
		}
		else // Not pursuing an item.
		{
			// For players to target enemies.
			if(!IsEnemy)
				targets = Manager_Targeting.instance.enemyTargets;
		}
		foreach(Transform curTarget in targets)
		{
			if(curTarget != null)
			{
				// Just another check seeing if an item checking doesn't have a parent.
				// Detection radius already does this but double checks can be good.
				// If a character is what we are looking at, we make sure they are
				// alive.
				if(((curTarget.tag == "Player" || curTarget.tag == "Enemy") && curTarget.GetComponent<CharacterStatus>().Stats[0] > 0)
				   || (curTarget.tag == "ItemStorer" || (curTarget.tag == "Item" && curTarget.parent == null)))
				{
					if(curTarget.tag == "Item"
					   && curTarget.GetComponent<Base_Item>().ItemType == Base_Item.ItemTypes.Collectable)
					{
						// If we are checking an item and we have less than
						// 90% health left and the item is a collectable, we will
						// go for that right away.
						if(_charStatus.Stats[0] < _charStatus.Stats[1] * 0.9f)
						{
							nearestTarget = curTarget;
							break;
						}
					}
					float dist = Vector3.Distance(transform.position, curTarget.position);
					// Here we check to see that the distance checking is less than the shortest so far.
					// Then we see if the curTarget is not an item, or if it is, we see that we have less than
					// max health and the curTarget is a healing item, otherwise, we simply check that it is not
					// a healing item.
					if(dist < shortestSoFar && (curTarget.tag != "Item" || ( (_charStatus.Stats[0] < _charStatus.Stats[1] && _healingItemNames.Any(itemName => curTarget.name.Contains(itemName) ) )
						|| (_healingItemNames.All(itemName => !curTarget.name.Contains(itemName) ) ) ) ) )
					{
						shortestSoFar = dist;
						nearestTarget = curTarget;
					}
				}
			}
		}
		if(nearestTarget != null)
		{
			if(nearestTarget.tag == "Player" || nearestTarget.tag == "Enemy")
			{
				// We now have a targeted character.
				_charAttacking.TargetedCharacter = nearestTarget;
				// AI players also retarget the same way human players do.
				if(gameObject.tag == "Player")
					Manager_Targeting.instance.TargetACharacter(_charStatus.PlayerNumber, _charAttacking);
				// Get references from them.
				targetCharStatus = nearestTarget.GetComponent<CharacterStatus>();
				targetDetRadius = targetCharStatus.detectionRadius;
			}
			this.targetForNavMesh = nearestTarget;
		}
		return nearestTarget;
	}
示例#38
0
    /** Initializes reference variables.
     * If you override this function you should in most cases call base.Awake () at the start of it.
      * */
    protected virtual void Awake()
    {
        seeker = GetComponent<Seeker>();

        AnimControl = GetComponent<AIStates>();

        //This is a simple optimization, cache the transform component lookup
        tr = transform;

        //Make sure we receive callbacks when paths complete
        seeker.pathCallback += OnPathComplete;

        //Cache some other components (not all are necessarily there)
        controller = GetComponent<CharacterController>();
        navController = GetComponent<NavmeshController>();
        rigid = rigidbody;
    }
 void UpdateState()
 {
     if (health < 1) curstate = AIStates.Dead;
 }
示例#40
0
    // Update is called once per frame
    void Update()
    {
        switch(currentState) {

        case AIStates.MOVING_RIGHT:
            transform.Translate(new Vector3(moveSpeed * Time.deltaTime, 0, 0), Space.World);

            if(transform.position.x - player.position.x > 5)
                currentState = AIStates.MOVING_LEFT;

            break;

        case AIStates.MOVING_LEFT:
            transform.Translate(new Vector3(-moveSpeed * Time.deltaTime, 0, 0), Space.World);

            if(transform.position.x - player.position.x < -5) {
                // Set up the swoop info
                startPosition = transform.position;
                endPosition = player.transform.position;
                swoopCenter = player.transform.position;
                swoopCenter.y = transform.position.y; // above the player at the bee's level

                startSwoop = startPosition - swoopCenter;
                endSwoop = endPosition - swoopCenter;

                currentState = AIStates.SWOOPING_DOWN;
            }

            break;

        case AIStates.SWOOPING_DOWN:
            swoopTime += Time.deltaTime;
            transform.position = Vector3.Slerp(startSwoop, endSwoop, swoopTime * 2);
            transform.position += swoopCenter;
            if(swoopTime > 0.5f) {
                swoopTime = 0.0f;

                // Calculate second half of swoop
                Vector3 temp = startPosition;
                startPosition = endPosition;
                endPosition = temp + new Vector3(10, 0, 0);

                startSwoop = startPosition - swoopCenter;
                endSwoop = endPosition - swoopCenter;

                currentState = AIStates.SWOOPING_UP;
            }

            break;

        case AIStates.SWOOPING_UP:
            swoopTime += Time.deltaTime;
            transform.position = Vector3.Slerp(startSwoop, endSwoop, swoopTime * 2);
            transform.position += swoopCenter;
            if(swoopTime > 0.5f) {
                swoopTime = 0.0f;

                currentState = AIStates.MOVING_LEFT;
            }

            break;
        default:
            break;

        }

        switch(currentHealth) {
        case 3:
            transform.Find("MeanBee").renderer.material.mainTexture = beeTextures[0];
            break;
        case 2:
            transform.Find("MeanBee").renderer.material.mainTexture = beeTextures[1];
            break;
        case 1:
            transform.Find("MeanBee").renderer.material.mainTexture = beeTextures[2];
            break;
        default:
            // Empty the bar, then destroy the Bee object
            Destroy(beeHealthBarFill);
            Destroy(gameObject);
            break;

        }
    }
示例#41
0
        /// <summary>
        /// ProcessHit gets the last hit location coordinates and will ask AddTarget to
        /// create targets around that location by calling the method four times each time with
        /// a new location around the last hit location.
        /// It will then set the state of the AI and if it's not Searching or targetingShip then
        /// start ReOrderTargets.
        /// </summary>
        /// <param name="row"></param>
        /// <param name="col"></param>
        private void ProcessHit(int row, int col)
        {
            _LastHit.Add(_CurrentTarget);

            //Uses _CurrentTarget as the source
            AddTarget(row - 1, col);
            AddTarget(row, col - 1);
            AddTarget(row + 1, col);
            AddTarget(row, col + 1);

            if (_CurrentState == AIStates.Searching)
            {
                _CurrentState = AIStates.TargetingShip;
            }
            else
            {
                //either targetting or hitting... both are the same here
                _CurrentState = AIStates.HittingShip;

                ReOrderTargets();
            }
        }
示例#42
0
	// Here we check to see if we can attack and what distance away we are.
	// If we are holding a throwable, the distance will be increased so that
	// we can throw it at a further range.
	void AttemptAttack(float distFromTarget)
	{
		if(targetCharStatus == null || (detectionRadius.inCloseRangeChar.Count == 0
		   && anim.GetInteger("HoldStage") != 1)) // HoldStage 1 means we are holding a throwable.
			return;
		float minDistUsing = minAttackDist;
		float maxDistUsing = maxAttackDist;
		bool holdingThrowable = false;
		if(anim.GetInteger("HoldStage") == 1)
		{
			maxDistUsing = maxAttackDist + 3;
			holdingThrowable = true;
		}

		// This part determines if we are in range to attack.
		if(distFromTarget > minDistUsing && distFromTarget < maxDistUsing)
		{
			// Face our target when within range and in idle. Otherwise just get the angle from us
			// facing our target currently.
			float angle = FaceCharacterTarget();
			// If facing our target by a good amount and making sure
			// they are vulnerable and are not guarding. If they are, they will
			// have a small chance of attacking.
			if(targetCharStatus.Vulnerable) // Make sure they are Vulnerable.
			{
				if(angle < 55
				   && (!targetCharStatus.BaseStateInfo.IsTag("Guard")
				   || (targetCharStatus.BaseStateInfo.IsTag("Guard") && Random.value > 0.95f)))
				{
					if(Random.Range(0, 100) < attackRatio)
					{
						if(!holdingThrowable)
						{
							// Attempt a grab. Grabs are done by moving slightly.
							if(canUseGrabs && _charItem.ItemHolding == null && anim.GetFloat("Move") > 0.2f && Random.value > 0.7f)
								_charAttacking.AttackSetup(3, 0); // Attempt grab.
							else
							{
								int attackUsed = 1;
								if(anim.GetFloat("Move") > 0.94f)
									attackUsed = 2; // If moving too fast, go for the slide attack.
								float vDir = 0;
								// If we are next to an itemStorer, we will use our
								// low attack and kick it.
								if(detectionRadius.NextToItemStorer && detectionRadius.inCloseRangeChar.Count == 0)
									vDir = -1;
								_charAttacking.AttackSetup(attackUsed, vDir);
							}
						}
						// If we are holding a throwable, then throw it!
						else _charItem.Throw();
					}
				}
			}
			else // They aren't vulnerable so a random chance to retreat below.
				// if they aren't simply dodging.
			{
				if(!targetCharStatus.BaseStateInfo.IsTag("Dodging"))
					if(Random.Range(0f, 20f) > 19f)
						aiState = AIStates.Retreat;
			}
		}
	}
        public override void Update(GameTime gameTime)
        {
            Player player = GetNeareastPlayer();

            switch (AIState)
            {
                case AIStates.DODGE:

                    break;
                case AIStates.ATTACK:

                    break;
                case AIStates.ROAM:
                    if (!(Vector2.Distance(DestinationPos, Position) < 5))
                    {
                        var dir = DestinationPos - Position;
                        dir.Normalize();
                        Position += dir * 5f;
                    }
                    else
                    {
                        destPos = new Vector2(rand.Next(width / 2 + 5, Game1.GAME_WIDTH - width / 2),
                            rand.Next(height / 2 + 5, Game1.GAME_HEIGHT - height / 2));
                    }
                    break;
                default:
                    AIState = AIStates.DODGE;
                    break;
            }

            foreach (Player p in GameplayState.Players)
            {
                // Why would I check if my bullets hit me? Well... there's probably many
                //     resons but for now, keep it my way.
                if (p == this) continue;

                // Laser guns are an exception to bullet checks... instead, they're just a
                // giant rectangle.  The laser isn't removed if it's hitting me
                if (p.equippedWeapon.GetType() == typeof(LaserGun))
                {
                    var weapon = (LaserGun)p.equippedWeapon;
                    if (weapon.Laser.Bounds.Intersects(Bounds) && weapon.Laser.IsActive)
                        Damage(p.equippedWeapon.Damage);
                }
                else
                {
                    // Here's the bullet foreach loop, it just uses a fancy lambda expression
                    p.equippedWeapon.Bullets.ForEach((b) =>
                    {
                        // If there's no forcefield then KILL ME
                        if (!forceField)
                        {
                            if (b.Bounds.Intersects(Bounds))
                            {
                                Damage(p.equippedWeapon.Damage);
                                b.DestroyMe = true;
                            }
                        }
                        // If there is a force field then don't kill me
                        else
                        {
                            if (b.Bounds.Intersects(ForceFieldBounds))
                            {
                                b.DestroyMe = true;
                            }
                        }
                    });
                }
            }

            equippedWeapon.Update(gameTime);
        }
示例#44
0
    // Use this for initialization
    void Start()
    {
        textPanel.SetActive(false);
        updateLocation();
        if(board == null) {
            board = GameObject.Find("Board");
        }
        if(goalPoint == null) {
            // Debug.Log("goal being set");

            chooseNewGoal();
            //  Debug.Log(string.Format("the goalpoint name is {0}", goalPoint));
            findPath();
            state = AIStates.IDLE;
            // state = (AIStates)Random.Range(0, 3);
        }
        Player.turn += StateMachine;

        // this flags all the squares as hot
        foreach(GameObject square in persueRoom) {
            square.GetComponent<ClickObject>().personalSquare();
        }
    }
示例#45
0
	void OnEnable()
	{
		// Reenable our Agent if it isn't active.
		if(Agent)
		{
			if(!Agent.gameObject.activeSelf)
				Agent.gameObject.SetActive(true);
			Agent.Resume();
		}
		if(!IsEnemy)
			aiState = AIStates.Wander; // Default state upon enable for players.
	}
示例#46
0
        //Pet bobs around a point.
        void Idle()
        {
            switch (_currentIdleState)
            {
                case IdleState.NONE:
                    break;
                case IdleState.RECORDING_POSITON:
                    lastLocation = transform.position;
                    _currentIdleState = IdleState.DOIN_MY_THANG;
                    break;
                case IdleState.DOIN_MY_THANG:
                    transform.position = new Vector3(transform.position.x,lastLocation.y + ((float)Math.Sin(Time.time) / floatingStrength),transform.position.z);
                    idleTimeLeft -= Time.deltaTime;
                    if (idleTimeLeft < 0f)
                        _currentAIState = AIStates.DECIDING;

                    break;
            }
            //Currently Only Moves Up and Down.
        }
示例#47
0
        void CheckParalyze()
        {
            if (rb.velocity != Vector3.zero && rb.angularVelocity != Vector3.zero)
            {
                if (_currentAIState == AIStates.PLAYING)
                    _currentPlayingState = PlayingState.STUNNED;
                else
                    _currentAIState = AIStates.PARALYZED;

            }

            //_currentAIState = AIStates.IDLING;
        }
示例#48
0
 public override AIStates OnGetHit( Mobile by, AIStates AIState, int dmg )
 {
     if ( by != summonedFrom && AIState != AIStates.Attack && AIState != AIStates.Fighting )
         return AIStates.BeingAttacked;
     return AIState;
 }
示例#49
0
 void Stabalize()
 {
     if (_currentAIState == AIStates.PARALYZED)
     {
         if (Time.time > stablizeTime + stablizeCooldown)
         {
             stablizeTime = Time.time;
             rb.velocity = Vector3.zero;
             rb.angularVelocity = Vector3.zero;
             _currentAIState = AIStates.DECIDING;
         }
     }
     else if (_currentPlayingState == PlayingState.STUNNED)
     {
         if (Time.time > playStablizeTime + playStablizeCooldown)
         {
             playStablizeTime = Time.time;
             rb.velocity = Vector3.zero;
             rb.angularVelocity = Vector3.zero;
             _currentPlayingState = PlayingState.SETTING_UP;
         }
     }
 }
 // Use this for initialization
 void Start()
 {
     myState = AIStates.Roaming;
 }
示例#51
0
 public void Play()
 {
     _currentAIState = AIStates.PLAYING;
     if (_currentPlayingState == PlayingState.NONE)
         _currentPlayingState = PlayingState.SETTING_UP;
 }
示例#52
0
	// This is only called for enemies.
	public IEnumerator SpawnIn(EnemySpawnType spawnType)
	{
		// Make sure the enemies are spawned with the rotation of the spawn point
		// so make it face the direction facing the trigger area for the current
		// battle zone.
		aiState = AIStates.Spawn;
		Vector3 moveDir = myTransform.forward;
		// Entered area becomes true after exiting our spawn spot trigger bounds
		// for the current area.
		while(!_enteredArea)
		{
			if(spawnType == EnemySpawnType.Normal)
				_charMotor.Move(moveDir, false, false);
			else if (spawnType == EnemySpawnType.Find_Way && !targetForNavMesh)
				targetForNavMesh = FindNearestTarget();
			yield return new WaitForSeconds(0.0001f);
		}
		// We can now target a character.
		// I just change the character's name to the name given in the
		// corresponding enum. Just a personal preference.
		gameObject.name = _charStatus.myCharacterEnemy.ToString ();
		aiState = AIStates.Wander;
		_charStatus.Vulnerable = true; // We can now be hit.
		// We are now added to the enemyTargets list so players can target us.
		Manager_Targeting.instance.enemyTargets.Add (myTransform);
		StopCoroutine ("SpawnIn");
		yield break;
	}
示例#53
0
        void Deciding()
        {
            ResetAIStates();

            if (IsOutOfPlayerLimits())
            {
                _currentAIState = AIStates.RETURNING;
                if (_currentReturningState == ReturningState.NONE)
                    _currentReturningState = ReturningState.LOOKING_FOR_TARGET;
            }
            else
            {
                if (Random.value < 0.5f)
                {
                    _currentAIState = AIStates.IDLING;
                    if (_currentIdleState == IdleState.NONE)
                        _currentIdleState = IdleState.DOIN_MY_THANG;
                }
                else
                {
                    _currentAIState = AIStates.ROAMING;
                    if (_currentRoamingState == RoamingState.NONE)
                        _currentRoamingState = RoamingState.LOOKING_FOR_TARGET;
                }
            }
        }
示例#54
0
	void Update()
	{
		if(Manager_Cutscene.instance.inCutscene || Manager_Game.instance.IsPaused)
			return;

		if(_charStatus.Busy)
		{
			// If we are in an attack state...
			if(_charStatus.BaseStateInfo.IsTag("Attack") && !_charStatus.BaseStateInfo.IsName("Atk_Slide"))
			{
				// If we landed an attack and are no longer in attack hit delay...
				if(Manager_BattleZone.instance.InBattle && anim.GetBool("AttackHit") && _charAttacking.HitDelayTime == 0)
				{
					// Atk_HeavyHigh is the launch attack state that sends the
					// hit character into the air setting them up for air combos.
					if(!_charStatus.BaseStateInfo.IsName("Atk_HeavyHigh"))
					{
						if(!_charStatus.BaseStateInfo.IsName("Atk_Heavy_N")) // Only bother if we are not in our finisher.
						{
							// Choose a combo if we haven't achieved a long enough one
							// past our max given only if there is only one character in close range,
							// or we are an enemy and are not in hard.  Otherwise we will attempt to
							// dodge since you can dodge after an attack hits. AI players act more
							// like hard AI enemies.
							bool chooseToCombo = (!IsEnemy && detectionRadius.inCloseRangeChar.Count < 2)
								|| (IsEnemy && (_difficulty != GameDifficulty.Hard || detectionRadius.inCloseRangeChar.Count < 2));
							if(chooseToCombo && _charAttacking.Combo < maxCombo)
								ComboSetup();
							else if(!chooseToCombo && detectionRadius.inCloseRangeChar.Any(enemy => enemy.GetComponent<CharacterAttacking>().IsAttacking))
								_charAttacking.DodgeSetup(Random.Range(-1, 2), Random.Range(-1, 2));
						}
					}
					else // We launched the target up into the air, so we get ready to jump to pursue them.
					{
						if(canUseAirAttacks && (_charAttacking.TargetedCharacter && _charAttacking.TargetedCharacter.position.y > myTransform.position.y + 1.2f))
						{
							if(Random.value > 0.6f)
							{
								_charAttacking.AnimEventActivateHitbox(0);
								// True here is for jumping, no need to move (Vector3.zero)
								// Just jump.
								_charMotor.Move (Vector3.zero, true, false);
							}
						}
					}
				}
			}
			else if(_charStatus.BaseStateInfo.IsName("Guard_Hit"))
			{
				// Counter after being hit when guarding. Can only be done
				// before 80% of the animation has finished. Can be lowered if
				// desired.
				if(!anim.IsInTransition(0) && _charStatus.BaseStateInfo.normalizedTime < 0.8f
				   && Random.Range(0, 100) < attackRatio)
					_charAttacking.AttackSetup(1, 0);
			}
			// Next is where we attack or throw a grabbed character.
			else if(_charStatus.BaseStateInfo.IsTag("Grab"))
			{
				if(!anim.IsInTransition(0))
				{
					// Grab_Idle is the base grabbing state where we can
					// choose to throw or hit a grabbed character.
					if(_charStatus.BaseStateInfo.IsName("Grab_Idle"))
					{
						// I only make the AI hit a grabbed character no more
						// than 4 times (> 3). If they have, then they will
						// throw them.
						if(Random.value > 0.9f || _hitsWhileGrabbing > 3)
							_charAttacking.GrabAttackSetup(2); // Throw em'
						else
						{
							if(Random.Range (0, 100) < attackRatio)
							{
								_hitsWhileGrabbing++;
								_charAttacking.GrabAttackSetup(1); // Hit em'
							}
						}
					}
				}
			}
			else
			{
				// If we are guarding.
				if(anim.GetBool("IsGuarding"))
				{
					// If there are no more opposing characters nearby or
					// our targetedCharacter is no longer attacking.
					if(detectionRadius.inCloseRangeChar.Count == 0
					   || (targetCharStatus && !targetCharStatus.AmIAttacking))
					{
						if(anim.GetBool("IsGuarding") && Random.value > 0.5f)
						{
							// Stop guarding.
							anim.SetBool("IsGuarding", false);
						}
					}
				}
			}
			return;
		}
		// Checks to see if any items are present and nearby.
		bool itemsCloseNearby = detectionRadius.inGrabRangeItems.Count > 0;
		bool itemsNearby = detectionRadius.inRangeItems.Count > 0
			|| detectionRadius.itemStorersInRange.Count > 0;
		// See if player 1's health is less than ours - healthBelowForHealthItem (random amount), only applies to players of course.
		// Since there is only one other player, we check all players by using Any and see if the status we are checking
        // is not our own and if its health Stats[0] is less than our by our chosen amount. I use
		// this bool anytime we check for healing items below.
        bool letTeamMateGet = !IsEnemy && (Manager_Game.instance.allPlayerStatus.Any(status => status != _charStatus && status.Stats[0] < _charStatus.Stats[0] - healthBelowForHealthItem) );
		// Here is where I make the AI get rid of an item they are holding if they
		// find a healing item/collectable nearby if they have less than 90% health.
		if(_charItem.ItemHolding != null && (_charStatus.Stats[0] < _charStatus.Stats[1] * 0.9f))
		{
			// If there is a healing item nearby we seek it out by getting
			// rid of an item we are holding so we can grab that one and heal
			// ourselves, unless we are a player and player 1's health is less than ours.
			if(itemsNearby && detectionRadius.inRangeItems.Count > 0
				&& detectionRadius.inRangeItems.Any(item => item != null && _healingItemNames.Any(itemName => item.name.Contains(itemName))))
			{
				if(!letTeamMateGet && Random.value > 0.96f)
				{
					// Holding a weapon
					if(anim.GetInteger("HoldStage") == 3)
						_charItem.DropItem ();
					// Holding a throwable
					else if(anim.GetInteger("HoldStage") == 1)
						_charItem.Throw();
					// Target that item.
					targetForNavMesh = detectionRadius.inRangeItems.Find(item => item != null && _healingItemNames.Any(itemName => item.name.Contains(itemName)));
					aiState = AIStates.Pursue_Item;
				}
			}
		}

		// This next part is only for players when you aren't in battle. The AI
		// will follow the leader player, when they aren't going after an item that
		// is. Same goes for if there are no enemy targets present.
		if(!IsEnemy && (!Manager_BattleZone.instance.InBattle || Manager_Targeting.instance.enemyTargets.Count == 0))
		{
			if(_strafeDir != 0)
				_strafeDir = 0;
			if(!leadPlayer)
				return;
            if(itemsNearby)
			{
				if(Random.Range(0f, 20f) > 19.5f)
				{
					// First check to see if there are any item containers nearby. If not, next
					// check to see if there are items nearby, and if so, we look through them all and
					// see if any of their names contain one from our _healingItemNames array, otherwise,
					// we simply check to see that none of any of them are not a healing item by using All()
					// on the _healingItemNames array.
					if( detectionRadius.itemStorersInRange.Count > 0 ||
						(detectionRadius.inRangeItems.Count > 0 && (!letTeamMateGet
							&& detectionRadius.inRangeItems.Any(item => item != null && _healingItemNames.Any(itemName => item.name.Contains(itemName))) )
							|| (detectionRadius.inRangeItems.Any(item => item != null && _healingItemNames.All(itemName => !item.name.Contains(itemName))) ))
						|| (!letTeamMateGet && _charStatus.Stats[0] < _charStatus.Stats[1])) // Do not have full health.
					{
						aiState = AIStates.Pursue_Item;
						targetForNavMesh = FindNearestTarget();
					}
				}
			}
			// If we aren't pursuing an item, lets follow the leader player.
			if(aiState != AIStates.Pursue_Item && targetForNavMesh != leadPlayer)
			{
				if(Agent.stoppingDistance != _charStatus.PlayerNumber - 1)
					Agent.stoppingDistance = _charStatus.PlayerNumber - 1;
				targetForNavMesh = leadPlayer;
			}
			// Otherwise we want to get an item nearby first.
			else if(aiState == AIStates.Pursue_Item)
			{
				if(targetForNavMesh && (targetForNavMesh.tag == "Item"
				   || targetForNavMesh.tag == "ItemStorer"))
				{
					if(Agent.stoppingDistance != 0.3f)
						Agent.stoppingDistance = 0.3f;
					if(itemsCloseNearby)
					{
						if(_charStatus.BaseStateInfo.IsTag("NotBusy") &&
						   _charMotor.onGround)
						{
							if(Random.value > 0.98f)
							{
								_charItem.Pickup();
							}
						}
					}
					if(detectionRadius.NextToItemStorer)
					{
						FaceCharacterTarget(); // Face the item container.
						if(Random.value > 0.97f)
						{
							// Use low attack (-1 second parameter)
							_charAttacking.AttackSetup(1, -1);
						}
					}
				}
				if (!itemsNearby || _charItem.ItemHolding != null || targetForNavMesh == null)
					aiState = AIStates.Wander;
			}

			if(targetForNavMesh)
			{
				this.targetPos = targetForNavMesh.position;
				Agent.SetDestination(targetPos);
				// update the agent's position
				Agent.transform.position = myTransform.position;
				Vector3 moveDir = Agent.desiredVelocity.normalized;
				distFromTarget = Vector3.Distance(myTransform.position, targetForNavMesh.position);
				float distToSlowDown = (aiState != AIStates.Pursue_Item) ? 3 : 1.2f;
				if(distFromTarget < distToSlowDown) moveDir *= (aiState != AIStates.Pursue_Item ? 0.5f : 0.2f); // Walk or move very slow if pursuing an item and near it.
				// If the desired velocity is that small, just zero it out.
				// A personal preference of mine to aid in preventing the
				// character from doing unnecessary small movements.
				if(moveDir.magnitude < 0.2f)
					moveDir = Vector3.zero;
				_charMotor.Move(moveDir, false, _charAttacking.TargetedCharacter && distFromTarget < 3 && aiState != AIStates.Retreat); // AI will go into targeting and strafing mode if less than 3 units away from their targeted character and not retreating.
			}
			return;
		}
		// Have enemies just wander if there are no players around to target.
		// That would be in the case of a Game Over. If we don't have a
		// targetForNavMesh, we will simply choose random spots to move to around
		// our current location.
		if(IsEnemy && Manager_Targeting.instance.playerTargets.Count == 0)
		{
			aiState = AIStates.Wander;
			Wander ();
		}
		// Reset any hits given while grabbing a character after leaving
		// grabbing by either throwing or our grab being broken out of.
		if(_hitsWhileGrabbing > 0)
		{
			if(_charStatus.BaseStateInfo.IsName("Grab_Throw")
			   || _charStatus.BaseStateInfo.IsName("Grab_Break"))
				_hitsWhileGrabbing = 0;
		}
		// Players who have chosen a new path have a different stopping distance, the end boundary in the
		// current battle area's x and z position with their own y position.
		if(Agent.stoppingDistance != 0.1f && (IsEnemy || (!IsEnemy && !_choseNewPath)))
			Agent.stoppingDistance = 0.1f;
		distFromTarget = 10;
		float enemiesNearPlayer = 0;
		// This is the only place where a new targetForNavMesh is found for sake of
		// convenience. When you want to find a new one at some point, I make the
		// current one null, so during the next frame it will find a new one here
		// depending on what our current AI state is.
		if(aiState != AIStates.Spawn)
		{
			// I don't want players (!IsEnemy) to have another player targeted when
			// reaching this point since we are in battle.
			if(targetForNavMesh == null || (!IsEnemy && targetForNavMesh.tag == "Player"))
				targetForNavMesh = FindNearestTarget();
			else
			{
				if(targetForNavMesh.tag == "Item")
					distFromTarget = Vector3.Distance(myTransform.position, targetForNavMesh.position);
				else
				{
					if(_charAttacking.TargetedCharacter)
						distFromTarget = Vector3.Distance(new Vector3(myTransform.position.x, 0, myTransform.position.z),
						                                  new Vector3(_charAttacking.TargetedCharacter.position.x, 0, _charAttacking.TargetedCharacter.position.z));
				}
			}
			// An easy way to find out how many enemies are close to our
			// targeted character.
			if(targetDetRadius != null)
				enemiesNearPlayer = targetDetRadius.inCloseRangeChar.Count;
		}

		if(aiState != AIStates.Pursue)
			if(_strafeDir != 0)
				_strafeDir = 0; // Reset strafing if not pursuing.
		if (targetForNavMesh)
		{
			Vector3 move = Agent.desiredVelocity;
			float maxDistForRetreat = 5;
			// update the progress if the character has made it to the previous target
			if(aiState != AIStates.Retreat)
				targetPos = targetForNavMesh.position + _randomOffset;
			else // Retreating
			{
				// I found this part here works well for retreating from a target.
				if(targetForNavMesh && !_choseNewPath)
				{
                    if(distFromTarget < maxDistForRetreat)
                    {
                        targetPos = myTransform.position + ( (myTransform.position -
                            (targetForNavMesh.position) ) * maxDistForRetreat); // Go out at least as far as the distance you are checking against (maxDistForRetreat) so that the enemy stays away nicely
                    }
					else move = Vector3.zero; // Far enough away, don't need to move so we can face our target, done below with MinMovement on EnemyMotor.
				}
			}
			// If our retreat position has gone outside of the bounds of the navmesh...
			if (!Agent.hasPath && !_choseNewPath && _enteredArea && aiState == AIStates.Retreat)
			{
				// We will use the position of the end boundary for the current battle area, and use our
				// y position instead.
				Vector3 newPos = Manager_BattleZone.instance.zonesEnd[Manager_BattleZone.instance.currentAreaNumber].transform.position;
				newPos.y = myTransform.position.y + 0.05f;
				targetPos = newPos;
				if (!IsEnemy)
					Agent.stoppingDistance = 3; // The players can't get close enough to the end boundary since they can't go through its collider like the enemies so I increase this.
				_choseNewPath = true; // Now we can't change our new position until we get out of retreat since it would interfere.
			}
			Agent.SetDestination(targetPos);
			// update the agent's position 
			Agent.nextPosition = myTransform.position;
			if(move.magnitude < 0.1f)
				move = Vector3.zero;
			// This bool refers to if we should rotate and face our target, whether we are close enough and not retreating,
			// or far away enough when retreating.
			bool faceTarget = _charAttacking.TargetedCharacter && ((distFromTarget < 3 && aiState != AIStates.Retreat) || (aiState == AIStates.Retreat && distFromTarget > maxDistForRetreat));
			// use the values to move the character
			_charMotor.Move(move, jump, faceTarget);
		}
		else // If no target for nav mesh
		{
			// We still need to call the character's move method, but we send zeroed input as the move param.
			_charMotor.Move(Vector3.zero, jump, false);
		}
		if(jump) // Reset this in case we jumped above.
			jump = false;
		// This will be true if there are any opposing characters close by us.
		bool charCloseNearby = detectionRadius.inCloseRangeChar.Count > 0;

		if(targetForNavMesh == null)
			return;
		// A random chance of choosing a closer target if there is more
		// than one available.
		if(_charAttacking.TargetedCharacter)
		{
			// Choose appropriate list based on if we are an enemy or a player.
			List<Transform> charChecking = Manager_Targeting.instance.playerTargets;
			if(!IsEnemy) charChecking = Manager_Targeting.instance.enemyTargets;

			_changeNewTargetTimer += Time.deltaTime;
			if(_changeNewTargetTimer > Random.Range(4, 8))
			{
				_changeNewTargetTimer = 0;
				foreach(Transform character in charChecking)
				{
					if(character != null && character != _charAttacking.TargetedCharacter)
					{
						if(Vector3.Distance(myTransform.position, character.position) < distFromTarget)
						{
						   if(Random.value > 0.5f)
							{
								// Reset so that we will find a new target on the
								// next frame which will be closer since
								// FindNearestTarget() does just that.
								ResetPlayerTarget();
								return;
							}
						}
					}
				}
			}
		}
		// I put these here so that an enemy will always be able to attack or guard
		// when nearby a targeted character. If their target is dead, they will
		// reset it. If there are any nearby characters will be ready to guard or
		// dodge if possible.
		if(targetCharStatus)
		{
			if(charCloseNearby)
				AttemptGuardOrDodge ();
			AttemptAttack (distFromTarget);
			if(targetCharStatus.Stats[0] < 0)
			{
				ResetPlayerTarget();
				return;
			}
		}
		// Here, in each state, I specify specific unique things the character
		// will do in each state. Pursuing for example, they will choose a spot
		// around their targeted character to move to and attack when close.
		// Going into other states from the current state are done here as
		// well.
		switch(aiState)
		{
		case AIStates.Wander:
			// Choose random spots around a target to move to.
			Wander ();
			if(targetForNavMesh.tag == "Player" && targetCharStatus && targetCharStatus.Vulnerable
					&& enemiesNearPlayer < Manager_Targeting.instance.playerTargets.Count + 1)
			{
				if(Random.Range(-10f, 10f) > 9f)
					aiState = AIStates.Pursue;
			}
			// If we are able to get items and there are some nearby, have a
			// chance at going after them if no opposing characters are close by.
			if(canGetItems && itemsNearby && !charCloseNearby)
			{
				if(Random.Range(0f, 20f) > 18f)
					aiState = AIStates.Pursue_Item;
			}
			break;

		case AIStates.Pursue:
			if(targetForNavMesh.tag == "Player" || targetForNavMesh.tag == "Enemy")
			{
                if(!IsEnemy || (enemiesNearPlayer < Manager_Targeting.instance.playerTargets.Count + 1))
				{
						// Stop any strafing if too far away from our target.
					if (distFromTarget > 3 && _strafeDir != 0)
						_strafeDir = 0;
					if(targetCharStatus.Vulnerable)
					{
					  // Choose a random spot to go to near a target and make sure
					  // there isn't already an opposing character there.
						if(!_chosenRandomOffset && targetDetRadius)
						{
							if(!targetDetRadius.FoeNearBack && Random.Range(-20f, 20f) > 19f)
							{
								_chosenRandomOffset = true;
								_randomOffset = -targetForNavMesh.forward * 0.95f;
							}
							else if(!targetDetRadius.FoeNearRight && Random.Range(-20f, 20f) > 19f)
							{
								_chosenRandomOffset = true;
								_randomOffset = targetForNavMesh.right * 0.95f;
							}
							else if(!targetDetRadius.FoeNearLeft && Random.Range(-20f, 20f) > 18.8f)
							{
								_chosenRandomOffset = true;
								_randomOffset = -targetForNavMesh.right * 0.95f;
							}
						}
						else
						{
							// A random chance to choose a strafe direction only if
							// our targeted character is close by.
							if(charCloseNearby && detectionRadius.inCloseRangeChar.Contains(targetCharStatus.transform)
							   && _canChooseStrafeDir)
							{
								if(Random.value > 0.5f)
									_strafeDir = -1;
								else _strafeDir = 1;
								_canChooseStrafeDir = false;
							}
							// If they aren't nearby... stop strafing.
							else if(!charCloseNearby || !detectionRadius.inCloseRangeChar.Contains(targetCharStatus.transform))
							{
								if(_strafeDir != 0 && Random.value > 0.98f)
								{
									_strafeDir = 0;
									_canChooseStrafeDir = true;
								}
							}
							// Reset our current strafe direction after a set time
							// so we can choose a new one.
							_choseRandomOffsetTimer += Time.deltaTime;
							if(_choseRandomOffsetTimer > Random.Range(4, 6))
							{
								if(!_canChooseStrafeDir && Random.value > 0.99f)
									_canChooseStrafeDir = true;
								if(_choseRandomOffsetTimer > Random.Range(8f, 14f))
								{
									_chosenRandomOffset = false;
									_choseRandomOffsetTimer = 0;
									_canChooseStrafeDir = true;
								}
							}
						}
					}
					else
					{
						// Make sure our target is alive (health > 0)
						if(targetCharStatus.Stats[0] > 0)
						{
							if(!targetCharStatus.BaseStateInfo.IsTag("Dodging")
							   && distFromTarget < 3 && Random.Range(0f, 10f) > 9f)
								aiState = AIStates.Retreat;
						}
						else // They are dead.
						{
							// Reset our target and we will choose another on the
							// next frame from the same location way above.
                            FindNearestTarget();
							return;
						}
					}
				}
				else // A go back to wander chance if they are too many opposing characters already around our target.
				{
					if(Random.Range(0f, 10f) > 9.8f)
						aiState = AIStates.Wander;
				}
			}
			else if(targetForNavMesh.tag == "Item")
			{
				// Go after that item we have targeted if no opposing characters
				// are close by.
				if(canGetItems && !charCloseNearby)
					aiState = AIStates.Pursue_Item;
				// Reset this regardless so we can choose a new targetForNavMesh.
				targetForNavMesh = null;
				return;
			}
			// If all of these are true, we will have a chance of going at a
			// nearby item.
			if(canGetItems && !charCloseNearby && itemsCloseNearby)
			{
				if(Random.Range(0f, 20f) > 19.2f)
				{
					aiState = AIStates.Pursue_Item;
					targetForNavMesh = null;
					return;
				}
			}
			break;
			// When retreating, we wait until our targeted player is vulnerable
			// again. There is a chance that targetCharacterStatus could become
			// null if the player were to die, so if that were to happen, we
			// would reset our player target and return to wandering. A new target
			// will be chosen again if one is available.
		case AIStates.Retreat:
			if(targetCharStatus != null)
			{
                if (targetCharStatus.Stats[0] > 0)
                {
                    if (!targetCharStatus.Vulnerable)
                    {
                        // If far enough away, I make the character face their target
                        // while they are in retreat and in idle.
                        if (distFromTarget > 5)
                            FaceCharacterTarget();
                    }
                    else
                    {
                        // Try to pursue again after they are vulnerable.
                        if (Random.Range(0f, 10f) > 9.7f)
                        {
                            if (_choseNewPath)
                                _choseNewPath = false;
                            aiState = AIStates.Pursue;
                        }
                    }
                }
                else
                {
                    FindNearestTarget();
                    return;
                }
			}
			else
			{
				if(Random.value > 0.97f)
				{
					if (_choseNewPath)
						_choseNewPath = false;
					ResetPlayerTarget();
					aiState = AIStates.Wander;
					return;
				}
			}
			break;

		case AIStates.Pursue_Item:
			if(!canGetItems)
				aiState = AIStates.Wander;

			// Get rid of any random offset when going after items since we
			// don't want it. We just want the item's position.
			if(_randomOffset.magnitude > 0)
				_randomOffset = Vector3.zero;
			// If we are currently holding an item.
			if(_charItem.ItemHolding != null)
			{
				targetForNavMesh = null;
				aiState = AIStates.Pursue;
				return;
			}
			else // Not holding an item.
			{
				if(!itemsNearby)
				{
					targetForNavMesh = null;
					aiState = AIStates.Pursue;
					return;
				}
			   // Make sure there are no players nearby before going after an item.
				if(!charCloseNearby)
				{
					if(targetForNavMesh.tag == "Item")
					{
						if(itemsCloseNearby)
						{
							// Attempt to pick up an item in grab range.
							if(Random.value > 0.98f)
								_charItem.Pickup();
						}
					}
					// We reset this so at the top we will begin searching for
					// a new target, an item this time which is done in the
					// FindNearestTarget() method.
					else
					{
						targetForNavMesh = null;
						return;
					}
				}
				else // There are opposing characters nearby.
				{
					// We will attempt to go after them.
					if(Random.Range(0f, 20f) > 19.4f)
						aiState = AIStates.Pursue;
				}
			}
			break;
		}
	}
示例#55
0
 void Roaming()
 {
     switch (_currentRoamingState)
     {
         case RoamingState.NONE:
             break;
         case RoamingState.LOOKING_FOR_TARGET:
             targetLocation = RandomPointInPlayerSphere();
             _currentRoamingState = RoamingState.MOVING;
             break;
         case RoamingState.MOVING:
             transform.position = Vector3.MoveTowards(transform.position, targetLocation,Time.deltaTime / movementRate);
             if (ReachedTarget())
                 _currentRoamingState = RoamingState.REACHED_TARGET;
             break;
         case RoamingState.REACHED_TARGET:
             _currentAIState = AIStates.DECIDING;
             break;
         default:
             throw new ArgumentOutOfRangeException();
     }
 }
示例#56
0
    // States: Wander, Persue, Idle
    void StateMachine()
    {
        // Debug.Log("statemachine being called at time " + Time.time);
        //Debug.Log(string.Format("at time {0} the state is {1}", Time.time, state));
        checkRoomInvasion();
        switch(state) {
            case AIStates.WANDER:
                if(goalPoint == null) {
                    selectRandomState();
                    chooseNewGoal();
                    return;
                }
                if(currentSquare.Equals(goalPoint)) {
                    // you done!
                    // choose a new state and return
                    //     Debug.Log("we have moved into the goal square so we are calculating a new square to wander to");
                    selectRandomState();
                    chooseNewGoal();
                    cleanPathNodes();
                    findPath();
                    //      Debug.Log(goalPoint);
                    return;
                }
                // sets the current square to not holding this character anymore in anticipation for the move
                // then choose a square that advances the ai towards the target square

                currentSquare = findNextMove();
                updateLocation();
                break;
            case AIStates.PERSUE:
             //   Debug.Log("You GETTIN CHASED");
                foreach(GameObject square in persueRoom) {
                    if(squareContainsPlayer(square)) {
                        // we do a persuit
                        goalPoint = square;
                        cleanPathNodes();
                        findPath();
                        currentSquare = findNextMove();
                        updateLocation();
                        return;
                    }
                }
                selectRandomState();
                // this is not in use for now
                // selectRandomState();
                break;
            case AIStates.IDLE:
                state = AIStates.WANDER;
                goalPoint = null;
                break;
            default:
                break;
        }
    }
示例#57
0
        /// <summary>
        /// ProcessShot is able to process each shot that is made and call the right methods belonging
        /// to that shot. For example, if its a miss = do nothing, if it's a hit = process that hit location
        /// </summary>
        /// <param name="row">the row that was shot at</param>
        /// <param name="col">the column that was shot at</param>
        /// <param name="result">the result from that hit</param>
        protected override void ProcessShot(int row, int col, AttackResult result)
        {
            switch (result.Value)
            {
                case ResultOfAttack.Miss:
                    _CurrentTarget = null;
                    break;
                case ResultOfAttack.Hit:
                    ProcessHit(row, col);
                    break;
                case ResultOfAttack.Destroyed:
                    ProcessDestroy(row, col, result.Ship);
                    break;
                case ResultOfAttack.ShotAlready:
                    throw new ApplicationException("Error in AI");
            }

            if (_Targets.Count == 0)
                _CurrentState = AIStates.Searching;
        }
示例#58
0
using Microsoft.VisualBasic;
示例#59
0
        /// <summary>
        /// RemoveShotsAround will remove targets that belong to the destroyed ship by checking if
        /// the source of the targets belong to the destroyed ship. If they don't put them on a new stack.
        /// Then clear the targets stack and move all the targets that still need to be shot at back
        /// onto the targets stack
        /// </summary>
        /// <param name="toRemove"></param>
        private void RemoveShotsAround(Location toRemove)
        {
            Stack<Target> newStack = new Stack<Target>();
            //create a new stack

            //check all targets in the _Targets stack

            foreach (Target t in _Targets)
            {
                //if the source of the target does not belong to the destroyed ship put them on the newStack
                if (!object.ReferenceEquals(t.Source, toRemove))
                    newStack.Push(t);
            }

            _Targets.Clear();
            //clear the _Targets stack

            //for all the targets in the newStack, move them back onto the _Targets stack
            foreach (Target t in newStack)
            {
                _Targets.Push(t);
            }

            //if the _Targets stack is 0 then change the AI's state back to searching
            if (_Targets.Count == 0)
                _CurrentState = AIStates.Searching;
        }
示例#60
0
 // Use this for initialization
 void Start()
 {
     currentHealth = MAX_HEALTH;
     _pixelInset = beeHealthBarFill.pixelInset;
     currentState = AIStates.MOVING_RIGHT;
 }