Decompiled source of Quality v0.5.3

plugins/ItemQualities/ItemQualities.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using AK.Wwise;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.Barrel;
using EntityStates.BossGroupHealNovaController;
using EntityStates.Drifter;
using EntityStates.Drone.DroneJunk;
using EntityStates.FriendUnit;
using EntityStates.Headstompers;
using EntityStates.JellyfishMonster;
using EntityStates.LaserTurbine;
using EntityStates.Missions.Goldshores;
using EntityStates.MushroomShield;
using EntityStates.ScavMonster;
using EntityStates.SharedSufferingOrb;
using EntityStates.VagrantMonster;
using EntityStates.VagrantNovaItem;
using HG;
using HG.Coroutines;
using HG.Reflection;
using IL.EntityStates;
using IL.EntityStates.Chef;
using IL.EntityStates.DefectiveUnit;
using IL.EntityStates.Drifter;
using IL.EntityStates.Drone.DroneBombardment;
using IL.EntityStates.Drone.DroneJunk;
using IL.EntityStates.Headstompers;
using IL.EntityStates.JellyfishMonster;
using IL.EntityStates.JunkCube;
using IL.EntityStates.Mage;
using IL.EntityStates.ScavMonster;
using IL.EntityStates.Seeker;
using IL.EntityStates.SolusAmalgamator;
using IL.EntityStates.VagrantMonster;
using IL.EntityStates.VagrantNovaItem;
using IL.RoR2;
using IL.RoR2.Items;
using IL.RoR2.Projectile;
using IL.RoR2.UI;
using IL.RoR2.VoidRaidCrab;
using ItemQualities;
using ItemQualities.ContentManagement;
using ItemQualities.Items;
using ItemQualities.ModCompatibility;
using ItemQualities.Orbs;
using ItemQualities.Utilities;
using ItemQualities.Utilities.Extensions;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using On.EntityStates.Drifter;
using On.EntityStates.Missions.Goldshores;
using On.RoR2;
using On.RoR2.Artifacts;
using On.RoR2.Items;
using On.RoR2.Projectile;
using On.RoR2.SolusWingGrid;
using On.RoR2.UI;
using On.RoR2.UI.LogBook;
using R2API;
using R2API.Utils;
using ReviveAPI;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Audio;
using RoR2.ContentManagement;
using RoR2.EntitlementManagement;
using RoR2.ExpansionManagement;
using RoR2.Items;
using RoR2.Navigation;
using RoR2.Orbs;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.SolusWingGrid;
using RoR2.UI;
using RoR2.UI.LogBook;
using RoR2.VoidRaidCrab;
using RoR2BepInExPack.GameAssetPaths.Version_1_35_0;
using RoR2BepInExPack.GameAssetPathsBetter;
using RoR2BepInExPack.Utilities;
using ShaderSwapper;
using TMPro;
using Unity;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[assembly: OptIn]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace EntityStates.SharedSufferingOrb
{
	public sealed class SharedSufferingOrbDeath : EntityState
	{
		private static GameObject _deathEffectPrefab;

		public static float ExplosionDamageCoefficient;

		public static float ExplosionForce;

		[ContentInitializer]
		private static IEnumerator LoadContent(ContentIntializerArgs args)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			AsyncOperationHandle<GameObject> val = AddressableUtil.LoadTempAssetAsync<GameObject>(RoR2_Base_WeeklyRun.TimeCrystalDeath_prefab);
			val.OnSuccess(delegate(GameObject timeCrystalDeath)
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				_deathEffectPrefab = PrefabAPI.InstantiateClone(timeCrystalDeath, "SharedSufferingOrbDeathEffect", false);
				args.ContentPack.effectDefs.Add<EffectDef>(new EffectDef(_deathEffectPrefab));
			});
			return val.AsProgressCoroutine<GameObject>(args.ProgressReceiver);
		}

		public override void OnEnter()
		{
			((EntityState)this).OnEnter();
			explode();
		}

		private void explode()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Expected O, but got Unknown
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator))
			{
				if (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator.modelBaseTransform))
				{
					EntityState.Destroy((Object)(object)((Component)((EntityState)this).modelLocator.modelBaseTransform).gameObject);
				}
				if (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator.modelTransform))
				{
					EntityState.Destroy((Object)(object)((Component)((EntityState)this).modelLocator.modelTransform).gameObject);
				}
			}
			SharedSufferingOrbController component = ((EntityState)this).GetComponent<SharedSufferingOrbController>();
			float num = (Object.op_Implicit((Object)(object)component) ? component.BlastRadius : 0f);
			if (Object.op_Implicit((Object)(object)_deathEffectPrefab))
			{
				EffectManager.SpawnEffect(_deathEffectPrefab, new EffectData
				{
					origin = ((EntityState)this).transform.position,
					scale = num,
					rotation = Quaternion.identity
				}, false);
			}
			if (NetworkServer.active)
			{
				GenericOwnership component2 = ((EntityState)this).GetComponent<GenericOwnership>();
				GameObject val = (Object.op_Implicit((Object)(object)component2) ? component2.ownerObject : null);
				CharacterBody val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<CharacterBody>() : null);
				TeamIndex val3 = (TeamIndex)((!Object.op_Implicit((Object)(object)val2)) ? (-1) : ((int)val2.teamComponent.teamIndex));
				Vector3 position = ((EntityState)this).transform.position;
				float damage = ExplosionDamageCoefficient * (Object.op_Implicit((Object)(object)val2) ? val2.damage : Run.instance.teamlessDamageCoefficient);
				foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList)
				{
					if (FriendlyFireManager.ShouldSplashHitProceed(readOnlyInstances.healthComponent, val3) && !((Object)(object)readOnlyInstances == (Object)(object)val2) && !((Object)(object)readOnlyInstances == (Object)(object)((EntityState)this).characterBody) && !(Vector3.Distance(readOnlyInstances.corePosition, position) >= num))
					{
						DamageInfo val4 = new DamageInfo
						{
							attacker = val,
							inflictor = ((EntityState)this).gameObject,
							damage = damage,
							crit = (Object.op_Implicit((Object)(object)val2) && val2.RollCrit()),
							damageType = DamageTypeCombo.op_Implicit((DamageType)131072),
							damageColorIndex = (DamageColorIndex)16,
							procCoefficient = 0f,
							position = position
						};
						float explosionForce = ExplosionForce;
						Vector3 val5 = readOnlyInstances.corePosition - position;
						val4.force = explosionForce * ((Vector3)(ref val5)).normalized + ExplosionForce * 0.5f * Vector3.up;
						DamageInfo val6 = val4;
						DamageAPI.AddModdedDamageType(ref val6.damageType, DamageTypes.ForceAddToSharedSuffering);
						readOnlyInstances.healthComponent.TakeDamage(val6);
						GlobalEventManager.instance.OnHitEnemy(val6, ((Component)readOnlyInstances).gameObject);
						GlobalEventManager.instance.OnHitAll(val6, ((Component)readOnlyInstances).gameObject);
					}
				}
			}
			EntityState.Destroy((Object)(object)((EntityState)this).gameObject);
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)9;
		}
	}
}
namespace EntityStates.MushroomShield
{
	public abstract class MushroomBubbleBaseState : EntityState
	{
		[NonSerialized]
		public float EffectRadius;

		public override void OnSerialize(NetworkWriter writer)
		{
			((EntityState)this).OnSerialize(writer);
			writer.Write(EffectRadius);
		}

		public override void OnDeserialize(NetworkReader reader)
		{
			((EntityState)this).OnDeserialize(reader);
			EffectRadius = reader.ReadSingle();
		}

		public override void ModifyNextState(EntityState nextState)
		{
			((EntityState)this).ModifyNextState(nextState);
			if (nextState is MushroomBubbleBaseState mushroomBubbleBaseState)
			{
				mushroomBubbleBaseState.EffectRadius = EffectRadius;
			}
		}

		public abstract void Undeploy(bool immediate);
	}
	public sealed class MushroomBubbleDeploy : MushroomBubbleBaseState
	{
		public static string StartSoundString;

		private CharacterBody _ownerBody;

		private float _startMoveStopwatchValue;

		private float _undeployLifetime;

