示例#1
0
    bool TryMeleeAttack(Weapon weapon, SquadControl target, int direction)
    {
        if (!weapon)
        {
            return(false);
        }

        bool        attackedUsingReach = false;
        bool        attackDodged       = false;
        bool        needsToAdvance     = false;
        string      attackResult       = "";
        int         attackDirection    = direction;
        UnitControl victim             = null;

        //check forward
        Vector3 dir        = Quaternion.AngleAxis(90 * direction, Vector3.up) * (transform.forward * 3);
        Vector3 forwardPos = unitControl.SquadPosition + dir;

        victim = CheckForTarget(forwardPos);

        // secondary attack if direction is forward;
        if (weapon.isSecondary)
        {
            if (victim)
            {
                animator.SetTrigger("AttackSecondary");
                weapon.StartAttack();
                lastAttackTarget = victim;
                lastWeaponUsed   = weapon;
                return(true);
            }
            Debug.Log("No Target for Secondary");
            return(false);
        }

        //check forward with reach
        if (!victim && weapon.hasReach)
        {
            dir    = Quaternion.AngleAxis(90 * direction, Vector3.up) * (transform.forward * 2);
            victim = CheckForTarget(forwardPos + dir);
            if (victim)
            {
                attackedUsingReach = true;
            }
        }

        //Special attacks if attacking forward
        if (direction == 0)
        {
            //no special attacks from the backrow
            if (!victim)
            {
                float distanceForMe    = Vector3.Distance(unitControl.SquadPosition, target.transform.position);
                float distanceForSquad = Vector3.Distance(unitControl.Squad.transform.position, target.transform.position);
                if (distanceForMe > distanceForSquad)
                {
                    return(false);
                }
            }

            // advance and check right
            if (!victim)
            {
                dir             = Quaternion.AngleAxis(90 * -1, Vector3.up) * (transform.forward * 2);
                victim          = CheckForTarget(forwardPos + dir);
                attackDirection = -1;
                needsToAdvance  = true;
            }

            // advance and check left
            if (!victim)
            {
                dir             = Quaternion.AngleAxis(90 * 1, Vector3.up) * (transform.forward * 2);
                victim          = CheckForTarget(forwardPos + dir);
                attackDirection = 1;
                needsToAdvance  = true;
            }

            // advance and check forward
            if (!victim)
            {
                dir             = (transform.forward * 2);
                victim          = CheckForTarget(forwardPos + dir);
                attackDirection = 0;
                needsToAdvance  = true;
            }
        }

        if (victim)
        {
            animator.SetInteger("AttackDirection", attackDirection);

            if (needsToAdvance)
            {
                animator.SetTrigger("Advance");
            }

            if (attackedUsingReach)
            {
                animator.SetTrigger("UseReachAttack");
            }

            //find if attack hits
            float attackRoll = Random.value;
            attackRoll += unitControl.AttackBonus;
            attackRoll += weapon.AttackBonus;
            attackRoll -= unitControl.ParryBonus;

            float victimOffset = Vector3.Dot(victim.transform.forward,
                                             Quaternion.AngleAxis(90 * attackDirection, Vector3.up) * transform.forward);

            if (victimOffset > -0.75)
            {
                attackResult = "Primary";
            }
            else if (attackRoll > 0.5f || attackedUsingReach)
            {
                attackResult = "Primary";
                if (victim.DodgeBonus > Random.value)
                {
                    attackDodged = true;
                    victim.DodgeAttack(attackDirection);
                }
            }
            else
            {
                attackResult = "Blocked";
                victim.BlockAttack(attackDirection);
            }

            if (!needsToAdvance && !attackedUsingReach)
            {
                animator.SetTrigger("Attack" + attackResult);
            }

            weapon.StartAttack();

            lastAttackTarget = attackDodged ? null : victim;
            lastWeaponUsed   = weapon;

            return(true);
        }
        return(false);
    }