public void TakeDamage(DamageInfo damageInfo)
        {
            if (!NetworkServer.active)
            {
                Debug.LogWarning("[Server] function 'System.Void RoR2.HealthComponent::TakeDamage(RoR2.DamageInfo)' called on client");
                return;
            }
            if (!this.alive || this.godMode)
            {
                return;
            }
            CharacterBody characterBody = null;

            if (damageInfo.attacker)
            {
                characterBody = damageInfo.attacker.GetComponent <CharacterBody>();
            }
            base.BroadcastMessage("OnIncomingDamage", damageInfo, SendMessageOptions.DontRequireReceiver);
            CharacterMaster master = this.body.master;

            base.GetComponent <TeamComponent>();
            if (master && master.inventory)
            {
                int itemCount = master.inventory.GetItemCount(ItemIndex.Bear);
                if (itemCount > 0 && Util.CheckRoll((1f - 1f / (0.15f * (float)itemCount + 1f)) * 100f, 0f, null))
                {
                    EffectData effectData = new EffectData
                    {
                        origin   = damageInfo.position,
                        rotation = Util.QuaternionSafeLookRotation((damageInfo.force != Vector3.zero) ? damageInfo.force : UnityEngine.Random.onUnitSphere)
                    };
                    EffectManager.instance.SpawnEffect(Resources.Load <GameObject>("Prefabs/Effects/BearProc"), effectData, true);
                    damageInfo.rejected = true;
                }
            }
            if (this.body.HasBuff(BuffIndex.Immune) && (!characterBody || !characterBody.HasBuff(BuffIndex.GoldEmpowered)))
            {
                EffectManager.instance.SpawnEffect(Resources.Load <GameObject>("Prefabs/Effects/DamageRejected"), new EffectData
                {
                    origin = damageInfo.position
                }, true);
                damageInfo.rejected = true;
            }
            if (damageInfo.rejected)
            {
                return;
            }
            float num = damageInfo.damage;

            if (characterBody)
            {
                CharacterMaster master2 = characterBody.master;
                if (master2 && master2.inventory)
                {
                    if (this.combinedHealth >= this.fullCombinedHealth * 0.9f)
                    {
                        int itemCount2 = master2.inventory.GetItemCount(ItemIndex.Crowbar);
                        if (itemCount2 > 0)
                        {
                            Util.PlaySound("Play_item_proc_crowbar", base.gameObject);
                            num *= 1.5f + 0.3f * (float)(itemCount2 - 1);
                            EffectManager.instance.SimpleImpactEffect(Resources.Load <GameObject>("Prefabs/Effects/ImpactEffects/ImpactCrowbar"), damageInfo.position, -damageInfo.force, true);
                        }
                    }
                    if (this.body.isBoss)
                    {
                        int itemCount3 = master2.inventory.GetItemCount(ItemIndex.BossDamageBonus);
                        if (itemCount3 > 0)
                        {
                            num *= 1.2f + 0.1f * (float)(itemCount3 - 1);
                            damageInfo.damageColorIndex = DamageColorIndex.WeakPoint;
                            EffectManager.instance.SimpleImpactEffect(Resources.Load <GameObject>("Prefabs/Effects/ImpactEffects/ImpactBossDamageBonus"), damageInfo.position, -damageInfo.force, true);
                        }
                    }
                }
            }
            if (damageInfo.crit)
            {
                num *= 2f;
            }
            if ((damageInfo.damageType & DamageType.WeakPointHit) != DamageType.Generic)
            {
                num *= 1.5f;
                damageInfo.damageColorIndex = DamageColorIndex.WeakPoint;
            }
            if ((damageInfo.damageType & DamageType.BypassArmor) == DamageType.Generic)
            {
                float armor = this.body.armor;
                float num2  = (armor >= 0f) ? (1f - armor / (armor + 100f)) : (2f - 100f / (100f - armor));
                num = Mathf.Max(1f, num * num2);
            }
            if ((damageInfo.damageType & DamageType.BarrierBlocked) != DamageType.Generic)
            {
                damageInfo.force *= 0.5f;
                IBarrier component = base.GetComponent <IBarrier>();
                if (component != null)
                {
                    component.BlockedDamage(damageInfo, num);
                }
                damageInfo.procCoefficient = 0f;
                num = 0f;
            }
            if (this.hasOneshotProtection)
            {
                num = Mathf.Min(num, this.fullCombinedHealth * 0.9f);
            }
            if ((damageInfo.damageType & DamageType.SlowOnHit) != DamageType.Generic)
            {
                this.body.AddTimedBuff(BuffIndex.Slow50, 2f);
            }
            if ((damageInfo.damageType & DamageType.ClayGoo) != DamageType.Generic && (this.body.bodyFlags & CharacterBody.BodyFlags.ImmuneToGoo) == CharacterBody.BodyFlags.None)
            {
                this.body.AddTimedBuff(BuffIndex.ClayGoo, 2f);
            }
            if (master && master.inventory)
            {
                int itemCount4 = master.inventory.GetItemCount(ItemIndex.GoldOnHit);
                if (itemCount4 > 0)
                {
                    float num3 = num / this.fullCombinedHealth;
                    uint  num4 = (uint)Mathf.Max(master.money * num3 * (float)itemCount4, damageInfo.damage * (float)itemCount4);
                    master.money = (uint)Mathf.Max(0f, master.money - num4);
                    EffectManager.instance.SimpleImpactEffect(Resources.Load <GameObject>("Prefabs/Effects/ImpactEffects/CoinImpact"), damageInfo.position, Vector3.up, true);
                }
            }
            if ((damageInfo.damageType & DamageType.NonLethal) != DamageType.Generic)
            {
                num = Mathf.Max(Mathf.Min(num, this.health - 1f), 0f);
            }
            if (this.shield > 0f)
            {
                float num5 = Mathf.Min(num, this.shield);
                float num6 = num - num5;
                this.Networkshield = Mathf.Max(this.shield - num5, 0f);
                if (this.shield == 0f)
                {
                    float scale = 1f;
                    if (this.body)
                    {
                        scale = this.body.radius;
                    }
                    EffectManager.instance.SpawnEffect(Resources.Load <GameObject>("Prefabs/Effects/ShieldBreakEffect"), new EffectData
                    {
                        origin = base.transform.position,
                        scale  = scale
                    }, true);
                }
                if (num6 > 0f)
                {
                    this.Networkhealth = this.health - num6;
                }
            }
            else
            {
                this.Networkhealth = this.health - num;
            }
            this.TakeDamageForce(damageInfo, false);
            base.SendMessage("OnTakeDamage", damageInfo, SendMessageOptions.DontRequireReceiver);
            DamageReport damageReport = new DamageReport
            {
                victim     = this,
                damageInfo = damageInfo
            };

            damageReport.damageInfo.damage = num;
            if (num > 0f)
            {
                HealthComponent.SendDamageDealt(damageReport);
            }
            this.UpdateLastHitTime(damageInfo.damage, damageInfo.position, (damageInfo.damageType & DamageType.Silent) > DamageType.Generic);
            if (damageInfo.attacker)
            {
                damageInfo.attacker.SendMessage("OnDamageDealt", damageReport, SendMessageOptions.DontRequireReceiver);
            }
            GlobalEventManager.ServerDamageDealt(damageReport);
            if (this.isFrozen && this.combinedHealthFraction < 0.3f)
            {
                this.Networkhealth = 0f;
                EffectManager.instance.SpawnEffect(FrozenState.cullEffectPrefab, new EffectData
                {
                    origin = this.body.corePosition,
                    scale  = (this.body ? this.body.radius : 1f)
                }, true);
            }
            if (!this.alive)
            {
                base.BroadcastMessage("OnKilled", damageInfo, SendMessageOptions.DontRequireReceiver);
                if (damageInfo.attacker)
                {
                    damageInfo.attacker.SendMessage("OnKilledOther", damageReport, SendMessageOptions.DontRequireReceiver);
                }
                GlobalEventManager.instance.OnCharacterDeath(damageReport);
                return;
            }
            if (master && master.inventory)
            {
                int itemCount5 = master.inventory.GetItemCount(ItemIndex.Phasing);
                if (itemCount5 > 0 && Util.CheckRoll(damageInfo.damage / this.fullCombinedHealth * 100f, master))
                {
                    this.body.AddTimedBuff(BuffIndex.Cloak, 1.5f + (float)itemCount5 * 1.5f);
                    this.body.AddTimedBuff(BuffIndex.CloakSpeed, 1.5f + (float)itemCount5 * 1.5f);
                    EffectManager.instance.SpawnEffect(Resources.Load <GameObject>("Prefabs/Effects/ProcStealthkit"), new EffectData
                    {
                        origin   = base.transform.position,
                        rotation = Quaternion.identity
                    }, true);
                }
            }
        }
