示例#1
0
    public void TakeDamage(int damageAmount)
    {
        //Ignore damage if already dead
        if (isDead)
        {
            return;
        }

        if (isInvulnerable)
        {
            OnHitWhileInvulnerable.Invoke();
            return;
        }

        //Finally take damage
        isInvulnerable = true;
        currentHP     -= damageAmount;

        if (currentHP <= 0)
        {
            OnDeath.Invoke();
            Death();
        }
        else
        {
            OnReceiveDamage.Invoke();
            Hit();
        }
    }
    public void TakeDamage(float amount)
    {
        if (amount < 0)
        {
            throw new System.Exception("You can't deal a negative damage value to the character health");
        }

        if (OnReceiveDamage != null)
        {
            OnReceiveDamage.Invoke(amount);
        }

        _health -= amount;
        _health  = Mathf.Clamp(_health, 0, maxHealth);

        if (OnHealthChange != null)
        {
            OnHealthChange.Invoke(_health);
        }

        if (_health == 0 && OnDie != null)
        {
            OnDie.Invoke();
        }
    }
示例#3
0
        public void ApplyDamage(DamageMessage data)
        {
            if (currentHitPoints <= 0)
            {//ignore damage if already dead. TODO : may have to change that if we want to detect hit on death...
                return;
            }

            if (isInvulnerable)
            {
                OnHitWhileInvulnerable.Invoke();
                return;
            }

            Vector3 forward = transform.forward;

            forward = Quaternion.AngleAxis(hitForwardRotation, transform.up) * forward;

            //we project the direction to damager to the plane formed by the direction of damage
            Vector3 positionToDamager = data.damageSource - transform.position;

            positionToDamager -= transform.up * Vector3.Dot(transform.up, positionToDamager);

            if (Vector3.Angle(forward, positionToDamager) > hitAngle * 0.5f)
            {
                return;
            }

            isInvulnerable    = true;
            currentHitPoints -= data.amount;

            if (currentHitPoints <= 0)
            {
                schedule += OnDeath.Invoke; //This avoid race condition when objects kill each other.
                myOnDeath.Invoke(this, data);
            }
            else
            {
                OnReceiveDamage.Invoke();
                myOnDamageReceived?.Invoke(this, data);
            }

            var messageType = currentHitPoints <= 0 ? MessageType.DEAD : MessageType.DAMAGED;

            for (var i = 0; i < onDamageMessageReceivers.Count; ++i)
            {
                var receiver = onDamageMessageReceivers[i] as IMessageReceiver;
                receiver.OnReceiveMessage(messageType, this, data);
            }
        }
 /// <summary>
 /// Apply Damage to Current Health
 /// </summary>
 /// <param name="damage">damage</param>
 public virtual void TakeDamage(vDamage damage)
 {
     if (damage != null)
     {
         currentHealthRecoveryDelay = currentHealth <= 0 ? 0 : healthRecoveryDelay;
         if (damage.damageValue > 0 && !inHealthRecovery)
         {
             StartCoroutine(RecoverHealth());
         }
         onReceiveDamage.Invoke(damage);
         if (currentHealth > 0)
         {
             currentHealth -= damage.damageValue;
         }
     }
 }
        public void ApplyDamage(DamageMessage data)
        {
            if (currentHitPoints <= 0)
            {
                return;
            }

            if (isInvulnerable)
            {
                OnHitWhileInvulnerable.Invoke();
                return;
            }

            Vector3 forward = transform.forward;

            forward = Quaternion.AngleAxis(hitForwardRotation, transform.up) * forward;
            //将受击方向投影到xz平面上
            Vector3 positionToDamager = data.damageSource - transform.position;

            positionToDamager -= transform.up * Vector3.Dot(transform.up, positionToDamager);
            //判断攻击是否在hitAngle范围内
            if (Vector3.Angle(positionToDamager, forward) > hitAngle * 0.5f)
            {
                return;
            }

            isInvulnerable    = true;
            currentHitPoints -= data.amount;

            if (currentHitPoints <= 0)
            {
                schedule += OnDeath.Invoke;
            }
            else
            {
                OnReceiveDamage.Invoke();
            }

            var message = currentHitPoints <= 0 ? MessageType.DEAD : MessageType.DAMAGED;

            for (var i = 0; i < onDamageMessageReceivers.Count; ++i)
            {
                var receiver = onDamageMessageReceivers[i] as IMessageReceiver;
                receiver.OnReceiveMessage(message, this, data);
            }
        }
        void Update()
        {
            m_currentHitPoints = (int)(dstManager.GetComponentData<AttributeValues>(this.attributeEntity).CurrentValue.Health);

            if (isInvulnerable)
            {
                m_timeSinceLastHit += Time.deltaTime;
                if (m_timeSinceLastHit > invulnerabiltyTime)
                {
                    m_timeSinceLastHit = 0.0f;
                    isInvulnerable = false;
                    OnBecomeVulnerable.Invoke();
                }
            }

            // This logic is to delay the processing of hp checks by a frame, since the
            // attribute update logic runs after one frame
            if (wasDamaged)
            {
                wasDamaged = false;
                for (var j = 0; j < damageMessagesToAction.Count; j++)
                {
                    var data = damageMessagesToAction[j];
                    if (currentHitPoints <= 0)
                        schedule += OnDeath.Invoke; //This avoid race condition when objects kill each other.
                    else
                        OnReceiveDamage.Invoke();

                    var messageType = currentHitPoints <= 0 ? MessageType.DEAD : MessageType.DAMAGED;

                    for (var i = 0; i < onDamageMessageReceivers.Count; ++i)
                    {
                        var receiver = onDamageMessageReceivers[i] as IMessageReceiver;
                        receiver.OnReceiveMessage(messageType, this, data);
                    }
                }
                damageMessagesToAction.Clear();
            }

            if (damageMessagesToAction.Count > 0)
            {
                wasDamaged = true;
            }

        }
