Ejemplo n.º 1
0
 public void AimTo(float _zRotation, float _xDiff)
 {
     if (_xDiff > 0 + degreesOfDeadZone)
     {
         //We should be facing right
         transform.eulerAngles = new Vector3(0, 0, 0);
         playerSettings.FlipName(false);
         //Rotate gun to point at mouse
         weaponPivot.rotation = Quaternion.Euler(0, 0, _zRotation);
     }
     else if (_xDiff < 0 - degreesOfDeadZone)
     {
         //We should be facing left
         transform.eulerAngles = new Vector3(0, 180, 0);
         playerSettings.FlipName(true);
         //Rotate gun to point at mouse but gun is upside down, so flip 180 on x
         //And compansate fliping x by inverting z rotation
         weaponPivot.rotation = Quaternion.Euler(180, 0, -_zRotation);
     }
 }
Ejemplo n.º 2
0
/*
    private void FixedUpdate() {
        onSyncWithFixedUpdate = true;
    }

    // Update is called once per frame
    private void Update()
    {
        //This will sync with FixedUpdate with the intention of pausing the game and 
        if(!onSyncWithFixedUpdate){
            return;
        }else{
            onSyncWithFixedUpdate = false;
        }
*/

    // Update is called once per frame
    void FixedUpdate()
    {
        //Return if this player isn't an AI player
        if(!ps.iAmAI){
            curState = AIState.WaitingForTurn;//Just in case something external ends the AI turn
            return;
        }
        switch (curState)
        {
            case(AIState.WaitingForTurn):
                //Change state when player starts turn
                if(ps.isMyTurn){
                    //Debug.Log("starting turn");
                    curState = AIState.Pause;
                    StartCoroutine(ChangeStateIn(AIState.PickingTarget, 2f));
                }
                break;
                
            case(AIState.PickingTarget):
                //Reset List
                targets.Clear(); 
                allEnemiesHealth = 0;
                for(int i = 0; i < GLOBALS.numTeams; i++){
                    //Check if this team is alive, else skip it
                    if(GM.teamsHealth[i] <= 0)
                        continue; //team is dead, move on
                    
                    //Check if this team is the AI team
                    if(ps.teamID == i)
                        continue; //Don't target allies
                    
                    for(int j = 0; j < GLOBALS.teamSize; j++){
                        //Check if this Soldier is alive, else skip it
                        if(GM.soldiersHealth[i,j] <= 0)
                            continue; //Soldier is dead, move on
                        
                        //Add Soldier to possible targets to shoot
                        if(GM.teams[i,j] != null){
                            targets.Add(GM.teams[i,j].transform);
                            //And record it's health for Infinity Gauntlet Calculations
                            allEnemiesHealth += GM.soldiersHealth[i,j];
                        }
                    }
                }

                //We now have all possible targets, now we need to sort them:

                //sort by distance to player ascending
                targets = targets.OrderBy(x => Vector2.Distance(this.transform.position,x.position)).ToList();
                //sort by teams health decending
                targets = targets.OrderBy(x => -GM.teamsHealth[x.GetComponent<PlayerSettings>().teamID]).ToList();
                //sort by soldiers health decending
                targets = targets.OrderBy(x => -x.GetComponent<DamageHandler>().health).ToList();

                curState = AIState.Pause;
                StartCoroutine(ChangeStateIn(AIState.tryingStraightShot, 1f));
                break;

            case(AIState.tryingStraightShot):
                //Debug.Log("tryingStraightShot");
                //Reset target
                target = null; 

                //Loop thru all enemies and chose the first one with direct line of sight
                foreach (Transform tar in targets){
                    //Find direction vector from self to target and normalize it to length 1
                    dir3 = tar.position - weaponContr.weaponPivot.transform.position;
                    dir3.Normalize();
                    dir3.z = 0;

                    //Direct cast from Vector3s to Vector2s
                    origin = weaponContr.weaponPivot.transform.position;
                    direction = dir3;

                    //Send a ray and store the information in hit
                    hit = Physics2D.Raycast(origin + direction*1.5f, direction);
                    //Check if we are hitting a player and that player is not in our team
                    if(hit.transform.tag == "Player" && ps.teamID != hit.transform.GetComponent<PlayerSettings>().teamID){
                        Debug.Log("AI Player says: Found a Target!!");
                        target = hit.transform;
                        break;
                    }
                }
                
                
                if(target == null){//change state TODO
                    Debug.Log("AI Player says: No target in sight");
                    //Set target to be the closest one
                    target = targets.First();

                    //Change state and wait 
                    curState = AIState.Pause;
                    StartCoroutine(ChangeStateIn(AIState.tryingParabolicShot, 1f));
                    //leave state
                    break;
                }
                

                zRotation = CalculateStraightShotAngle(target);

                //Find a default weapon to fall back to
                if(TryWeapon(WeaponCodes.Sniper))               {/*Nothing to do*/}
                else if(TryWeapon(WeaponCodes.Shotgun))         {/*Nothing to do*/}
                else if(TryWeapon(WeaponCodes.Holy_Grenade))    {/*Nothing to do*/}
                else if(TryWeapon(WeaponCodes.Hadouken))        {/*Nothing to do*/}
                else if(TryWeapon(WeaponCodes.BFG9000))         {/*Nothing to do*/}
                else if(TryWeapon(WeaponCodes.Mine))            {/*Nothing to do*/}
                else if(TryWeapon(WeaponCodes.Grenade))         {/*Nothing to do*/}
                else if(TryWeapon(WeaponCodes.Bazooka))         {/*Nothing to do*/}
                else   {TryWeapon(WeaponCodes.Bang_Pistol);}

                //-------Default Weapon has been set---------//

                //If distance between target is small, then prioritize other short range weapons
                if(Vector2.Distance(target.position, transform.position) < 10f){

                    //Try to use Shotgun, else use the Hadouken, else ThunderGun
                    if(TryWeapon(WeaponCodes.Shotgun))          {/*Nothing to do*/}
                    else if(TryWeapon(WeaponCodes.Hadouken))    {/*Nothing to do*/}
                    else if(TryWeapon(WeaponCodes.ThunderGun))  {/*Nothing to do*/}
                    else                                        {/*Keep default weapon*/}

                    //If the angle is good for launching, then prioritize ThunderGun
                    if(zRotation > 30f && zRotation < 60f){
                        TryWeapon(WeaponCodes.ThunderGun);
                    }

                    //If target is in melee range, then prioritize Mjolnir
                    if(Vector2.Distance(target.position, transform.position) < 4f){
                        //Close enough for Mjolnir
                        TryWeapon(WeaponCodes.Mjolnir);
                    }
                }
                
                float rotationOffset = 0f;
                switch (curWeapon)
                {
                    case (int)WeaponCodes.Mjolnir:
                    case (int)WeaponCodes.ThunderGun:
                        rotationOffset = 7f;
                        break;

                    case (int)WeaponCodes.Hadouken:
                        rotationOffset = 1.5f;
                        break;

                    case (int)WeaponCodes.Mine:
                    case (int)WeaponCodes.Bazooka:
                    case (int)WeaponCodes.Grenade:
                    case (int)WeaponCodes.Holy_Grenade:
                    case (int)WeaponCodes.Teleport_Grenade:
                        //**************TODO********************
                        break;
                    default:
                        break;
                }
                
                if(Mathf.Abs(zRotation) < 90f){
                    zRotation += rotationOffset;//raise weapon x degrees up
                }else{
                    zRotation -= rotationOffset;//raise weapon x degrees up
                }

                //Change state and wait 
                curState = AIState.Pause;
                StartCoroutine(ChangeStateIn(AIState.Aiming, 1f));
                break;

            case(AIState.tryingParabolicShot):
                //Debug.Log("tryingParabolicShot");
                
                //This is for ThunderGun and sets yDiff and xDiff 
                zRotation = CalculateStraightShotAngle(target);
                angle_1 = angle_2 = 0f;
                
                if(TryWeapon(WeaponCodes.ThunderGun) && Vector2.Distance(target.position, transform.position) < 10f && zRotation > 10f && zRotation < 70f)
                {/*In ThunderGun range and optimal angle range*/}
                else if(TryWeapon(WeaponCodes.BFG9000) && targets.Last().GetComponent<DamageHandler>().health < 50)
                {/*The target has low health*/
                    zRotation = CalculateStraightShotAngle(targets.Last());
                }
                else if(TryWeapon(WeaponCodes.Infinity_Gauntlet) && (dh.health < allEnemiesHealth/2f) && dh.health != GM.teamsHealth[ps.teamID])
                {/*AI has low health and is not the last man of its team*/}
                else if(TryWeapon(WeaponCodes.PlaneBomber) || TryWeapon(WeaponCodes.Plane_Nuke))
                {
                    //Sort list for farthest and highest targets
                    targets = targets.OrderBy(x => -(x.position.y * 100 + Vector2.Distance(this.transform.position,x.position))).ToList();
                    target = targets.First();
                }
                else if(TryWeapon(WeaponCodes.Homing_Bazooka))
                {
                    zRotation = 90;
                    weaponScript.fireTriggered = true;
                }
                else{
                    if(CalculateParabolicShotAngles(target, WeaponCodes.Bazooka) && TryWeapon(WeaponCodes.Bazooka) && rand.NextDouble() > 0.5)      {/*Nothing to do*/}
                    else if(CalculateParabolicShotAngles(target, WeaponCodes.Mine) && TryWeapon(WeaponCodes.Mine))                                  {/*Nothing to do*/}
                    else if(CalculateParabolicShotAngles(target, WeaponCodes.Holy_Grenade) && TryWeapon(WeaponCodes.Holy_Grenade))                  {/*Nothing to do*/}
                    else if(CalculateParabolicShotAngles(target, WeaponCodes.Grenade) && TryWeapon(WeaponCodes.Grenade) && rand.NextDouble() > 0.5) {/*Nothing to do*/}
                    else if(CalculateParabolicShotAngles(target, WeaponCodes.Teleport_Grenade) && TryWeapon(WeaponCodes.Teleport_Grenade))          {/*Nothing to do*/}
                    else{TryWeapon(WeaponCodes.Bang_Pistol);}

                    zRotation = angle_1;
                }
                
                //Change state and wait 
                curState = AIState.Pause;
                StartCoroutine(ChangeStateIn(AIState.Aiming, 1f));
                break;

            case(AIState.Aiming):
                //Check if gun is close to the correct angle
                if(Mathf.Abs(currentRotation - (360 + zRotation) % 360) < 5f){
                    //Debug.Log("Finished Aiming");
                    weaponContr.AimTo(zRotation, xDiff);
                    curState = AIState.Pause;
                    StartCoroutine(ChangeStateIn(AIState.Shooting, 1f));
                    break;
                }

                //Rotate Weapon
                currentRotation = (currentRotation + 4) % 360;
                
                if (Mathf.Cos(currentRotation * Mathf.Deg2Rad) > 0)
                {
                    //We should be facing right
                    transform.eulerAngles = new Vector3(0, 0, 0);
                    ps.FlipName(false);
                    //Rotate gun to point at mouse
                    weaponContr.weaponPivot.rotation = Quaternion.Euler(0, 0, currentRotation);
                }
                else
                {
                    //We should be facing left
                    transform.eulerAngles = new Vector3(0, 180, 0);
                    ps.FlipName(true);
                    //Rotate gun to point at mouse but gun is upside down, so flip 180 on x
                    //And compansate fliping x by inverting z rotation
                    weaponContr.weaponPivot.rotation = Quaternion.Euler(180, 0, -currentRotation);
                }

                break;

            case(AIState.Shooting):
                //Debug.Log("Shooting " + curWeapon);
                curState = AIState.Pause;
                StartCoroutine(ChangeStateIn(AIState.WaitingForTurn, 1f));
                weaponScript.fireTriggered = true;
                break;

            case(AIState.Moving):
                //***************************TODO**************************
                break;

            case(AIState.Pause):
                //This is a dead state meant for the AI to just wait for some time
                //This state should only be called along with the coroutine ChangeStateIn()
                break;

            default:
                Debug.LogError("Invalid State reached... but HOW??!!");
                break;
        }
    }