Пример #1
0
    public override MeleeBlockType SendMeleeDamage(Damage damage, Vector3 hitNormal, Character attacker, float knockBackChance)
    {
        MyEventHandler.TriggerOnTakingHit();
        float attackerAngle = Vector3.Angle(transform.forward, transform.position - attacker.transform.position);

        if (ActionState == HumanActionStates.None && attackerAngle > 135 && UnityEngine.Random.value < 0.4f)
        {
            MyAnimator.SetTrigger("BlockSuccess");
            return(MeleeBlockType.SoftArmor);
        }
        else
        {
            OnInjury(hitNormal, UnityEngine.Random.value <= knockBackChance);
            MyAI.Sensor.OnTakingDamage(attacker);
            float finalDamage = damage.SharpDamage + damage.BluntDamage;

            if (damage.IsCritical)
            {
                finalDamage *= 1.5f;
            }

            if (this.Inventory.ArmorSlot != null)
            {
                float padding     = (float)this.Inventory.ArmorSlot.GetAttributeByName("Padding").Value;
                float armorRating = (float)this.Inventory.ArmorSlot.GetAttributeByName("Armor").Value;
                float coverage    = (float)this.Inventory.ArmorSlot.GetAttributeByName("Coverage").Value;
                float chance      = UnityEngine.Random.value;
                if (chance < coverage)
                {
                    //when hitting armor, only blunt damage applies
                    finalDamage = damage.BluntDamage - padding + damage.SharpDamage - armorRating;
                    if (finalDamage < 0)
                    {
                        finalDamage = 0;
                    }
                }
                else
                {
                    finalDamage = damage.SharpDamage + damage.BluntDamage;
                }
            }

            if (finalDamage > 0)
            {
                PlayVocal(VocalType.Injury);
            }

            if (finalDamage > 0 && damage.Bleeding > 0)
            {
                MyStatus.AddBleeding(damage.Bleeding);
            }

            MyStatus.Health -= finalDamage;
            DeathReason      = damage.Type;

            if (MyStatus.Health <= 0)
            {
                MyStatus.Health = 0;
                OnDeath(hitNormal);
            }
        }


        return(MeleeBlockType.NoBlock);
    }
Пример #2
0
    public override bool SendDamage(Damage damage, Vector3 hitNormal, Character attacker, Weapon attackerWeapon)
    {
        OnInjury(hitNormal, damage.IsCritical);
        MyAI.Sensor.OnTakingDamage(attacker);

        float finalDamage = 0;

        if (damage.Type == DamageType.Bullet)
        {
            finalDamage = damage.KineticDamage;
        }
        else if (damage.Type == DamageType.Explosive)
        {
            finalDamage = damage.BlastDamage;
        }

        if (damage.IsCritical)
        {
            PlayVocal(VocalType.Injury);
            finalDamage *= 1.5f;
            if (this.Inventory.HeadSlot != null)
            {
                float armorRating = (float)this.Inventory.HeadSlot.GetAttributeByName("Armor").Value;
                float coverage    = (float)this.Inventory.HeadSlot.GetAttributeByName("Coverage").Value;
                float chance      = UnityEngine.Random.value;
                if (chance < coverage)
                {
                    //covered, calculate armor rating vs penetration
                    if (damage.Penetration >= armorRating)
                    {
                        //penetrated the armor
                        finalDamage = finalDamage * Mathf.Clamp01((damage.Penetration - armorRating) / armorRating);
                    }
                    else
                    {
                        //not penetrated
                        return(true);
                    }
                }
            }
        }
        else if (this.Inventory.ArmorSlot != null)
        {
            float armorRating = (float)this.Inventory.ArmorSlot.GetAttributeByName("Armor").Value;
            float coverage    = (float)this.Inventory.ArmorSlot.GetAttributeByName("Coverage").Value;
            float chance      = UnityEngine.Random.value;
            if (chance < coverage)
            {
                //covered, calculate armor rating vs penetration
                if (damage.Penetration >= armorRating)
                {
                    //penetrated the armor
                    finalDamage = finalDamage * Mathf.Clamp01((damage.Penetration - armorRating) / armorRating);
                }
                else
                {
                    //not penetrated
                    return(true);
                }
            }
            else
            {
                //uncovered area are less vulnerable. this does NOT apply to critical (head) hits.
                finalDamage *= 0.5f;
            }
        }


        if (finalDamage > 0 && damage.Bleeding > 0)
        {
            MyStatus.AddBleeding(damage.Bleeding);
        }

        MyStatus.Health -= finalDamage;

        DeathReason = damage.Type;

        if (MyStatus.Health <= 0)
        {
            MyStatus.Health = 0;
            OnDeath(hitNormal);
        }


        return(false);
    }