Пример #1
0
    IEnumerator doSwing(SwingEvent swingEvent)
    {
        if (status.dodging)
        {
            //animated.animation.Stop();// Stop("bjorn_dodge");
            //animated.animation.Play("bjorn_idle");
            status.dodging = false;
            // dumb hack because Unity animation system is dumb dumb dumb
            //yield return new WaitForSeconds(0.02f);
        }

        /*
         * bool stunAttack = (swingEvent.damage.effects.ContainsKey("OnStun"));
         * if(stunAttack)
         * {
         *      var fx = Resources.Load("Effects/effect_fire_sword") as GameObject;
         *
         *      var fireEffect = Instantiate(fx, mainWeapon.transform.position, mainWeapon.transform.rotation) as GameObject;
         *      fireEffect.transform.parent = mainWeapon.transform;
         *      fireEffect.name = "stunEffect";
         * }
         */

        status.attacking = true;
        gameObject.BroadcastMessage("OnDisable");

        if (telegraphAttacks && swingNumber <= 1)
        {
            animated.animation.Play(swingEvent.animation.name + "_telegraph");

            activeTelegraph.gameObject.SetActive(true);
            //activeTelegraphCircle.gameObject.SetActive(true);
            //activeTelegraphCircle.localScale = Vector3.one;
            //activeTelegraphCircle.SendMessage("OnTelegraph", telegraphRate * 2.0f);
            yield return(new WaitForSeconds(telegraphRate - 0.2f));

            // this is a bit heavy and shouldn't be living here
            foreach (Transform decalChild in activeTelegraph)
            {
                decalChild.renderer.material.SetColor("_TintColor", Color.white);
            }
            status.unbalanced = true;
            yield return(new WaitForSeconds(0.2f));
        }

        // if we don't telegraph, set unbalanced for the duration of the attack
        status.unbalanced = true;

        // don't remove telegraph until the attack chain is over
        int maxSwings = 1;        //mainWeapon.swingPrefabs.Length;

        if (activeTelegraph != null && (swingNumber == maxSwings || maxSwings <= 1))
        {
            activeTelegraph.gameObject.SetActive(false);
            //activeTelegraphCircle.gameObject.SetActive(false);
            foreach (Transform decalChild in activeTelegraph)
            {
                decalChild.renderer.material.SetColor("_TintColor", originalTelegraphColor);
            }
        }

        // step into the attack
        //iTween.MoveTo(gameObject, transform.position + (transform.forward * 10.0f), 0.2f);
        dude.AddForce(transform.forward * swingEvent.step * Time.fixedDeltaTime);

        // fire actual weapon

        gameObject.SendMessage("OnFire");

        /*
         * if(mainWeapon.swingSound != null)
         * {
         *      float originalPitch = audio.pitch;
         *      audio.pitch = (1.0f - swingEvent.rate);// + 0.5f;
         *      //audio.PlayOneShot(mainWeapon.swingSound);
         *      audio.pitch = originalPitch;
         * }
         */
        // dumb hack because Unity animation system is dumb dumb dumb
        //animated.animation.Stop();
        //animated.animation.Play("bjorn_idle");
        //yield return new WaitForSeconds(0.02f);
        yield return(new WaitForEndOfFrame());

        //string animName = mainWeapon.swingAnimations[swingNumber - 1].name;
        if (swingEvent.animation != null)
        {
            string animName = swingEvent.animation.name;
            animated.animation[animName].speed = attackAnimationRatio / swingEvent.rate;
            animated.animation.Play(animName, PlayMode.StopAll);            //CrossFade(animName);
        }

        yield return(new WaitForSeconds(swingEvent.rate * (1.0f - attackCancelWindow)));

        if (swingNumber < maxSwings)
        {
            status.attacking         = false;
            status.unbalanced        = false;
            status.attackingRecovery = true;
        }

        yield return(new WaitForSeconds(swingEvent.rate * attackCancelWindow));

        gameObject.BroadcastMessage("OnEnable");

        status.attacking         = false;
        status.unbalanced        = false;
        status.attackingRecovery = false;

        /*
         * if(stunAttack)
         * {
         *      Transform fx = mainWeapon.transform.FindChild("stunEffect");
         *      fx.particleEmitter.emit = false;
         *      fx.parent = null;
         * }
         */

        // reset swing animation entirely
        ResetAnimation();

        gameObject.SendMessage("OnFollowUp");
    }