示例#7
0
        public void ApplyDamage(DamageMessage data)
        {
            if (currentHitPoints <= 0)
            {
                return;
            }

            currentHitPoints -= data.amount;

            if (currentHitPoints <= 0)
            {
                OnDeath.Invoke();
            }
            else
            {
                OnReceiveDamage.Invoke();
            }
        }
示例#8
0
        public virtual void TakeDamage(vDamage damage)
        {
            if (healthController == null && targetReceiver)
            {
                healthController = targetReceiver.GetComponent <vIHealthController>();
            }
            else if (healthController == null)
            {
                healthController = GetComponentInParent <vIHealthController>();
            }

            if (healthController != null)
            {
                var _damage = ApplyDamageModifiers(damage);
                healthController.TakeDamage(_damage);
                onReceiveDamage.Invoke(_damage);
            }
        }
示例#9
0
        public void TakeDamage(Damager damager, bool ignoreInvincible = false)
        {
            //ignore damage if already dead. TODO : may have to change that if we want to detect hit on death...
            if ((m_Invulnerable && !ignoreInvincible) || m_CurrentHealth <= 0)
            {
                return;
            }

            if (m_Invulnerable && !ignoreInvincible)
            {
                OnHitWhileInvulnerable.Invoke();
                return;
            }

            Vector3 forward = transform.forward;

            forward = Quaternion.AngleAxis(hitForwardRotation, transform.up) * forward;

            //we project the direction to damager to the plane formed by the direction of damage
            Vector3 positionToDamager = damager.transform.position - transform.position;

            positionToDamager -= transform.up * Vector3.Dot(transform.up, positionToDamager);

            if (Vector3.Angle(forward, positionToDamager) > hitAngle * 0.5f)
            {
                return;
            }

            m_Invulnerable   = true;
            m_CurrentHealth -= damager.damage;

            if (m_CurrentHealth <= 0)
            {
                schedule += OnDeath.Invoke;
            }
            else
            {
                OnReceiveDamage.Invoke();
                if (invulnerableAfterDamage)
                {
                    EnableInvulnerability();
                }
            }
        }