		public override void OnEnter()
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).OnEnter();
			Util.PlaySound(StartSoundString, ((EntityState)this).gameObject);
			GenericOwnership component = ((EntityState)this).GetComponent<GenericOwnership>();
			if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.ownerObject))
			{
				return;
			}
			_ownerBody = component.ownerObject.GetComponent<CharacterBody>();
			if (Object.op_Implicit((Object)(object)_ownerBody))
			{
				ItemQualityCounts itemCountsEffective = ItemQualitiesContent.ItemQualityGroups.Mushroom.GetItemCountsEffective(_ownerBody.inventory);
				_undeployLifetime = itemCountsEffective.UncommonCount + 3 * itemCountsEffective.RareCount + 6 * itemCountsEffective.EpicCount + 12 * itemCountsEffective.LegendaryCount;
				float num = 30f;
				switch (itemCountsEffective.HighestQuality)
				{
				case QualityTier.Uncommon:
					num = 30f;
					break;
				case QualityTier.Rare:
					num = 25f;
					break;
				case QualityTier.Epic:
					num = 20f;
					break;
				case QualityTier.Legendary:
					num = 15f;
					break;
				}
				EffectRadius = num;
				((EntityState)this).transform.localScale = Vector3.one * (num / 20f);
				_startMoveStopwatchValue = _ownerBody.notMovingStopwatch;
			}
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			if (((EntityState)this).isAuthority && (!Object.op_Implicit((Object)(object)_ownerBody) || !Object.op_Implicit((Object)(object)_ownerBody.healthComponent) || !_ownerBody.healthComponent.alive || _ownerBody.notMovingStopwatch < _startMoveStopwatchValue))
			{
				Undeploy(immediate: false);
			}
		}

		public override void Undeploy(bool immediate)
		{
			if (((EntityState)this).isAuthority)
			{
				if (immediate)
				{
					((EntityState)this).outer.SetNextState((EntityState)(object)new MushroomBubbleFlashOut());
					return;
				}
				((EntityState)this).outer.SetNextState((EntityState)(object)new MushroomBubbleUndeploy
				{
					Duration = _undeployLifetime
				});
			}
		}
	}
	public sealed class MushroomBubbleFlashOut : MushroomBubbleBaseState
	{
		private static EffectIndex _bubbleShieldEndEffect = (EffectIndex)(-1);

		public static string EndSoundString;

		public static float Duration;

		private BeginRapidlyActivatingAndDeactivating _blinkController;

		[SystemInitializer(new Type[] { typeof(EffectCatalogUtils) })]
		private static void Init()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			_bubbleShieldEndEffect = EffectCatalogUtils.FindEffectIndex("BubbleShieldEndEffect");
			if ((int)_bubbleShieldEndEffect == -1)
			{
				Log.Warning("Failed to find charge effect index", "X:\\Git\\RoR2\\ItemQualities\\ItemQualities\\Assets\\ItemQualities\\Scripts\\EntityStates\\MushroomShield\\MushroomBubbleFlashOut.cs", "Init", 16);
			}
		}

		public override void OnEnter()
		{
			((EntityState)this).OnEnter();
			_blinkController = ((EntityState)this).GetComponent<BeginRapidlyActivatingAndDeactivating>();
			if (Object.op_Implicit((Object)(object)_blinkController))
			{
				_blinkController.delayBeforeBeginningBlinking = 0f;
				_blinkController.fixedAge = 0f;
				((Behaviour)_blinkController).enabled = true;
			}
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= Duration)
			{
				EntityState.Destroy((Object)(object)((EntityState)this).gameObject);
			}
		}

		public override void OnExit()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			((EntityState)this).OnExit();
			EffectManager.SpawnEffect(_bubbleShieldEndEffect, new EffectData
			{
				origin = ((EntityState)this).transform.position,
				rotation = ((EntityState)this).transform.rotation,
				scale = EffectRadius
			}, false);
			Util.PlaySound(EndSoundString, ((EntityState)this).gameObject);
			if (Object.op_Implicit((Object)(object)_blinkController))
			{
				((Behaviour)_blinkController).enabled = false;
			}
		}

		public override void Undeploy(bool immediate)
		{
		}
	}
	public sealed class MushroomBubbleUndeploy : MushroomBubbleBaseState
	{
		[NonSerialized]
		public float Duration;

		public override void OnSerialize(NetworkWriter writer)
		{
			base.OnSerialize(writer);
			writer.Write(Duration);
		}

		public override void OnDeserialize(NetworkReader reader)
		{
			base.OnDeserialize(reader);
			Duration = reader.ReadSingle();
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= Duration - MushroomBubbleFlashOut.Duration)
			{
				Undeploy(immediate: true);
			}
		}

		public override void Undeploy(bool immediate)
		{
			if (((EntityState)this).isAuthority && immediate)
			{
				((EntityState)this).outer.SetNextState((EntityState)(object)new MushroomBubbleFlashOut());
			}
		}
	}
}
namespace EntityStates.FriendUnit
{
	public sealed class FriendUnitPunt : BaseState
	{
		public static float BaseVelocity;

		public static float MaxLockOnAngle;

		public static float MaxDistance;

		public static float LaunchHorizontalSpeedMultiplier;

		public static string PuntSound;

		[NonSerialized]
		public GameObject Punter;

		[NonSerialized]
		public Ray AimRay;

		public override void OnSerialize(NetworkWriter writer)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).OnSerialize(writer);
			writer.Write(Punter);
			writer.Write(AimRay);
		}

		public override void OnDeserialize(NetworkReader reader)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).OnDeserialize(reader);
			Punter = reader.ReadGameObject();
			AimRay = reader.ReadRay();
		}

		public override void OnEnter()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			if (((EntityState)this).isAuthority)
			{
				((EntityState)this).characterBody.isSprinting = true;
			}
			((BaseState)this).OnEnter();
			if (((EntityState)this).isAuthority)
			{
				BullseyeSearch val = new BullseyeSearch
				{
					searchOrigin = ((Ray)(ref AimRay)).origin,
					searchDirection = ((Ray)(ref AimRay)).direction,
					viewer = (Object.op_Implicit((Object)(object)Punter) ? Punter.GetComponent<CharacterBody>() : null),
					filterByLoS = true,
					filterByDistinctEntity = true,
					maxAngleFilter = MaxLockOnAngle,
					maxDistanceFilter = MaxDistance,
					sortMode = (SortMode)2,
					queryTriggerInteraction = (QueryTriggerInteraction)1,
					teamMaskFilter = TeamMask.GetEnemyTeams(TeamComponent.GetObjectTeam(Punter))
				};
				val.RefreshCandidates();
				Vector3 val2 = Vector3.zero;
				IPhysMotor val3 = default(IPhysMotor);
				if (Object.op_Implicit((Object)(object)Punter) && Punter.TryGetComponent<IPhysMotor>(ref val3))
				{
					val2 = val3.velocity;
				}
				Vector3 val4 = val2;
				val4.y = 0f;
				float num = ((Vector3)(ref val4)).magnitude + BaseVelocity + base.moveSpeedStat * LaunchHorizontalSpeedMultiplier;
				Vector3 force = ((Ray)(ref AimRay)).direction * num;
				using (IEnumerator<HurtBox> enumerator = val.GetResults().GetEnumerator())
				{
					if (enumerator.MoveNext())
					{
						HurtBox current = enumerator.Current;
						force = Trajectory.CalculateInitialVelocityFromHSpeed(((EntityState)this).transform.position, ((Component)current).transform.position, num, 0f, float.PositiveInfinity);
					}
				}
				CharacterMotor characterMotor = ((EntityState)this).characterMotor;
				PhysForceInfo val5 = new PhysForceInfo
				{
					force = force
				};
				((PhysForceInfo)(ref val5)).massIsOne = true;
				((PhysForceInfo)(ref val5)).disableAirControlUntilCollision = true;
				((PhysForceInfo)(ref val5)).resetVelocity = true;
				((PhysForceInfo)(ref val5)).ignoreGroundStick = true;
				characterMotor.ApplyForceImpulse(ref val5);
				((EntityState)this).characterMotor.onMovementHit += new MovementHitDelegate(onMovementHit);
			}
			Util.PlaySound(PuntSound, ((EntityState)this).gameObject);
		}

		public override void OnExit()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			((EntityState)this).OnExit();
			if (((EntityState)this).isAuthority)
			{
				((EntityState)this).characterBody.isSprinting = false;
				((EntityState)this).characterMotor.onMovementHit -= new MovementHitDelegate(onMovementHit);
			}
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			if (((EntityState)this).isAuthority)
			{
				((EntityState)this).characterBody.isSprinting = true;
			}
		}

		private void onMovementHit(ref MovementHitInfo movementHitInfo)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).outer.SetNextState((EntityState)(object)new FriendUnitPuntImpact
			{
				Punter = Punter,
				ImpactNormal = movementHitInfo.hitNormal,
				ImpactVelocity = movementHitInfo.velocity,
				DamageMultiplierFromSpeed = Mathf.Max(1f, ((Vector3)(ref movementHitInfo.velocity)).magnitude / base.moveSpeedStat)
			});
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)7;
		}
	}
	public sealed class FriendUnitPuntImpact : BaseState
	{
		private static EffectIndex _explosionEffectIndex = (EffectIndex)(-1);

		public static float ImpactBounciness;

		public static string ImpactSoundString;

		[NonSerialized]
		public GameObject Punter;

		[NonSerialized]
		public Vector3 ImpactNormal;

		[NonSerialized]
		public Vector3 ImpactVelocity;

		[NonSerialized]
		public float DamageMultiplierFromSpeed;

		[SystemInitializer(new Type[] { typeof(EffectCatalogUtils) })]
		private static void Init()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			_explosionEffectIndex = EffectCatalogUtils.FindEffectIndex("OmniExplosionVFXRoboBallDeath");
			if ((int)_explosionEffectIndex == -1)
			{
				Log.Error("Failed to find explosion effect index", "X:\\Git\\RoR2\\ItemQualities\\ItemQualities\\Assets\\ItemQualities\\Scripts\\EntityStates\\FriendUnit\\FriendUnitPuntImpact.cs", "Init", 20);
			}
		}

		public override void OnSerialize(NetworkWriter writer)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).OnSerialize(writer);
			writer.Write(Punter);
			writer.Write(ImpactNormal);
			writer.Write(ImpactVelocity);
			writer.Write(DamageMultiplierFromSpeed);
		}

		public override void OnDeserialize(NetworkReader reader)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).OnDeserialize(reader);
			Punter = reader.ReadGameObject();
			ImpactNormal = reader.ReadVector3();
			ImpactVelocity = reader.ReadVector3();
			DamageMultiplierFromSpeed = reader.ReadSingle();
		}

		public override void OnEnter()
		{
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Expected O, but got Unknown
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Invalid comparison between Unknown and I4
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Expected O, but got Unknown
			((BaseState)this).OnEnter();
			if (NetworkServer.active)
			{
				CharacterMaster master = ((EntityState)this).characterBody.master;
				ItemQualityCounts itemQualityCounts = default(ItemQualityCounts);
				if (Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.minionOwnership.ownerMaster))
				{
					itemQualityCounts = ItemQualitiesContent.ItemQualityGroups.PhysicsProjectile.GetItemCountsEffective(master.minionOwnership.ownerMaster.inventory);
				}
				if (itemQualityCounts.TotalQualityCount == 0)
				{
					itemQualityCounts.UncommonCount = 1;
				}
				float num;
				switch (itemQualityCounts.HighestQuality)
				{
				case QualityTier.Uncommon:
					num = 4f;
					break;
				case QualityTier.Rare:
					num = 6f;
					break;
				case QualityTier.Epic:
					num = 8f;
					break;
				case QualityTier.Legendary:
					num = 10f;
					break;
				default:
					Log.Error($"Quality tier {itemQualityCounts.HighestQuality} is not implemented", "X:\\Git\\RoR2\\ItemQualities\\ItemQualities\\Assets\\ItemQualities\\Scripts\\EntityStates\\FriendUnit\\FriendUnitPuntImpact.cs", "OnEnter", 91);
					num = 1f;
					break;
				}
				float radius = 10f * (float)itemQualityCounts.UncommonCount + 15f * (float)itemQualityCounts.RareCount + 25f * (float)itemQualityCounts.EpicCount + 35f * (float)itemQualityCounts.LegendaryCount;
				radius = ExplodeOnDeath.GetExplosionRadius(radius, ((EntityState)this).characterBody);
				BlastAttack val = new BlastAttack
				{
					position = ((EntityState)this).characterBody.corePosition,
					radius = radius,
					baseDamage = num * base.damageStat * DamageMultiplierFromSpeed,
					damageType = new DamageTypeCombo(DamageTypeCombo.op_Implicit((DamageType)32), (DamageTypeExtended)0, (DamageSource)1),
					crit = ((BaseState)this).RollCrit(),
					attacker = ((EntityState)this).gameObject,
					inflictor = ((EntityState)this).gameObject,
					attackerFiltering = (AttackerFiltering)2,
					damageColorIndex = (DamageColorIndex)3,
					falloffModel = (FalloffModel)3,
					procCoefficient = 1f,
					teamIndex = ((BaseState)this).GetTeam()
				};
				val.Fire();
				if ((int)_explosionEffectIndex != -1)
				{
					EffectManager.SpawnEffect(_explosionEffectIndex, new EffectData
					{
						origin = val.position,
						scale = val.radius
					}, true);
				}
			}
			Util.PlaySound(ImpactSoundString, ((EntityState)this).gameObject);
			EffectManager.SimpleImpactEffect(KineticAura.knockbackEffectPrefab, ((EntityState)this).characterBody.corePosition, -ImpactNormal, false);
			if (((EntityState)this).isAuthority)
			{
				if (ImpactVelocity == Vector3.zero)
				{
					ImpactVelocity = ((EntityState)this).characterMotor.velocity;
				}
				Vector3 force;
				if (ImpactNormal != Vector3.zero)
				{
					Vector3 val2 = Vector3.Reflect(((Vector3)(ref ImpactVelocity)).normalized, ImpactNormal);
					float num2 = ((Vector3)(ref ImpactVelocity)).magnitude * ImpactBounciness;
					force = val2 * num2;
				}
				else
				{
					force = ((EntityState)this).characterMotor.velocity * (0f - ImpactBounciness);
				}
				CharacterMotor characterMotor = ((EntityState)this).characterMotor;
				PhysForceInfo val3 = new PhysForceInfo
				{
					force = force
				};
				((PhysForceInfo)(ref val3)).resetVelocity = true;
				((PhysForceInfo)(ref val3)).disableAirControlUntilCollision = true;
				((PhysForceInfo)(ref val3)).ignoreGroundStick = true;
				((PhysForceInfo)(ref val3)).massIsOne = true;
				characterMotor.ApplyForceImpulse(ref val3);
				((EntityState)this).outer.SetNextStateToMain();
			}
		}
	}
}
namespace EntityStates.BossGroupHealNovaController
{
	public class BossGroupHealNovaPulse : EntityState
	{
		private class HealPulse
		{
			private readonly HashSet<HealthComponent> _healedTargets = new HashSet<HealthComponent>();