Beispiel #2
0
        public void TakeDamage(DamageInfo damageInfo)
        {
            if (!NetworkServer.active)
            {
                Debug.LogWarning("[Server] function 'System.Void RoR2.HealthComponent::TakeDamage(RoR2.DamageInfo)' called on client");
                return;
            }
            if (!alive || godMode)
            {
                return;
            }
            CharacterBody characterBody = null;

            if (damageInfo.attacker)
            {
                characterBody = damageInfo.attacker.GetComponent <CharacterBody>();
            }
            BroadcastMessage("OnIncomingDamage", damageInfo, SendMessageOptions.DontRequireReceiver);
            var master = body.master;

            GetComponent <TeamComponent>();
            if (master && master.inventory)
            {
                var itemCount = master.inventory.GetItemCount((ItemIndex)1);
                if (itemCount > 0 && Util.CheckRoll((1f - 1f / (0.15f * itemCount + 1f)) * 100f, 0f, null))
                {
                    var effectData = new EffectData
                    {
                        origin   = damageInfo.position,
                        rotation = Util.QuaternionSafeLookRotation((damageInfo.force != Vector3.zero) ? damageInfo.force : Random.onUnitSphere)
                    };
                    EffectManager.instance.SpawnEffect(Resources.Load <GameObject>("Prefabs/Effects/BearProc"), effectData, true);
                    damageInfo.rejected = true;
                }
            }
            if (body.HasBuff((BuffIndex)3))
            {
                damageInfo.rejected = true;
            }
            if (body.HasBuff((BuffIndex)23) && (!characterBody || !characterBody.HasBuff((BuffIndex)22)))
            {
                EffectManager.instance.SpawnEffect(Resources.Load <GameObject>("Prefabs/Effects/DamageRejected"), new EffectData
                {
                    origin = damageInfo.position
                }, true);
                damageInfo.rejected = true;
            }
            if (damageInfo.rejected)
            {
                return;
            }
            var num = damageInfo.damage;

            if (characterBody)
            {
                var master2 = characterBody.master;
                if (master2 && master2.inventory)
                {
                    if (combinedHealth >= fullCombinedHealth * 0.9f)
                    {
                        var itemCount2 = master2.inventory.GetItemCount((ItemIndex)17);
                        if (itemCount2 > 0)
                        {
                            Util.PlaySound("Play_item_proc_crowbar", gameObject);
                            num *= 1.5f + 0.3f * (itemCount2 - 1);
                            EffectManager.instance.SimpleImpactEffect(Resources.Load <GameObject>("Prefabs/Effects/ImpactEffects/ImpactCrowbar"), damageInfo.position, -damageInfo.force, true);
                        }
                    }
                    if (body.isBoss)
                    {
                        var itemCount3 = master2.inventory.GetItemCount((ItemIndex)61);
                        if (itemCount3 > 0)
                        {
                            num *= 1.2f + 0.1f * (itemCount3 - 1);
                            damageInfo.damageColorIndex = (DamageColorIndex)5;
                            EffectManager.instance.SimpleImpactEffect(Resources.Load <GameObject>("Prefabs/Effects/ImpactEffects/ImpactBossDamageBonus"), damageInfo.position, -damageInfo.force, true);
                        }
                    }
                }
            }
            if (damageInfo.crit)
            {
                num *= 2f;
            }
            if ((damageInfo.damageType & DamageType.WeakPointHit) != 0)
            {
                num *= 1.5f;
                damageInfo.damageColorIndex = (DamageColorIndex)5;
            }
            if ((damageInfo.damageType & DamageType.BypassArmor) == 0)
            {
                var armor = body.armor;
                var num2  = armor >= 0f ? 1f - armor / (armor + 100f) : 2f - 100f / (100f - armor);
                num = Mathf.Max(1f, num * num2);
            }
            if ((damageInfo.damageType & DamageType.BarrierBlocked) != 0)
            {
                damageInfo.force *= 0.5f;
                var component = GetComponent <IBarrier>();
                component?.BlockedDamage(damageInfo, num);
                damageInfo.procCoefficient = 0f;
                num = 0f;
            }
            if (hasOneshotProtection)
            {
                num = Mathf.Min(num, fullCombinedHealth * 0.40f);                 // Make this more aggressive; 90% -> 40%
            }
            if ((damageInfo.damageType & DamageType.SlowOnHit) != 0)
            {
                body.AddTimedBuff(0, 2f);
            }
            if ((damageInfo.damageType & DamageType.ClayGoo) != 0 && (body.bodyFlags & CharacterBody.BodyFlags.ImmuneToGoo) == 0)
            {
                body.AddTimedBuff((BuffIndex)21, 2f);
            }
            if (master && master.inventory)
            {
                var itemCount4 = master.inventory.GetItemCount((ItemIndex)44);
                if (itemCount4 > 0)
                {
                    var num3 = num / fullCombinedHealth;
                    var num4 = (uint)Mathf.Max(master.money * num3 * itemCount4, damageInfo.damage * itemCount4);
                    master.money = (uint)Mathf.Max(0f, master.money - num4);
                    EffectManager.instance.SimpleImpactEffect(Resources.Load <GameObject>("Prefabs/Effects/ImpactEffects/CoinImpact"), damageInfo.position, Vector3.up, true);
                }
            }
            if ((damageInfo.damageType & DamageType.NonLethal) != 0)
            {
                num = Mathf.Max(Mathf.Min(num, health - 1f), 0f);
            }
            if (shield > 0f)
            {
                var num5 = Mathf.Min(num, shield);
                var num6 = num - num5;
                Networkshield = Mathf.Max(shield - num5, 0f);
                if (Mathf.Approximately(shield, 0f))
                {
                    var scale = 1f;
                    if (body)
                    {
                        scale = body.radius;
                    }
                    EffectManager.instance.SpawnEffect(Resources.Load <GameObject>("Prefabs/Effects/ShieldBreakEffect"), new EffectData
                    {
                        origin = transform.position,
                        scale  = scale
                    }, true);
                }
                if (num6 > 0f)
                {
                    Networkhealth = health - num6;
                }
            }
            else
            {
                Networkhealth = health - num;
            }
            TakeDamageForce(damageInfo, false);
            SendMessage("OnTakeDamage", damageInfo, SendMessageOptions.DontRequireReceiver);
            var damageReport = new DamageReport
            {
                victim     = this,
                damageInfo = damageInfo
            };

            damageReport.damageInfo.damage = num;
            if (num > 0f)
            {
                SendDamageDealt(damageReport);
            }
            UpdateLastHitTime(damageInfo.damage, damageInfo.position, (damageInfo.damageType & (DamageType)2048) > 0);
            if (damageInfo.attacker)
            {
                damageInfo.attacker.SendMessage("OnDamageDealt", damageReport, SendMessageOptions.DontRequireReceiver);
            }
            GlobalEventManager.ServerDamageDealt(damageReport);
            if (isInFrozenState && (body.bodyFlags & (CharacterBody.BodyFlags) 16) == 0 && combinedHealthFraction < 0.3f)
            {
                Networkhealth = -1f;
                EffectManager.instance.SpawnEffect(FrozenState.executeEffectPrefab, new EffectData
                {
                    origin = body.corePosition,
                    scale  = body ? body.radius : 1f
                }, true);
            }
            if (!alive)
            {
                BroadcastMessage("OnKilled", damageInfo, SendMessageOptions.DontRequireReceiver);
                if (damageInfo.attacker)
                {
                    damageInfo.attacker.SendMessage("OnKilledOther", damageReport, SendMessageOptions.DontRequireReceiver);
                }
                GlobalEventManager.instance.OnCharacterDeath(damageReport);
                return;
            }
            if (master && master.inventory)
            {
                var itemCount5 = master.inventory.GetItemCount((ItemIndex)25);
                if (itemCount5 > 0 && Util.CheckRoll(damageInfo.damage / fullCombinedHealth * 100f, master))
                {
                    body.AddTimedBuff((BuffIndex)7, 1.5f + itemCount5 * 1.5f);
                    body.AddTimedBuff((BuffIndex)8, 1.5f + itemCount5 * 1.5f);
                    EffectManager.instance.SpawnEffect(Resources.Load <GameObject>("Prefabs/Effects/ProcStealthkit"), new EffectData
                    {
                        origin   = transform.position,
                        rotation = Quaternion.identity
                    }, true);
                }
            }
        }