示例#10
0
        public void ApplyDamage(DamageMessage data)
        {
            if (currentHitPoints <= 0)
            {//ignore damage if already dead. TODO : may have to change that if we want to detect hit on death...
                return;
            }

            Vector3 forward = transform.forward;

            forward = Quaternion.AngleAxis(hitForwardRotation, transform.up) * forward;

            //we project the direction to damager to the plane formed by the direction of damage
            Vector3 positionToDamager = data.damageSource - transform.position;

            positionToDamager -= transform.up * Vector3.Dot(transform.up, positionToDamager);

            if (Vector3.Angle(forward, positionToDamager) > hitAngle * 0.5f)
            {
                return;
            }

            currentHitPoints -= data.amount;

            if (currentHitPoints <= 0)
            {
                //schedule += OnDeath.Invoke; //This avoid race condition when objects kill each other.
                // OnDeath can only be called once
                Debug.Log(string.Format("{0} die", gameObject.name));
            }
            else
            {
                OnReceiveDamage.Invoke();
            }

            var messageType = currentHitPoints <= 0 ? MsgType.DEAD : MsgType.DAMAGED;

            for (var i = 0; i < onDamageMessageReceivers.Count; ++i)
            {
                var receiver = onDamageMessageReceivers[i] as IMessageReceiver;
                receiver.OnReceiveMessage(messageType, this, data);
            }
        }
示例#11
0
 /// <summary>
 /// Apply Damage to Current Health
 /// </summary>
 /// <param name="damage">damage</param>
 public virtual void TakeDamage(vDamage damage)
 {
     if (restrictWeaponType)
     {
         WeaponEquipListener type = damage.sender.gameObject.GetComponent<WeaponEquipListener>();
         if(type.equippedWeaponType != weaponType)
         {
             return;
         }
     }
     if (damage != null)
     {
         currentHealthRecoveryDelay = currentHealth <= 0 ? 0 : healthRecoveryDelay;
         if (damage.damageValue > 0 && !inHealthRecovery)
             StartCoroutine(RecoverHealth());
         onReceiveDamage.Invoke(damage);
         if (currentHealth > 0)
             currentHealth -= damage.damageValue;
     }
 }
示例#12
0
    protected override void Damaged(int dam)
    {
        int d = dam;

        if (dam > ShieldCurrent)
        {
            dam           = dam - ShieldCurrent;
            ShieldCurrent = 0;
        }
        else
        {
            ShieldCurrent -= dam;
            dam            = 0;
        }
        CurrentHeath -= dam;
        if (PlayerCurrent == this && d != 0)
        {
            OnReceiveDamage?.Invoke();
        }
        lastTimeReceivedamage = Time.time;
    }
        public void TakeDamage(vDamage damage)
        {
            if (!ragdoll)
            {
                return;
            }
            if (!ragdoll.iChar.isDead)
            {
                inAddDamage = true;
                float multiplier = (useRandomValues && !fixedValues) ? Random.Range(minDamageMultiplier, maxDamageMultiplier) :
                                   (useRandomValues && fixedValues) ? randomChange ? maxDamageMultiplier:minDamageMultiplier :damageMultiplier;

                if (overrideReactionID)
                {
                    if (useRandomValues && !fixedValues)
                    {
                        damage.reaction_id = Random.Range(minReactionID, maxReactionID);
                    }
                    else if (useRandomValues && fixedValues)
                    {
                        damage.reaction_id = randomChange ? maxReactionID:minReactionID;
                    }
                    else
                    {
                        damage.reaction_id = reactionID;
                    }
                }

                var _damage = new vDamage(damage);
                var value   = (float)_damage.damageValue;
                _damage.damageValue = (int)(value * multiplier);
                if (multiplier == maxDamageMultiplier)
                {
                    OnGetMaxValue.Invoke();
                }
                ragdoll.ApplyDamage(damage);
                onReceiveDamage.Invoke(_damage);
                Invoke("ResetAddDamage", 0.1f);
            }
        }
示例#14
0
    public void ApplyDamage(DamageInfo info)
    {
        if (currentHitPoints <= 0)
        {
            return;
        }

        if (isInvulnerable)
        {
            OnHitWhileInvulnerable.Invoke();
            return;
        }

        var forward = transform.forward;

        forward = Quaternion.AngleAxis(hitForwardRotation, transform.up) * forward;

        Vector3 positionToDamager = info.damageSource - transform.position;

        positionToDamager -= transform.up * Vector3.Dot(transform.up, positionToDamager);

        if (Vector3.Angle(forward, positionToDamager) > hitAngle * 0.5f)
        {
            return;
        }

        isInvulnerable    = true;
        currentHitPoints -= info.amount;

        if (currentHitPoints <= 0)
        {
            schedule += OnDeath.Invoke;
        }
        else
        {
            OnReceiveDamage.Invoke();
        }
    }