			private readonly SphereSearch _sphereSearch;

			private readonly float _duration;

			private readonly float _finalRadius;

			private readonly float _healFractionValue;

			private readonly TeamMask _teamMask;

			private readonly List<HurtBox> _hurtBoxesList = new List<HurtBox>();

			private float _timeElapsed;

			public HealPulse(Vector3 origin, float finalRadius, float healFractionValue, float duration, TeamIndex teamIndex)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Expected O, but got Unknown
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				_sphereSearch = new SphereSearch
				{
					mask = ((LayerIndex)(ref LayerIndex.entityPrecise)).mask,
					origin = origin,
					queryTriggerInteraction = (QueryTriggerInteraction)2,
					radius = 0f
				};
				_finalRadius = finalRadius;
				_healFractionValue = healFractionValue;
				_duration = duration;
				_teamMask = default(TeamMask);
				((TeamMask)(ref _teamMask)).AddTeam(teamIndex);
			}

			public void Update(float deltaTime)
			{
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				_timeElapsed += deltaTime;
				float num = Mathf.Clamp01(_timeElapsed / _duration);
				_sphereSearch.radius = _finalRadius * NovaRadiusCurve.Evaluate(num);
				_sphereSearch.RefreshCandidates().FilterCandidatesByHurtBoxTeam(_teamMask).FilterCandidatesByDistinctHurtBoxEntities()
					.GetHurtBoxes(_hurtBoxesList);
				foreach (HurtBox hurtBoxes in _hurtBoxesList)
				{
					if (_healedTargets.Add(hurtBoxes.healthComponent))
					{
						healTarget(hurtBoxes.healthComponent);
					}
				}
				_hurtBoxesList.Clear();
			}

			private void healTarget(HealthComponent target)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				target.HealFraction(_healFractionValue, default(ProcChainMask));
				Util.PlaySound("Play_item_proc_TPhealingNova_hitPlayer", ((Component)target).gameObject);
			}
		}

		public static AnimationCurve NovaRadiusCurve;

		public static float GrowDuration;

		public static float LingerDuration;

		private float _totalDuration;

		private Transform _effectTransform;

		private HealPulse _healPulse;

		private float _radius;

		public override void OnEnter()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).OnEnter();
			_totalDuration = GrowDuration + LingerDuration;
			BossGroupHealNovaSpawner bossGroupHealNovaSpawner = default(BossGroupHealNovaSpawner);
			if (Object.op_Implicit((Object)(object)((EntityState)this).transform.parent) && ((Component)((EntityState)this).transform.parent).TryGetComponent<BossGroupHealNovaSpawner>(ref bossGroupHealNovaSpawner))
			{
				_radius = bossGroupHealNovaSpawner.NovaRadius;
			}
			TeamFilter component = ((EntityState)this).GetComponent<TeamFilter>();
			TeamIndex teamIndex = (TeamIndex)((!Object.op_Implicit((Object)(object)component)) ? (-1) : ((int)component.teamIndex));
			if (NetworkServer.active)
			{
				_healPulse = new HealPulse(((EntityState)this).transform.position, _radius, 0.5f, GrowDuration, teamIndex);
			}
			_effectTransform = ((EntityState)this).transform.Find("PulseEffect");
			if (Object.op_Implicit((Object)(object)_effectTransform))
			{
				((Component)_effectTransform).gameObject.SetActive(true);
			}
		}

		public override void OnExit()
		{
			if (Object.op_Implicit((Object)(object)_effectTransform))
			{
				((Component)_effectTransform).gameObject.SetActive(false);
			}
			((EntityState)this).OnExit();
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			if (NetworkServer.active)
			{
				_healPulse.Update(((EntityState)this).GetDeltaTime());
				if (((EntityState)this).fixedAge >= _totalDuration)
				{
					EntityState.Destroy((Object)(object)((Component)base.outer).gameObject);
				}
			}
		}

		public override void Update()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_effectTransform))
			{
				float num = _radius * NovaRadiusCurve.Evaluate(Mathf.Clamp01(((EntityState)this).fixedAge / GrowDuration));
				_effectTransform.localScale = new Vector3(num, num, num);
			}
		}
	}
	public class BossGroupHealNovaWindup : EntityState
	{
		private static EffectIndex _chargeEffectIndex = (EffectIndex)(-1);

		public static float Duration;

		[SystemInitializer(new Type[] { typeof(EffectCatalogUtils) })]
		private static void Init()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			_chargeEffectIndex = EffectCatalogUtils.FindEffectIndex("ChargeTPHealingNova");
			if ((int)_chargeEffectIndex == -1)
			{
				Log.Warning("Failed to find charge effect index", "X:\\Git\\RoR2\\ItemQualities\\ItemQualities\\Assets\\ItemQualities\\Scripts\\EntityStates\\BossGroupHealNovaController\\BossGroupHealNovaWindup.cs", "Init", 16);
			}
		}

		public override void OnEnter()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			((EntityState)this).OnEnter();
			if ((int)_chargeEffectIndex != -1)
			{
				EffectManager.SpawnEffect(_chargeEffectIndex, new EffectData
				{
					origin = ((EntityState)this).transform.position
				}, false);
			}
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= Duration)
			{
				base.outer.SetNextStateToMain();
			}
		}
	}
}
namespace ItemQualities
{
	[DefaultExecutionOrder(-1000)]
	public class AssignAddressableReferences : MonoBehaviour, IAsyncContentLoadCallback
	{
		[Serializable]
		public class ComponentFieldAddressableAssignment
		{
			[Tooltip("The object to assign the field on")]
			[SerializeField]
			[FormerlySerializedAs("TargetObject")]
			private Object _targetObject;

			[SerializeField]
			[HideInInspector]
			private Component _targetObjectComponent;

			[Tooltip("If set, the first component of this type will be located on the Target Object and used as the field instance")]
			[RequiredBaseType(typeof(Component))]
			public SerializableSystemType TargetObjectComponentType;

			[Tooltip("The name of the field or property to set")]
			public string FieldName;

			[Tooltip("Address of the asset to load")]
			public AssetReferenceT<Object> AssetReference = new AssetReferenceT<Object>(string.Empty);

			[Tooltip("Determines what type is used to load the asset, if not set, the type of the field/property is used")]
			[RequiredBaseType(typeof(Object))]
			public SerializableSystemType AssetTypeOverride;