Пример #2
0
    public void OnShot(DamageEvent d)
    {
        // heal bullet!
        if (d.damage < 0)
        {
            // heal my own team, do nothing to other people
            if (d.team == team)
            {
                AddHealth(-d.damage);
            }
            return;
        }
        if (d.team == team || invincible)
        {
            return;
        }

        Vector3 attackVec = Vector3.zero;

        if (d.owner != null)
        {
            Vector3 ownerPos = d.owner.transform.position;
            // bring them to the same y level as us, to make sure we don't knock them up over terrain
            ownerPos.y = transform.position.y;
            attackVec  = (transform.position - ownerPos).normalized;
        }

        if (d.knockback > 0.0f)
        {
            Vector3 forceVec;
            // for melee weapons, knockback should be from the attacker

            /*
             * if(d.owner != null)
             *      forceVec = (transform.position - d.owner.transform.position).normalized;
             * else
             *      // for ranged weapons, knockback should come form the bullet
             *      forceVec = (transform.position - d. .position).normalized;
             */
            dude.AddForce(attackVec * d.knockback);
        }

        // certain effects bypass blocking, so we apply them now

        /*
         * var bypassEffects = new string[]
         * {
         *      "OnWeakened"
         * };
         * if(d.effects.Count > 0)
         * {
         *      foreach(var effect in bypassEffects)
         *      {
         *              if(d.effects.ContainsKey(effect))
         *              {
         *                      gameObject.SendMessage(effect, d.effects[effect], SendMessageOptions.DontRequireReceiver);
         *                      d.effects.Remove(effect);
         *              }
         *      }
         * }
         */

        // calculate angle-affected stuff
        var angle = Vector3.Dot(attackVec, transform.forward);

        // see if I'm blocking in the correct direction
        if (dude.blocking)
        {
            if (directionalBlock && angle > 0.0f)
            {
                // not blocking in the right direction!
            }
            else
            {
                Instantiate(blockEffect, transform.position, transform.rotation);
                gameObject.BroadcastMessage("OnShotBlocked", d);
                return;
            }
        }

        // start calculating bonus damage, etc. //////////////////////////

        /*
         * if(d.damage > 0)
         * {
         *      // backstab
         *      if(swordz.status.stunned || angle > backstabAngle)
         *      {
         *              d.damage *= 2;
         *              Debug.Log("CRITICAL HIT! " + d.damage + " - " + angle);
         *      }
         * }
         */

        d.damage -= (int)(d.damage * armor);

        // no more damage calculation below this point ///////////////////

        // handle armor
        //swordz.armor;

        // the hit has officially caused damage, we're spawning an effect ////////
        if (hitEffect != null && d.damage > 0)
        {
            //var blood = Instantiate(hitEffect, Util.flatten(transform.position), transform.rotation) as GameObject;
            var blood = Instantiate(hitEffect, transform.position, transform.rotation) as GameObject;
        }

        // calculate inflicted damage... if this is a killing blow we only count damage inflicted to kill
        int inflicted = Mathf.Min(health, d.damage);

        attacker = d.owner;
        health  -= d.damage;
        if (health <= 0)
        {
            killer = d.owner;
            gameObject.BroadcastMessage("OnKill", killer);
        }
        else if (health > maxHealth)
        {
            health = maxHealth;
        }

        // record metrics

        // send special effects
        foreach (KeyValuePair <string, object> pair in d.effects)
        {
            gameObject.SendMessage(pair.Key, pair.Value, SendMessageOptions.DontRequireReceiver);
        }

        // report to the owner that the hit was successful
        // FIXME: I am screwing with damage here 'cause it's just a lot easier than copying
        d.damage = inflicted;
        if (d.owner != null)
        {
            d.owner.BroadcastMessage("OnShotHit", d, SendMessageOptions.DontRequireReceiver);
        }

        //if(!invincibleWhenHit)
        //	gameObject.SendMessage("OnInterrupt");

        if (invincibleWhenHit && d.damage > 0 && health > 0)
        {
            StartCoroutine("doInvincible", invincibilityDuration);
        }

        if (gameObject.CompareTag("Player") && d.damage > 0)
        {
            /*
             * GameObject director = GameObject.FindGameObjectWithTag("Director");
             * if(director != null)
             *      director.SendMessage("OnPlayerHit", d);
             */
        }
    }