示例#15
0
        public void ApplyDamage(DamageMessage data)
        {
            if (currentHitPoints <= 0)
            {//ignore damage if already dead. TODO : may have to change that if we want to detect hit on death...
                return;
            }

            if (isInvulnerable)
            {
                OnHitWhileInvulnerable.Invoke();
                return;
            }

            Vector3 forward = transform.forward;

            forward = Quaternion.AngleAxis(hitForwardRotation, transform.up) * forward;

            //we project the direction to damager to the plane formed by the direction of damage
            Vector3 positionToDamager = data.damageSource - transform.position;

            positionToDamager -= transform.up * Vector3.Dot(transform.up, positionToDamager);

            if (Vector3.Angle(forward, positionToDamager) > hitAngle * 0.5f)
            {
                return;
            }

            isInvulnerable    = true;
            currentHitPoints -= data.amount;

            if (currentHitPoints <= 0)
            {
                schedule += OnDeath.Invoke;     //This avoid race condition when objects kill each other.
                if (this.gameObject.layer == 9) //Player
                {
                    if (data.damager.gameObject.name == "BodyDamager")
                    {
                        PlayerDeathEvent?.Invoke(ENEMY_TYPE.CHOMPER);
                    }

                    else if (data.damager.gameObject.name == "Spit(Clone)")
                    {
                        PlayerDeathEvent?.Invoke(ENEMY_TYPE.SPITTER);
                    }
                }

                else if (this.gameObject.layer == 23) // Enemy
                {
                    if (gameObject.name == "Chomper")
                    {
                        EnemyDeathEvent?.Invoke(gameObject, ENEMY_TYPE.CHOMPER);
                    }

                    else if (gameObject.name == "Spitter")
                    {
                        EnemyDeathEvent?.Invoke(gameObject, ENEMY_TYPE.SPITTER);
                    }
                }
            }

            else
            {
                if (data.damager.gameObject.name == "BodyDamager")
                {
                    PlayerHurtEvent?.Invoke(ENEMY_TYPE.CHOMPER);
                }

                else if (data.damager.gameObject.name == "Spit(Clone)")
                {
                    PlayerHurtEvent?.Invoke(ENEMY_TYPE.SPITTER);
                }

                OnReceiveDamage.Invoke();
            }

            var messageType = currentHitPoints <= 0 ? MessageType.DEAD : MessageType.DAMAGED;

            for (var i = 0; i < onDamageMessageReceivers.Count; ++i)
            {
                var receiver = onDamageMessageReceivers[i] as IMessageReceiver;
                receiver.OnReceiveMessage(messageType, this, data);
            }
        }
示例#16
0
    public void TakeHit(Damager damager)
    {
        //for hit angle and stuff
        Vector3 forward = transform.forward;

        forward = Quaternion.AngleAxis(hitForwardRotation, transform.up) * forward;

        //we project the direction to damager to the plane formed by the direction of damage
        Vector3 positionToDamager = damager.transform.position - transform.position;

        positionToDamager -= transform.up * Vector3.Dot(transform.up, positionToDamager);

        if (Vector3.Angle(forward, positionToDamager) > hitAngle * 0.5f)
        {
            return;
        }

        //check invulnerability
        if (m_Invulnerable)
        {
            return;
        }

        //damage
        currentHealth -= damager.damage;

        if (currentHealth > 0)
        {
            actor.Damaged(damager);
            OnReceiveDamage.Invoke();

            //status
            if (damager.appliedStatus > 0)
            {
                actor.ApplyStatus(damager.appliedStatus, damager.statusDuration);
            }

            //physical impact
            knockOutBuildUp += damager.hitPower;
            if (knockOutLimit > 0 && knockOutThreshold > 0 && knockOutBuildUp >= knockOutLimit && damager.hitPower >= knockOutThreshold)
            {
                knockOutBuildUp = 0;
                actor.ApplyImpact(damager, "KnockOut");
            }
            else if (knockBackThreshold > 0 && damager.hitPower >= knockBackThreshold)
            {
                actor.ApplyImpact(damager, "KnockBack");
            }
            else if (flinchThreshold > 0 && damager.hitPower >= flinchThreshold)
            {
                actor.ApplyImpact(damager, "Flinch");
            }

            if (invulnerableAfterDamage)
            {
                StartCoroutine(AfterHitInvulnerability(invulnerabilityDuration));
            }
        }
        else
        {
            schedule += OnDeath.Invoke;
        }
    }