			public Object TargetObject
			{
				get
				{
					if (!Object.op_Implicit((Object)(object)_targetObjectComponent))
					{
						return _targetObject;
					}
					return (Object)(object)_targetObjectComponent;
				}
			}

			public void OnValidate()
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				_targetObjectComponent = null;
				Type type = (Type)TargetObjectComponentType;
				if (!(type != null) || !Object.op_Implicit(_targetObject))
				{
					return;
				}
				Object targetObject = _targetObject;
				GameObject val = (GameObject)(object)((targetObject is GameObject) ? targetObject : null);
				if (val == null)
				{
					Component val2 = (Component)(object)((targetObject is Component) ? targetObject : null);
					if (val2 != null)
					{
						_targetObjectComponent = val2.GetComponent(type);
					}
				}
				else
				{
					_targetObjectComponent = val.GetComponent(type);
				}
			}
		}

		public ComponentFieldAddressableAssignment[] FieldAssignments = Array.Empty<ComponentFieldAddressableAssignment>();

		[SerializeField]
		[HideInInspector]
		private bool _hasLoaded;

		public bool HasLoaded => _hasLoaded;

		private void Awake()
		{
			if (!_hasLoaded)
			{
				Log.Warning(Util.GetGameObjectHierarchyName(((Component)this).gameObject) + ": Addressable references were not assigned to prefab during init, loading assets now", "X:\\Git\\RoR2\\ItemQualities\\ItemQualities\\Assets\\ItemQualities\\Scripts\\AssignAddressableReferences.cs", "Awake", 32);
				IEnumerator enumerator = AssignFieldsAsync();
				while (enumerator.MoveNext())
				{
				}
			}
		}

		IEnumerator IAsyncContentLoadCallback.OnContentLoad(IProgress<float> progressReceiver)
		{
			return AssignFieldsAsync(progressReceiver);
		}

		public IEnumerator AssignFieldsAsync(IProgress<float> progressReceiver = null)
		{
			if (FieldAssignments.Length != 0)
			{
				if (progressReceiver != null)
				{
					ParallelProgressCoroutine val = new ParallelProgressCoroutine(progressReceiver);
					ComponentFieldAddressableAssignment[] fieldAssignments = FieldAssignments;
					foreach (ComponentFieldAddressableAssignment componentFieldAssignment in fieldAssignments)
					{
						ReadableProgress<float> val2 = new ReadableProgress<float>();
						val.Add(assignComponentFieldAsync(componentFieldAssignment, (IProgress<float>)val2), val2);
					}
					yield return val;
				}
				else
				{
					ParallelCoroutine val3 = new ParallelCoroutine();
					ComponentFieldAddressableAssignment[] fieldAssignments = FieldAssignments;
					foreach (ComponentFieldAddressableAssignment componentFieldAssignment2 in fieldAssignments)
					{
						val3.Add(assignComponentFieldAsync(componentFieldAssignment2));
					}
					yield return val3;
				}
			}
			_hasLoaded = true;
			((Behaviour)this).enabled = false;
		}

		private IEnumerator assignComponentFieldAsync(ComponentFieldAddressableAssignment componentFieldAssignment, IProgress<float> progressReceiver = null)
		{
			if (!Object.op_Implicit(componentFieldAssignment.TargetObject))
			{
				yield break;
			}
			Type type = ((object)componentFieldAssignment.TargetObject).GetType();
			Type memberType;
			MemberInfo targetMember = findTargetMember(type, componentFieldAssignment.FieldName, out memberType);
			if (targetMember == null)
			{
				Log.Error($"Failed to find field '{componentFieldAssignment.FieldName}' on component {componentFieldAssignment.TargetObject}", "X:\\Git\\RoR2\\ItemQualities\\ItemQualities\\Assets\\ItemQualities\\Scripts\\AssignAddressableReferences.cs", "assignComponentFieldAsync", 87);
				yield break;
			}
			Type assetType = ((Type)componentFieldAssignment.AssetTypeOverride) ?? memberType;
			AsyncOperationHandle assetLoadHandle = AddressableUtil.LoadAssetAsync((AssetReference)(object)componentFieldAssignment.AssetReference, assetType, (AsyncReferenceHandleUnloadType)2);
			try
			{
				yield return assetLoadHandle.AsProgressCoroutine(progressReceiver);
				AssignAddressableReferences assignAddressableReferences = this;
				object result = ((AsyncOperationHandle)(ref assetLoadHandle)).Result;
				assignAddressableReferences.applyFieldValue(componentFieldAssignment, targetMember, (Object)((result is Object) ? result : null));
			}
			finally
			{
				AddressableUtil.UnloadAsset((AssetReference)(object)componentFieldAssignment.AssetReference, assetType);
			}
		}

		private void applyFieldValue(ComponentFieldAddressableAssignment componentFieldAssignment, MemberInfo member, Object value)
		{
			Type type = ((object)componentFieldAssignment.TargetObject).GetType();
			object runtimeKey = ((AssetReference)componentFieldAssignment.AssetReference).RuntimeKey;
			if (!Object.op_Implicit(value))
			{
				Log.Warning($"{Util.GetGameObjectHierarchyName(((Component)this).gameObject)} ({type.FullName}.{componentFieldAssignment.FieldName}): Null asset loaded for asset {runtimeKey}", "X:\\Git\\RoR2\\ItemQualities\\ItemQualities\\Assets\\ItemQualities\\Scripts\\AssignAddressableReferences.cs", "applyFieldValue", 113);
			}
			try
			{
				if (!(member is FieldInfo fieldInfo))
				{
					if (member is PropertyInfo propertyInfo)
					{
						propertyInfo.SetValue(componentFieldAssignment.TargetObject, value);
					}
				}
				else
				{
					fieldInfo.SetValue(componentFieldAssignment.TargetObject, value);
				}
			}
			catch (Exception ex)
			{
				Log.Error_NoCallerPrefix($"{Util.GetGameObjectHierarchyName(((Component)this).gameObject)}: Failed to set field {type.FullName}.{componentFieldAssignment.FieldName} to asset {value} from {runtimeKey}: {ex}");
			}
		}

