using System;
using System.Collections.Generic;
using System.Linq;
using HG;
using JetBrains.Annotations;
using RoR2.Orbs;
using RoR2.Projectile;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;

namespace RoR2;

public class GlobalEventManager : MonoBehaviour
{
	private static class CommonAssets
	{
		public static CharacterMaster wispSoulMasterPrefabMasterComponent;

		public static GameObject igniteOnKillExplosionEffectPrefab;

		public static GameObject missilePrefab;

		public static GameObject explodeOnDeathPrefab;

		public static GameObject daggerPrefab;

		public static GameObject bleedOnHitAndExplodeImpactEffect;

		public static GameObject bleedOnHitAndExplodeBlastEffect;

		public static GameObject minorConstructOnKillProjectile;

		public static GameObject knockbackFinEffect;

		public static GameObject runicMeteorEffect;

		public static GameObject missileVoidPrefab;

		public static GameObject eliteEarthHealerMaster;

		public static PickupDropTable dtSonorousEchoPath;

		public static GameObject loseCoinsImpactEffectPrefab;

		public static void Load()
		{
			AsyncOperationHandle<GameObject> asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/CharacterMasters/WispSoulMaster");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				wispSoulMasterPrefabMasterComponent = x.Result.GetComponent<CharacterMaster>();
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Effects/ImpactEffects/IgniteExplosionVFX");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				igniteOnKillExplosionEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Projectiles/MissileProjectile");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				missilePrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Projectiles/DaggerProjectile");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				daggerPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Effects/ImpactEffects/BleedOnHitAndExplode_Impact");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				bleedOnHitAndExplodeImpactEffect = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/NetworkedObjects/BleedOnHitAndExplodeDelay");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				bleedOnHitAndExplodeBlastEffect = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Projectiles/MissileVoidProjectile");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				missileVoidPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Effects/ImpactEffects/KnockBackHitEnemiesImpact");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				knockbackFinEffect = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Effects/RunicMeteorStrikePredictionEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				runicMeteorEffect = x.Result;
			};
			asyncOperationHandle = Addressables.LoadAssetAsync<GameObject>("RoR2/DLC1/EliteEarth/AffixEarthHealerMaster.prefab");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				eliteEarthHealerMaster = x.Result;
			};
			asyncOperationHandle = Addressables.LoadAssetAsync<GameObject>("RoR2/Base/ExplodeOnDeath/WilloWispDelay.prefab");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				explodeOnDeathPrefab = x.Result;
			};
			asyncOperationHandle = Addressables.LoadAssetAsync<GameObject>("RoR2/DLC1/MinorConstructOnKill/MinorConstructOnKillProjectile.prefab");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				minorConstructOnKillProjectile = x.Result;
			};
			AsyncOperationHandle<PickupDropTable> asyncOperationHandle2 = Addressables.LoadAssetAsync<PickupDropTable>("RoR2/DLC2/Items/ResetChests/dtSonorousEcho.asset");
			asyncOperationHandle2.Completed += delegate(AsyncOperationHandle<PickupDropTable> x)
			{
				dtSonorousEchoPath = x.Result;
			};
			asyncOperationHandle = Addressables.LoadAssetAsync<GameObject>("RoR2/Base/Common/VFX/CoinImpact.prefab");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				loseCoinsImpactEffectPrefab = x.Result;
			};
		}
	}

	public static GlobalEventManager instance;

	[Obsolete("Transform of the global event manager should not be used! You probably meant something else instead.", true)]
	private new Transform transform;

	[Obsolete("GameObject of the global event manager should not be used! You probably meant something else instead.", true)]
	private new GameObject gameObject;

	private static readonly string[] standardDeathQuoteTokens = (from i in Enumerable.Range(0, 37)
		select "PLAYER_DEATH_QUOTE_" + TextSerialization.ToStringInvariant(i)).ToArray();

	private static readonly string[] fallDamageDeathQuoteTokens = (from i in Enumerable.Range(0, 5)
		select "PLAYER_DEATH_QUOTE_FALLDAMAGE_" + TextSerialization.ToStringInvariant(i)).ToArray();

	private static readonly SphereSearch igniteOnKillSphereSearch = new SphereSearch();

	private static readonly List<HurtBox> igniteOnKillHurtBoxBuffer = new List<HurtBox>();

	public static event Action<DamageReport> onCharacterDeathGlobal;

	public static event Action<TeamIndex> onTeamLevelUp;

	public static event Action<CharacterBody> onCharacterLevelUp;

	public static event Action<Interactor, IInteractable, GameObject> OnInteractionsGlobal;

	public static event Action<DamageDealtMessage> onClientDamageNotified;

	public static event Action<DamageReport> onServerDamageDealt;

	public static event Action<DamageReport, float> onServerCharacterExecuted;

	[InitDuringStartup]
	private static void Init()
	{
		CommonAssets.Load();
	}

	private void OnEnable()
	{
		if ((bool)instance)
		{
			Debug.LogError("Only one GlobalEventManager can exist at a time.");
		}
		else
		{
			instance = this;
		}
	}

	private void OnDisable()
	{
		if (instance == this)
		{
			instance = null;
		}
	}

	public void OnHitEnemy([NotNull] DamageInfo damageInfo, [NotNull] GameObject victim)
	{
		ProcessHitEnemy(damageInfo, victim);
	}

	private void ProcessHitEnemy([NotNull] DamageInfo damageInfo, [NotNull] GameObject victim)
	{
		if (damageInfo.procCoefficient == 0f || damageInfo.rejected || !NetworkServer.active)
		{
			return;
		}
		if (damageInfo.attacker == null)
		{
			HandleDamageWithNoAttacker(damageInfo, victim);
		}
		if (!damageInfo.attacker || !(damageInfo.procCoefficient > 0f))
		{
			return;
		}
		uint? maxStacksFromAttacker = null;
		if ((bool)damageInfo?.inflictor)
		{
			ProjectileDamage component = damageInfo.inflictor.GetComponent<ProjectileDamage>();
			if ((bool)component && component.useDotMaxStacksFromAttacker)
			{
				maxStacksFromAttacker = component.dotMaxStacksFromAttacker;
			}
		}
		CharacterBody component2 = damageInfo.attacker.GetComponent<CharacterBody>();
		CharacterBody characterBody = (victim ? victim.GetComponent<CharacterBody>() : null);
		if ((ulong)(damageInfo.damageType & DamageType.LunarRuin) != 0)
		{
			if ((ulong)(damageInfo.damageType & DamageTypeExtended.ApplyBuffPermanently) != 0L)
			{
				characterBody.AddTimedBuff(DLC2Content.Buffs.lunarruin, 420f);
			}
			else
			{
				DotController.InflictDot(characterBody.gameObject, damageInfo.attacker, DotController.DotIndex.LunarRuin, 5f);
			}
		}
		if ((ulong)(damageInfo.damageType & DamageTypeExtended.DisableAllSkills) != 0L)
		{
			if ((ulong)(damageInfo.damageType & DamageTypeExtended.ApplyBuffPermanently) != 0L)
			{
				Debug.LogFormat("Adding DisableAllSkills");
				characterBody.AddTimedBuff(DLC2Content.Buffs.DisableAllSkills, 420f);
			}
			else
			{
				Debug.LogFormat("Adding DisableAllSkills for 5s");
				characterBody.AddTimedBuff(DLC2Content.Buffs.DisableAllSkills, 5f);
			}
		}
		if (!component2)
		{
			return;
		}
		if ((ulong)(damageInfo.damageType & DamageType.PoisonOnHit) != 0)
		{
			DotController.InflictDot(victim, damageInfo.attacker, DotController.DotIndex.Poison, 10f * damageInfo.procCoefficient, 1f, maxStacksFromAttacker);
		}
		CharacterMaster master = component2.master;
		if (!master)
		{
			return;
		}
		Inventory inventory = master.inventory;
		TeamComponent component3 = component2.GetComponent<TeamComponent>();
		TeamIndex teamIndex = (component3 ? component3.teamIndex : TeamIndex.Neutral);
		Vector3 aimOrigin = component2.aimOrigin;
		if (damageInfo.crit)
		{
			instance.OnCrit(component2, damageInfo, master, damageInfo.procCoefficient, damageInfo.procChainMask);
		}
		if (!damageInfo.procChainMask.HasProc(ProcType.HealOnHit))
		{
			int itemCount = inventory.GetItemCount(RoR2Content.Items.Seed);
			if (itemCount > 0)
			{
				HealthComponent component4 = component2.GetComponent<HealthComponent>();
				if ((bool)component4)
				{
					ProcChainMask procChainMask = damageInfo.procChainMask;
					procChainMask.AddProc(ProcType.HealOnHit);
					component4.Heal((float)itemCount * damageInfo.procCoefficient, procChainMask);
				}
			}
		}
		if (!damageInfo.procChainMask.HasProc(ProcType.BleedOnHit))
		{
			bool flag = (ulong)(damageInfo.damageType & DamageType.BleedOnHit) != 0 || (inventory.GetItemCount(RoR2Content.Items.BleedOnHitAndExplode) > 0 && damageInfo.crit);
			if ((component2.bleedChance > 0f || flag) && (flag || Util.CheckRoll(damageInfo.procCoefficient * component2.bleedChance, master)))
			{
				ProcChainMask procChainMask2 = damageInfo.procChainMask;
				procChainMask2.AddProc(ProcType.BleedOnHit);
				DotController.InflictDot(victim, damageInfo.attacker, DotController.DotIndex.Bleed, 3f * damageInfo.procCoefficient, 1f, maxStacksFromAttacker);
			}
		}
		if (!damageInfo.procChainMask.HasProc(ProcType.FractureOnHit))
		{
			int itemCount2 = inventory.GetItemCount(DLC1Content.Items.BleedOnHitVoid);
			itemCount2 += (component2.HasBuff(DLC1Content.Buffs.EliteVoid) ? 10 : 0);
			if (itemCount2 > 0 && Util.CheckRoll(damageInfo.procCoefficient * (float)itemCount2 * 10f, master))
			{
				ProcChainMask procChainMask3 = damageInfo.procChainMask;
				procChainMask3.AddProc(ProcType.FractureOnHit);
				DotController.DotDef dotDef = DotController.GetDotDef(DotController.DotIndex.Fracture);
				DotController.InflictDot(victim, damageInfo.attacker, DotController.DotIndex.Fracture, dotDef.interval, 1f, maxStacksFromAttacker);
			}
		}
		bool flag2 = (ulong)(damageInfo.damageType & DamageType.BlightOnHit) != 0;
		if (flag2 && flag2)
		{
			_ = damageInfo.procChainMask;
			DotController.InflictDot(victim, damageInfo.attacker, DotController.DotIndex.Blight, 5f * damageInfo.procCoefficient, 1f, maxStacksFromAttacker);
		}
		if ((ulong)(damageInfo.damageType & DamageType.WeakOnHit) != 0)
		{
			characterBody.AddTimedBuff(RoR2Content.Buffs.Weak, 6f * damageInfo.procCoefficient);
		}
		if ((ulong)(damageInfo.damageType & DamageType.IgniteOnHit) != 0 || component2.HasBuff(RoR2Content.Buffs.AffixRed))
		{
			float num = 0.5f;
			InflictDotInfo inflictDotInfo = default(InflictDotInfo);
			inflictDotInfo.attackerObject = damageInfo.attacker;
			inflictDotInfo.victimObject = victim;
			inflictDotInfo.totalDamage = damageInfo.damage * num;
			inflictDotInfo.damageMultiplier = 1f;
			inflictDotInfo.dotIndex = DotController.DotIndex.Burn;
			inflictDotInfo.maxStacksFromAttacker = maxStacksFromAttacker;
			InflictDotInfo dotInfo = inflictDotInfo;
			StrengthenBurnUtils.CheckDotForUpgrade(inventory, ref dotInfo);
			DotController.InflictDot(ref dotInfo);
		}
		int num2 = (component2.HasBuff(RoR2Content.Buffs.AffixWhite) ? 1 : 0);
		num2 += (component2.HasBuff(RoR2Content.Buffs.AffixHaunted) ? 2 : 0);
		if (num2 > 0 && (bool)characterBody)
		{
			EffectManager.SimpleImpactEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/AffixWhiteImpactEffect"), damageInfo.position, Vector3.up, transmit: true);
			characterBody.AddTimedBuff(RoR2Content.Buffs.Slow80, 1.5f * damageInfo.procCoefficient * (float)num2);
		}
		int itemCount3 = master.inventory.GetItemCount(RoR2Content.Items.SlowOnHit);
		if (itemCount3 > 0 && (bool)characterBody)
		{
			characterBody.AddTimedBuff(RoR2Content.Buffs.Slow60, 2f * (float)itemCount3);
		}
		int itemCount4 = master.inventory.GetItemCount(DLC1Content.Items.SlowOnHitVoid);
		if (itemCount4 > 0 && (bool)characterBody && Util.CheckRoll(Util.ConvertAmplificationPercentageIntoReductionPercentage(5f * (float)itemCount4 * damageInfo.procCoefficient), master))
		{
			characterBody.AddTimedBuff(RoR2Content.Buffs.Nullified, 1f * (float)itemCount4);
		}
		if ((component2.HasBuff(RoR2Content.Buffs.AffixPoison) ? 1 : 0) > 0 && (bool)characterBody)
		{
			characterBody.AddTimedBuff(RoR2Content.Buffs.HealingDisabled, 8f * damageInfo.procCoefficient);
		}
		int itemCount5 = inventory.GetItemCount(RoR2Content.Items.GoldOnHit);
		if (itemCount5 > 0 && Util.CheckRoll(30f * damageInfo.procCoefficient, master))
		{
			GoldOrb goldOrb = new GoldOrb();
			goldOrb.origin = damageInfo.position;
			goldOrb.target = component2.mainHurtBox;
			goldOrb.goldAmount = (uint)((float)itemCount5 * 2f * Run.instance.difficultyCoefficient);
			OrbManager.instance.AddOrb(goldOrb);
			EffectManager.SimpleImpactEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/CoinImpact"), damageInfo.position, Vector3.up, transmit: true);
		}
		if (!damageInfo.procChainMask.HasProc(ProcType.Missile))
		{
			int itemCount6 = inventory.GetItemCount(RoR2Content.Items.Missile);
			if (itemCount6 > 0)
			{
				if (Util.CheckRoll(10f * damageInfo.procCoefficient, master))
				{
					float damageCoefficient = 3f * (float)itemCount6;
					float missileDamage = Util.OnHitProcDamage(damageInfo.damage, component2.damage, damageCoefficient);
					MissileUtils.FireMissile(component2.corePosition, component2, damageInfo.procChainMask, victim, missileDamage, damageInfo.crit, CommonAssets.missilePrefab, DamageColorIndex.Item, addMissileProc: true);
				}
			}
			else
			{
				itemCount6 = inventory.GetItemCount(DLC1Content.Items.MissileVoid);
				if (itemCount6 > 0 && component2.healthComponent.shield > 0f)
				{
					int valueOrDefault = (component2?.inventory?.GetItemCount(DLC1Content.Items.MoreMissile)).GetValueOrDefault();
					float num3 = Mathf.Max(1f, 1f + 0.5f * (float)(valueOrDefault - 1));
					float damageCoefficient2 = 0.4f * (float)itemCount6;
					float damageValue = Util.OnHitProcDamage(damageInfo.damage, component2.damage, damageCoefficient2) * num3;
					int num4 = ((valueOrDefault <= 0) ? 1 : 3);
					for (int i = 0; i < num4; i++)
					{
						MissileVoidOrb missileVoidOrb = new MissileVoidOrb();
						missileVoidOrb.origin = aimOrigin;
						missileVoidOrb.damageValue = damageValue;
						missileVoidOrb.isCrit = damageInfo.crit;
						missileVoidOrb.teamIndex = teamIndex;
						missileVoidOrb.attacker = damageInfo.attacker;
						missileVoidOrb.procChainMask = damageInfo.procChainMask;
						missileVoidOrb.procChainMask.AddProc(ProcType.Missile);
						missileVoidOrb.procCoefficient = 0.2f;
						missileVoidOrb.damageColorIndex = DamageColorIndex.Void;
						HurtBox mainHurtBox = characterBody.mainHurtBox;
						if ((bool)mainHurtBox)
						{
							missileVoidOrb.target = mainHurtBox;
							OrbManager.instance.AddOrb(missileVoidOrb);
						}
					}
				}
			}
		}
		if (component2.HasBuff(JunkContent.Buffs.LoaderPylonPowered) && !damageInfo.procChainMask.HasProc(ProcType.LoaderLightning))
		{
			float damageCoefficient3 = 0.3f;
			float damageValue2 = Util.OnHitProcDamage(damageInfo.damage, component2.damage, damageCoefficient3);
			LightningOrb lightningOrb = new LightningOrb();
			lightningOrb.origin = damageInfo.position;
			lightningOrb.damageValue = damageValue2;
			lightningOrb.isCrit = damageInfo.crit;
			lightningOrb.bouncesRemaining = 3;
			lightningOrb.teamIndex = teamIndex;
			lightningOrb.attacker = damageInfo.attacker;
			lightningOrb.bouncedObjects = new List<HealthComponent> { victim.GetComponent<HealthComponent>() };
			lightningOrb.procChainMask = damageInfo.procChainMask;
			lightningOrb.procChainMask.AddProc(ProcType.LoaderLightning);
			lightningOrb.procCoefficient = 0f;
			lightningOrb.lightningType = LightningOrb.LightningType.Loader;
			lightningOrb.damageColorIndex = DamageColorIndex.Item;
			lightningOrb.range = 20f;
			HurtBox hurtBox = lightningOrb.PickNextTarget(damageInfo.position);
			if ((bool)hurtBox)
			{
				lightningOrb.target = hurtBox;
				OrbManager.instance.AddOrb(lightningOrb);
			}
		}
		int itemCount7 = inventory.GetItemCount(RoR2Content.Items.ChainLightning);
		float num5 = 25f;
		if (itemCount7 > 0 && !damageInfo.procChainMask.HasProc(ProcType.ChainLightning) && Util.CheckRoll(num5 * damageInfo.procCoefficient, master))
		{
			float damageCoefficient4 = 0.8f;
			float damageValue3 = Util.OnHitProcDamage(damageInfo.damage, component2.damage, damageCoefficient4);
			LightningOrb lightningOrb2 = new LightningOrb();
			lightningOrb2.origin = damageInfo.position;
			lightningOrb2.damageValue = damageValue3;
			lightningOrb2.isCrit = damageInfo.crit;
			lightningOrb2.bouncesRemaining = 2 * itemCount7;
			lightningOrb2.teamIndex = teamIndex;
			lightningOrb2.attacker = damageInfo.attacker;
			lightningOrb2.bouncedObjects = new List<HealthComponent> { victim.GetComponent<HealthComponent>() };
			lightningOrb2.procChainMask = damageInfo.procChainMask;
			lightningOrb2.procChainMask.AddProc(ProcType.ChainLightning);
			lightningOrb2.procCoefficient = 0.2f;
			lightningOrb2.lightningType = LightningOrb.LightningType.Ukulele;
			lightningOrb2.damageColorIndex = DamageColorIndex.Item;
			lightningOrb2.range += 2 * itemCount7;
			HurtBox hurtBox2 = lightningOrb2.PickNextTarget(damageInfo.position);
			if ((bool)hurtBox2)
			{
				lightningOrb2.target = hurtBox2;
				OrbManager.instance.AddOrb(lightningOrb2);
			}
		}
		int itemCount8 = inventory.GetItemCount(DLC1Content.Items.ChainLightningVoid);
		float num6 = 25f;
		if (itemCount8 > 0 && !damageInfo.procChainMask.HasProc(ProcType.ChainLightning) && Util.CheckRoll(num6 * damageInfo.procCoefficient, master))
		{
			float damageCoefficient5 = 0.6f;
			float damageValue4 = Util.OnHitProcDamage(damageInfo.damage, component2.damage, damageCoefficient5);
			VoidLightningOrb voidLightningOrb = new VoidLightningOrb();
			voidLightningOrb.origin = damageInfo.position;
			voidLightningOrb.damageValue = damageValue4;
			voidLightningOrb.isCrit = damageInfo.crit;
			voidLightningOrb.totalStrikes = 3 * itemCount8;
			voidLightningOrb.teamIndex = teamIndex;
			voidLightningOrb.attacker = damageInfo.attacker;
			voidLightningOrb.procChainMask = damageInfo.procChainMask;
			voidLightningOrb.procChainMask.AddProc(ProcType.ChainLightning);
			voidLightningOrb.procCoefficient = 0.2f;
			voidLightningOrb.damageColorIndex = DamageColorIndex.Void;
			voidLightningOrb.secondsPerStrike = 0.1f;
			HurtBox mainHurtBox2 = characterBody.mainHurtBox;
			if ((bool)mainHurtBox2)
			{
				voidLightningOrb.target = mainHurtBox2;
				OrbManager.instance.AddOrb(voidLightningOrb);
			}
		}
		int itemCount9 = inventory.GetItemCount(RoR2Content.Items.BounceNearby);
		if (itemCount9 > 0)
		{
			float num7 = (1f - 100f / (100f + 20f * (float)itemCount9)) * 100f;
			if (!damageInfo.procChainMask.HasProc(ProcType.BounceNearby) && Util.CheckRoll(num7 * damageInfo.procCoefficient, master))
			{
				List<HurtBox> list = CollectionPool<HurtBox, List<HurtBox>>.RentCollection();
				int maxTargets = 5 + itemCount9 * 5;
				BullseyeSearch search = new BullseyeSearch();
				List<HealthComponent> list2 = CollectionPool<HealthComponent, List<HealthComponent>>.RentCollection();
				if ((bool)component2 && (bool)component2.healthComponent)
				{
					list2.Add(component2.healthComponent);
				}
				if ((bool)characterBody && (bool)characterBody.healthComponent)
				{
					list2.Add(characterBody.healthComponent);
				}
				BounceOrb.SearchForTargets(search, teamIndex, damageInfo.position, 30f, maxTargets, list, list2);
				CollectionPool<HealthComponent, List<HealthComponent>>.ReturnCollection(list2);
				List<HealthComponent> bouncedObjects = new List<HealthComponent> { victim.GetComponent<HealthComponent>() };
				float damageCoefficient6 = 1f;
				float damageValue5 = Util.OnHitProcDamage(damageInfo.damage, component2.damage, damageCoefficient6);
				int j = 0;
				for (int count = list.Count; j < count; j++)
				{
					HurtBox hurtBox3 = list[j];
					if ((bool)hurtBox3)
					{
						BounceOrb bounceOrb = new BounceOrb();
						bounceOrb.origin = damageInfo.position;
						bounceOrb.damageValue = damageValue5;
						bounceOrb.isCrit = damageInfo.crit;
						bounceOrb.teamIndex = teamIndex;
						bounceOrb.attacker = damageInfo.attacker;
						bounceOrb.procChainMask = damageInfo.procChainMask;
						bounceOrb.procChainMask.AddProc(ProcType.BounceNearby);
						bounceOrb.procCoefficient = 0.33f;
						bounceOrb.damageColorIndex = DamageColorIndex.Item;
						bounceOrb.bouncedObjects = bouncedObjects;
						bounceOrb.target = hurtBox3;
						OrbManager.instance.AddOrb(bounceOrb);
					}
				}
				CollectionPool<HurtBox, List<HurtBox>>.ReturnCollection(list);
			}
		}
		int itemCount10 = inventory.GetItemCount(RoR2Content.Items.StickyBomb);
		if (itemCount10 > 0 && Util.CheckRoll(5f * (float)itemCount10 * damageInfo.procCoefficient, master) && (bool)characterBody)
		{
			bool alive = characterBody.healthComponent.alive;
			float num8 = 5f;
			Vector3 position = damageInfo.position;
			Vector3 forward = characterBody.corePosition - position;
			float magnitude = forward.magnitude;
			Quaternion rotation = ((magnitude != 0f) ? Util.QuaternionSafeLookRotation(forward) : UnityEngine.Random.rotationUniform);
			float damageCoefficient7 = 1.8f;
			float damage = Util.OnHitProcDamage(damageInfo.damage, component2.damage, damageCoefficient7);
			ProjectileManager.instance.FireProjectile(LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/StickyBomb"), position, rotation, damageInfo.attacker, damage, 100f, damageInfo.crit, DamageColorIndex.Item, null, alive ? (magnitude * num8) : (-1f));
		}
		if (!damageInfo.procChainMask.HasProc(ProcType.Rings) && damageInfo.damage / component2.damage >= 4f)
		{
			if (component2.HasBuff(RoR2Content.Buffs.ElementalRingsReady))
			{
				int itemCount11 = inventory.GetItemCount(RoR2Content.Items.IceRing);
				int itemCount12 = inventory.GetItemCount(RoR2Content.Items.FireRing);
				component2.RemoveBuff(RoR2Content.Buffs.ElementalRingsReady);
				for (int k = 1; (float)k <= 10f; k++)
				{
					component2.AddTimedBuff(RoR2Content.Buffs.ElementalRingsCooldown, k);
				}
				ProcChainMask procChainMask4 = damageInfo.procChainMask;
				procChainMask4.AddProc(ProcType.Rings);
				Vector3 position2 = damageInfo.position;
				if (itemCount11 > 0)
				{
					float damageCoefficient8 = 2.5f * (float)itemCount11;
					float damage2 = Util.OnHitProcDamage(damageInfo.damage, component2.damage, damageCoefficient8);
					DamageInfo damageInfo2 = new DamageInfo
					{
						damage = damage2,
						damageColorIndex = DamageColorIndex.Item,
						damageType = DamageType.Generic,
						attacker = damageInfo.attacker,
						crit = damageInfo.crit,
						force = Vector3.zero,
						inflictor = null,
						position = position2,
						procChainMask = procChainMask4,
						procCoefficient = 1f
					};
					EffectManager.SimpleImpactEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/IceRingExplosion"), position2, Vector3.up, transmit: true);
					characterBody.AddTimedBuff(RoR2Content.Buffs.Slow80, 3f * (float)itemCount11);
					characterBody.healthComponent.TakeDamage(damageInfo2);
				}
				if (itemCount12 > 0)
				{
					GameObject gameObject = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/FireTornado");
					float resetInterval = gameObject.GetComponent<ProjectileOverlapAttack>().resetInterval;
					float lifetime = gameObject.GetComponent<ProjectileSimple>().lifetime;
					float damageCoefficient9 = 3f * (float)itemCount12;
					float damage3 = Util.OnHitProcDamage(damageInfo.damage, component2.damage, damageCoefficient9) / lifetime * resetInterval;
					float speedOverride = 0f;
					Quaternion rotation2 = Quaternion.identity;
					Vector3 vector = position2 - aimOrigin;
					vector.y = 0f;
					if (vector != Vector3.zero)
					{
						speedOverride = -1f;
						rotation2 = Util.QuaternionSafeLookRotation(vector, Vector3.up);
					}
					ProjectileManager.instance.FireProjectile(new FireProjectileInfo
					{
						damage = damage3,
						crit = damageInfo.crit,
						damageColorIndex = DamageColorIndex.Item,
						position = position2,
						procChainMask = procChainMask4,
						force = 0f,
						owner = damageInfo.attacker,
						projectilePrefab = gameObject,
						rotation = rotation2,
						speedOverride = speedOverride,
						target = null
					});
				}
			}
			else if (component2.HasBuff(DLC1Content.Buffs.ElementalRingVoidReady))
			{
				int itemCount13 = inventory.GetItemCount(DLC1Content.Items.ElementalRingVoid);
				component2.RemoveBuff(DLC1Content.Buffs.ElementalRingVoidReady);
				for (int l = 1; (float)l <= 20f; l++)
				{
					component2.AddTimedBuff(DLC1Content.Buffs.ElementalRingVoidCooldown, l);
				}
				ProcChainMask procChainMask5 = damageInfo.procChainMask;
				procChainMask5.AddProc(ProcType.Rings);
				if (itemCount13 > 0)
				{
					GameObject projectilePrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/ElementalRingVoidBlackHole");
					float damageCoefficient10 = 1f * (float)itemCount13;
					float damage4 = Util.OnHitProcDamage(damageInfo.damage, component2.damage, damageCoefficient10);
					ProjectileManager.instance.FireProjectile(new FireProjectileInfo
					{
						damage = damage4,
						crit = damageInfo.crit,
						damageColorIndex = DamageColorIndex.Void,
						position = damageInfo.position,
						procChainMask = procChainMask5,
						force = 6000f,
						owner = damageInfo.attacker,
						projectilePrefab = projectilePrefab,
						rotation = Quaternion.identity,
						target = null
					});
				}
			}
		}
		int itemCount14 = master.inventory.GetItemCount(RoR2Content.Items.DeathMark);
		int num9 = 0;
		if (itemCount14 >= 1 && !characterBody.HasBuff(RoR2Content.Buffs.DeathMark))
		{
			BuffIndex[] debuffBuffIndices = BuffCatalog.debuffBuffIndices;
			foreach (BuffIndex buffType in debuffBuffIndices)
			{
				if (characterBody.HasBuff(buffType))
				{
					num9++;
				}
			}
			DotController dotController = DotController.FindDotController(victim.gameObject);
			if ((bool)dotController)
			{
				for (DotController.DotIndex dotIndex = DotController.DotIndex.Bleed; dotIndex < DotController.DotIndex.Count; dotIndex++)
				{
					if (dotController.HasDotActive(dotIndex))
					{
						num9++;
					}
				}
			}
			if (num9 >= 4)
			{
				characterBody.AddTimedBuff(RoR2Content.Buffs.DeathMark, 7f * (float)itemCount14);
			}
		}
		if (damageInfo != null && damageInfo.inflictor != null && damageInfo.inflictor.GetComponent<BoomerangProjectile>() != null && !damageInfo.procChainMask.HasProc(ProcType.BleedOnHit))
		{
			int num10 = 0;
			if (inventory.GetEquipmentIndex() == RoR2Content.Equipment.Saw.equipmentIndex)
			{
				num10 = 1;
			}
			bool flag3 = (ulong)(damageInfo.damageType & DamageType.BleedOnHit) != 0;
			if ((num10 > 0 || flag3) && (flag3 || Util.CheckRoll(100f, master)))
			{
				ProcChainMask procChainMask6 = damageInfo.procChainMask;
				procChainMask6.AddProc(ProcType.BleedOnHit);
				DotController.InflictDot(victim, damageInfo.attacker, DotController.DotIndex.Bleed, 4f * damageInfo.procCoefficient, 1f, maxStacksFromAttacker);
			}
		}
		if (damageInfo.crit && (ulong)(damageInfo.damageType & DamageType.SuperBleedOnCrit) != 0L)
		{
			DotController.InflictDot(victim, damageInfo.attacker, DotController.DotIndex.SuperBleed, 15f * damageInfo.procCoefficient, 1f, maxStacksFromAttacker);
		}
		if (component2.HasBuff(RoR2Content.Buffs.LifeSteal))
		{
			float amount = damageInfo.damage * 0.2f;
			component2.healthComponent.Heal(amount, damageInfo.procChainMask);
		}
		int itemCount15 = inventory.GetItemCount(RoR2Content.Items.FireballsOnHit);
		if (itemCount15 > 0 && !damageInfo.procChainMask.HasProc(ProcType.Meatball))
		{
			InputBankTest component5 = component2.GetComponent<InputBankTest>();
			Vector3 vector2 = (characterBody.characterMotor ? (victim.transform.position + Vector3.up * (characterBody.characterMotor.capsuleHeight * 0.5f + 2f)) : (victim.transform.position + Vector3.up * 2f));
			Vector3 vector3 = (component5 ? component5.aimDirection : victim.transform.forward);
			vector3 = Vector3.up;
			float num11 = 20f;
			if (Util.CheckRoll(10f * damageInfo.procCoefficient, master))
			{
				EffectData effectData = new EffectData
				{
					scale = 1f,
					origin = vector2
				};
				EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/MuzzleFlashes/MuzzleflashFireMeatBall"), effectData, transmit: true);
				int num12 = 3;
				float damageCoefficient11 = 3f * (float)itemCount15;
				float damage5 = Util.OnHitProcDamage(damageInfo.damage, component2.damage, damageCoefficient11);
				float maxInclusive = 30f;
				ProcChainMask procChainMask7 = damageInfo.procChainMask;
				procChainMask7.AddProc(ProcType.Meatball);
				float speedOverride2 = UnityEngine.Random.Range(15f, maxInclusive);
				float num13 = 360 / num12;
				_ = num13 / 360f;
				float num14 = 1f;
				float num15 = num13;
				for (int n = 0; n < num12; n++)
				{
					float num16 = (float)n * MathF.PI * 2f / (float)num12;
					FireProjectileInfo fireProjectileInfo = default(FireProjectileInfo);
					fireProjectileInfo.projectilePrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/FireMeatBall");
					fireProjectileInfo.position = vector2 + new Vector3(num14 * Mathf.Sin(num16), 0f, num14 * Mathf.Cos(num16));
					fireProjectileInfo.rotation = Util.QuaternionSafeLookRotation(vector3);
					fireProjectileInfo.procChainMask = procChainMask7;
					fireProjectileInfo.target = victim;
					fireProjectileInfo.owner = component2.gameObject;
					fireProjectileInfo.damage = damage5;
					fireProjectileInfo.crit = damageInfo.crit;
					fireProjectileInfo.force = 200f;
					fireProjectileInfo.damageColorIndex = DamageColorIndex.Item;
					fireProjectileInfo.speedOverride = speedOverride2;
					fireProjectileInfo.useSpeedOverride = true;
					FireProjectileInfo fireProjectileInfo2 = fireProjectileInfo;
					num15 += num13;
					ProjectileManager.instance.FireProjectile(fireProjectileInfo2);
					vector3.x += Mathf.Sin(num16 + UnityEngine.Random.Range(0f - num11, num11));
					vector3.z += Mathf.Cos(num16 + UnityEngine.Random.Range(0f - num11, num11));
				}
			}
		}
		int itemCount16 = inventory.GetItemCount(RoR2Content.Items.LightningStrikeOnHit);
		if (itemCount16 > 0 && !damageInfo.procChainMask.HasProc(ProcType.LightningStrikeOnHit) && Util.CheckRoll(10f * damageInfo.procCoefficient, master))
		{
			float damageValue6 = Util.OnHitProcDamage(damageInfo.damage, component2.damage, 5f * (float)itemCount16);
			ProcChainMask procChainMask8 = damageInfo.procChainMask;
			procChainMask8.AddProc(ProcType.LightningStrikeOnHit);
			HurtBox target = characterBody.mainHurtBox;
			if ((bool)characterBody.hurtBoxGroup)
			{
				target = characterBody.hurtBoxGroup.hurtBoxes[UnityEngine.Random.Range(0, characterBody.hurtBoxGroup.hurtBoxes.Length)];
			}
			OrbManager.instance.AddOrb(new SimpleLightningStrikeOrb
			{
				attacker = component2.gameObject,
				damageColorIndex = DamageColorIndex.Item,
				damageValue = damageValue6,
				isCrit = Util.CheckRoll(component2.crit, master),
				procChainMask = procChainMask8,
				procCoefficient = 1f,
				target = target
			});
		}
		if ((ulong)(damageInfo.damageType & DamageType.LunarSecondaryRootOnHit) != 0L && (bool)characterBody)
		{
			int itemCount17 = master.inventory.GetItemCount(RoR2Content.Items.LunarSecondaryReplacement);
			characterBody.AddTimedBuff(RoR2Content.Buffs.LunarSecondaryRoot, 3f * (float)itemCount17);
		}
		if ((ulong)(damageInfo.damageType & DamageType.FruitOnHit) != 0L && (bool)characterBody)
		{
			characterBody.AddTimedBuff(RoR2Content.Buffs.Fruiting, 10f);
		}
		if (inventory.GetItemCount(DLC1Content.Items.DroneWeaponsBoost) > 0)
		{
			DroneWeaponsBoostBehavior component6 = component2.GetComponent<DroneWeaponsBoostBehavior>();
			if ((bool)component6)
			{
				component6.OnEnemyHit(damageInfo, characterBody);
			}
		}
		if (victim.tag != "Player" && inventory.GetItemCount(DLC2Content.Items.IncreaseDamageOnMultiKill) > 0)
		{
			component2.AddIncreasedDamageMultiKillTime();
		}
		if (component2.luminousShotReady)
		{
			DamageInfo damageInfo3 = new DamageInfo
			{
				damage = component2.luminousShotDamage,
				damageColorIndex = DamageColorIndex.Luminous,
				damageType = DamageType.Generic,
				attacker = component2.gameObject,
				position = characterBody.transform.position,
				crit = damageInfo.crit,
				force = Vector3.zero,
				inflictor = null,
				procCoefficient = 1f
			};
			characterBody.healthComponent.TakeDamage(damageInfo3);
			EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/IncreasePrimaryDamageImpact"), new EffectData
			{
				origin = characterBody.transform.position
			}, transmit: true);
			component2.IncreasePrimaryDamageReset();
			Util.PlaySound("Play_item_proc_increasePrimaryDamage", characterBody.gameObject);
		}
		if (component2.HasBuff(DLC2Content.Buffs.CookingRolling))
		{
			characterBody.AddBuff(DLC2Content.Buffs.CookingRolled);
		}
		else if (component2.HasBuff(DLC2Content.Buffs.CookingSearing))
		{
			characterBody.AddBuff(DLC2Content.Buffs.CookingRoasted);
		}
		if (characterBody.HasBuff(DLC2Content.Buffs.CookingOiled) && component2.HasBuff(DLC2Content.Buffs.CookingSearing))
		{
			characterBody.AddBuff(DLC2Content.Buffs.CookingFlambe);
			characterBody.RemoveBuff(DLC2Content.Buffs.CookingOiled);
		}
		if (characterBody.HasBuff(DLC2Content.Buffs.CookingFlambe) && (DamageTypeExtended)damageInfo.damageType == DamageTypeExtended.ChefSearDamage)
		{
			float num17 = 0.75f;
			InflictDotInfo inflictDotInfo = default(InflictDotInfo);
			inflictDotInfo.attackerObject = damageInfo.attacker;
			inflictDotInfo.victimObject = victim;
			inflictDotInfo.totalDamage = component2.damage * num17;
			inflictDotInfo.damageMultiplier = 1f;
			inflictDotInfo.dotIndex = DotController.DotIndex.StrongerBurn;
			inflictDotInfo.maxStacksFromAttacker = maxStacksFromAttacker;
			InflictDotInfo dotInfo2 = inflictDotInfo;
			StrengthenBurnUtils.CheckDotForUpgrade(inventory, ref dotInfo2);
			for (int num18 = 0; num18 < 3; num18++)
			{
				DotController.InflictDot(ref dotInfo2);
			}
		}
		int itemCount18 = inventory.GetItemCount(DLC2Content.Items.MeteorAttackOnHighDamage);
		if (itemCount18 > 0 && !damageInfo.procChainMask.HasProc(ProcType.MeteorAttackOnHighDamage))
		{
			float num19 = 0f;
			float num20 = (int)(damageInfo.damage / component2.damage);
			num19 = 5f + 1f * num20 * (float)itemCount18;
			if (num19 > 50f)
			{
				num19 = 50f;
			}
			if (Util.CheckRoll(num19 * damageInfo.procCoefficient, master))
			{
				ProcChainMask procChainMask9 = damageInfo.procChainMask;
				procChainMask9.AddProc(ProcType.MeteorAttackOnHighDamage);
				float num21 = 20f + 0.5f * (float)itemCount18 * num20;
				if (num21 > 75f)
				{
					num21 = 75f;
				}
				num21 *= component2.damage;
				Vector3 vector4 = damageInfo.position;
				float num22 = 10f;
				float blastForce = 5000f;
				Vector3 origin = vector4 + Vector3.up * 6f;
				Vector3 onUnitSphere = UnityEngine.Random.onUnitSphere;
				onUnitSphere.y = -1f;
				if (Physics.Raycast(origin, onUnitSphere, out var hitInfo, 12f, LayerIndex.world.mask, QueryTriggerInteraction.Ignore))
				{
					vector4 = hitInfo.point;
				}
				else if (Physics.Raycast(vector4, Vector3.down, out hitInfo, float.PositiveInfinity, LayerIndex.world.mask, QueryTriggerInteraction.Ignore))
				{
					vector4 = hitInfo.point;
				}
				if (!component2.runicLensMeteorReady)
				{
					Util.PlaySound("Play_item_proc_meteorAttackOnHighDamage", component2.gameObject);
					EffectManager.SpawnEffect(CommonAssets.runicMeteorEffect, new EffectData
					{
						origin = vector4,
						scale = num22
					}, transmit: true);
					new EffectData().origin = vector4;
					component2.runicLensUpdateVariables(num21, vector4, damageInfo, blastForce, num22);
				}
			}
		}
		int itemCount19 = inventory.GetItemCount(DLC2Content.Items.KnockBackHitEnemies);
		if (itemCount19 > 0 && !characterBody.isBoss)
		{
			CharacterMotor component7 = victim.GetComponent<CharacterMotor>();
			victim.GetComponent<RigidbodyMotor>();
			if ((bool)component7 && component7.isGrounded && !characterBody.isChampion && (characterBody.bodyFlags & CharacterBody.BodyFlags.IgnoreFallDamage) == 0 && !characterBody.HasBuff(DLC2Content.Buffs.KnockUpHitEnemies) && Util.CheckRoll(Util.ConvertAmplificationPercentageIntoReductionPercentage(7.5f * (float)itemCount19 * damageInfo.procCoefficient)))
			{
				Ray aimRay = component2.inputBank.GetAimRay();
				characterBody.AddTimedBuff(DLC2Content.Buffs.KnockUpHitEnemies, 5f);
				float scale = 1f;
				switch (characterBody.hullClassification)
				{
				case HullClassification.Human:
					scale = 1f;
					break;
				case HullClassification.Golem:
					scale = 5f;
					break;
				case HullClassification.BeetleQueen:
					scale = 10f;
					break;
				}
				EffectManager.SpawnEffect(CommonAssets.knockbackFinEffect, new EffectData
				{
					origin = characterBody.gameObject.transform.position,
					scale = scale
				}, transmit: true);
				if (!characterBody.mainHurtBox)
				{
					_ = characterBody.transform;
				}
				else
				{
					_ = characterBody.mainHurtBox.transform;
				}
				Vector3 vector5 = new Vector3(0f, 1f, 0f);
				float num23 = component7.mass * 20f;
				float num24 = num23 + num23 / 10f * (float)(itemCount19 - 1);
				component7.ApplyForce(num24 * vector5);
				component7.ApplyForce(num24 / 2f * aimRay.direction);
				Util.PlaySound("Play_item_proc_knockBackHitEnemies", component2.gameObject);
			}
		}
		int itemCount20 = inventory.GetItemCount(DLC2Content.Items.StunAndPierce);
		if (itemCount20 > 0 && !damageInfo.procChainMask.HasProc(ProcType.StunAndPierceDamage) && Util.CheckRoll(15f * damageInfo.procCoefficient, master))
		{
			float damage6 = component2.damage * 0.3f * (float)itemCount20;
			ProcChainMask procChainMask10 = damageInfo.procChainMask;
			procChainMask10.AddProc(ProcType.StunAndPierceDamage);
			Quaternion rotation3 = Quaternion.LookRotation(new Ray(component2.inputBank.aimOrigin, component2.inputBank.aimDirection).direction);
			GameObject projectilePrefab2 = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/StunAndPierceBoomerang");
			FireProjectileInfo fireProjectileInfo = default(FireProjectileInfo);
			fireProjectileInfo.projectilePrefab = projectilePrefab2;
			fireProjectileInfo.crit = component2.RollCrit();
			fireProjectileInfo.damage = damage6;
			fireProjectileInfo.damageColorIndex = DamageColorIndex.Item;
			fireProjectileInfo.force = 0f;
			fireProjectileInfo.owner = component2.gameObject;
			fireProjectileInfo.position = aimOrigin;
			fireProjectileInfo.rotation = rotation3;
			FireProjectileInfo fireProjectileInfo3 = fireProjectileInfo;
			fireProjectileInfo3.procChainMask = procChainMask10;
			ProjectileManager.instance.FireProjectile(fireProjectileInfo3);
		}
		if (characterBody.HasBuff(DLC2Content.Buffs.EliteBeadCorruption) && !component2.HasBuff(DLC2Content.Buffs.EliteBead) && !damageInfo.procChainMask.HasProc(ProcType.Thorns))
		{
			float damageValue7 = component2.maxHealth * 0.025f;
			component2.RollCrit();
			_ = characterBody.teamComponent.teamIndex;
			LightningOrb lightningOrb3 = new LightningOrb();
			lightningOrb3.attacker = characterBody.gameObject;
			lightningOrb3.bouncedObjects = null;
			lightningOrb3.bouncesRemaining = 0;
			lightningOrb3.damageCoefficientPerBounce = 1f;
			lightningOrb3.damageColorIndex = DamageColorIndex.WeakPoint;
			lightningOrb3.damageValue = damageValue7;
			lightningOrb3.isCrit = false;
			lightningOrb3.lightningType = LightningOrb.LightningType.BeadDamage;
			lightningOrb3.origin = characterBody.transform.position;
			lightningOrb3.procChainMask = default(ProcChainMask);
			lightningOrb3.procChainMask.AddProc(ProcType.Thorns);
			lightningOrb3.procCoefficient = 0.3f;
			lightningOrb3.range = 0f;
			lightningOrb3.target = component2.mainHurtBox;
			OrbManager.instance.AddOrb(lightningOrb3);
		}
		if (component2.HasBuff(DLC2Content.Buffs.EliteAurelionite))
		{
			CharacterMaster master2 = component2.master;
			int baseCost = 2;
			int difficultyScaledCost = Run.instance.GetDifficultyScaledCost(baseCost);
			uint money = master2.money;
			master2.money = (uint)Mathf.Max(0f, (float)master2.money - (float)difficultyScaledCost);
			if (money - master2.money != 0)
			{
				GoldOrb goldOrb2 = new GoldOrb();
				goldOrb2.origin = damageInfo.position;
				goldOrb2.target = (component2 ? component2.mainHurtBox : characterBody.mainHurtBox);
				goldOrb2.goldAmount = (uint)difficultyScaledCost + (uint)((float)difficultyScaledCost * 0.2f);
				OrbManager.instance.AddOrb(goldOrb2);
				EffectManager.SimpleImpactEffect(CommonAssets.loseCoinsImpactEffectPrefab, damageInfo.position, Vector3.up, transmit: true);
			}
		}
	}

	private void HandleDamageWithNoAttacker([NotNull] DamageInfo damageInfo, [NotNull] GameObject victim)
	{
		CharacterBody characterBody = (victim ? victim.GetComponent<CharacterBody>() : null);
		if (characterBody == null)
		{
			return;
		}
		if ((ulong)(damageInfo.damageType & DamageType.LunarRuin) != 0)
		{
			if ((ulong)(damageInfo.damageType & DamageTypeExtended.ApplyBuffPermanently) != 0L)
			{
				characterBody.AddTimedBuff(DLC2Content.Buffs.lunarruin, 420f);
			}
			else
			{
				DotController.InflictDot(characterBody.gameObject, damageInfo.attacker, DotController.DotIndex.LunarRuin, 5f);
			}
		}
		if ((ulong)(damageInfo.damageType & DamageTypeExtended.DisableAllSkills) != 0L)
		{
			if ((ulong)(damageInfo.damageType & DamageTypeExtended.ApplyBuffPermanently) != 0L)
			{
				Debug.LogFormat("Adding DisableAllSkills");
				characterBody.AddTimedBuff(DLC2Content.Buffs.DisableAllSkills, 420f);
			}
			else
			{
				Debug.LogFormat("Adding DisableAllSkills for 5s");
				characterBody.AddTimedBuff(DLC2Content.Buffs.DisableAllSkills, 5f);
			}
		}
	}

	public void OnCharacterHitGroundServer(CharacterBody characterBody, CharacterMotor.HitGroundInfo hitGroundInfo)
	{
		bool flag = RunArtifactManager.instance.IsArtifactEnabled(RoR2Content.Artifacts.weakAssKneesArtifactDef);
		float num = Mathf.Abs(hitGroundInfo.velocity.y);
		Inventory inventory = characterBody.inventory;
		_ = characterBody.master;
		CharacterMotor characterMotor = characterBody.characterMotor;
		bool tookFallDamage = false;
		if ((((bool)inventory && inventory.GetItemCount(RoR2Content.Items.FallBoots) != 0) ? 1 : 0) <= (false ? 1 : 0) && (characterBody.bodyFlags & CharacterBody.BodyFlags.IgnoreFallDamage) == 0)
		{
			float num2 = Mathf.Max(num - (characterBody.jumpPower + 20f), 0f);
			if (num2 > 0f)
			{
				HealthComponent component = characterBody.GetComponent<HealthComponent>();
				if ((bool)component)
				{
					tookFallDamage = true;
					float num3 = num2 / 60f;
					DamageInfo damageInfo = new DamageInfo
					{
						attacker = null,
						inflictor = null,
						crit = false,
						damage = num3 * characterBody.maxHealth,
						damageType = (DamageType.NonLethal | DamageType.FallDamage),
						force = Vector3.zero,
						position = characterBody.footPosition,
						procCoefficient = 0f
					};
					if (flag || (characterBody.teamComponent.teamIndex == TeamIndex.Player && Run.instance.selectedDifficulty >= DifficultyIndex.Eclipse3))
					{
						damageInfo.damage *= 2f;
						damageInfo.damageType &= (DamageTypeCombo)(~DamageType.NonLethal);
						damageInfo.damageType |= (DamageTypeCombo)DamageType.BypassOneShotProtection;
					}
					component.TakeDamage(damageInfo);
				}
			}
		}
		OnCharacterHitGroundSFX(characterBody, hitGroundInfo, tookFallDamage);
		characterMotor.CallRpcOnHitGroundSFX(hitGroundInfo, tookFallDamage);
	}

	public void OnCharacterHitGroundSFX(CharacterBody characterBody, CharacterMotor.HitGroundInfo hitGroundInfo, bool tookFallDamage)
	{
		CharacterMotor characterMotor = characterBody.characterMotor;
		if (!characterMotor || (!hitGroundInfo.isValidForEffect && !(Run.FixedTimeStamp.now - characterMotor.lastGroundedTime > 0.2f)))
		{
			return;
		}
		Vector3 footPosition = characterBody.footPosition;
		float radius = characterBody.radius;
		if (!Physics.Raycast(new Ray(footPosition + Vector3.up * 1.5f, Vector3.down), out var hitInfo, 4f, (int)LayerIndex.world.mask | (int)LayerIndex.water.mask, QueryTriggerInteraction.Collide))
		{
			return;
		}
		SurfaceDef objectSurfaceDef = SurfaceDefProvider.GetObjectSurfaceDef(hitInfo.collider, hitInfo.point);
		if (!objectSurfaceDef)
		{
			return;
		}
		if (NetworkServer.active)
		{
			EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/CharacterLandImpact"), new EffectData
			{
				origin = footPosition,
				scale = radius,
				color = objectSurfaceDef.approximateColor
			}, transmit: true);
		}
		if ((bool)objectSurfaceDef.footstepEffectPrefab)
		{
			EffectManager.SpawnEffect(objectSurfaceDef.footstepEffectPrefab, new EffectData
			{
				origin = hitInfo.point,
				scale = radius * 3f
			}, transmit: false);
		}
		SfxLocator component = characterBody.GetComponent<SfxLocator>();
		if ((bool)component)
		{
			if (objectSurfaceDef.materialSwitchString != null && objectSurfaceDef.materialSwitchString.Length > 0)
			{
				AkSoundEngine.SetSwitch("material", objectSurfaceDef.materialSwitchString, characterBody.gameObject);
			}
			else
			{
				AkSoundEngine.SetSwitch("material", "dirt", characterBody.gameObject);
			}
			Util.PlaySound(component.landingSound, characterBody.gameObject);
			if (tookFallDamage)
			{
				Util.PlaySound(component.fallDamageSound, characterBody.gameObject);
			}
		}
	}

	[Obsolete("Use OnCharacterHitGroundServer instead, which this is just a backwards-compatibility wrapper for.", false)]
	public void OnCharacterHitGround(CharacterBody characterBody, Vector3 impactVelocity)
	{
		OnCharacterHitGroundServer(characterBody, new CharacterMotor.HitGroundInfo
		{
			velocity = impactVelocity
		});
	}

	private void OnPlayerCharacterDeath(DamageReport damageReport, NetworkUser victimNetworkUser)
	{
		if ((bool)victimNetworkUser)
		{
			CharacterBody victimBody = damageReport.victimBody;
			string text = (((ulong)(damageReport.damageInfo.damageType & DamageType.VoidDeath) != 0L) ? "PLAYER_DEATH_QUOTE_VOIDDEATH" : (damageReport.isFallDamage ? fallDamageDeathQuoteTokens[UnityEngine.Random.Range(0, fallDamageDeathQuoteTokens.Length)] : ((!victimBody || !victimBody.inventory || victimBody.inventory.GetItemCount(RoR2Content.Items.LunarDagger) <= 0) ? standardDeathQuoteTokens[UnityEngine.Random.Range(0, standardDeathQuoteTokens.Length)] : "PLAYER_DEATH_QUOTE_BRITTLEDEATH")));
			if ((bool)victimNetworkUser.masterController)
			{
				victimNetworkUser.masterController.finalMessageTokenServer = text;
			}
			Chat.SendBroadcastChat(new Chat.PlayerDeathChatMessage
			{
				subjectAsNetworkUser = victimNetworkUser,
				baseToken = text
			});
		}
	}

	private static void ProcIgniteOnKill(DamageReport damageReport, int igniteOnKillCount, CharacterBody victimBody, TeamIndex attackerTeamIndex)
	{
		float num = 8f + 4f * (float)igniteOnKillCount;
		float radius = victimBody.radius;
		float num2 = num + radius;
		float num3 = 1.5f;
		float baseDamage = damageReport.attackerBody.damage * num3;
		Vector3 corePosition = victimBody.corePosition;
		igniteOnKillSphereSearch.origin = corePosition;
		igniteOnKillSphereSearch.mask = LayerIndex.entityPrecise.mask;
		igniteOnKillSphereSearch.radius = num2;
		igniteOnKillSphereSearch.RefreshCandidates();
		igniteOnKillSphereSearch.FilterCandidatesByHurtBoxTeam(TeamMask.GetUnprotectedTeams(attackerTeamIndex));
		igniteOnKillSphereSearch.FilterCandidatesByDistinctHurtBoxEntities();
		igniteOnKillSphereSearch.OrderCandidatesByDistance();
		igniteOnKillSphereSearch.GetHurtBoxes(igniteOnKillHurtBoxBuffer);
		igniteOnKillSphereSearch.ClearCandidates();
		float value = (float)(1 + igniteOnKillCount) * 0.75f * damageReport.attackerBody.damage;
		for (int i = 0; i < igniteOnKillHurtBoxBuffer.Count; i++)
		{
			HurtBox hurtBox = igniteOnKillHurtBoxBuffer[i];
			if ((bool)hurtBox.healthComponent)
			{
				InflictDotInfo inflictDotInfo = default(InflictDotInfo);
				inflictDotInfo.victimObject = hurtBox.healthComponent.gameObject;
				inflictDotInfo.attackerObject = damageReport.attacker;
				inflictDotInfo.totalDamage = value;
				inflictDotInfo.dotIndex = DotController.DotIndex.Burn;
				inflictDotInfo.damageMultiplier = 1f;
				InflictDotInfo dotInfo = inflictDotInfo;
				if ((bool)damageReport?.attackerMaster?.inventory)
				{
					StrengthenBurnUtils.CheckDotForUpgrade(damageReport.attackerMaster.inventory, ref dotInfo);
				}
				DotController.InflictDot(ref dotInfo);
			}
		}
		igniteOnKillHurtBoxBuffer.Clear();
		BlastAttack blastAttack = new BlastAttack();
		blastAttack.radius = num2;
		blastAttack.baseDamage = baseDamage;
		blastAttack.procCoefficient = 0f;
		blastAttack.crit = Util.CheckRoll(damageReport.attackerBody.crit, damageReport.attackerMaster);
		blastAttack.damageColorIndex = DamageColorIndex.Item;
		blastAttack.attackerFiltering = AttackerFiltering.Default;
		blastAttack.falloffModel = BlastAttack.FalloffModel.None;
		blastAttack.attacker = damageReport.attacker;
		blastAttack.teamIndex = attackerTeamIndex;
		blastAttack.position = corePosition;
		blastAttack.Fire();
		EffectManager.SpawnEffect(CommonAssets.igniteOnKillExplosionEffectPrefab, new EffectData
		{
			origin = corePosition,
			scale = num2,
			rotation = Util.QuaternionSafeLookRotation(damageReport.damageInfo.force)
		}, transmit: true);
	}

	public void OnCharacterDeath(DamageReport damageReport)
	{
		if (!NetworkServer.active || damageReport == null)
		{
			return;
		}
		DamageInfo damageInfo = damageReport.damageInfo;
		GameObject gameObject = null;
		if ((bool)damageReport.victim)
		{
			gameObject = damageReport.victim.gameObject;
		}
		CharacterBody victimBody = damageReport.victimBody;
		TeamComponent teamComponent = null;
		CharacterMaster victimMaster = damageReport.victimMaster;
		TeamIndex teamIndex = damageReport.victimTeamIndex;
		Vector3 vector = Vector3.zero;
		Quaternion quaternion = Quaternion.identity;
		Vector3 vector2 = Vector3.zero;
		Transform transform = gameObject.transform;
		if ((bool)transform)
		{
			vector = transform.position;
			quaternion = transform.rotation;
			vector2 = vector;
		}
		InputBankTest inputBankTest = null;
		EquipmentIndex equipmentIndex = EquipmentIndex.None;
		EquipmentDef equipmentDef = null;
		if ((bool)victimBody)
		{
			teamComponent = victimBody.teamComponent;
			inputBankTest = victimBody.inputBank;
			vector2 = victimBody.corePosition;
			if ((bool)victimBody.equipmentSlot)
			{
				equipmentIndex = victimBody.equipmentSlot.equipmentIndex;
				equipmentDef = EquipmentCatalog.GetEquipmentDef(equipmentIndex);
			}
		}
		Ray ray = (inputBankTest ? inputBankTest.GetAimRay() : new Ray(vector, quaternion * Vector3.forward));
		GameObject attacker = damageReport.attacker;
		CharacterBody attackerBody = damageReport.attackerBody;
		CharacterMaster attackerMaster = damageReport.attackerMaster;
		Inventory inventory = (attackerMaster ? attackerMaster.inventory : null);
		TeamIndex attackerTeamIndex = damageReport.attackerTeamIndex;
		if ((bool)teamComponent)
		{
			teamIndex = teamComponent.teamIndex;
		}
		if ((bool)victimBody && (bool)victimMaster)
		{
			PlayerCharacterMasterController playerCharacterMasterController = victimMaster.playerCharacterMasterController;
			if ((bool)playerCharacterMasterController)
			{
				NetworkUser networkUser = playerCharacterMasterController.networkUser;
				if ((bool)networkUser)
				{
					OnPlayerCharacterDeath(damageReport, networkUser);
				}
			}
			if (victimBody.HasBuff(RoR2Content.Buffs.AffixWhite))
			{
				Vector3 position = vector2;
				GameObject gameObject2 = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/GenericDelayBlast"), position, Quaternion.identity);
				float num = 12f + victimBody.radius;
				gameObject2.transform.localScale = new Vector3(num, num, num);
				DelayBlast component = gameObject2.GetComponent<DelayBlast>();
				if ((bool)component)
				{
					component.position = position;
					component.baseDamage = victimBody.damage * 1.5f;
					component.baseForce = 2300f;
					component.attacker = gameObject;
					component.radius = num;
					component.crit = Util.CheckRoll(victimBody.crit, victimMaster);
					component.procCoefficient = 0.75f;
					component.maxTimer = 2f;
					component.falloffModel = BlastAttack.FalloffModel.None;
					component.explosionEffect = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/AffixWhiteExplosion");
					component.delayEffect = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/AffixWhiteDelayEffect");
					component.damageType = DamageType.Freeze2s;
					TeamFilter component2 = gameObject2.GetComponent<TeamFilter>();
					if ((bool)component2)
					{
						component2.teamIndex = TeamComponent.GetObjectTeam(component.attacker);
					}
				}
			}
			if (victimBody.HasBuff(RoR2Content.Buffs.AffixPoison))
			{
				Vector3 position2 = vector2;
				Quaternion rotation = Quaternion.LookRotation(ray.direction);
				GameObject gameObject3 = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/CharacterMasters/UrchinTurretMaster"), position2, rotation);
				CharacterMaster component3 = gameObject3.GetComponent<CharacterMaster>();
				if ((bool)component3)
				{
					component3.teamIndex = teamIndex;
					NetworkServer.Spawn(gameObject3);
					component3.SpawnBodyHere();
				}
			}
			if (RunArtifactManager.instance.IsArtifactEnabled(RoR2Content.Artifacts.wispOnDeath) && teamIndex == TeamIndex.Monster && victimMaster.masterIndex != CommonAssets.wispSoulMasterPrefabMasterComponent.masterIndex)
			{
				MasterSummon masterSummon = new MasterSummon();
				masterSummon.position = vector2;
				masterSummon.ignoreTeamMemberLimit = true;
				masterSummon.masterPrefab = CommonAssets.wispSoulMasterPrefabMasterComponent.gameObject;
				masterSummon.summonerBodyObject = gameObject;
				masterSummon.rotation = Quaternion.LookRotation(ray.direction);
				masterSummon.Perform();
			}
			if (victimBody.HasBuff(RoR2Content.Buffs.Fruiting) || (damageReport.damageInfo != null && (ulong)(damageReport.damageInfo.damageType & DamageType.FruitOnHit) != 0))
			{
				EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/TreebotFruitDeathEffect.prefab"), new EffectData
				{
					origin = vector,
					rotation = UnityEngine.Random.rotation
				}, transmit: true);
				int num2 = Mathf.Min(Math.Max(1, (int)(victimBody.bestFitRadius * 2f)), 8);
				GameObject original = LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/TreebotFruitPack");
				for (int i = 0; i < num2; i++)
				{
					GameObject obj = UnityEngine.Object.Instantiate(original, vector + UnityEngine.Random.insideUnitSphere * victimBody.radius * 0.5f, UnityEngine.Random.rotation);
					TeamFilter component4 = obj.GetComponent<TeamFilter>();
					if ((bool)component4)
					{
						component4.teamIndex = attackerTeamIndex;
					}
					obj.GetComponentInChildren<HealthPickup>();
					obj.transform.localScale = new Vector3(1f, 1f, 1f);
					NetworkServer.Spawn(obj);
				}
			}
			if (victimBody.HasBuff(DLC1Content.Buffs.EliteEarth))
			{
				MasterSummon masterSummon2 = new MasterSummon();
				masterSummon2.position = vector2;
				masterSummon2.ignoreTeamMemberLimit = true;
				masterSummon2.masterPrefab = CommonAssets.eliteEarthHealerMaster;
				masterSummon2.summonerBodyObject = gameObject;
				masterSummon2.rotation = Quaternion.LookRotation(ray.direction);
				masterSummon2.Perform();
			}
			if (victimBody.HasBuff(DLC1Content.Buffs.EliteVoid) && (!victimMaster || victimMaster.IsDeadAndOutOfLivesServer()))
			{
				Vector3 position3 = vector2;
				GameObject gameObject4 = UnityEngine.Object.Instantiate(Addressables.LoadAssetAsync<GameObject>("RoR2/DLC1/EliteVoid/VoidInfestorMaster.prefab").WaitForCompletion(), position3, Quaternion.identity);
				CharacterMaster component5 = gameObject4.GetComponent<CharacterMaster>();
				if ((bool)component5)
				{
					component5.teamIndex = TeamIndex.Void;
					NetworkServer.Spawn(gameObject4);
					component5.SpawnBodyHere();
				}
			}
		}
		if ((bool)attackerBody)
		{
			attackerBody.HandleOnKillEffectsServer(damageReport);
			if ((bool)attackerMaster && (bool)inventory)
			{
				int itemCount = inventory.GetItemCount(RoR2Content.Items.IgniteOnKill);
				if (itemCount > 0)
				{
					ProcIgniteOnKill(damageReport, itemCount, victimBody, attackerTeamIndex);
				}
				int itemCount2 = inventory.GetItemCount(RoR2Content.Items.ExplodeOnDeath);
				if (itemCount2 > 0)
				{
					Vector3 position4 = vector2;
					float damageCoefficient = 3.5f * (1f + (float)(itemCount2 - 1) * 0.8f);
					float baseDamage = Util.OnKillProcDamage(attackerBody.damage, damageCoefficient);
					GameObject obj2 = UnityEngine.Object.Instantiate(CommonAssets.explodeOnDeathPrefab, position4, Quaternion.identity);
					DelayBlast component6 = obj2.GetComponent<DelayBlast>();
					if ((bool)component6)
					{
						component6.position = position4;
						component6.baseDamage = baseDamage;
						component6.baseForce = 2000f;
						component6.bonusForce = Vector3.up * 1000f;
						component6.radius = 12f + 2.4f * ((float)itemCount2 - 1f);
						component6.attacker = damageInfo.attacker;
						component6.inflictor = null;
						component6.crit = Util.CheckRoll(attackerBody.crit, attackerMaster);
						component6.maxTimer = 0.5f;
						component6.damageColorIndex = DamageColorIndex.Item;
						component6.falloffModel = BlastAttack.FalloffModel.SweetSpot;
					}
					TeamFilter component7 = obj2.GetComponent<TeamFilter>();
					if ((bool)component7)
					{
						component7.teamIndex = attackerTeamIndex;
					}
					NetworkServer.Spawn(obj2);
				}
				int itemCount3 = inventory.GetItemCount(RoR2Content.Items.Dagger);
				if (itemCount3 > 0)
				{
					float damageCoefficient2 = 1.5f * (float)itemCount3;
					Vector3 vector3 = vector + Vector3.up * 1.8f;
					for (int j = 0; j < 3; j++)
					{
						ProjectileManager.instance.FireProjectile(CommonAssets.daggerPrefab, vector3 + UnityEngine.Random.insideUnitSphere * 0.5f, Util.QuaternionSafeLookRotation(Vector3.up + UnityEngine.Random.insideUnitSphere * 0.1f), attackerBody.gameObject, Util.OnKillProcDamage(attackerBody.damage, damageCoefficient2), 200f, Util.CheckRoll(attackerBody.crit, attackerMaster), DamageColorIndex.Item);
					}
				}
				int itemCount4 = inventory.GetItemCount(RoR2Content.Items.Tooth);
				if (itemCount4 > 0)
				{
					float num3 = Mathf.Pow(itemCount4, 0.25f);
					GameObject obj3 = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/HealPack"), vector, UnityEngine.Random.rotation);
					TeamFilter component8 = obj3.GetComponent<TeamFilter>();
					if ((bool)component8)
					{
						component8.teamIndex = attackerTeamIndex;
					}
					HealthPickup componentInChildren = obj3.GetComponentInChildren<HealthPickup>();
					if ((bool)componentInChildren)
					{
						componentInChildren.flatHealing = 8f;
						componentInChildren.fractionalHealing = 0.02f * (float)itemCount4;
					}
					obj3.transform.localScale = new Vector3(num3, num3, num3);
					NetworkServer.Spawn(obj3);
				}
				float num4 = 0f;
				float num5 = 0f;
				float num6 = 0f;
				float num7 = 0f;
				if (victimBody.HasBuff(DLC2Content.Buffs.CookingChopped))
				{
					num4 += 1f;
					num5 += 2f;
					num6 += 0.04f;
					num7 += 0.75f;
				}
				if (victimBody.HasBuff(DLC2Content.Buffs.CookingOiled))
				{
					num4 += 1f;
					num5 += 2f;
					num6 += 0.04f;
					num7 += 0.75f;
				}
				if (victimBody.HasBuff(DLC2Content.Buffs.CookingRoasted))
				{
					num4 += 1f;
					num5 += 2f;
					num6 += 0.04f;
					num7 += 0.75f;
				}
				if (victimBody.HasBuff(DLC2Content.Buffs.CookingRolled))
				{
					num4 += 1f;
					num5 += 2f;
					num6 += 0.04f;
					num7 += 0.75f;
				}
				if (victimBody.HasBuff(DLC2Content.Buffs.CookingFlambe))
				{
					num4 += 1f;
					num5 += 2f;
					num6 += 0.04f;
					num7 += 0.75f;
				}
				if (num4 > 1f)
				{
					GameObject obj4 = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Chef/ChefFoodPickup"), vector, UnityEngine.Random.rotation);
					TeamFilter component9 = obj4.GetComponent<TeamFilter>();
					if ((bool)component9)
					{
						component9.teamIndex = attackerTeamIndex;
					}
					HealthPickup componentInChildren2 = obj4.GetComponentInChildren<HealthPickup>();
					if ((bool)componentInChildren2)
					{
						componentInChildren2.flatHealing = num5;
						componentInChildren2.fractionalHealing = num6;
					}
					obj4.transform.localScale = new Vector3(num7, num7, num7);
					NetworkServer.Spawn(obj4);
				}
				int itemCount5 = inventory.GetItemCount(RoR2Content.Items.Infusion);
				if (itemCount5 > 0)
				{
					int num8 = itemCount5 * 100;
					if (inventory.infusionBonus < num8)
					{
						InfusionOrb infusionOrb = new InfusionOrb();
						infusionOrb.origin = vector;
						infusionOrb.target = Util.FindBodyMainHurtBox(attackerBody);
						infusionOrb.maxHpValue = itemCount5;
						OrbManager.instance.AddOrb(infusionOrb);
					}
				}
				if ((DamageType)(damageInfo.damageType & DamageType.ResetCooldownsOnKill) == DamageType.ResetCooldownsOnKill)
				{
					EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/Bandit2ResetEffect"), new EffectData
					{
						origin = damageInfo.position
					}, transmit: true);
					SkillLocator skillLocator = attackerBody.skillLocator;
					if ((bool)skillLocator)
					{
						skillLocator.ResetSkills();
					}
				}
				if ((DamageType)(damageInfo.damageType & DamageType.GiveSkullOnKill) == DamageType.GiveSkullOnKill && (bool)victimMaster)
				{
					EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/Bandit2KillEffect"), new EffectData
					{
						origin = damageInfo.position
					}, transmit: true);
					attackerBody.AddBuff(RoR2Content.Buffs.BanditSkull);
				}
				int itemCount6 = inventory.GetItemCount(RoR2Content.Items.Talisman);
				if (itemCount6 > 0 && (bool)attackerBody.equipmentSlot)
				{
					inventory.DeductActiveEquipmentCooldown(2f + (float)itemCount6 * 2f);
				}
				int itemCount7 = inventory.GetItemCount(JunkContent.Items.TempestOnKill);
				if (itemCount7 > 0 && Util.CheckRoll(25f, attackerMaster))
				{
					GameObject obj5 = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/TempestWard"), victimBody.footPosition, Quaternion.identity);
					TeamFilter component10 = obj5.GetComponent<TeamFilter>();
					if ((bool)component10)
					{
						component10.teamIndex = attackerTeamIndex;
					}
					BuffWard component11 = obj5.GetComponent<BuffWard>();
					if ((bool)component11)
					{
						component11.expireDuration = 2f + 6f * (float)itemCount7;
					}
					NetworkServer.Spawn(obj5);
				}
				int itemCount8 = inventory.GetItemCount(RoR2Content.Items.Bandolier);
				if (itemCount8 > 0 && Util.CheckRoll((1f - 1f / Mathf.Pow(itemCount8 + 1, 0.33f)) * 100f, attackerMaster))
				{
					GameObject obj6 = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/AmmoPack"), vector, UnityEngine.Random.rotation);
					TeamFilter component12 = obj6.GetComponent<TeamFilter>();
					if ((bool)component12)
					{
						component12.teamIndex = attackerTeamIndex;
					}
					NetworkServer.Spawn(obj6);
				}
				if ((bool)victimBody && damageReport.victimIsElite)
				{
					int itemCount9 = inventory.GetItemCount(RoR2Content.Items.HeadHunter);
					int itemCount10 = inventory.GetItemCount(RoR2Content.Items.KillEliteFrenzy);
					if (itemCount9 > 0)
					{
						float duration = 3f + 5f * (float)itemCount9;
						for (int k = 0; k < BuffCatalog.eliteBuffIndices.Length; k++)
						{
							BuffIndex buffIndex = BuffCatalog.eliteBuffIndices[k];
							if (victimBody.HasBuff(buffIndex))
							{
								attackerBody.AddTimedBuff(buffIndex, duration);
							}
						}
					}
					if (itemCount10 > 0)
					{
						attackerBody.AddTimedBuff(RoR2Content.Buffs.NoCooldowns, (float)itemCount10 * 4f);
					}
				}
				int itemCount11 = inventory.GetItemCount(RoR2Content.Items.GhostOnKill);
				if (itemCount11 > 0 && (bool)victimBody && Util.CheckRoll(7f, attackerMaster))
				{
					Util.TryToCreateGhost(victimBody, attackerBody, itemCount11 * 30);
				}
				if (inventory.GetItemCount(DLC1Content.Items.MinorConstructOnKill) > 0 && (bool)victimBody && victimBody.isElite && !attackerMaster.IsDeployableLimited(DeployableSlot.MinorConstructOnKill))
				{
					Vector3 forward = Quaternion.AngleAxis(UnityEngine.Random.Range(0, 360), Vector3.up) * Quaternion.AngleAxis(-80f, Vector3.right) * Vector3.forward;
					FireProjectileInfo fireProjectileInfo = default(FireProjectileInfo);
					fireProjectileInfo.projectilePrefab = CommonAssets.minorConstructOnKillProjectile;
					fireProjectileInfo.position = vector;
					fireProjectileInfo.rotation = Util.QuaternionSafeLookRotation(forward);
					fireProjectileInfo.procChainMask = default(ProcChainMask);
					fireProjectileInfo.target = gameObject;
					fireProjectileInfo.owner = attackerBody.gameObject;
					fireProjectileInfo.damage = 0f;
					fireProjectileInfo.crit = false;
					fireProjectileInfo.force = 0f;
					fireProjectileInfo.damageColorIndex = DamageColorIndex.Item;
					FireProjectileInfo fireProjectileInfo2 = fireProjectileInfo;
					ProjectileManager.instance.FireProjectile(fireProjectileInfo2);
				}
				int itemCount12 = inventory.GetItemCount(DLC1Content.Items.MoveSpeedOnKill);
				if (itemCount12 > 0)
				{
					int num9 = itemCount12 - 1;
					int num10 = 5;
					float num11 = 1f + (float)num9 * 0.5f;
					attackerBody.ClearTimedBuffs(DLC1Content.Buffs.KillMoveSpeed);
					for (int l = 0; l < num10; l++)
					{
						attackerBody.AddTimedBuff(DLC1Content.Buffs.KillMoveSpeed, num11 * (float)(l + 1) / (float)num10);
					}
					EffectData effectData = new EffectData();
					effectData.origin = attackerBody.corePosition;
					CharacterMotor characterMotor = attackerBody.characterMotor;
					bool flag = false;
					if ((bool)characterMotor)
					{
						Vector3 moveDirection = characterMotor.moveDirection;
						if (moveDirection != Vector3.zero)
						{
							effectData.rotation = Util.QuaternionSafeLookRotation(moveDirection);
							flag = true;
						}
					}
					if (!flag)
					{
						effectData.rotation = attackerBody.transform.rotation;
					}
					EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/MoveSpeedOnKillActivate"), effectData, transmit: true);
				}
				if ((bool)equipmentDef && Util.CheckRoll(equipmentDef.dropOnDeathChance * 100f, attackerMaster) && (bool)victimBody)
				{
					PickupDropletController.CreatePickupDroplet(PickupCatalog.FindPickupIndex(equipmentIndex), vector + Vector3.up * 1.5f, Vector3.up * 20f + ray.direction * 2f);
				}
				int itemCount13 = inventory.GetItemCount(RoR2Content.Items.BarrierOnKill);
				if (itemCount13 > 0 && (bool)attackerBody.healthComponent)
				{
					attackerBody.healthComponent.AddBarrier(15f * (float)itemCount13);
				}
				int itemCount14 = inventory.GetItemCount(RoR2Content.Items.BonusGoldPackOnKill);
				if (itemCount14 > 0 && Util.CheckRoll(4f * (float)itemCount14, attackerMaster))
				{
					GameObject obj7 = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/BonusMoneyPack"), vector, UnityEngine.Random.rotation);
					TeamFilter component13 = obj7.GetComponent<TeamFilter>();
					if ((bool)component13)
					{
						component13.teamIndex = attackerTeamIndex;
					}
					NetworkServer.Spawn(obj7);
				}
				int itemCount15 = inventory.GetItemCount(RoR2Content.Items.Plant);
				if (itemCount15 > 0)
				{
					GameObject obj8 = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/InterstellarDeskPlant"), victimBody.footPosition, Quaternion.identity);
					DeskPlantController component14 = obj8.GetComponent<DeskPlantController>();
					if ((bool)component14)
					{
						if ((bool)component14.teamFilter)
						{
							component14.teamFilter.teamIndex = attackerTeamIndex;
						}
						component14.itemCount = itemCount15;
					}
					NetworkServer.Spawn(obj8);
				}
				int incubatorOnKillCount = attackerMaster.inventory.GetItemCount(JunkContent.Items.Incubator);
				if (incubatorOnKillCount > 0 && attackerMaster.GetDeployableCount(DeployableSlot.ParentPodAlly) + attackerMaster.GetDeployableCount(DeployableSlot.ParentAlly) < incubatorOnKillCount && Util.CheckRoll(7f + 1f * (float)incubatorOnKillCount, attackerMaster))
				{
					DirectorSpawnRequest directorSpawnRequest = new DirectorSpawnRequest(LegacyResourcesAPI.Load<SpawnCard>("SpawnCards/CharacterSpawnCards/cscParentPod"), new DirectorPlacementRule
					{
						placementMode = DirectorPlacementRule.PlacementMode.Approximate,
						minDistance = 3f,
						maxDistance = 20f,
						spawnOnTarget = transform
					}, RoR2Application.rng);
					directorSpawnRequest.summonerBodyObject = attacker;
					directorSpawnRequest.onSpawnedServer = (Action<SpawnCard.SpawnResult>)Delegate.Combine(directorSpawnRequest.onSpawnedServer, (Action<SpawnCard.SpawnResult>)delegate(SpawnCard.SpawnResult spawnResult)
					{
						if (spawnResult.success)
						{
							Inventory inventory2 = spawnResult.spawnedInstance.GetComponent<CharacterMaster>().inventory;
							if ((bool)inventory2)
							{
								inventory2.GiveItem(RoR2Content.Items.BoostDamage, 30);
								inventory2.GiveItem(RoR2Content.Items.BoostHp, 10 * incubatorOnKillCount);
							}
						}
					});
					DirectorCore.instance.TrySpawnObject(directorSpawnRequest);
				}
				int itemCount16 = inventory.GetItemCount(RoR2Content.Items.BleedOnHitAndExplode);
				if (itemCount16 > 0 && (bool)victimBody && (victimBody.HasBuff(RoR2Content.Buffs.Bleeding) || victimBody.HasBuff(RoR2Content.Buffs.SuperBleed)))
				{
					Util.PlaySound("Play_bleedOnCritAndExplode_explode", gameObject);
					Vector3 position5 = vector2;
					float damageCoefficient3 = 4f * (float)(1 + (itemCount16 - 1));
					float num12 = 0.15f * (float)(1 + (itemCount16 - 1));
					float baseDamage2 = Util.OnKillProcDamage(attackerBody.damage, damageCoefficient3) + victimBody.maxHealth * num12;
					GameObject obj9 = UnityEngine.Object.Instantiate(CommonAssets.bleedOnHitAndExplodeBlastEffect, position5, Quaternion.identity);
					DelayBlast component15 = obj9.GetComponent<DelayBlast>();
					component15.position = position5;
					component15.baseDamage = baseDamage2;
					component15.baseForce = 0f;
					component15.radius = 16f;
					component15.attacker = damageInfo.attacker;
					component15.inflictor = null;
					component15.crit = Util.CheckRoll(attackerBody.crit, attackerMaster);
					component15.maxTimer = 0f;
					component15.damageColorIndex = DamageColorIndex.Item;
					component15.falloffModel = BlastAttack.FalloffModel.SweetSpot;
					obj9.GetComponent<TeamFilter>().teamIndex = attackerTeamIndex;
					NetworkServer.Spawn(obj9);
				}
				if (attackerMaster.inventory.GetItemCount(DLC2Content.Items.ResetChests) > 0)
				{
					int itemCount17 = attackerMaster.inventory.GetItemCount(DLC2Content.Items.ResetChests);
					if (victimBody.isChampion && Util.CheckRoll(100f, attackerMaster) && (bool)victimBody)
					{
						PickupDropletController.CreatePickupDroplet(CommonAssets.dtSonorousEchoPath.GenerateDrop(Run.instance.runRNG), vector + Vector3.up * 1.5f, Vector3.up * 20f + ray.direction * 2f);
					}
					if (victimBody.isElite && Util.CheckRoll(2f + 1f * (float)itemCount17, attackerMaster) && (bool)victimBody)
					{
						PickupDropletController.CreatePickupDroplet(CommonAssets.dtSonorousEchoPath.GenerateDrop(Run.instance.runRNG), vector + Vector3.up * 1.5f, Vector3.up * 20f + ray.direction * 2f);
					}
				}
			}
		}
		GlobalEventManager.onCharacterDeathGlobal?.Invoke(damageReport);
	}

	public void OnHitAll(DamageInfo damageInfo, GameObject hitObject)
	{
		OnHitAllProcess(damageInfo, hitObject);
	}

	private void OnHitAllProcess(DamageInfo damageInfo, GameObject hitObject)
	{
		if (damageInfo.procCoefficient == 0f || damageInfo.rejected)
		{
			return;
		}
		_ = NetworkServer.active;
		if (!damageInfo.attacker)
		{
			return;
		}
		CharacterBody component = damageInfo.attacker.GetComponent<CharacterBody>();
		if (!component)
		{
			return;
		}
		CharacterMaster master = component.master;
		if (!master)
		{
			return;
		}
		Inventory inventory = master.inventory;
		if (!master.inventory)
		{
			return;
		}
		if (!damageInfo.procChainMask.HasProc(ProcType.Behemoth))
		{
			int itemCount = inventory.GetItemCount(RoR2Content.Items.Behemoth);
			if (itemCount > 0 && damageInfo.procCoefficient != 0f)
			{
				float num = (1.5f + 2.5f * (float)itemCount) * damageInfo.procCoefficient;
				float damageCoefficient = 0.6f;
				float baseDamage = Util.OnHitProcDamage(damageInfo.damage, component.damage, damageCoefficient);
				EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/OmniEffect/OmniExplosionVFXQuick"), new EffectData
				{
					origin = damageInfo.position,
					scale = num,
					rotation = Util.QuaternionSafeLookRotation(damageInfo.force)
				}, transmit: true);
				BlastAttack obj = new BlastAttack
				{
					position = damageInfo.position,
					baseDamage = baseDamage,
					baseForce = 0f,
					radius = num,
					attacker = damageInfo.attacker,
					inflictor = null
				};
				obj.teamIndex = TeamComponent.GetObjectTeam(obj.attacker);
				obj.crit = damageInfo.crit;
				obj.procChainMask = damageInfo.procChainMask;
				obj.procCoefficient = 0f;
				obj.damageColorIndex = DamageColorIndex.Item;
				obj.falloffModel = BlastAttack.FalloffModel.None;
				obj.damageType = damageInfo.damageType;
				obj.Fire();
			}
		}
		if ((component.HasBuff(RoR2Content.Buffs.AffixBlue) ? 1 : 0) > 0)
		{
			float damageCoefficient2 = 0.5f;
			float damage = Util.OnHitProcDamage(damageInfo.damage, component.damage, damageCoefficient2);
			float force = 0f;
			Vector3 position = damageInfo.position;
			ProjectileManager.instance.FireProjectile(LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/LightningStake"), position, Quaternion.identity, damageInfo.attacker, damage, force, damageInfo.crit, DamageColorIndex.Item);
		}
	}

	public void OnCrit(CharacterBody body, DamageInfo damageInfo, CharacterMaster master, float procCoefficient, ProcChainMask procChainMask)
	{
		Vector3 hitPos = body.corePosition;
		GameObject gameObject = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/Critspark");
		if ((bool)body)
		{
			if (body.critMultiplier > 2f)
			{
				gameObject = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/CritsparkHeavy");
			}
			if ((bool)body && procCoefficient > 0f && (bool)master && (bool)master.inventory)
			{
				Inventory inventory = master.inventory;
				if (!procChainMask.HasProc(ProcType.HealOnCrit))
				{
					procChainMask.AddProc(ProcType.HealOnCrit);
					int itemCount = inventory.GetItemCount(RoR2Content.Items.HealOnCrit);
					if (itemCount > 0 && (bool)body.healthComponent)
					{
						Util.PlaySound("Play_item_proc_crit_heal", body.gameObject);
						if (NetworkServer.active)
						{
							body.healthComponent.Heal((4f + (float)itemCount * 4f) * procCoefficient, procChainMask);
						}
					}
				}
				if (inventory.GetItemCount(RoR2Content.Items.AttackSpeedOnCrit) > 0)
				{
					body.AddTimedBuff(RoR2Content.Buffs.AttackSpeedOnCrit, 3f * procCoefficient);
				}
				int itemCount2 = inventory.GetItemCount(JunkContent.Items.CooldownOnCrit);
				if (itemCount2 > 0)
				{
					Util.PlaySound("Play_item_proc_crit_cooldown", body.gameObject);
					SkillLocator component = body.GetComponent<SkillLocator>();
					if ((bool)component)
					{
						float dt = (float)itemCount2 * procCoefficient;
						if ((bool)component.primary)
						{
							component.primary.RunRecharge(dt);
						}
						if ((bool)component.secondary)
						{
							component.secondary.RunRecharge(dt);
						}
						if ((bool)component.utility)
						{
							component.utility.RunRecharge(dt);
						}
						if ((bool)component.special)
						{
							component.special.RunRecharge(dt);
						}
					}
				}
			}
		}
		if (damageInfo != null)
		{
			hitPos = damageInfo.position;
		}
		if ((bool)gameObject)
		{
			EffectManager.SimpleImpactEffect(gameObject, hitPos, Vector3.up, transmit: true);
		}
	}

	public static void OnTeamLevelUp(TeamIndex teamIndex)
	{
		GlobalEventManager.onTeamLevelUp?.Invoke(teamIndex);
	}

	public static void OnCharacterLevelUp(CharacterBody characterBody)
	{
		GlobalEventManager.onCharacterLevelUp?.Invoke(characterBody);
	}

	public void OnInteractionBegin(Interactor interactor, IInteractable interactable, GameObject interactableObject)
	{
		if (!interactor)
		{
			Debug.LogError("OnInteractionBegin invalid interactor!");
			return;
		}
		if (interactable == null)
		{
			Debug.LogError("OnInteractionBegin invalid interactable!");
			return;
		}
		if (!interactableObject)
		{
			Debug.LogError("OnInteractionBegin invalid interactableObject!");
			return;
		}
		GlobalEventManager.OnInteractionsGlobal?.Invoke(interactor, interactable, interactableObject);
		CharacterBody component = interactor.GetComponent<CharacterBody>();
		Vector3 vector = Vector3.zero;
		Quaternion rotation = Quaternion.identity;
		Transform transform = interactableObject.transform;
		if ((bool)transform)
		{
			vector = transform.position;
			rotation = transform.rotation;
		}
		if (!component)
		{
			return;
		}
		Inventory inventory = component.inventory;
		if (!inventory)
		{
			return;
		}
		InteractionProcFilter interactionProcFilter = interactableObject.GetComponent<InteractionProcFilter>();
		int itemCount = inventory.GetItemCount(RoR2Content.Items.Firework);
		if (itemCount > 0 && InteractableIsPermittedForSpawn((MonoBehaviour)interactable))
		{
			Transform transform2 = interactableObject.GetComponent<ModelLocator>()?.modelTransform?.GetComponent<ChildLocator>()?.FindChild("FireworkOrigin");
			Vector3 position = (transform2 ? transform2.position : (interactableObject.transform.position + Vector3.up * 2f));
			int remaining = 4 + itemCount * 4;
			FireworkLauncher component2 = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/FireworkLauncher"), position, Quaternion.identity).GetComponent<FireworkLauncher>();
			component2.owner = interactor.gameObject;
			component2.crit = Util.CheckRoll(component.crit, component.master);
			component2.remaining = remaining;
		}
		int squidStacks = inventory.GetItemCount(RoR2Content.Items.Squid);
		if (squidStacks > 0 && InteractableIsPermittedForSpawn((MonoBehaviour)interactable))
		{
			CharacterSpawnCard spawnCard = LegacyResourcesAPI.Load<CharacterSpawnCard>("SpawnCards/CharacterSpawnCards/cscSquidTurret");
			DirectorPlacementRule placementRule = new DirectorPlacementRule
			{
				placementMode = DirectorPlacementRule.PlacementMode.Approximate,
				minDistance = 5f,
				maxDistance = 25f,
				position = interactableObject.transform.position
			};
			DirectorSpawnRequest directorSpawnRequest = new DirectorSpawnRequest(spawnCard, placementRule, RoR2Application.rng);
			directorSpawnRequest.teamIndexOverride = TeamIndex.Player;
			directorSpawnRequest.summonerBodyObject = interactor.gameObject;
			directorSpawnRequest.onSpawnedServer = (Action<SpawnCard.SpawnResult>)Delegate.Combine(directorSpawnRequest.onSpawnedServer, (Action<SpawnCard.SpawnResult>)delegate(SpawnCard.SpawnResult result)
			{
				if (result.success && (bool)result.spawnedInstance)
				{
					CharacterMaster component5 = result.spawnedInstance.GetComponent<CharacterMaster>();
					if ((bool)component5 && (bool)component5.inventory)
					{
						component5.inventory.GiveItem(RoR2Content.Items.HealthDecay, 30);
						component5.inventory.GiveItem(RoR2Content.Items.BoostAttackSpeed, 10 * (squidStacks - 1));
					}
				}
			});
			DirectorCore.instance.TrySpawnObject(directorSpawnRequest);
		}
		int itemCount2 = inventory.GetItemCount(RoR2Content.Items.MonstersOnShrineUse);
		if (itemCount2 <= 0)
		{
			return;
		}
		PurchaseInteraction component3 = interactableObject.GetComponent<PurchaseInteraction>();
		if (!component3 || !component3.isShrine || (bool)interactableObject.GetComponent<ShrineCombatBehavior>())
		{
			return;
		}
		GameObject gameObject = LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/Encounters/MonstersOnShrineUseEncounter");
		if (!gameObject)
		{
			return;
		}
		GameObject gameObject2 = UnityEngine.Object.Instantiate(gameObject, vector, Quaternion.identity);
		NetworkServer.Spawn(gameObject2);
		CombatDirector component4 = gameObject2.GetComponent<CombatDirector>();
		if ((bool)component4 && (bool)Stage.instance)
		{
			float monsterCredit = 40f * Stage.instance.entryDifficultyCoefficient * (float)itemCount2;
			DirectorCard directorCard = component4.SelectMonsterCardForCombatShrine(monsterCredit);
			if (directorCard != null)
			{
				component4.CombatShrineActivation(interactor, monsterCredit, directorCard);
				EffectData effectData = new EffectData
				{
					origin = vector,
					rotation = rotation
				};
				EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/MonstersOnShrineUse"), effectData, transmit: true);
			}
			else
			{
				NetworkServer.Destroy(gameObject2);
			}
		}
		bool InteractableIsPermittedForSpawn(MonoBehaviour interactableAsMonoBehaviour)
		{
			if (!interactableAsMonoBehaviour)
			{
				return false;
			}
			if ((bool)interactionProcFilter)
			{
				return interactionProcFilter.shouldAllowOnInteractionBeginProc;
			}
			if ((bool)interactableAsMonoBehaviour.GetComponent<DelusionChestController>())
			{
				if (interactableAsMonoBehaviour.GetComponent<PickupPickerController>().enabled)
				{
					return false;
				}
				return true;
			}
			if ((bool)interactableAsMonoBehaviour.GetComponent<GenericPickupController>())
			{
				return false;
			}
			if ((bool)interactableAsMonoBehaviour.GetComponent<VehicleSeat>())
			{
				return false;
			}
			if ((bool)interactableAsMonoBehaviour.GetComponent<NetworkUIPromptController>())
			{
				return false;
			}
			return true;
		}
	}

	public static void ClientDamageNotified(DamageDealtMessage damageDealtMessage)
	{
		GlobalEventManager.onClientDamageNotified?.Invoke(damageDealtMessage);
	}

	public static void ServerDamageDealt(DamageReport damageReport)
	{
		GlobalEventManager.onServerDamageDealt?.Invoke(damageReport);
	}

	public static void ServerCharacterExecuted(DamageReport damageReport, float executionHealthLost)
	{
		GlobalEventManager.onServerCharacterExecuted?.Invoke(damageReport, executionHealthLost);
	}
}
