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); } } }
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); } } }