		private void OnValidate()
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			ComponentFieldAddressableAssignment[] fieldAssignments = FieldAssignments;
			foreach (ComponentFieldAddressableAssignment componentFieldAddressableAssignment in fieldAssignments)
			{
				componentFieldAddressableAssignment.OnValidate();
				if (!Object.op_Implicit(componentFieldAddressableAssignment.TargetObject))
				{
					continue;
				}
				Type type = ((object)componentFieldAddressableAssignment.TargetObject).GetType();
				if (findTargetMember(type, componentFieldAddressableAssignment.FieldName, out var memberType) == null)
				{
					Debug.LogWarning((object)("Field or property '" + componentFieldAddressableAssignment.FieldName + "' does not exist in type " + type.FullName), (Object)(object)this);
					continue;
				}
				if (!typeof(Object).IsAssignableFrom(memberType))
				{
					Debug.LogWarning((object)("Invalid type " + memberType.FullName + " on field " + type.FullName + "." + componentFieldAddressableAssignment.FieldName + " (must be UnityEngine.Object)"), (Object)(object)this);
				}
				Type type2 = (Type)componentFieldAddressableAssignment.AssetTypeOverride;
				if (type2 != null && !memberType.IsAssignableFrom(type2))
				{
					Debug.LogWarning((object)("Asset type " + type2.FullName + " cannot be assigned to field of type " + memberType.FullName + " (" + type.FullName + "." + componentFieldAddressableAssignment.FieldName + ")"), (Object)(object)this);
				}
			}
		}

		private static MemberInfo findTargetMember(Type componentType, string fieldName, out Type memberType)
		{
			FieldInfo field = componentType.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				memberType = field.FieldType;
				return field;
			}
			PropertyInfo property = componentType.GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null)
			{
				memberType = property.PropertyType;
				return property;
			}
			memberType = null;
			return null;
		}
	}
	public class AxisBillboard : MonoBehaviour
	{
		public Vector3 Axis = Vector3.up;

		private void OnEnable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			SceneCamera.onSceneCameraPreCull += new SceneCameraDelegate(onSceneCameraPreCull);
		}

		private void OnDisable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			SceneCamera.onSceneCameraPreCull -= new SceneCameraDelegate(onSceneCameraPreCull);
		}

		private void onSceneCameraPreCull(SceneCamera sceneCamera)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.ProjectOnPlane(((Component)this).transform.position, Axis);
			Vector3 val2 = Vector3.ProjectOnPlane(((Component)sceneCamera).transform.position, Axis);
			Transform transform = ((Component)this).transform;
			Vector3 val3 = val2 - val;
			transform.rotation = Util.QuaternionSafeLookRotation(((Vector3)(ref val3)).normalized);
		}
	}
	public sealed class BarrierPickup : MonoBehaviour
	{
		[Tooltip("The base object to destroy when this pickup is consumed.")]
		public GameObject BaseObject;

		[Tooltip("The team filter object which determines who can pick up this pack.")]
		public TeamFilter TeamFilter;

		public GameObject PickupEffect;

		public float FlatAmount;

		public float FractionalAmount;

		private bool _alive = true;

		private void OnTriggerStay(Collider other)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			if (!NetworkServer.active || !_alive || TeamComponent.GetObjectTeam(((Component)other).gameObject) != TeamFilter.teamIndex)
			{
				return;
			}
			CharacterBody component = ((Component)other).GetComponent<CharacterBody>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			HealthComponent healthComponent = component.healthComponent;
			if (Object.op_Implicit((Object)(object)healthComponent))
			{
				healthComponent.AddBarrier(FlatAmount + healthComponent.fullBarrier * FractionalAmount);
				if (Object.op_Implicit((Object)(object)PickupEffect))
				{
					EffectManager.SpawnEffect(PickupEffect, new EffectData
					{
						origin = ((Component)this).transform.position
					}, true);
				}
			}
			Object.Destroy((Object)(object)BaseObject);
			_alive = false;
		}
	}
	[RequireComponent(typeof(NetworkedBodyAttachment))]
	public class BodyAttachmentVFXController : MonoBehaviour, INetworkedBodyAttachmentListener
	{
		public enum RadiusMode
		{
			Constant,
			BodyRadius,
			BodyBestFitRadius,
			BodyBestFitActualRadius
		}

		[SerializeField]
		private InstantiateAddressablePrefab _bodyVFXInstantiator;

		[SerializeField]
		private RadiusMode _radiusMode = RadiusMode.BodyRadius;

		[SerializeField]
		[Min(0f)]
		private float _radiusMultiplier = 1f;

		private NetworkedBodyAttachment _bodyAttachment;

		private void Awake()
		{
			_bodyAttachment = ((Component)this).GetComponent<NetworkedBodyAttachment>();
			_bodyVFXInstantiator.OnInstantiated += onVFXInstantiated;
		}

		private void OnDestroy()
		{
			_bodyVFXInstantiator.OnInstantiated -= onVFXInstantiated;
		}

		private void onVFXInstantiated(GameObject vfx)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			TemporaryVisualEffect val = default(TemporaryVisualEffect);
			if (!vfx.TryGetComponent<TemporaryVisualEffect>(ref val))
			{
				return;
			}
			CharacterBody attachedBody = _bodyAttachment.attachedBody;
			if (Object.op_Implicit((Object)(object)attachedBody))
			{
				float num = _radiusMode switch
				{
					RadiusMode.Constant => 1f, 
					RadiusMode.BodyRadius => attachedBody.radius, 
					RadiusMode.BodyBestFitRadius => attachedBody.bestFitRadius, 
					RadiusMode.BodyBestFitActualRadius => attachedBody.bestFitActualRadius, 
					_ => throw new NotImplementedException($"Radius mode {_radiusMode} is not implemented"), 
				};
				val.parentTransform = attachedBody.coreTransform;
				val.visualState = (VisualState)0;
				val.healthComponent = attachedBody.healthComponent;
				val.radius = num * _radiusMultiplier;
				LocalCameraEffect val2 = default(LocalCameraEffect);
				if (((Component)val).TryGetComponent<LocalCameraEffect>(ref val2))
				{
					val2.targetCharacter = ((Component)attachedBody).gameObject;
				}
			}
		}

		void INetworkedBodyAttachmentListener.OnAttachedBodyDiscovered(NetworkedBodyAttachment networkedBodyAttachment, CharacterBody attachedBody)
		{
			_bodyVFXInstantiator.InstantiatePrefab();
		}
	}
	public class BossArenaHealNovaManager : MonoBehaviour
	{
		public BossGroup WatchingBossGroup;

		public float ArenaRadius = 100f;

		private readonly GameObject[] _healNovaSpawnersByTeam = (GameObject[])(object)new GameObject[TeamsAPICompat.TeamsCount];

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			GridManager.OnTierSet += new hook_OnTierSet(GridManager_OnTierSet);
		}

		private void Awake()
		{
			InstanceTracker.Add<BossArenaHealNovaManager>(this);
			if (NetworkServer.active)
			{
				BossGroup.onBossGroupDefeatedServer += onBossGroupDefeatedServer;
			}
		}

		private void OnDisable()
		{
			GameObject[] healNovaSpawnersByTeam = _healNovaSpawnersByTeam;
			foreach (GameObject val in healNovaSpawnersByTeam)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}

		private void OnDestroy()
		{
			BossGroup.onBossGroupDefeatedServer -= onBossGroupDefeatedServer;
		}

		private static void GridManager_OnTierSet(orig_OnTierSet orig, GridManager self, int tier)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self, tier);
			foreach (BossArenaHealNovaManager instances in InstanceTracker.GetInstancesList<BossArenaHealNovaManager>())
			{
				Vector3 position = ((Component)instances).transform.position;
				position.y = self.GetLavaPosition(tier).y;
				((Component)instances).transform.position = position;
				TeamIndex val = (TeamIndex)0;
				while ((int)val < TeamsAPICompat.TeamsCount)
				{
					GameObject val2 = instances._healNovaSpawnersByTeam[val];
					if (Object.op_Implicit((Object)(object)val2))
					{
						val2.transform.position = ((Component)instances).transform.position;
					}
					val = (TeamIndex)(sbyte)(val + 1);
				}
			}
		}

		private void onBossGroupDefeatedServer(BossGroup bossGroup)
		{
			if ((Object)(object)bossGroup == (Object)(object)WatchingBossGroup)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private void FixedUpdate()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				return;
			}
			TeamIndex val = (TeamIndex)0;
			while ((int)val < TeamsAPICompat.TeamsCount)
			{
				bool flag = ItemQualitiesContent.ItemQualityGroups.TPHealingNova.GetTeamItemCounts(val, requireAlive: false).TotalQualityCount > 0;
				ref GameObject reference = ref _healNovaSpawnersByTeam[val];
				if (Object.op_Implicit((Object)(object)reference) != flag)
				{
					if (flag)
					{
						reference = Object.Instantiate<GameObject>(ItemQualitiesContent.NetworkedPrefabs.BossArenaHealNovaSpawner, ((Component)this).transform.position, ((Component)this).transform.rotation);
						reference.GetComponent<TeamFilter>().teamIndex = val;
						BossGroupHealNovaSpawner component = reference.GetComponent<BossGroupHealNovaSpawner>();
						component.BossGroup = WatchingBossGroup;
						component.NetworkNovaRadius = ArenaRadius;
						NetworkServer.Spawn(reference);
					}
					else
					{
						Object.Destroy((Object)(object)reference);
						reference = null;
					}
				}
				val = (TeamIndex)(sbyte)(val + 1);
			}
		}
	}
	[RequireComponent(typeof(TeamFilter))]
	public class BossGroupHealNovaSpawner : NetworkBehaviour
	{
		private static GameObject _pulsePrefab;

		public BossGroup BossGroup;

		public float MinSecondsBetweenPulses = 1f;

		[SyncVar]
		public float NovaRadius = 100f;

		private TeamFilter _teamFilter;

		private float _lastPulseFraction;

		private float _pulseAvailableTimer;

		public float NetworkNovaRadius
		{
			get
			{
				return NovaRadius;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<float>(value, ref NovaRadius, 1u);
			}
		}

		[ContentInitializer]
		private static IEnumerator LoadContent(ContentIntializerArgs args)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			AsyncOperationHandle<GameObject> val = AddressableUtil.LoadTempAssetAsync<GameObject>(RoR2_Base_TPHealingNova.TeleporterHealNovaPulse_prefab);
			val.OnSuccess(delegate(GameObject novaPulse)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				_pulsePrefab = PrefabAPI.InstantiateClone(novaPulse, "BossGroupHealNovaPulse");
				EntityStateMachine component = _pulsePrefab.GetComponent<EntityStateMachine>();
				component.initialStateType = new SerializableEntityStateType(typeof(BossGroupHealNovaWindup));
				component.mainStateType = new SerializableEntityStateType(typeof(BossGroupHealNovaPulse));
				args.ContentPack.networkedObjectPrefabs.Add<GameObject>(_pulsePrefab);
			});
			return val.AsProgressCoroutine<GameObject>(args.ProgressReceiver);
		}

		private void Awake()
		{
			_teamFilter = ((Component)this).GetComponent<TeamFilter>();
		}

		private void Start()
		{
			if (NetworkServer.active)
			{
				_lastPulseFraction = getCurrentBossProgressFraction();
			}
		}

		private void OnDisable()
		{
			((Component)this).transform.DetachChildren();
		}

		private void FixedUpdate()
		{
			if (NetworkServer.active)
			{
				fixedUpdateServer(Time.fixedDeltaTime);
			}
		}

		private void fixedUpdateServer(float deltaTime)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (_pulseAvailableTimer > 0f)
			{
				_pulseAvailableTimer -= deltaTime;
				return;
			}
			ItemQualityCounts teamItemCounts = ItemQualitiesContent.ItemQualityGroups.TPHealingNova.GetTeamItemCounts(_teamFilter.teamIndex, requireAlive: true);
			float nextPulseFraction = getNextPulseFraction(teamItemCounts.UncommonCount + 2 * teamItemCounts.RareCount + 3 * teamItemCounts.EpicCount + 5 * teamItemCounts.LegendaryCount, _lastPulseFraction);
			if (getCurrentBossProgressFraction() > nextPulseFraction)
			{
				spawnPulse();
				_lastPulseFraction = nextPulseFraction;
				_pulseAvailableTimer = MinSecondsBetweenPulses;
			}
		}

		private float getCurrentBossProgressFraction()
		{
			if (!Object.op_Implicit((Object)(object)BossGroup) || !Object.op_Implicit((Object)(object)BossGroup.combatSquad))
			{
				return 0f;
			}
			if (BossGroup.combatSquad.defeatedServer)
			{
				return 1f;
			}
			float totalMaxObservedMaxHealth = BossGroup.totalMaxObservedMaxHealth;
			float totalObservedHealth = BossGroup.totalObservedHealth;
			float num = ((totalMaxObservedMaxHealth > 0f) ? Mathf.Clamp01(totalObservedHealth / totalMaxObservedMaxHealth) : 1f);
			return 1f - num;
		}

		private static float getNextPulseFraction(int pulseCount, float lastPulseFraction)
		{
			float num = 1f / (float)(pulseCount + 1);
			for (int i = 0; i < pulseCount; i++)
			{
				float num2 = num * (float)(i + 1);
				if (num2 > lastPulseFraction)
				{
					return num2;
				}
			}
			return 1f;
		}

		private void spawnPulse()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(_pulsePrefab, ((Component)this).transform.position, ((Component)this).transform.rotation, ((Component)this).transform);
			obj.GetComponent<TeamFilter>().teamIndex = _teamFilter.teamIndex;
			NetworkServer.Spawn(obj);
		}

		private void UNetVersion()
		{
		}

		public override bool OnSerialize(NetworkWriter writer, bool forceAll)
		{
			if (forceAll)
			{
				writer.Write(NovaRadius);
				return true;
			}
			bool flag = false;
			if ((((NetworkBehaviour)this).syncVarDirtyBits & (true ? 1u : 0u)) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(NovaRadius);
			}
			if (!flag)
			{
				writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
			}
			return flag;
		}

		public override void OnDeserialize(NetworkReader reader, bool initialState)
		{
			if (initialState)
			{
				NovaRadius = reader.ReadSingle();
				return;
			}
			int num = (int)reader.ReadPackedUInt32();
			if (((uint)num & (true ? 1u : 0u)) != 0)
			{
				NovaRadius = reader.ReadSingle();
			}
		}

		public override void PreStartClient()
		{
		}
	}
	[StructLayout(LayoutKind.Explicit)]
	public struct BuffQualityCounts : IEquatable<BuffQualityCounts>
	{
		[FieldOffset(0)]
		private unsafe fixed int _buffCounts[5];

		[FieldOffset(0)]
		public int BaseCount;

		[FieldOffset(4)]
		public int UncommonCount;

		[FieldOffset(8)]
		public int RareCount;

		[FieldOffset(12)]
		public int EpicCount;

		[FieldOffset(16)]
		public int LegendaryCount;

		public readonly int TotalCount => BaseCount + UncommonCount + RareCount + EpicCount + LegendaryCount;

		public readonly int TotalQualityCount => UncommonCount + RareCount + EpicCount + LegendaryCount;

		public unsafe ref int this[QualityTier qualityTier] => ref _buffCounts[(int)(qualityTier + 1)];

		public unsafe readonly QualityTier HighestQuality
		{
			get
			{
				for (QualityTier qualityTier = QualityTier.Legendary; qualityTier >= QualityTier.Uncommon; qualityTier--)
				{
					if (_buffCounts[(int)(qualityTier + 1)] > 0)
					{
						return qualityTier;
					}
				}
				return QualityTier.None;
			}
		}

		public BuffQualityCounts(int baseCount, int uncommonCount, int rareCount, int epicCount, int legendaryCount)
		{
			BaseCount = Math.Max(0, baseCount);
			UncommonCount = Math.Max(0, uncommonCount);
			RareCount = Math.Max(0, rareCount);
			EpicCount = Math.Max(0, epicCount);
			LegendaryCount = Math.Max(0, legendaryCount);
		}

		public override readonly bool Equals(object obj)
		{
			if (obj is BuffQualityCounts other)
			{
				return Equals(in other);
			}
			return false;
		}

		readonly bool IEquatable<BuffQualityCounts>.Equals(BuffQualityCounts other)
		{
			return Equals(in other);
		}

		public readonly bool Equals(in BuffQualityCounts other)
		{
			if (BaseCount == other.BaseCount && UncommonCount == other.UncommonCount && RareCount == other.RareCount && EpicCount == other.EpicCount)
			{
				return LegendaryCount == other.LegendaryCount;
			}
			return false;
		}

		public override readonly int GetHashCode()
		{
			return HashCode.Combine(BaseCount, UncommonCount, RareCount, EpicCount, LegendaryCount);
		}

		public override readonly string ToString()
		{
			return $"Normal={BaseCount}, Uncommon={UncommonCount}, Rare={RareCount}, Epic={EpicCount}, Legendary={LegendaryCount}";
		}

		public static bool operator ==(in BuffQualityCounts left, in BuffQualityCounts right)
		{
			return left.Equals(in right);
		}

		public static bool operator !=(in BuffQualityCounts left, in BuffQualityCounts right)
		{
			return !left.Equals(in right);
		}

		public static BuffQualityCounts operator +(in BuffQualityCounts left, in BuffQualityCounts right)
		{
			return new BuffQualityCounts(left.BaseCount + right.BaseCount, left.UncommonCount + right.UncommonCount, left.RareCount + right.RareCount, left.EpicCount + right.EpicCount, left.LegendaryCount + right.LegendaryCount);
		}

		public static BuffQualityCounts operator -(in BuffQualityCounts left, in BuffQualityCounts right)
		{
			return new BuffQualityCounts(left.BaseCount - right.BaseCount, left.UncommonCount - right.UncommonCount, left.RareCount - right.RareCount, left.EpicCount - right.EpicCount, left.LegendaryCount - right.LegendaryCount);
		}
	}
	[CreateAssetMenu(menuName = "ItemQualities/Buffs/BuffQualityGroup")]
	public class BuffQualityGroup : ScriptableObject, IAsyncContentLoadCallback
	{
		[NonSerialized]
		[HideInInspector]
		public BuffQualityGroupIndex GroupIndex = BuffQualityGroupIndex.Invalid;

		public AssetReferenceT<BuffDef> BaseBuffReference = new AssetReferenceT<BuffDef>(string.Empty);

		[SerializeField]
		private BuffDef _uncommonBuff;

		[SerializeField]
		private BuffDef _rareBuff;

		[SerializeField]
		private BuffDef _epicBuff;

		[SerializeField]
		private BuffDef _legendaryBuff;

		[NonSerialized]
		[HideInInspector]
		public BuffIndex BaseBuffIndex = (BuffIndex)(-1);

		public BuffIndex UncommonBuffIndex
		{
			get
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)_uncommonBuff))
				{
					return (BuffIndex)(-1);
				}
				return _uncommonBuff.buffIndex;
			}
		}

		public BuffIndex RareBuffIndex
		{
			get
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)_rareBuff))
				{
					return (BuffIndex)(-1);
				}
				return _rareBuff.buffIndex;
			}
		}

		public BuffIndex EpicBuffIndex
		{
			get
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)_epicBuff))
				{
					return (BuffIndex)(-1);
				}
				return _epicBuff.buffIndex;
			}
		}

		public BuffIndex LegendaryBuffIndex
		{
			get
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)_legendaryBuff))
				{
					return (BuffIndex)(-1);
				}
				return _legendaryBuff.buffIndex;
			}
		}

		public BuffIndex GetBuffIndex(QualityTier qualityTier)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			return (BuffIndex)(qualityTier switch
			{
				QualityTier.None => BaseBuffIndex, 
				QualityTier.Uncommon => UncommonBuffIndex, 
				QualityTier.Rare => RareBuffIndex, 
				QualityTier.Epic => EpicBuffIndex, 
				QualityTier.Legendary => LegendaryBuffIndex, 
				_ => throw new NotImplementedException($"Quality tier '{qualityTier}' is not implemented"), 
			});
		}

		public BuffQualityCounts GetBuffCounts(CharacterBody body)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Invalid comparison between Unknown and I4
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Invalid comparison between Unknown and I4
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)body))
			{
				return default(BuffQualityCounts);
			}
			int baseCount = (((int)BaseBuffIndex != -1) ? body.GetBuffCount(BaseBuffIndex) : 0);
			int uncommonCount = (((int)UncommonBuffIndex != -1) ? body.GetBuffCount(UncommonBuffIndex) : 0);
			int rareCount = (((int)RareBuffIndex != -1) ? body.GetBuffCount(RareBuffIndex) : 0);
			int epicCount = (((int)EpicBuffIndex != -1) ? body.GetBuffCount(EpicBuffIndex) : 0);
			int legendaryCount = (((int)LegendaryBuffIndex != -1) ? body.GetBuffCount(LegendaryBuffIndex) : 0);
			return new BuffQualityCounts(baseCount, uncommonCount, rareCount, epicCount, legendaryCount);
		}

		public bool HasBuff(CharacterBody body)
		{
			QualityTier buffQualityTier;
			return HasBuff(body, out buffQualityTier);
		}

		public bool HasBuff(CharacterBody body, out QualityTier buffQualityTier)
		{
			BuffQualityCounts buffCounts = GetBuffCounts(body);
			buffQualityTier = buffCounts.HighestQuality;
			return buffCounts.TotalCount > 0;
		}

		public bool HasQualityBuff(CharacterBody body)
		{
			QualityTier buffQualityTier;
			return HasQualityBuff(body, out buffQualityTier);
		}

		public bool HasQualityBuff(CharacterBody body, out QualityTier buffQualityTier)
		{
			if (HasBuff(body, out buffQualityTier))
			{
				return buffQualityTier > QualityTier.None;
			}
			return false;
		}

		public void EnsureBuffQualities(CharacterBody body, QualityTier buffQualityTier, bool includeBaseBuff = false)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Invalid comparison between Unknown and I4
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Invalid comparison between Unknown and I4
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				Log.Warning("Called on client", "X:\\Git\\RoR2\\ItemQualities\\ItemQualities\\Assets\\ItemQualities\\Scripts\\BuffQualityGroup.cs", "EnsureBuffQualities", 111);
				return;
			}
			BuffIndex val = GetBuffIndex(buffQualityTier);
			if (!includeBaseBuff && buffQualityTier == QualityTier.None)
			{
				val = (BuffIndex)(-1);
			}
			BuffDef buffDef = BuffCatalog.GetBuffDef(val);
			for (QualityTier qualityTier = (includeBaseBuff ? QualityTier.None : QualityTier.Uncommon); qualityTier < QualityTier.Count; qualityTier++)
			{
				if (qualityTier == buffQualityTier)
				{
					continue;
				}
				BuffIndex buffIndex = GetBuffIndex(qualityTier);
				if ((int)buffIndex == -1)
				{
					continue;
				}
				for (int num = body.GetBuffCount(buffIndex); num > 0; num--)
				{
					body.RemoveBuff(buffIndex);
					if ((int)val != -1 && Object.op_Implicit((Object)(object)buffDef) && (buffDef.canStack || !body.HasBuff(val)))
					{
						body.AddBuff(val);
					}
				}
			}
		}

		IEnumerator IAsyncContentLoadCallback.OnContentLoad(IProgress<float> progressReceiver)
		{
			if (BaseBuffReference == null || !((AssetReference)BaseBuffReference).RuntimeKeyIsValid())
			{
				progressReceiver.Report(1f);
				yield break;
			}
			AsyncOperationHandle<BuffDef> baseBuffLoad = AssetAsyncReferenceManager<BuffDef>.LoadAsset(BaseBuffReference, (AsyncReferenceHandleUnloadType)2);
			yield return baseBuffLoad.AsProgressCoroutine<BuffDef>(progressReceiver);
			BuffDef baseBuff;
			if (baseBuffLoad.IsValid() && (int)baseBuffLoad.Status == 1)
			{
				baseBuff = baseBuffLoad.Result;
				populateBuffAsset(_uncommonBuff, QualityTier.Uncommon);
				populateBuffAsset(_rareBuff, QualityTier.Rare);
				populateBuffAsset(_epicBuff, QualityTier.Epic);
				populateBuffAsset(_legendaryBuff, QualityTier.Legendary);
				AssetAsyncReferenceManager<BuffDef>.UnloadAsset(BaseBuffReference);
			}
			else
			{
				Log.Error(string.Format("Failed to load base buff for quality group '{0}': {1}", ((Object)this).name, baseBuffLoad.IsValid() ? ((object)baseBuffLoad.OperationException) : ((object)"Invalid handle")), "X:\\Git\\RoR2\\ItemQualities\\ItemQualities\\Assets\\ItemQualities\\Scripts\\BuffQualityGroup.cs", "OnContentLoad", 179);
			}
			void populateBuffAsset(BuffDef buff, QualityTier qualityTier)
			{
				if (!Object.op_Implicit((Object)(object)buff))
				{
					Log.Warning($"Missing variant '{qualityTier}' in buff group '{((Object)this).name}'", "X:\\Git\\RoR2\\ItemQualities\\ItemQualities\\Assets\\ItemQualities\\Scripts\\BuffQualityGroup.cs", "OnContentLoad", 161);
				}
				else
				{
					if (!Object.op_Implicit((Object)(object)buff.eliteDef))
					{
						buff.eliteDef = baseBuff.eliteDef;
					}
					if (!Object.op_Implicit((Object)(object)buff.startSfx))
					{
						buff.startSfx = baseBuff.startSfx;
					}
				}
			}
		}
	}
	public enum BuffQualityGroupIndex
	{
		Invalid = -1
	}
	public sealed class CharacterBodyExtraStatsTracker : NetworkBehaviour, IOnIncomingDamageServerReceiver, IOnTakeDamageServerReceiver
	{
		private NetworkIdentity _netIdentity;

		private CharacterBody _body;

		private CharacterModel _cachedCharacterModel;

		private bool _statsDirty;

		private TemporaryVisualEffect _qualityDeathMarkEffectInstance;

		private TemporaryVisualEffect _sprintArmorStrongEffectInstance;

		private TemporaryOverlayInstance _healCritBoostOverlay;

		public ItemQualityCounts LastExtraStatsOnLevelUpCounts;

		private const float BaseCrowbarMinHealthFraction = 0.9f;

		private float _crowbarMinHealthFraction = 0.9f;

		private float _executeBossHealthFraction;

		private float _stealthKitActivationThreshold = HealthComponent.lowHealthFraction;

		private float _airControlBonus = 1f;

		[SyncVar(hook = "hookSetIsPerformingQuailJump")]
		private bool _isPerformingQuailJump;

		[CompilerGenerated]
		private HitGroundDelegate m_OnHitGroundAuthority;

		private static int kCmdCmdOnHitGround;

		private static int kCmdCmdSetPerformingQuailJump;

		public float CrowbarMinHealthFraction
		{
			get
			{
				recalculateStatsIfNeeded();
				return _crowbarMinHealthFraction;
			}
		}

		public float ExecuteBossHealthFraction
		{
			get
			{
				recalculateStatsIfNeeded();
				return _executeBossHealthFraction;
			}
		}

		public float StealthKitActivationThreshold
		{
			get
			{
				recalculateStatsIfNeeded();
				return _stealthKitActivationThreshold;
			}
		}

		public float AirControlBonus
		{
			get
			{
				recalculateStatsIfNeeded();
				return _airControlBonus;
			}
		}

		public bool HasEffectiveAuthority => Util.HasEffectiveAuthority(_netIdentity);

		public bool IsPerformingQuailJump
		{
			get
			{
				return _isPerformingQuailJump;
			}
			private set
			{
				Network_isPerformingQuailJump = value;
				if (HasEffectiveAuthority && !NetworkServer.active)
				{
					CallCmdSetPerformingQuailJump(_isPerformingQuailJump);
				}
			}
		}

		public FixedTimeStamp LastQuailLandTimeAuthority { get; private set; } = FixedTimeStamp.positiveInfinity;


		public Vector3 LastQuailJumpVelocityAuthority { get; private set; } = Vector3.zero;


		public int QuailJumpComboAuthority { get; private set; }

		public bool HasHadAnyQualityDeathMarkDebuffServer { get; private set; }

		public float CurrentMedkitProcTimeSinceLastHit { get; set; }

		public int EliteKillCount { get; private set; }

		public CharacterMasterExtraStatsTracker MasterExtraStatsTracker { get; private set; }

		public bool Network_isPerformingQuailJump
		{
			get
			{
				return _isPerformingQuailJump;
			}
			[param: In]
			set
			{
				ref bool isPerformingQuailJump = ref _isPerformingQuailJump;
				if (NetworkServer.localClientActive && !((NetworkBehaviour)this).syncVarHookGuard)
				{
					((NetworkBehaviour)this).syncVarHookGuard = true;
					hookSetIsPerformingQuailJump(value);
					((NetworkBehaviour)this).syncVarHookGuard = false;
				}
				((NetworkBehaviour)this).SetSyncVar<bool>(value, ref isPerformingQuailJump, 1u);
			}
		}

		public event Action<DamageInfo> OnIncomingDamageServer;

		public event Action<DamageReport> OnTakeDamageServer;

		public event HitGroundDelegate OnHitGroundAuthority
		{
			[CompilerGenerated]
			add
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Expected O, but got Unknown
				HitGroundDelegate val = this.m_OnHitGroundAuthority;
				HitGroundDelegate val2;
				do
				{
					val2 = val;
					HitGroundDelegate value2 = (HitGroundDelegate)Delegate.Combine((Delegate?)(object)val2, (Delegate?)(object)value);
					val = Interlocked.CompareExchange(ref this.m_OnHitGroundAuthority, value2, val2);
				}
				while (val != val2);
			}
			[CompilerGenerated]
			remove
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Expected O, but got Unknown
				HitGroundDelegate val = this.m_OnHitGroundAuthority;
				HitGroundDelegate val2;
				do
				{
					val2 = val;
					HitGroundDelegate value2 = (HitGroundDelegate)Delegate.Remove((Delegate?)(object)val2, (Delegate?)(object)value);
					val = Interlocked.CompareExchange(ref this.m_OnHitGroundAuthority, value2, val2);
				}
				while (val != val2);
			}
		}

		public event Action<HitGroundInfo> OnHitGroundServer;

		public event Action<DamageReport> OnKilledOther;

		[SystemInitializer(new Type[] { typeof(BodyCatalog) })]
		private static void Init()
		{
			foreach (GameObject allBodyPrefab in BodyCatalog.allBodyPrefabs)
			{
				UnityObjectExtensions.EnsureComponent<CharacterBodyExtraStatsTracker>(allBodyPrefab);
			}
			GlobalEventManager.onCharacterDeathGlobal += onCharacterDeathGlobal;
		}

		private static void onCharacterDeathGlobal(DamageReport damageReport)
		{
			CharacterBodyExtraStatsTracker characterBodyExtraStatsTracker = default(CharacterBodyExtraStatsTracker);
			if (Object.op_Implicit((Object)(object)damageReport.attacker) && damageReport.attacker.TryGetComponent<CharacterBodyExtraStatsTracker>(ref characterBodyExtraStatsTracker))
			{
				characterBodyExtraStatsTracker.onKilledOther(damageReport);
			}
		}

		private void Awake()
		{
			_netIdentity = ((Component)this).GetComponent<NetworkIdentity>();
			_body = ((Component)this).GetComponent<CharacterBody>();
		}

		private void Start()
		{
			if (Object.op_Implicit((Object)(object)_body.master))
			{
				MasterExtraStatsTracker = ((Component)_body.master).GetComponent<CharacterMasterExtraStatsTracker>();
			}
		}

		private void OnEnable()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			recalculateExtraStats();
			_body.onInventoryChanged += onBodyInventoryChanged;
			if (Object.op_Implicit((Object)(object)_body.characterMotor))
			{
				_body.characterMotor.onHitGroundAuthority += new HitGroundDelegate(onHitGroundAuthority);
			}
			if (Object.op_Implicit((Object)(object)_body.modelLocator))
			{
				_body.modelLocator.onModelChanged += refreshModelReference;
			}
			refreshModelReference(Object.op_Implicit((Object)(object)_body.modelLocator) ? _body.modelLocator.modelTransform : null);
		}

		private void OnDisable()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			_body.onInventoryChanged -= onBodyInventoryChanged;
			if (Object.op_Implicit((Object)(object)_body.characterMotor))
			{
				_body.characterMotor.onHitGroundAuthority -= new HitGroundDelegate(onHitGroundAuthority);
			}
			if (Object.op_Implicit((Object)(object)_body.modelLocator))
			{
				_body.modelLocator.onModelChanged -= refreshModelReference;
			}
		}

		private void FixedUpdate()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			recalculateStatsIfNeeded();
			if (NetworkServer.active && !HasHadAnyQualityDeathMarkDebuffServer && DeathMark.HasAnyQualityDeathMarkDebuff(_body))
			{
				HasHadAnyQualityDeathMarkDebuffServer = true;
			}
			if (HasEffectiveAuthority && QuailJumpComboAuthority > 0 && !IsPerformingQuailJump)
			{
				FixedTimeStamp lastQuailLandTimeAuthority = LastQuailLandTimeAuthority;
				if (((FixedTimeStamp)(ref lastQuailLandTimeAuthority)).timeSince > 0.1f)
				{
					QuailJumpComboAuthority = 0;
				}
			}
			updateOverlays();
		}

		private void onBodyInventoryChanged()
		{
			MarkAllStatsDirty();
			if (NetworkServer.active)
			{
				setItemBehavior<MoveSpeedOnKillQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.MoveSpeedOnKill.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<AttackSpeedOnCritQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.AttackSpeedOnCrit.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<SprintOutOfCombatQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.SprintOutOfCombat.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<SprintArmorQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.SprintArmor.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<HealOnCritQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.HealOnCrit.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<EnergizedOnEquipmentUseItemBehavior>(ItemQualitiesContent.ItemQualityGroups.EnergizedOnEquipmentUse.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<BarrierOnOverHealQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.BarrierOnOverHeal.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<KillEliteFrenzyQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.KillEliteFrenzy.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<ArmorPlateQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.ArmorPlate.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<BoostAllStatsQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.BoostAllStats.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<IgniteOnKillQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.IgniteOnKill.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<MushroomVoidQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.MushroomVoid.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<FragileDamageBonusQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.FragileDamageBonus.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<MushroomQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.Mushroom.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<EquipmentMagazineQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.EquipmentMagazine.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<DuplicatorQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.Duplicator.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<FeatherQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.Feather.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<DronesDropDynamiteQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.DronesDropDynamite.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<DronesDropDynamiteDroneItemQualityItemBehavior>(_body.inventory.GetItemCountEffective(ItemQualitiesContent.Items.DronesDropDynamiteQualityDroneItem) > 0);
				setItemBehavior<ShieldBoosterQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.ShieldBooster.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<WarCryOnMultiKillQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.WarCryOnMultiKill.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
			}
			if (HasEffectiveAuthority)
			{
				setItemBehavior<SecondarySkillMagazineQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.SecondarySkillMagazine.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
				setItemBehavior<UtilitySkillMagazineQualityItemBehavior>(ItemQualitiesContent.ItemQualityGroups.UtilitySkillMagazine.GetItemCountsEffective(_body.inventory).TotalQualityCount > 0);
			}
			void setItemBehavior<T>(bool enabled) where T : Behaviour
			{
				T component = ((Component)this).GetComponent<T>();
				if ((Object.op_Implicit((Object)(object)component) && ((Behaviour)component).enabled) != enabled)
				{
					if (Object.op_Implicit((Object)(object)component))
					{
						((Behaviour)component).enabled = enabled;
					}
					else if (enabled)
					{
						((Component)this).gameObject.AddComponent<T>();
					}
				}
			}
		}

		private void refreshModelReference(Transform modelTransform)
		{
			_cachedCharacterModel = (Object.op_Implicit((Object)(object)modelTransform) ? ((Component)modelTransform).GetComponent<CharacterModel>() : null);
		}

		private void updateOverlays()
		{
			setOverlay(ref _healCritBoostOverlay, ItemQualitiesContent.Materials.HealCritBoost, _body.HasBuff(ItemQualitiesContent.Buffs.HealCritBoost));
			void setOverlay(ref TemporaryOverlayInstance overlayInstance, Material material, bool active)
			{
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Expected O, but got Unknown
				if (Object.op_Implicit((Object)(object)material))
				{
					if (!Object.op_Implicit((Object)(object)_cachedCharacterModel))
					{
						active = false;
					}
					if ((overlayInstance != null && (Object)(object)overlayInstance.assignedCharacterModel == (Object)(object)_cachedCharacterModel) != active)
					{
						if (overlayInstance != null)
						{
							overlayInstance.RemoveFromCharacterModel();
							overlayInstance = null;
						}
						if (active)
						{
							overlayInstance = new TemporaryOverlayInstance(((Component)this).gameObject)
							{
								duration = float.PositiveInfinity,
								destroyComponentOnEnd = true,
								originalMaterial = material
							};
							overlayInstance.AddToCharacterModel(_cachedCharacterModel);
						}
					}
				}
			}
		}

		public void MarkAllStatsDirty()
		{
			_statsDirty = true;
		}

		private void recalculateStatsIfNeeded()
		{
			if (_statsDirty)
			{
				_statsDirty = false;
				recalculateExtraStats();
			}
		}

		private void recalculateExtraStats()
		{
			ItemQualityCounts itemQualityCounts = default(ItemQualityCounts);
			ItemQualityCounts itemQualityCounts2 = default(ItemQualityCounts);
			ItemQualityCounts itemQualityCounts3 = default(ItemQualityCounts);
			ItemQualityCounts itemQualityCounts4 = default(ItemQualityCounts);
			if (Object.op_Implicit((Object)(object)_body) && Object.op_Implicit((Object)(object)_body.inventory))
			{
				itemQualityCounts = ItemQualitiesContent.ItemQualityGroups.Crowbar.GetItemCountsEffective(_body.inventory);
				itemQualityCounts2 = ItemQualitiesContent.ItemQualityGroups.ExecuteLowHealthElite.GetItemCountsEffective(_body.inventory);
				itemQualityCounts3 = ItemQualitiesContent.ItemQualityGroups.Phasing.GetItemCountsEffective(_body.inventory);
				itemQualityCounts4 = ItemQualitiesContent.ItemQualityGroups.JumpBoost.GetItemCountsEffective(_body.inventory);
			}
			float num = Util.ConvertAmplificationPercentageIntoReductionNormalized(0.25f * (float)itemQualityCounts.UncommonCount + 0.43f * (float)itemQualityCounts.RareCount + 1f * (float)itemQualityCounts.EpicCount + 3f * (float)itemQualityCounts.LegendaryCount);
			_crowbarMinHealthFraction = Mathf.Lerp(0.9f, 0.45f, num);
			_executeBossHealthFraction = Util.ConvertAmplificationPercentageIntoReductionNormalized(0.1f * (float)itemQualityCounts2.UncommonCount + 0.15f * (float)itemQualityCounts2.RareCount + 0.25f * (float)itemQualityCounts2.EpicCount + 0.4f * (float)itemQualityCounts2.LegendaryCount);
			float num2 = 1f;
			num2 *= Mathf.Pow(0.9f, (float)itemQualityCounts3.UncommonCount);
			num2 *= Mathf.Pow(0.75f, (float)itemQualityCounts3.RareCount);
			num2 *= Mathf.Pow(0.5f, (float)itemQualityCounts3.EpicCount);
			num2 *= Mathf.Pow(0.25f, (float)itemQualityCounts3.LegendaryCount);
			_stealthKitActivationThreshold = 1f - (1f - HealthComponent.lowHealthFraction) * num2;
			float num3 = 0f;
			if (IsPerformingQuailJump)
			{
				switch (itemQualityCounts4.HighestQuality)
				{
				case QualityTier.Uncommon:
					num3 += 0.1f;
					break;
				case QualityTier.Rare:
					num3 += 0.2f;
					break;
				case QualityTier.Epic:
					num3 += 0.3f;
					break;
				case QualityTier.Legendary:
					num3 += 0.5f;
					break;
				}
			}
			_airControlBonus = num3;
		}

		void IOnIncomingDamageServerReceiver.OnIncomingDamageServer(DamageInfo damageInfo)
		{
			if (Object.op_Implicit((Object)(object)MasterExtraStatsTracker))
			{
				MasterExtraStatsTracker.OnIncomingDamageServer(damageInfo);
			}
			this.OnIncomingDamageServer?.Invoke(damageInfo);
		}

		void IOnTakeDamageServerReceiver.OnTakeDamageServer(DamageReport damageReport)
		{
			this.OnTakeDamageServer?.Invoke(damageReport);
		}

		private void onKilledOther(DamageReport damageReport)
		{
			if (damageReport.victimIsElite)
			{
				EliteKillCount++;
			}
			this.OnKilledOther?.Invoke(damageReport);
		}

		private void onHitGroundAuthority(ref HitGroundInfo hitGroundInfo)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (IsPerformingQuailJump)
			{
				LastQuailLandTimeAuthority = FixedTimeStamp.now;
				IsPerformingQuailJump = false;
			}
			HitGroundDelegate obj = this.OnHitGroundAuthority;
			if (obj != null)
			{
				obj.Invoke(ref hitGroundInfo);
			}
			CallCmdOnHitGround(hitGroundInfo.velocity, hitGroundInfo.position, hitGroundInfo.isValidForEffect);
		}

		[Command]
		private void CmdOnHitGround(Vector3 velocity, Vector3 position, bool isValidForEffect)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			this.OnHitGroundServer?.Invoke(new HitGroundInfo
			{
				velocity = velocity,
				position = position,
				isValidForEffect = isValidForEffect,
				ownerBodyObject = ((Component)this).gameObject
			});
		}

		public void UpdateAllTemporaryVisualEffects()
		{
			_body.UpdateSingleTemporaryVisualEffect(ref _qualityDeathMarkEffectInstance, ItemQualitiesContent.Prefabs.DeathMarkQualityEffect, _body.radius, DeathMark.HasAnyQualityDeathMarkDebuff(_body), "");
			_body.UpdateSingleTemporaryVisualEffect(ref _sprintArmorStrongEffectInstance, SprintArmor.BucklerDefenseBigPrefab, _body.radius * 1.5f, _body.HasBuff(ItemQualitiesContent.Buffs.SprintArmorStrong), "");
		}

		public void OnQuailJumpAuthority()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			if (!HasEffectiveAuthority)
			{
				Log.Warning("Caller must have authority", "X:\\Git\\RoR2\\ItemQualities\\ItemQualities\\Assets\\ItemQualities\\Scripts\\CharacterBodyExtraStatsTracker.cs", "OnQuailJumpAuthorit