using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.CompilerServices;
using EntityStates;
using EntityStates.Railgunner.Scope;
using HG;
using RoR2.Audio;
using RoR2.Items;
using RoR2.Navigation;
using RoR2.Networking;
using RoR2.PostProcessing;
using RoR2.Projectile;
using RoR2.Skills;
using Unity;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.Serialization;

namespace RoR2;

[DisallowMultipleComponent]
[RequireComponent(typeof(TeamComponent))]
[RequireComponent(typeof(SkillLocator))]
public class CharacterBody : NetworkBehaviour, ILifeBehavior, IDisplayNameProvider, IOnTakeDamageServerReceiver, IOnKilledOtherServerReceiver
{
	public static class CommonAssets
	{
		public static SkillDef lunarUtilityReplacementSkillDef;

		public static SkillDef lunarPrimaryReplacementSkillDef;

		public static SkillDef lunarSecondaryReplacementSkillDef;

		public static SkillDef lunarSpecialReplacementSkillDef;

		public static NetworkSoundEventDef nullifiedBuffAppliedSound;

		public static NetworkSoundEventDef pulverizeBuildupBuffAppliedSound;

		public static NetworkSoundEventDef[] procCritAttackSpeedSounds;

		public static GameObject thornExplosionEffect;

		public static GameObject teleportOnLowHealthVFX;

		public static GameObject teleportOnLowHealthExplosion;

		public static GameObject teleportOnLowHealthExplosionNova;

		public static GameObject prayerBeadEffect;

		public static GameObject goldOnStageStartEffect;

		public static void Load()
		{
			LegacyResourcesAPI.LoadAsyncCallback("NetworkSoundEventDefs/nseNullifiedBuffApplied", delegate(NetworkSoundEventDef asset)
			{
				nullifiedBuffAppliedSound = asset;
			});
			LegacyResourcesAPI.LoadAsyncCallback("NetworkSoundEventDefs/nsePulverizeBuildupBuffApplied", delegate(NetworkSoundEventDef asset)
			{
				pulverizeBuildupBuffAppliedSound = asset;
			});
			procCritAttackSpeedSounds = new NetworkSoundEventDef[3];
			LegacyResourcesAPI.LoadAsyncCallback("NetworkSoundEventDefs/nseProcCritAttackSpeed1", delegate(NetworkSoundEventDef asset)
			{
				procCritAttackSpeedSounds[0] = asset;
			});
			LegacyResourcesAPI.LoadAsyncCallback("NetworkSoundEventDefs/nseProcCritAttackSpeed2", delegate(NetworkSoundEventDef asset)
			{
				procCritAttackSpeedSounds[1] = asset;
			});
			LegacyResourcesAPI.LoadAsyncCallback("NetworkSoundEventDefs/nseProcCritAttackSpeed3", delegate(NetworkSoundEventDef asset)
			{
				procCritAttackSpeedSounds[2] = asset;
			});
			AsyncOperationHandle<GameObject> asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Effects/NoxiousThornExplosion");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				thornExplosionEffect = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Effects/TeleportOnLowHealthVFX");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				teleportOnLowHealthVFX = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Effects/TeleportOnLowHealthExplosion");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				teleportOnLowHealthExplosion = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Effects/VagrantNovaExplosion");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				teleportOnLowHealthExplosionNova = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Effects/ExtraStatsOnLevelUpScrapEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				prayerBeadEffect = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/Effects/GoldOnStageStartCoinGain");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				goldOnStageStartEffect = x.Result;
			};
			SkillCatalog.skillsDefined.CallWhenAvailable(delegate
			{
				lunarUtilityReplacementSkillDef = SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName("LunarUtilityReplacement"));
				lunarPrimaryReplacementSkillDef = SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName("LunarPrimaryReplacement"));
				lunarSecondaryReplacementSkillDef = SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName("LunarSecondaryReplacement"));
				lunarSpecialReplacementSkillDef = SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName("LunarDetonatorSpecialReplacement"));
			});
		}
	}

	private class TimedBuff
	{
		public BuffIndex buffIndex;

		public float timer;
	}

	public delegate void JumpDelegate();

	[Flags]
	public enum BodyFlags : uint
	{
		None = 0u,
		IgnoreFallDamage = 1u,
		Mechanical = 2u,
		Masterless = 4u,
		ImmuneToGoo = 8u,
		ImmuneToExecutes = 0x10u,
		SprintAnyDirection = 0x20u,
		ResistantToAOE = 0x40u,
		HasBackstabPassive = 0x80u,
		HasBackstabImmunity = 0x100u,
		OverheatImmune = 0x200u,
		Void = 0x400u,
		ImmuneToVoidDeath = 0x800u,
		IgnoreItemUpdates = 0x1000u,
		Devotion = 0x2000u,
		IgnoreKnockback = 0x4000u,
		ImmuneToLava = 0x8000u
	}

	private struct ItemAvailability
	{
		public int helfireCount;

		public bool hasFireTrail;

		public bool hasAffixLunar;

		public bool hasAffixPoison;
	}

	[Serializable]
	public struct NetworkItemBehaviorData
	{
		public int intItemValue;

		public float floatValue;

		public ItemIndex itemIndex
		{
			get
			{
				return (ItemIndex)intItemValue;
			}
			set
			{
				intItemValue = (int)value;
			}
		}

		public NetworkItemBehaviorData(ItemIndex _index, float _floatValue)
		{
			intItemValue = (int)_index;
			floatValue = _floatValue;
		}

		public NetworkItemBehaviorData(int _index, float _floatVal)
		{
			intItemValue = _index;
			floatValue = _floatVal;
		}
	}

	public class ItemBehavior : MonoBehaviour
	{
		public CharacterBody body;

		public int stack;
	}

	public class AffixHauntedBehavior : ItemBehavior
	{
		private GameObject affixHauntedWard;

		private void FixedUpdate()
		{
			if (!NetworkServer.active)
			{
				return;
			}
			bool flag = stack > 0;
			if ((bool)affixHauntedWard != flag)
			{
				if (flag)
				{
					affixHauntedWard = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/AffixHauntedWard"));
					affixHauntedWard.GetComponent<TeamFilter>().teamIndex = body.teamComponent.teamIndex;
					affixHauntedWard.GetComponent<BuffWard>().Networkradius = 30f + body.radius;
					affixHauntedWard.GetComponent<NetworkedBodyAttachment>().AttachToGameObjectAndSpawn(body.gameObject);
				}
				else
				{
					UnityEngine.Object.Destroy(affixHauntedWard);
					affixHauntedWard = null;
				}
			}
		}

		private void OnDisable()
		{
			if ((bool)affixHauntedWard)
			{
				UnityEngine.Object.Destroy(affixHauntedWard);
			}
		}
	}

	public class QuestVolatileBatteryBehaviorServer : ItemBehavior
	{
		private NetworkedBodyAttachment attachment;

		private void Start()
		{
			attachment = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/QuestVolatileBatteryAttachment")).GetComponent<NetworkedBodyAttachment>();
			attachment.AttachToGameObjectAndSpawn(body.gameObject);
		}

		private void OnDestroy()
		{
			if ((bool)attachment)
			{
				UnityEngine.Object.Destroy(attachment.gameObject);
				attachment = null;
			}
		}
	}

	public class TimeBubbleItemBehaviorServer : ItemBehavior
	{
		private void OnDestroy()
		{
			if ((bool)body.timeBubbleWardInstance)
			{
				UnityEngine.Object.Destroy(body.timeBubbleWardInstance);
			}
		}
	}

	public class ElementalRingsBehavior : ItemBehavior
	{
		private void OnDisable()
		{
			if ((bool)body)
			{
				if (body.HasBuff(RoR2Content.Buffs.ElementalRingsReady))
				{
					body.RemoveBuff(RoR2Content.Buffs.ElementalRingsReady);
				}
				if (body.HasBuff(RoR2Content.Buffs.ElementalRingsCooldown))
				{
					body.RemoveBuff(RoR2Content.Buffs.ElementalRingsCooldown);
				}
			}
		}

		private void FixedUpdate()
		{
			bool flag = body.HasBuff(RoR2Content.Buffs.ElementalRingsCooldown);
			bool flag2 = body.HasBuff(RoR2Content.Buffs.ElementalRingsReady);
			if (!flag && !flag2)
			{
				body.AddBuff(RoR2Content.Buffs.ElementalRingsReady);
			}
			if (flag2 && flag)
			{
				body.RemoveBuff(RoR2Content.Buffs.ElementalRingsReady);
			}
		}
	}

	public class AffixEchoBehavior : ItemBehavior
	{
		private DeployableMinionSpawner echoSpawner1;

		private DeployableMinionSpawner echoSpawner2;

		private CharacterSpawnCard spawnCard;

		private List<CharacterMaster> spawnedEchoes = new List<CharacterMaster>();

		private void FixedUpdate()
		{
			spawnCard.nodeGraphType = (body.isFlying ? MapNodeGroup.GraphType.Air : MapNodeGroup.GraphType.Ground);
		}

		private void Awake()
		{
			base.enabled = false;
		}

		private void OnEnable()
		{
			MasterCatalog.MasterIndex masterIndex = MasterCatalog.FindAiMasterIndexForBody(body.bodyIndex);
			spawnCard = ScriptableObject.CreateInstance<CharacterSpawnCard>();
			spawnCard.prefab = MasterCatalog.GetMasterPrefab(masterIndex);
			spawnCard.inventoryToCopy = body.inventory;
			spawnCard.equipmentToGrant = new EquipmentDef[1];
			spawnCard.itemsToGrant = new ItemCountPair[1]
			{
				new ItemCountPair
				{
					itemDef = RoR2Content.Items.SummonedEcho,
					count = 1
				}
			};
			CreateSpawners();
		}

		private void OnDisable()
		{
			UnityEngine.Object.Destroy(spawnCard);
			spawnCard = null;
			for (int num = spawnedEchoes.Count - 1; num >= 0; num--)
			{
				if ((bool)spawnedEchoes[num])
				{
					spawnedEchoes[num].TrueKill();
				}
			}
			DestroySpawners();
		}

		private void CreateSpawners()
		{
			Xoroshiro128Plus rng = new Xoroshiro128Plus(Run.instance.seed ^ (ulong)GetInstanceID());
			CreateSpawner(ref echoSpawner1, DeployableSlot.RoboBallRedBuddy, spawnCard);
			CreateSpawner(ref echoSpawner2, DeployableSlot.RoboBallGreenBuddy, spawnCard);
			void CreateSpawner(ref DeployableMinionSpawner buddySpawner, DeployableSlot deployableSlot, SpawnCard spawnCard)
			{
				buddySpawner = new DeployableMinionSpawner(body.master, deployableSlot, rng)
				{
					respawnInterval = 30f,
					spawnCard = spawnCard
				};
				buddySpawner.onMinionSpawnedServer += OnMinionSpawnedServer;
			}
		}

		private void DestroySpawners()
		{
			echoSpawner1?.Dispose();
			echoSpawner1 = null;
			echoSpawner2?.Dispose();
			echoSpawner2 = null;
		}

		private void OnMinionSpawnedServer(SpawnCard.SpawnResult spawnResult)
		{
			GameObject spawnedInstance = spawnResult.spawnedInstance;
			if (!spawnedInstance)
			{
				return;
			}
			CharacterMaster spawnedMaster = spawnedInstance.GetComponent<CharacterMaster>();
			if ((bool)spawnedMaster)
			{
				spawnedEchoes.Add(spawnedMaster);
				OnDestroyCallback.AddCallback(spawnedMaster.gameObject, delegate
				{
					spawnedEchoes.Remove(spawnedMaster);
				});
			}
		}
	}

	private static class AssetReferences
	{
		public static GameObject engiShieldTempEffectPrefab;

		public static GameObject bucklerShieldTempEffectPrefab;

		public static GameObject slowDownTimeTempEffectPrefab;

		public static GameObject crippleEffectPrefab;

		public static GameObject tonicBuffEffectPrefab;

		public static GameObject weakTempEffectPrefab;

		public static GameObject energizedTempEffectPrefab;

		public static GameObject barrierTempEffectPrefab;

		public static GameObject nullifyStack1EffectPrefab;

		public static GameObject nullifyStack2EffectPrefab;

		public static GameObject nullifyStack3EffectPrefab;

		public static GameObject regenBoostEffectPrefab;

		public static GameObject elephantDefenseEffectPrefab;

		public static GameObject healingDisabledEffectPrefab;

		public static GameObject noCooldownEffectPrefab;

		public static GameObject doppelgangerEffectPrefab;

		public static GameObject deathmarkEffectPrefab;

		public static GameObject crocoRegenEffectPrefab;

		public static GameObject mercExposeEffectPrefab;

		public static GameObject lifestealOnHitEffectPrefab;

		public static GameObject teamWarCryEffectPrefab;

		public static GameObject randomDamageEffectPrefab;

		public static GameObject lunarGolemShieldEffectPrefab;

		public static GameObject warbannerEffectPrefab;

		public static GameObject teslaFieldEffectPrefab;

		public static GameObject lunarSecondaryRootEffectPrefab;

		public static GameObject lunarDetonatorEffectPrefab;

		public static GameObject fruitingEffectPrefab;

		public static GameObject mushroomVoidTempEffectPrefab;

		public static GameObject bearVoidTempEffectPrefab;

		public static GameObject outOfCombatArmorEffectPrefab;

		public static GameObject voidFogMildEffectPrefab;

		public static GameObject voidFogStrongEffectPrefab;

		public static GameObject voidJailerSlowEffectPrefab;

		public static GameObject voidRaidcrabWardWipeFogEffectPrefab;

		public static GameObject aurelioniteBlessingEffectInstance;

		public static GameObject permanentDebuffEffectPrefab;

		public static void Resolve()
		{
			AsyncOperationHandle<GameObject> asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/EngiShield");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				engiShieldTempEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/BucklerDefense");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				bucklerShieldTempEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/SlowDownTime");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				slowDownTimeTempEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/CrippleEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				crippleEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/TonicBuffEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				tonicBuffEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/WeakEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				weakTempEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/EnergizedEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				energizedTempEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/BarrierEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				barrierTempEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/RegenBoostEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				regenBoostEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/ElephantDefense");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				elephantDefenseEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/HealingDisabledEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				healingDisabledEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/NoCooldownEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				noCooldownEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/DoppelgangerEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				doppelgangerEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/NullifyStack1Effect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				nullifyStack1EffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/NullifyStack2Effect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				nullifyStack2EffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/NullifyStack3Effect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				nullifyStack3EffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/DeathMarkEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				deathmarkEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/CrocoRegenEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				crocoRegenEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/MercExposeEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				mercExposeEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/LifeStealOnHitAura");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				lifestealOnHitEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/TeamWarCryAura");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				teamWarCryEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/LunarDefense");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				lunarGolemShieldEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/RandomDamageBuffEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				randomDamageEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/WarbannerBuffEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				warbannerEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/TeslaFieldBuffEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				teslaFieldEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/LunarSecondaryRootEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				lunarSecondaryRootEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/LunarDetonatorEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				lunarDetonatorEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/FruitingEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				fruitingEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/MushroomVoidEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				mushroomVoidTempEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/BearVoidEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				bearVoidTempEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/VoidFogMildEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				voidFogMildEffectPrefab = x.Result;
			};
			asyncOperationHandle = LegacyResourcesAPI.LoadAsync<GameObject>("Prefabs/TemporaryVisualEffects/VoidFogStrongEffect");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				voidFogStrongEffectPrefab = x.Result;
			};
			asyncOperationHandle = Addressables.LoadAssetAsync<GameObject>("RoR2/DLC1/VoidRaidCrab/VoidRaidCrabWardWipeFogEffect.prefab");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				voidRaidcrabWardWipeFogEffectPrefab = x.Result;
			};
			asyncOperationHandle = Addressables.LoadAssetAsync<GameObject>("RoR2/DLC1/OutOfCombatArmor/OutOfCombatArmorEffect.prefab");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				outOfCombatArmorEffectPrefab = x.Result;
			};
			asyncOperationHandle = Addressables.LoadAssetAsync<GameObject>("RoR2/DLC1/VoidJailer/VoidJailerTetherDebuff.prefab");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				voidJailerSlowEffectPrefab = x.Result;
			};
			asyncOperationHandle = Addressables.LoadAssetAsync<GameObject>("RoR2/DLC2/Elites/EliteAurelionite/AffixAurelioniteArmorBubble.prefab");
			asyncOperationHandle.Completed += delegate(AsyncOperationHandle<GameObject> x)
			{
				aurelioniteBlessingEffectInstance = x.Result;
			};
		}
	}

	private class ConstructTurretMessage : MessageBase
	{
		public GameObject builder;

		public Vector3 position;

		public Quaternion rotation;

		public MasterCatalog.NetworkMasterIndex turretMasterIndex;

		public override void Serialize(NetworkWriter writer)
		{
			writer.Write(builder);
			writer.Write(position);
			writer.Write(rotation);
			GeneratedNetworkCode._WriteNetworkMasterIndex_MasterCatalog(writer, turretMasterIndex);
		}

		public override void Deserialize(NetworkReader reader)
		{
			builder = reader.ReadGameObject();
			position = reader.ReadVector3();
			rotation = reader.ReadQuaternion();
			turretMasterIndex = GeneratedNetworkCode._ReadNetworkMasterIndex_MasterCatalog(reader);
		}
	}

	private class DelayedDamageInfo
	{
		public DamageInfo halfDamage = new DamageInfo();

		public float timeUntilDamage = 3f;
	}

	public class TeleportOnLowHealthBehavior : ItemBehavior
	{
		private CharacterBody characterBody;

		private bool hasActivated;

		private bool hasItem;

		private bool hasBuff;

		private bool hasCooldown;

		private void Start()
		{
			if (!hasActivated)
			{
				characterBody = GetComponent<CharacterBody>();
				characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealth);
				characterBody.RemoveOldestTimedBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown);
				characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown);
				characterBody.AddBuff(DLC2Content.Buffs.TeleportOnLowHealth);
				characterBody.hasTeleported = false;
				hasActivated = true;
			}
		}

		private void Update()
		{
			hasItem = characterBody.inventory.GetItemCount(DLC2Content.Items.TeleportOnLowHealth) > 0;
			hasBuff = characterBody.HasBuff(DLC2Content.Buffs.TeleportOnLowHealth);
			hasCooldown = characterBody.HasBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown);
			if (!hasItem)
			{
				if (hasBuff)
				{
					characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealth);
				}
				if (hasCooldown)
				{
					characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown);
				}
			}
			else if (!hasBuff && !hasCooldown && characterBody.hasTeleported)
			{
				characterBody.AddBuff(DLC2Content.Buffs.TeleportOnLowHealth);
				characterBody.hasTeleported = false;
			}
		}

		private void OnDisable()
		{
			characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealth);
			characterBody.RemoveOldestTimedBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown);
			characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown);
		}
	}

	public class DelayedDamageBehavior : ItemBehavior
	{
		private CharacterBody characterBody;

		private bool hasActivated;

		private bool hasItem;

		private bool hasBuff;

		private bool hasCooldown;

		private void Start()
		{
			if (!hasActivated)
			{
				characterBody = GetComponent<CharacterBody>();
				hasActivated = true;
			}
		}

		private void Update()
		{
			hasItem = characterBody.inventory.GetItemCount(DLC2Content.Items.DelayedDamage) > 0;
			hasBuff = characterBody.HasBuff(DLC2Content.Buffs.DelayedDamageBuff);
			hasCooldown = characterBody.HasBuff(DLC2Content.Buffs.DelayedDamageBuff);
			if (!hasItem)
			{
				if (hasBuff)
				{
					characterBody.RemoveBuff(DLC2Content.Buffs.DelayedDamageBuff);
					characterBody.RemoveOldestTimedBuff(DLC2Content.Buffs.DelayedDamageBuff);
				}
				if (hasCooldown)
				{
					characterBody.RemoveBuff(DLC2Content.Buffs.DelayedDamageBuff);
					characterBody.RemoveOldestTimedBuff(DLC2Content.Buffs.DelayedDamageBuff);
					characterBody.RemoveBuff(DLC2Content.Buffs.DelayedDamageDebuff);
				}
			}
		}
	}

	public class MeteorAttackOnHighDamageBehavior : ItemBehavior
	{
		private CharacterBody characterBody;

		private bool hasActivated;

		private void FixedUpdate()
		{
			if (!hasActivated)
			{
				characterBody = GetComponent<CharacterBody>();
				hasActivated = true;
			}
			if (characterBody.runicLensMeteorReady)
			{
				characterBody.runicLensStartTime = Run.instance.time;
				if (characterBody.runicLensStartTime >= characterBody.runicLensImpactTime && characterBody.runicLensMeteorReady)
				{
					characterBody.detonateRunicLensMeteor();
					characterBody.runicLensMeteorReady = false;
				}
			}
		}
	}

	[Serializable]
	public class CharacterBodyUnityEvent : UnityEvent<CharacterBody>
	{
	}

	[HideInInspector]
	[Tooltip("This is assigned to the prefab automatically by BodyCatalog at runtime. Do not set this value manually.")]
	public BodyIndex bodyIndex = BodyIndex.None;

	public bool CharacterIsVisible;

	[Tooltip("How much the combat director paid for this character. If this enemy is culled, then we refund the combat director for the cost it paid to spawn us.")]
	public float cost = -1f;

	public bool dontCull;

	[Tooltip("The baseline importance for this character. 0 is standard, elites get a +2 modifier, bosses get +10, players get +5000. Characters of low importance are culled in some circumstances.")]
	public int BaseImportance;

	[Tooltip("The dynamically calculated level of importance for this enemy.")]
	public int Importance = -1;

	public bool inLava;

	[Tooltip("The language token to use as the base name of this character.")]
	public string baseNameToken;

	public string subtitleNameToken;

	private BuffIndex[] activeBuffsList;

	private int activeBuffsListCount;

	private int[] buffs;

	private int eliteBuffCount;

	private List<TimedBuff> timedBuffs = new List<TimedBuff>();

	[NonSerialized]
	public int pendingTonicAfflictionCount;

	public JumpDelegate onJump;

	private int previousMultiKillBuffCount;

	private GameObject warCryEffectInstance;

	[EnumMask(typeof(BodyFlags))]
	public BodyFlags bodyFlags;

	private NetworkInstanceId masterObjectId;

	private GameObject _masterObject;

	private CharacterMaster _master;

	private bool linkedToMaster;

	private bool disablingHurtBoxes;

	private EquipmentIndex previousEquipmentIndex = EquipmentIndex.None;

	private new Transform transform;

	private SfxLocator sfxLocator;

	public float lavaCooldown = 0.2f;

	private float lavaTimer;

	private ItemAvailability itemAvailability;

	private static List<CharacterBody> instancesList;

	public static readonly ReadOnlyCollection<CharacterBody> readOnlyInstancesList;

	private bool _isSprinting;

	private const float outOfCombatDelay = 5f;

	private const float outOfDangerDelay = 7f;

	private float outOfCombatStopwatch;

	private float outOfDangerStopwatch;

	private bool _outOfDanger = true;

	private Vector3 previousPosition;

	private const float notMovingWait = 1f;

	private float notMovingStopwatch;

	public bool rootMotionInMainState;

	public float mainRootSpeed;

	public float baseMaxHealth;

	public float baseRegen;

	public float baseMaxShield;

	public float baseMoveSpeed;

	public float baseAcceleration;

	public float baseJumpPower;

	public float baseDamage;

	public float baseAttackSpeed;

	public float baseCrit;

	public float baseArmor;

	public float baseVisionDistance = float.PositiveInfinity;

	public int baseJumpCount = 1;

	public float sprintingSpeedMultiplier = 1.45f;

	public bool autoCalculateLevelStats;

	public float levelMaxHealth;

	public float levelRegen;

	public float levelMaxShield;

	public float levelMoveSpeed;

	public float levelJumpPower;

	public float levelDamage;

	public float levelAttackSpeed;

	public float levelCrit;

	public float levelArmor;

	private float m_surfaceSpeedBoost;

	private bool statsDirty;

	private int currentHealthLevel;

	private int oldHealthLevel;

	private float damageFromRecalculateStats;

	private int numberOfKills;

	private bool canCleanInventory = true;

	public int extraSecondaryFromSkill;

	public int extraSpecialFromSkill;

	private GameObject lowerHealthHigherDamageSteam;

	[HideInInspector]
	public LowerHealthHigherDamageEffectUpdater lowerHealthHigherDamageEffectUpdater;

	private bool boostAllStatsTimerStarted;

	private bool boostAllStatsCoolDownTimerStarted;

	private float boostAllStatsTimer;

	private float boostAllStatsTriggerTimer = 5f;

	private float boostAllStatsCoolDownTriggerTimer = 10f;

	private float boostAllStatsCoolDownStartTimer;

	private float boostAllStatsCoolDownTimer;

	private float boostAllStatsStartTimer;

	private float boostAllStatsTriggerChance;

	public bool canBoostAllStats;

	private float boostAllStatsDefaultTriggerChance = 0.25f;

	private float boostAllStatsTriggerIncrease = 0.1f;

	private float boostAllStatsMultiplier = 0.2f;

	private int extraStatsOnLevelUpCountModifier;

	[HideInInspector]
	public IncreaseDamageOnMultiKillItemDisplayUpdater increaseDamageOnMultiKillItemDisplayUpdater;

	private bool lowerPricedChestsActive;

	private bool canPurchaseLoweredPricedChests;

	public bool allSkillsDisabled;

	private ScreenDamageCalculatorDisabledSkills screenDamageSkillsDisabled;

	private int oldComboMeter;

	public bool isTeleporting;

	public int solitudeLevelCount;

	private float aimTimer;

	private const uint masterDirtyBit = 1u;

	private const uint buffsDirtyBit = 2u;

	private const uint outOfCombatBit = 4u;

	private const uint outOfDangerBit = 8u;

	private const uint sprintingBit = 16u;

	private const uint allDirtyBits = 31u;

	public Action<NetworkItemBehaviorData> OnNetworkItemBehaviorUpdate;

	private HelfireController helfireController;

	private float helfireLifetime;

	private DamageTrail fireTrail;

	public bool wasLucky;

	private const float poisonballAngle = 25f;

	private const float poisonballDamageCoefficient = 1f;

	private const float poisonballRefreshTime = 6f;

	private float poisonballTimer;

	private const float lunarMissileDamageCoefficient = 0.3f;

	private const float lunarMissileRefreshTime = 10f;

	private const float lunarMissileDelayBetweenShots = 0.1f;

	private float lunarMissileRechargeTimer = 10f;

	private float lunarMissileTimerBetweenShots;

	private int remainingMissilesToFire;

	private GameObject lunarMissilePrefab;

	private GameObject timeBubbleWardInstance;

	private TemporaryVisualEffect engiShieldTempEffectInstance;

	private TemporaryVisualEffect bucklerShieldTempEffectInstance;

	private TemporaryVisualEffect slowDownTimeTempEffectInstance;

	private TemporaryVisualEffect crippleEffectInstance;

	private TemporaryVisualEffect tonicBuffEffectInstance;

	private TemporaryVisualEffect weakTempEffectInstance;

	private TemporaryVisualEffect energizedTempEffectInstance;

	private TemporaryVisualEffect barrierTempEffectInstance;

	private TemporaryVisualEffect nullifyStack1EffectInstance;

	private TemporaryVisualEffect nullifyStack2EffectInstance;

	private TemporaryVisualEffect nullifyStack3EffectInstance;

	private TemporaryVisualEffect regenBoostEffectInstance;

	private TemporaryVisualEffect elephantDefenseEffectInstance;

	private TemporaryVisualEffect healingDisabledEffectInstance;

	private TemporaryVisualEffect noCooldownEffectInstance;

	private TemporaryVisualEffect doppelgangerEffectInstance;

	private TemporaryVisualEffect deathmarkEffectInstance;

	private TemporaryVisualEffect crocoRegenEffectInstance;

	private TemporaryVisualEffect mercExposeEffectInstance;

	private TemporaryVisualEffect lifestealOnHitEffectInstance;

	private TemporaryVisualEffect teamWarCryEffectInstance;

	private TemporaryVisualEffect randomDamageEffectInstance;

	private TemporaryVisualEffect lunarGolemShieldEffectInstance;

	private TemporaryVisualEffect warbannerEffectInstance;

	private TemporaryVisualEffect teslaFieldEffectInstance;

	private TemporaryVisualEffect lunarSecondaryRootEffectInstance;

	private TemporaryVisualEffect lunarDetonatorEffectInstance;

	private TemporaryVisualEffect fruitingEffectInstance;

	private TemporaryVisualEffect mushroomVoidTempEffectInstance;

	private TemporaryVisualEffect bearVoidTempEffectInstance;

	private TemporaryVisualEffect outOfCombatArmorEffectInstance;

	private TemporaryVisualEffect voidFogMildEffectInstance;

	private TemporaryVisualEffect voidFogStrongEffectInstance;

	private TemporaryVisualEffect voidJailerSlowEffectInstance;

	private TemporaryVisualEffect voidRaidcrabWardWipeFogEffectInstance;

	private TemporaryVisualEffect aurelioniteBlessingEffectInstance;

	[Tooltip("How long it takes for spread bloom to reset from full.")]
	public float spreadBloomDecayTime = 0.45f;

	[Tooltip("The spread bloom interpretation curve.")]
	public AnimationCurve spreadBloomCurve;

	private float spreadBloomInternal;

	[FormerlySerializedAs("crosshairPrefab")]
	[SerializeField]
	[Tooltip("The crosshair prefab used for this body.")]
	private GameObject _defaultCrosshairPrefab;

	[HideInInspector]
	public bool hideCrosshair;

	private const float multiKillMaxInterval = 1f;

	private float multiKillTimer;

	private const int multiKillThresholdForWarcry = 4;

	private const float increasedDamageMultiKillMaxInterval = 5f;

	private float increasedDamageKillTimer;

	private int oldKillcount;

	private const int multiKillThresholdForIncreasedDamage = 5;

	private int secondarySkillStacks;

	[HideInInspector]
	public IncreasePrimaryDamageEffectUpdater increasePrimaryDamageEffectUpdater;

	private float delayedDamageRefreshTime = 10f;

	private float secondHalfOfDamageTime = 3f;

	private int oldDelayedDamageCount;

	private bool halfDamageReady;

	private float halfDamageTimer;

	public bool protectFromOneShot;

	private DamageInfo secondHalfOfDamage;

	private List<DelayedDamageInfo> incomingDamageList = new List<DelayedDamageInfo>();

	public bool hasTeleported;

	private Vector3 runicLensPosition;

	private EffectData runicLensEffectData = new EffectData();

	private DamageInfo runicLensDamageInfo = new DamageInfo();

	private float runicLensDamage;

	private float runicLensBlastForce;

	private float runicLensBlastRadius;

	private float runicLensStartTime;

	private float runicLensImpactTime;

	public bool runicLensMeteorReady;

	private bool hasStackableDebuff;

	private bool tamperedHeartActive;

	private float tamperedHeartRegenBonus;

	private float tamperedHeartMSpeedBonus;

	private float tamperedHeartDamageBonus;

	private float tamperedHeartAttackSpeedBonus;

	private float tamperedHeartArmorBonus;

	[Tooltip("The child transform to be used as the aiming origin.")]
	public Transform aimOriginTransform;

	[Tooltip("The hull size to use when pathfinding for this object.")]
	public HullClassification hullClassification;

	[Tooltip("The icon displayed for ally healthbars")]
	public Texture portraitIcon;

	[Tooltip("The main color of the body. Currently only used in the logbook.")]
	public Color bodyColor = Color.clear;

	[Tooltip("By default, players and enemies are assigned to either PlayerBody or EnemyBody, based on team. But some enemies (Gups) want a specific layer - this will skip that assignment.")]
	public bool doNotReassignToTeamBasedCollisionLayer;

	[FormerlySerializedAs("isBoss")]
	[Tooltip("Whether or not this is a boss for dropping items on death.")]
	public bool isChampion;

	public VehicleSeat currentVehicle;

	[Tooltip("The pod prefab to use for handling this character's first-time spawn animation.")]
	public GameObject preferredPodPrefab;

	[Tooltip("The preferred state to use for handling the character's first-time spawn animation. Only used with no preferred pod prefab.")]
	public SerializableEntityStateType preferredInitialStateType = new SerializableEntityStateType(typeof(Uninitialized));

	public uint skinIndex;

	public string customKillTotalStatName;

	public Transform overrideCoreTransform;

	private static int kCmdCmdAddTimedBuff;

	private static int kCmdCmdSetInLava;

	private static int kCmdCmdUpdateSprint;

	private static int kCmdCmdOnSkillActivated;

	private static int kCmdCmdTransmitItemBehavior;

	private static int kRpcRpcTransmitItemBehavior;

	private static int kCmdCmdSpawnDelayedDamageEffect;

	private static int kRpcRpcTeleportCharacterToSafety;

	private static int kRpcRpcBark;

	private static int kCmdCmdRequestVehicleEjection;

	private static int kRpcRpcUsePreferredInitialStateType;

	public CharacterMaster master
	{
		get
		{
			if (!masterObject)
			{
				return null;
			}
			return _master;
		}
	}

	public Inventory inventory { get; private set; }

	public bool isPlayerControlled { get; private set; }

	public float executeEliteHealthFraction { get; private set; }

	public GameObject masterObject
	{
		get
		{
			if (!_masterObject)
			{
				if (NetworkServer.active)
				{
					_masterObject = NetworkServer.FindLocalObject(masterObjectId);
				}
				else if (NetworkClient.active)
				{
					_masterObject = ClientScene.FindLocalObject(masterObjectId);
				}
				_master = (_masterObject ? _masterObject.GetComponent<CharacterMaster>() : null);
				if ((bool)_master)
				{
					PlayerCharacterMasterController component = _masterObject.GetComponent<PlayerCharacterMasterController>();
					isPlayerControlled = component;
					if ((bool)inventory)
					{
						inventory.onInventoryChanged -= OnInventoryChanged;
					}
					inventory = _master.inventory;
					if ((bool)inventory)
					{
						inventory.onInventoryChanged += OnInventoryChanged;
						OnInventoryChanged();
					}
					statsDirty = true;
				}
			}
			return _masterObject;
		}
		set
		{
			masterObjectId = value.GetComponent<NetworkIdentity>().netId;
			statsDirty = true;
		}
	}

	public Rigidbody rigidbody { get; private set; }

	public NetworkIdentity networkIdentity { get; private set; }

	public CharacterMotor characterMotor { get; private set; }

	public CharacterDirection characterDirection { get; private set; }

	public TeamComponent teamComponent { get; private set; }

	public HealthComponent healthComponent { get; private set; }

	public EquipmentSlot equipmentSlot { get; private set; }

	public InputBankTest inputBank { get; private set; }

	public SkillLocator skillLocator { get; private set; }

	public ModelLocator modelLocator { get; private set; }

	public HurtBoxGroup hurtBoxGroup { get; private set; }

	public HurtBox mainHurtBox { get; private set; }

	public Transform coreTransform { get; private set; }

	public bool hasEffectiveAuthority { get; private set; }

	public bool isSprinting
	{
		get
		{
			return _isSprinting;
		}
		set
		{
			if (_isSprinting != value)
			{
				_isSprinting = value;
				RecalculateStats();
				if (value)
				{
					OnSprintStart();
				}
				else
				{
					OnSprintStop();
				}
				if (NetworkServer.active)
				{
					SetDirtyBit(16u);
				}
				else if (hasEffectiveAuthority)
				{
					CallCmdUpdateSprint(value);
				}
			}
		}
	}

	public bool outOfCombat { get; private set; } = true;


	public bool outOfDanger
	{
		get
		{
			return _outOfDanger;
		}
		private set
		{
			if (_outOfDanger != value)
			{
				_outOfDanger = value;
				OnOutOfDangerChanged();
			}
		}
	}

	public float experience { get; private set; }

	public float level { get; private set; }

	public float maxHealth { get; private set; }

	public float maxBarrier { get; private set; }

	public float barrierDecayRate { get; private set; }

	public float regen { get; private set; }

	public float maxShield { get; private set; }

	public float moveSpeed { get; private set; }

	public float acceleration { get; private set; }

	public float surfaceSpeedBoost
	{
		get
		{
			return m_surfaceSpeedBoost;
		}
		set
		{
			if (!Mathf.Approximately(m_surfaceSpeedBoost, value))
			{
				m_surfaceSpeedBoost = value;
				RecalculateStats();
			}
		}
	}

	public float jumpPower { get; private set; }

	public int maxJumpCount { get; private set; }

	public float maxJumpHeight { get; private set; }

	public float damage { get; private set; }

	public float attackSpeed { get; private set; }

	public float crit { get; private set; }

	public float critMultiplier { get; private set; }

	public float bleedChance { get; private set; }

	public float armor { get; private set; }

	public float visionDistance { get; private set; }

	public float critHeal { get; private set; }

	public float cursePenalty { get; private set; }

	public bool hasOneShotProtection { get; private set; }

	public bool isGlass { get; private set; }

	public float oneShotProtectionFraction { get; private set; }

	public bool canPerformBackstab { get; private set; }

	public bool canReceiveBackstab { get; private set; }

	public float maxBonusHealth { get; private set; }

	public bool shouldAim
	{
		get
		{
			if (aimTimer > 0f)
			{
				return !isSprinting;
			}
			return false;
		}
	}

	public int killCountServer { get; private set; }

	public float bestFitRadius => Mathf.Max(radius, characterMotor ? characterMotor.capsuleHeight : 1f);

	public float bestFitActualRadius => Mathf.Max(radius, characterMotor ? (characterMotor.capsuleHeight * 0.5f) : 1f);

	public bool hasCloakBuff
	{
		get
		{
			if (!HasBuff(RoR2Content.Buffs.Cloak))
			{
				return HasBuff(RoR2Content.Buffs.AffixHauntedRecipient);
			}
			return true;
		}
	}

	public float spreadBloomAngle => spreadBloomCurve.Evaluate(spreadBloomInternal);

	public GameObject defaultCrosshairPrefab => _defaultCrosshairPrefab;

	public int multiKillCount { get; private set; }

	public int increasedDamageKillCount { get; private set; }

	public int increasedDamageKillCountBuff { get; private set; }

	public float luminousShotDamage { get; private set; }

	public bool luminousShotReady { get; private set; }

	public Vector3 corePosition
	{
		get
		{
			if (!coreTransform)
			{
				return transform.position;
			}
			return coreTransform.position;
		}
	}

	public Vector3 footPosition
	{
		get
		{
			Vector3 position = transform.position;
			if ((bool)characterMotor)
			{
				position.y -= characterMotor.capsuleHeight * 0.5f;
			}
			return position;
		}
	}

	public float radius { get; private set; }

	public Vector3 aimOrigin
	{
		get
		{
			if (!aimOriginTransform)
			{
				return corePosition;
			}
			return aimOriginTransform.position;
		}
	}

	public bool isElite { get; private set; }

	public bool isBoss
	{
		get
		{
			if ((bool)master)
			{
				return master.isBoss;
			}
			return false;
		}
	}

	public bool isFlying
	{
		get
		{
			if ((bool)characterMotor)
			{
				return characterMotor.isFlying;
			}
			return true;
		}
	}

	public Run.FixedTimeStamp localStartTime { get; private set; } = Run.FixedTimeStamp.positiveInfinity;


	public bool isEquipmentActivationAllowed
	{
		get
		{
			if ((bool)currentVehicle)
			{
				return currentVehicle.isEquipmentActivationAllowed;
			}
			return true;
		}
	}

	public event Action onInventoryChanged;

	public event Action<GenericSkill> onSkillActivatedServer;

	public event Action<GenericSkill> onSkillActivatedAuthority;

	public static event Action<CharacterBody> onBodyAwakeGlobal;

	public static event Action<CharacterBody> onBodyDestroyGlobal;

	public static event Action<CharacterBody> onBodyStartGlobal;

	public static event Action<CharacterBody> onBodyInventoryChangedGlobal;

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public CharacterBody GetBody()
	{
		return this;
	}

	public void DebugDrawLine(Vector3 start, Vector3 end, Color color)
	{
		Debug.DrawLine(start, end, color, 5f);
	}

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

	public string GetDisplayName()
	{
		return Language.GetString(baseNameToken);
	}

	public string GetSubtitle()
	{
		return Language.GetString(subtitleNameToken);
	}

	public string GetUserName()
	{
		string text = "";
		if ((bool)master)
		{
			PlayerCharacterMasterController component = master.GetComponent<PlayerCharacterMasterController>();
			if ((bool)component)
			{
				text = component.GetDisplayName();
			}
		}
		if (string.IsNullOrEmpty(text))
		{
			text = GetDisplayName();
		}
		return text;
	}

	public string GetColoredUserName()
	{
		Color32 color = new Color32(127, 127, 127, byte.MaxValue);
		string text = null;
		if ((bool)master)
		{
			PlayerCharacterMasterController component = master.GetComponent<PlayerCharacterMasterController>();
			if ((bool)component)
			{
				GameObject networkUserObject = component.networkUserObject;
				if ((bool)networkUserObject)
				{
					NetworkUser component2 = networkUserObject.GetComponent<NetworkUser>();
					if ((bool)component2)
					{
						color = component2.userColor;
						text = component2.userName;
					}
				}
			}
		}
		if (text == null)
		{
			text = GetDisplayName();
		}
		return Util.GenerateColoredString(text, color);
	}

	[Server]
	private void WriteBuffs(NetworkWriter writer)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::WriteBuffs(UnityEngine.Networking.NetworkWriter)' called on client");
			return;
		}
		writer.Write((byte)activeBuffsListCount);
		for (int i = 0; i < activeBuffsListCount; i++)
		{
			BuffIndex buffIndex = activeBuffsList[i];
			BuffDef buffDef = BuffCatalog.GetBuffDef(buffIndex);
			writer.WriteBuffIndex(buffIndex);
			if (buffDef.canStack)
			{
				writer.WritePackedUInt32((uint)buffs[(int)buffIndex]);
			}
		}
	}

	[Client]
	private void ReadBuffs(NetworkReader reader)
	{
		if (!NetworkClient.active)
		{
			Debug.LogWarning("[Client] function 'System.Void RoR2.CharacterBody::ReadBuffs(UnityEngine.Networking.NetworkReader)' called on server");
			return;
		}
		if (activeBuffsList == null)
		{
			Debug.LogError("Trying to ReadBuffs, but our activeBuffsList is null");
			return;
		}
		int activeBuffsIndexToCheck = 0;
		int num = reader.ReadByte();
		BuffIndex buffIndex = BuffIndex.None;
		for (int i = 0; i < num; i++)
		{
			BuffIndex buffIndex2 = reader.ReadBuffIndex();
			BuffDef buffDef = BuffCatalog.GetBuffDef(buffIndex2);
			if (buffDef != null)
			{
				int num2 = 1;
				if (buffDef.canStack)
				{
					num2 = (int)reader.ReadPackedUInt32();
				}
				if (num2 > 0 && !NetworkServer.active)
				{
					ZeroBuffIndexRange(buffIndex + 1, buffIndex2);
					SetBuffCount(buffIndex2, num2);
				}
				buffIndex = buffIndex2;
			}
			else
			{
				Debug.LogErrorFormat("No BuffDef for index {0}. body={1}, netID={2}", buffIndex2, base.gameObject, base.netId);
			}
		}
		if (!NetworkServer.active)
		{
			ZeroBuffIndexRange(buffIndex + 1, (BuffIndex)BuffCatalog.buffCount);
		}
		void ZeroBuffIndexRange(BuffIndex start, BuffIndex end)
		{
			while (activeBuffsIndexToCheck < activeBuffsListCount)
			{
				BuffIndex buffIndex3 = activeBuffsList[activeBuffsIndexToCheck];
				if (end <= buffIndex3)
				{
					break;
				}
				int num3;
				if (start <= buffIndex3)
				{
					SetBuffCount(buffIndex3, 0);
					num3 = activeBuffsIndexToCheck - 1;
					activeBuffsIndexToCheck = num3;
				}
				num3 = activeBuffsIndexToCheck + 1;
				activeBuffsIndexToCheck = num3;
			}
		}
	}

	[Server]
	public void AddBuff(BuffIndex buffType)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddBuff(RoR2.BuffIndex)' called on client");
		}
		else if (buffType != BuffIndex.None)
		{
			SetBuffCount(buffType, buffs[(int)buffType] + 1);
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	[Server]
	public void AddBuff(BuffDef buffDef)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddBuff(RoR2.BuffDef)' called on client");
		}
		else
		{
			AddBuff(buffDef?.buffIndex ?? BuffIndex.None);
		}
	}

	[Server]
	public void RemoveBuff(BuffIndex buffType)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::RemoveBuff(RoR2.BuffIndex)' called on client");
		}
		else
		{
			if (buffType == BuffIndex.None)
			{
				return;
			}
			SetBuffCount(buffType, buffs[(int)buffType] - 1);
			if (buffType == RoR2Content.Buffs.MedkitHeal.buffIndex)
			{
				if (GetBuffCount(RoR2Content.Buffs.MedkitHeal.buffIndex) == 0)
				{
					int itemCount = inventory.GetItemCount(RoR2Content.Items.Medkit);
					float num = 20f;
					float num2 = maxHealth * 0.05f * (float)itemCount;
					healthComponent.Heal(num + num2, default(ProcChainMask));
					EffectData effectData = new EffectData
					{
						origin = transform.position
					};
					effectData.SetNetworkedObjectReference(base.gameObject);
					EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/MedkitHealEffect"), effectData, transmit: true);
				}
			}
			else if (buffType == RoR2Content.Buffs.TonicBuff.buffIndex)
			{
				if ((bool)inventory && GetBuffCount(RoR2Content.Buffs.TonicBuff) == 0 && pendingTonicAfflictionCount > 0)
				{
					inventory.GiveItem(RoR2Content.Items.TonicAffliction, pendingTonicAfflictionCount);
					PickupIndex pickupIndex = PickupCatalog.FindPickupIndex(RoR2Content.Items.TonicAffliction.itemIndex);
					GenericPickupController.SendPickupMessage(master, pickupIndex);
					pendingTonicAfflictionCount = 0;
				}
			}
			else if (buffType == DLC2Content.Buffs.SoulCost.buffIndex)
			{
				cursePenalty -= 0.1f * (float)GetBuffCount(DLC2Content.Buffs.SoulCost);
			}
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	[Server]
	public void RemoveBuff(BuffDef buffDef)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::RemoveBuff(RoR2.BuffDef)' called on client");
		}
		else
		{
			RemoveBuff(buffDef?.buffIndex ?? BuffIndex.None);
		}
	}

	public void SetBuffCount(BuffIndex buffType, int newCount)
	{
		newCount = Mathf.Max(newCount, 0);
		ref int reference = ref buffs[(int)buffType];
		if (newCount == reference)
		{
			return;
		}
		int num = reference;
		reference = newCount;
		BuffDef buffDef = BuffCatalog.GetBuffDef(buffType);
		bool flag = true;
		if (!buffDef.canStack)
		{
			flag = num == 0 != (newCount == 0);
		}
		if (flag)
		{
			if (newCount == 0)
			{
				ArrayUtils.ArrayRemoveAt(activeBuffsList, ref activeBuffsListCount, Array.IndexOf(activeBuffsList, buffType));
				OnBuffFinalStackLost(buffDef);
			}
			else if (num == 0)
			{
				int i;
				for (i = 0; i < activeBuffsListCount && buffType >= activeBuffsList[i]; i++)
				{
				}
				ArrayUtils.ArrayInsert(ref activeBuffsList, ref activeBuffsListCount, i, in buffType);
				OnBuffFirstStackGained(buffDef);
			}
			if (NetworkServer.active)
			{
				SetDirtyBit(2u);
			}
		}
		statsDirty = true;
		if (NetworkClient.active)
		{
			OnClientBuffsChanged();
		}
		UpdateItemAvailability();
	}

	private void OnBuffFirstStackGained(BuffDef buffDef)
	{
		if (buffDef.isElite)
		{
			eliteBuffCount++;
		}
		if (buffDef == RoR2Content.Buffs.Intangible)
		{
			UpdateHurtBoxesEnabled();
		}
		else if (buffDef == RoR2Content.Buffs.WarCryBuff)
		{
			if (HasBuff(RoR2Content.Buffs.TeamWarCry))
			{
				ClearTimedBuffs(RoR2Content.Buffs.TeamWarCry);
			}
		}
		else if (buffDef == RoR2Content.Buffs.TeamWarCry)
		{
			if (HasBuff(RoR2Content.Buffs.WarCryBuff))
			{
				ClearTimedBuffs(RoR2Content.Buffs.WarCryBuff);
			}
		}
		else if (buffDef == RoR2Content.Buffs.AffixEcho && NetworkServer.active)
		{
			AddItemBehavior<AffixEchoBehavior>(1);
		}
	}

	private void OnBuffFinalStackLost(BuffDef buffDef)
	{
		if (buffDef.isElite)
		{
			eliteBuffCount--;
		}
		if (buffDef.buffIndex == RoR2Content.Buffs.Intangible.buffIndex)
		{
			UpdateHurtBoxesEnabled();
		}
		else if (buffDef == RoR2Content.Buffs.AffixEcho && NetworkServer.active)
		{
			AddItemBehavior<AffixEchoBehavior>(0);
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public int GetBuffCount(BuffIndex buffType)
	{
		return ArrayUtils.GetSafe(buffs, (int)buffType);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public int GetBuffCount(BuffDef buffDef)
	{
		return GetBuffCount(buffDef?.buffIndex ?? BuffIndex.None);
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public bool HasBuff(BuffIndex buffType)
	{
		return GetBuffCount(buffType) > 0;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	public bool HasBuff(BuffDef buffDef)
	{
		return HasBuff(buffDef?.buffIndex ?? BuffIndex.None);
	}

	public void AddTimedBuffAuthority(BuffIndex buffType, float duration)
	{
		if (NetworkServer.active)
		{
			AddTimedBuff(buffType, duration);
		}
		else
		{
			CallCmdAddTimedBuff(buffType, duration);
		}
	}

	[Command]
	public void CmdAddTimedBuff(BuffIndex buffType, float duration)
	{
		AddTimedBuff(buffType, duration);
	}

	[Server]
	public void AddTimedBuff(BuffDef buffDef, float duration, int maxStacks)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddTimedBuff(RoR2.BuffDef,System.Single,System.Int32)' called on client");
		}
		else
		{
			if (ImmuneToDebuffBehavior.OverrideDebuff(buffDef, this))
			{
				return;
			}
			if (GetBuffCount(buffDef) < maxStacks)
			{
				AddTimedBuff(buffDef, duration);
				return;
			}
			int num = -1;
			float num2 = duration;
			for (int i = 0; i < timedBuffs.Count; i++)
			{
				if (timedBuffs[i].buffIndex == buffDef.buffIndex && timedBuffs[i].timer < num2)
				{
					num = i;
					num2 = timedBuffs[i].timer;
				}
			}
			if (num >= 0)
			{
				timedBuffs[num].timer = duration;
			}
		}
	}

	[Server]
	public void AddTimedBuff(BuffDef buffDef, float duration)
	{
		BuffIndex buffType;
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddTimedBuff(RoR2.BuffDef,System.Single)' called on client");
		}
		else
		{
			if ((object)buffDef == null || ImmuneToDebuffBehavior.OverrideDebuff(buffDef, this))
			{
				return;
			}
			buffType = buffDef.buffIndex;
			if (buffType == BuffIndex.None)
			{
				return;
			}
			if (buffDef == RoR2Content.Buffs.AttackSpeedOnCrit)
			{
				int num = (inventory ? inventory.GetItemCount(RoR2Content.Items.AttackSpeedOnCrit) : 0);
				int num2 = 1 + num * 2;
				int num3 = 0;
				int num4 = -1;
				float num5 = 999f;
				for (int i = 0; i < timedBuffs.Count; i++)
				{
					if (timedBuffs[i].buffIndex == buffType)
					{
						num3++;
						if (timedBuffs[i].timer < num5)
						{
							num4 = i;
							num5 = timedBuffs[i].timer;
						}
					}
				}
				if (num3 < num2)
				{
					timedBuffs.Add(new TimedBuff
					{
						buffIndex = buffType,
						timer = duration
					});
					AddBuff(buffType);
					ChildLocator component = modelLocator.modelTransform.GetComponent<ChildLocator>();
					if ((bool)component)
					{
						Transform obj = component.FindChild("HandL");
						Transform transform = component.FindChild("HandR");
						GameObject effectPrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/WolfProcEffect");
						if ((bool)obj)
						{
							EffectManager.SimpleMuzzleFlash(effectPrefab, base.gameObject, "HandL", transmit: true);
						}
						if ((bool)transform)
						{
							EffectManager.SimpleMuzzleFlash(effectPrefab, base.gameObject, "HandR", transmit: true);
						}
					}
				}
				else if (num4 > -1)
				{
					timedBuffs[num4].timer = duration;
				}
				EntitySoundManager.EmitSoundServer(CommonAssets.procCritAttackSpeedSounds[Mathf.Min(CommonAssets.procCritAttackSpeedSounds.Length - 1, num3)].index, networkIdentity);
			}
			else if (buffDef == RoR2Content.Buffs.BeetleJuice)
			{
				if (RefreshStacks() < 10)
				{
					timedBuffs.Add(new TimedBuff
					{
						buffIndex = buffType,
						timer = duration
					});
					AddBuff(buffType);
				}
			}
			else if (buffDef == RoR2Content.Buffs.NullifyStack)
			{
				if (HasBuff(RoR2Content.Buffs.Nullified))
				{
					return;
				}
				int num6 = 0;
				for (int j = 0; j < timedBuffs.Count; j++)
				{
					if (timedBuffs[j].buffIndex == buffType)
					{
						num6++;
						if (timedBuffs[j].timer < duration)
						{
							timedBuffs[j].timer = duration;
						}
					}
				}
				if (num6 < 2)
				{
					timedBuffs.Add(new TimedBuff
					{
						buffIndex = buffType,
						timer = duration
					});
					AddBuff(buffType);
				}
				else
				{
					ClearTimedBuffs(RoR2Content.Buffs.NullifyStack.buffIndex);
					AddTimedBuff(RoR2Content.Buffs.Nullified.buffIndex, 3f);
				}
			}
			else if (buffDef == RoR2Content.Buffs.AffixHauntedRecipient)
			{
				if (!HasBuff(RoR2Content.Buffs.AffixHaunted))
				{
					DefaultBehavior();
				}
			}
			else if (buffDef == DLC2Content.Buffs.EliteBeadCorruption)
			{
				if (!HasBuff(DLC2Content.Buffs.EliteBead))
				{
					DefaultBehavior();
				}
			}
			else if (buffDef == RoR2Content.Buffs.LunarDetonationCharge)
			{
				RefreshStacks();
				DefaultBehavior();
			}
			else if (buffDef == RoR2Content.Buffs.Overheat)
			{
				RefreshStacks();
				DefaultBehavior();
			}
			else if (buffDef == DLC2Content.Buffs.BoostAllStatsBuff)
			{
				RefreshStacks();
				DefaultBehavior();
			}
			else
			{
				DefaultBehavior();
			}
		}
		void DefaultBehavior()
		{
			bool flag = false;
			if (!buffDef.canStack)
			{
				for (int k = 0; k < timedBuffs.Count; k++)
				{
					if (timedBuffs[k].buffIndex == buffType)
					{
						flag = true;
						timedBuffs[k].timer = Mathf.Max(timedBuffs[k].timer, duration);
						break;
					}
				}
			}
			if (!flag)
			{
				timedBuffs.Add(new TimedBuff
				{
					buffIndex = buffType,
					timer = duration
				});
				AddBuff(buffType);
			}
			if ((bool)buffDef.startSfx)
			{
				EntitySoundManager.EmitSoundServer(buffDef.startSfx.index, networkIdentity);
			}
		}
		int RefreshStacks()
		{
			int num7 = 0;
			for (int l = 0; l < timedBuffs.Count; l++)
			{
				TimedBuff timedBuff = timedBuffs[l];
				if (timedBuff.buffIndex == buffType)
				{
					num7++;
					if (timedBuff.timer < duration)
					{
						timedBuff.timer = duration;
					}
				}
			}
			return num7;
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	[Server]
	public void AddTimedBuff(BuffIndex buffIndex, float duration)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddTimedBuff(RoR2.BuffIndex,System.Single)' called on client");
		}
		else
		{
			AddTimedBuff(BuffCatalog.GetBuffDef(buffIndex), duration);
		}
	}

	[Server]
	public void ClearTimedBuffs(BuffIndex buffType)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::ClearTimedBuffs(RoR2.BuffIndex)' called on client");
			return;
		}
		for (int num = timedBuffs.Count - 1; num >= 0; num--)
		{
			TimedBuff timedBuff = timedBuffs[num];
			if (timedBuff.buffIndex == buffType)
			{
				timedBuffs.RemoveAt(num);
				RemoveBuff(timedBuff.buffIndex);
			}
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	[Server]
	public void ClearTimedBuffs(BuffDef buffDef)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::ClearTimedBuffs(RoR2.BuffDef)' called on client");
		}
		else
		{
			ClearTimedBuffs(buffDef?.buffIndex ?? BuffIndex.None);
		}
	}

	[Server]
	public void RemoveOldestTimedBuff(BuffIndex buffType)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::RemoveOldestTimedBuff(RoR2.BuffIndex)' called on client");
			return;
		}
		float num = float.NegativeInfinity;
		int num2 = -1;
		for (int num3 = timedBuffs.Count - 1; num3 >= 0; num3--)
		{
			TimedBuff timedBuff = timedBuffs[num3];
			if (timedBuff.buffIndex == buffType && num < timedBuff.timer)
			{
				num = timedBuff.timer;
				num2 = num3;
			}
		}
		if (num2 > 0)
		{
			timedBuffs.RemoveAt(num2);
			RemoveBuff(buffType);
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	[Server]
	public void RemoveOldestTimedBuff(BuffDef buffDef)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::RemoveOldestTimedBuff(RoR2.BuffDef)' called on client");
		}
		else
		{
			RemoveOldestTimedBuff(buffDef?.buffIndex ?? BuffIndex.None);
		}
	}

	[Server]
	private void UpdateBuffs(float deltaTime)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::UpdateBuffs(System.Single)' called on client");
			return;
		}
		for (int num = timedBuffs.Count - 1; num >= 0; num--)
		{
			TimedBuff timedBuff = timedBuffs[num];
			timedBuff.timer -= deltaTime;
			if (timedBuff.timer <= 0f)
			{
				timedBuffs.RemoveAt(num);
				RemoveBuff(timedBuff.buffIndex);
			}
		}
	}

	[Client]
	private void OnClientBuffsChanged()
	{
		if (!NetworkClient.active)
		{
			Debug.LogWarning("[Client] function 'System.Void RoR2.CharacterBody::OnClientBuffsChanged()' called on server");
			return;
		}
		bool num = HasBuff(RoR2Content.Buffs.WarCryBuff);
		if (!num && (bool)warCryEffectInstance)
		{
			UnityEngine.Object.Destroy(warCryEffectInstance);
		}
		if (num && !warCryEffectInstance)
		{
			Transform transform = (mainHurtBox ? mainHurtBox.transform : this.transform);
			if ((bool)transform)
			{
				warCryEffectInstance = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/WarCryEffect"), transform.position, Quaternion.identity, transform);
			}
		}
		if ((bool)inventory && inventory.GetItemCount(DLC2Content.Items.IncreaseDamageOnMultiKill) > 0)
		{
			int buffCount = GetBuffCount(DLC2Content.Buffs.IncreaseDamageBuff);
			if ((bool)increaseDamageOnMultiKillItemDisplayUpdater)
			{
				increaseDamageOnMultiKillItemDisplayUpdater.UpdateKillCounterText(buffCount);
			}
			if (previousMultiKillBuffCount < buffCount)
			{
				Util.PlaySound("Play_item_proc_increaseDamageMultiKill", base.gameObject);
			}
			previousMultiKillBuffCount = buffCount;
		}
	}

	public NetworkInstanceId GetMasterObjectId()
	{
		return masterObjectId;
	}

	private void GetSelectedCharacterType()
	{
	}

	private void UpdateHurtBoxesEnabled()
	{
		bool flag = ((bool)inventory && inventory.GetItemCount(RoR2Content.Items.Ghost) > 0) || HasBuff(RoR2Content.Buffs.Intangible);
		if (flag == disablingHurtBoxes)
		{
			return;
		}
		if ((bool)hurtBoxGroup)
		{
			if (flag)
			{
				HurtBoxGroup obj = hurtBoxGroup;
				int hurtBoxesDeactivatorCounter = obj.hurtBoxesDeactivatorCounter + 1;
				obj.hurtBoxesDeactivatorCounter = hurtBoxesDeactivatorCounter;
			}
			else
			{
				HurtBoxGroup obj2 = hurtBoxGroup;
				int hurtBoxesDeactivatorCounter = obj2.hurtBoxesDeactivatorCounter - 1;
				obj2.hurtBoxesDeactivatorCounter = hurtBoxesDeactivatorCounter;
			}
		}
		disablingHurtBoxes = flag;
	}

	private void OnInventoryChanged()
	{
		EquipmentIndex currentEquipmentIndex = inventory.currentEquipmentIndex;
		if (currentEquipmentIndex != previousEquipmentIndex)
		{
			EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(previousEquipmentIndex);
			EquipmentDef equipmentDef2 = EquipmentCatalog.GetEquipmentDef(currentEquipmentIndex);
			if (equipmentDef != null)
			{
				OnEquipmentLost(equipmentDef);
			}
			if (equipmentDef2 != null)
			{
				OnEquipmentGained(equipmentDef2);
			}
			previousEquipmentIndex = currentEquipmentIndex;
		}
		statsDirty = true;
		UpdateHurtBoxesEnabled();
		AddItemBehavior<AffixHauntedBehavior>(HasBuff(RoR2Content.Buffs.AffixHaunted) ? 1 : 0);
		AddItemBehavior<AffixEarthBehavior>(HasBuff(DLC1Content.Buffs.EliteEarth) ? 1 : 0);
		AddItemBehavior<AffixVoidBehavior>(HasBuff(DLC1Content.Buffs.EliteVoid) ? 1 : 0);
		AddItemBehavior<AffixBeadBehavior>(HasBuff(DLC2Content.Buffs.EliteBead) ? 1 : 0);
		AddItemBehavior<AffixAurelioniteBehavior>(HasBuff(DLC2Content.Buffs.EliteAurelionite) ? 1 : 0);
		if (NetworkServer.active)
		{
			AddItemBehavior<QuestVolatileBatteryBehaviorServer>((inventory.GetEquipment(inventory.activeEquipmentSlot).equipmentDef == RoR2Content.Equipment.QuestVolatileBattery) ? 1 : 0);
			AddItemBehavior<ElementalRingsBehavior>(inventory.GetItemCount(RoR2Content.Items.IceRing) + inventory.GetItemCount(RoR2Content.Items.FireRing));
			AddItemBehavior<ElementalRingVoidBehavior>(inventory.GetItemCount(DLC1Content.Items.ElementalRingVoid));
			AddItemBehavior<OutOfCombatArmorBehavior>(inventory.GetItemCount(DLC1Content.Items.OutOfCombatArmor));
			AddItemBehavior<PrimarySkillShurikenBehavior>(inventory.GetItemCount(DLC1Content.Items.PrimarySkillShuriken));
			AddItemBehavior<MushroomVoidBehavior>(inventory.GetItemCount(DLC1Content.Items.MushroomVoid));
			AddItemBehavior<BearVoidBehavior>(inventory.GetItemCount(DLC1Content.Items.BearVoid));
			AddItemBehavior<LunarSunBehavior>(inventory.GetItemCount(DLC1Content.Items.LunarSun));
			AddItemBehavior<VoidMegaCrabItemBehavior>(inventory.GetItemCount(DLC1Content.Items.VoidMegaCrabItem));
			AddItemBehavior<DroneWeaponsBehavior>(inventory.GetItemCount(DLC1Content.Items.DroneWeapons));
			AddItemBehavior<DroneWeaponsBoostBehavior>(inventory.GetItemCount(DLC1Content.Items.DroneWeaponsBoost));
			AddItemBehavior<MeteorAttackOnHighDamageBehavior>(inventory.GetItemCount(DLC2Content.Items.MeteorAttackOnHighDamage));
			AddItemBehavior<TeleportOnLowHealthBehavior>(inventory.GetItemCount(DLC2Content.Items.TeleportOnLowHealth));
		}
		executeEliteHealthFraction = Util.ConvertAmplificationPercentageIntoReductionPercentage(13f * (float)inventory.GetItemCount(RoR2Content.Items.ExecuteLowHealthElite)) / 100f;
		if ((bool)skillLocator)
		{
			ReplaceSkillIfItemPresent(skillLocator.primary, RoR2Content.Items.LunarPrimaryReplacement.itemIndex, CommonAssets.lunarPrimaryReplacementSkillDef);
			ReplaceSkillIfItemPresent(skillLocator.secondary, RoR2Content.Items.LunarSecondaryReplacement.itemIndex, CommonAssets.lunarSecondaryReplacementSkillDef);
			ReplaceSkillIfItemPresent(skillLocator.special, RoR2Content.Items.LunarSpecialReplacement.itemIndex, CommonAssets.lunarSpecialReplacementSkillDef);
			ReplaceSkillIfItemPresent(skillLocator.utility, RoR2Content.Items.LunarUtilityReplacement.itemIndex, CommonAssets.lunarUtilityReplacementSkillDef);
		}
		this.onInventoryChanged?.Invoke();
		CharacterBody.onBodyInventoryChangedGlobal?.Invoke(this);
		UpdateItemAvailability();
	}

	private void ReplaceSkillIfItemPresent(GenericSkill skill, ItemIndex itemIndex, SkillDef skillDef)
	{
		if ((bool)skill)
		{
			if (inventory.GetItemCount(itemIndex) > 0 && (bool)skillDef)
			{
				skill.SetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Replacement);
			}
			else
			{
				skill.UnsetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Replacement);
			}
		}
	}

	private void OnEquipmentLost(EquipmentDef equipmentDef)
	{
		if (NetworkServer.active && (object)equipmentDef.passiveBuffDef != null)
		{
			RemoveBuff(equipmentDef.passiveBuffDef);
		}
	}

	private void OnEquipmentGained(EquipmentDef equipmentDef)
	{
		if (NetworkServer.active && (object)equipmentDef.passiveBuffDef != null)
		{
			AddBuff(equipmentDef.passiveBuffDef);
		}
	}

	private void UpdateMasterLink()
	{
		if (!linkedToMaster && (bool)master && (bool)master)
		{
			master.OnBodyStart(this);
			linkedToMaster = true;
			skinIndex = master.loadout.bodyLoadoutManager.GetSkinIndex(bodyIndex);
		}
	}

	public static void Init()
	{
		AssetReferences.Resolve();
	}

	private void Awake()
	{
		transform = base.transform;
		rigidbody = GetComponent<Rigidbody>();
		networkIdentity = GetComponent<NetworkIdentity>();
		teamComponent = GetComponent<TeamComponent>();
		healthComponent = GetComponent<HealthComponent>();
		equipmentSlot = GetComponent<EquipmentSlot>();
		skillLocator = GetComponent<SkillLocator>();
		modelLocator = GetComponent<ModelLocator>();
		characterMotor = GetComponent<CharacterMotor>();
		characterDirection = GetComponent<CharacterDirection>();
		inputBank = GetComponent<InputBankTest>();
		sfxLocator = GetComponent<SfxLocator>();
		activeBuffsList = BuffCatalog.GetPerBuffBuffer<BuffIndex>();
		buffs = BuffCatalog.GetPerBuffBuffer<int>();
		if ((bool)modelLocator)
		{
			modelLocator.onModelChanged += OnModelChanged;
			OnModelChanged(modelLocator.modelTransform);
		}
		radius = 1f;
		CapsuleCollider component = GetComponent<CapsuleCollider>();
		if ((bool)component)
		{
			radius = component.radius;
		}
		else
		{
			SphereCollider component2 = GetComponent<SphereCollider>();
			if ((bool)component2)
			{
				radius = component2.radius;
			}
		}
		try
		{
			CharacterBody.onBodyAwakeGlobal?.Invoke(this);
		}
		catch (Exception message)
		{
			Debug.LogError(message);
		}
	}

	private void OnModelChanged(Transform modelTransform)
	{
		hurtBoxGroup = null;
		mainHurtBox = null;
		coreTransform = transform;
		if ((bool)modelTransform)
		{
			hurtBoxGroup = modelTransform.GetComponent<HurtBoxGroup>();
			if ((bool)hurtBoxGroup)
			{
				mainHurtBox = hurtBoxGroup.mainHurtBox;
				if ((bool)mainHurtBox)
				{
					coreTransform = mainHurtBox.transform;
				}
			}
		}
		if ((bool)overrideCoreTransform)
		{
			coreTransform = overrideCoreTransform;
		}
	}

	private void Start()
	{
		UpdateAuthority();
		localStartTime = Run.FixedTimeStamp.now;
		bool num = (bodyFlags & BodyFlags.Masterless) != 0;
		outOfCombatStopwatch = float.PositiveInfinity;
		outOfDangerStopwatch = float.PositiveInfinity;
		notMovingStopwatch = 0f;
		if (NetworkServer.active)
		{
			outOfCombat = true;
			outOfDanger = true;
		}
		RecalculateStats();
		UpdateMasterLink();
		if (num)
		{
			healthComponent.Networkhealth = maxHealth;
		}
		if ((bool)sfxLocator && healthComponent.alive)
		{
			Util.PlaySound(sfxLocator.aliveLoopStart, base.gameObject);
		}
		if (!doNotReassignToTeamBasedCollisionLayer)
		{
			base.gameObject.layer = LayerIndex.GetAppropriateLayerForTeam(teamComponent.teamIndex);
			if (characterMotor != null)
			{
				characterMotor.Motor.RebuildCollidableLayers();
			}
		}
		CharacterBody.onBodyStartGlobal?.Invoke(this);
		if ((bool)master && NetworkServer.active)
		{
			if (master.devotionInventoryPrefab == null)
			{
				_ = master.isDevotedMinion;
			}
			if (isPlayerControlled && (bool)master.devotionInventoryPrefab)
			{
				_ = master.devotionInventoryPrefab != null;
			}
			int num2 = ((inventory != null) ? inventory.GetItemCount(DLC2Content.Items.GoldOnStageStart) : 0);
			if (num2 > 0)
			{
				TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.GoldOnStageStart.itemIndex, 0f));
				uint difficultyScaledCost = (uint)Run.instance.GetDifficultyScaledCost((int)(50f + level * 1.5f * (float)num2));
				master.GiveMoney(difficultyScaledCost);
			}
		}
	}

	public void Update()
	{
		float deltaTime = Time.deltaTime;
		outOfCombatStopwatch += deltaTime;
		outOfDangerStopwatch += deltaTime;
		aimTimer = Mathf.Max(aimTimer - deltaTime, 0f);
		UpdateOutOfCombatAndDanger();
		UpdateSpreadBloom(deltaTime);
		DoItemUpdates(deltaTime);
		UpdateNotMoving(deltaTime);
		HandleLavaDamage(deltaTime);
	}

	private void UpdateNotMoving(float deltaTime)
	{
		if (NetworkServer.active)
		{
			Vector3 position = transform.position;
			float num = 0.1f * deltaTime;
			if ((position - previousPosition).sqrMagnitude <= num * num)
			{
				notMovingStopwatch += deltaTime;
			}
			else
			{
				notMovingStopwatch = 0f;
			}
			previousPosition = position;
		}
	}

	private void DoItemUpdates(float deltaTime)
	{
		if ((bodyFlags & BodyFlags.IgnoreItemUpdates) == 0)
		{
			if (NetworkServer.active)
			{
				UpdateMultiKill(deltaTime);
				UpdateHelfire(deltaTime);
				UpdateAffixPoison(deltaTime);
				UpdateAffixLunar(deltaTime);
				UpdateLowerHealthHigherDamage();
				UpdateDelayedDamage(deltaTime);
				UpdateSecondHalfOfDamage(deltaTime);
			}
			UpdateFireTrail();
		}
	}

	private void UpdateOutOfCombatAndDanger()
	{
		bool active = NetworkServer.active;
		bool flag = outOfCombat;
		bool flag2 = flag;
		if (active || hasEffectiveAuthority)
		{
			flag2 = outOfCombatStopwatch >= 5f;
			if (outOfCombat != flag2)
			{
				if (NetworkServer.active)
				{
					SetDirtyBit(4u);
				}
				outOfCombat = flag2;
				statsDirty = true;
			}
		}
		if (active)
		{
			bool flag3 = outOfDangerStopwatch >= 7f;
			bool flag4 = outOfDanger;
			bool flag5 = flag && flag4;
			bool num = flag2 && flag3;
			if (outOfDanger != flag3)
			{
				SetDirtyBit(8u);
				outOfDanger = flag3;
				statsDirty = true;
			}
			if (num && !flag5)
			{
				OnOutOfCombatAndDangerServer();
			}
		}
	}

	[Command]
	public void CmdSetInLava(bool b)
	{
		inLava = b;
	}

	public void SetInLava(bool b)
	{
		if (inLava != b)
		{
			if (!NetworkServer.active && base.hasAuthority)
			{
				CallCmdSetInLava(b);
			}
			inLava = b;
		}
	}

	public void InflictLavaDamage()
	{
		DamageInfo damageInfo = new DamageInfo();
		damageInfo.damage = 10f;
		if (isChampion || isBoss)
		{
			damageInfo.damage = healthComponent.fullCombinedHealth / 100f;
		}
		else if (teamComponent.teamIndex == TeamIndex.Monster || teamComponent.teamIndex == TeamIndex.Void)
		{
			damageInfo.damage = healthComponent.fullCombinedHealth / 50f;
		}
		else
		{
			damageInfo.damage = healthComponent.fullCombinedHealth / 10f;
		}
		damageInfo.damageType = DamageType.IgniteOnHit;
		damageInfo.position = footPosition;
		healthComponent.TakeDamage(damageInfo);
	}

	public void HandleLavaDamage(float deltaTime)
	{
		bool flag = (bodyFlags & BodyFlags.ImmuneToLava) != 0;
		if (inLava && NetworkServer.active)
		{
			lavaTimer -= deltaTime;
			if (lavaTimer <= 0f && !flag)
			{
				InflictLavaDamage();
				lavaTimer = lavaCooldown;
			}
		}
		else
		{
			lavaTimer = 0f;
		}
	}

	private void UpdateItemAvailability()
	{
		if ((bool)inventory)
		{
			itemAvailability.helfireCount = inventory.GetItemCount(JunkContent.Items.BurnNearby);
		}
		itemAvailability.hasFireTrail = HasBuff(RoR2Content.Buffs.AffixRed);
		itemAvailability.hasAffixLunar = HasBuff(RoR2Content.Buffs.AffixLunar);
		itemAvailability.hasAffixPoison = HasBuff(RoR2Content.Buffs.AffixPoison);
	}

	public void FixedUpdate()
	{
		float fixedDeltaTime = Time.fixedDeltaTime;
		bool flag = (bodyFlags & BodyFlags.IgnoreItemUpdates) == 0;
		if (NetworkServer.active)
		{
			if (flag)
			{
				UpdateBuffs(fixedDeltaTime);
			}
			UpdateOutOfCombatAndDanger();
		}
		if (statsDirty)
		{
			RecalculateStats();
		}
	}

	public void OnDeathStart()
	{
		base.enabled = false;
		if ((bool)sfxLocator)
		{
			Util.PlaySound(sfxLocator.aliveLoopStop, base.gameObject);
		}
		if (NetworkServer.active && (bool)currentVehicle)
		{
			currentVehicle.EjectPassenger(base.gameObject);
		}
		if ((bool)master)
		{
			master.OnBodyDeath(this);
		}
		ModelLocator component = GetComponent<ModelLocator>();
		if (!component)
		{
			return;
		}
		Transform modelTransform = component.modelTransform;
		if ((bool)modelTransform)
		{
			CharacterModel component2 = modelTransform.GetComponent<CharacterModel>();
			if ((bool)component2)
			{
				component2.OnDeath();
			}
		}
	}

	public void OnTakeDamageServer(DamageReport damageReport)
	{
		if (damageReport.damageDealt > 0f)
		{
			outOfDangerStopwatch = 0f;
		}
		if ((bool)master)
		{
			master.OnBodyDamaged(damageReport);
		}
	}

	public void OnSkillActivated(GenericSkill skill)
	{
		if (skill.isCombatSkill)
		{
			outOfCombatStopwatch = 0f;
		}
		if (hasEffectiveAuthority)
		{
			this.onSkillActivatedAuthority?.Invoke(skill);
		}
		if (NetworkServer.active)
		{
			this.onSkillActivatedServer?.Invoke(skill);
			if (inventory.GetItemCount(DLC2Content.Items.IncreasePrimaryDamage) <= 0)
			{
				return;
			}
			if (bodyIndex == BodyCatalog.SpecialCases.RailGunner())
			{
				if ((object)skillLocator.primary == skill)
				{
					if (GetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff) > 0 && !BaseScopeState.inScope)
					{
						luminousShotReady = true;
					}
				}
				else
				{
					luminousShotReady = false;
				}
				if ((object)skillLocator.primary == skill && BaseScopeState.inScope)
				{
					AddIncreasePrimaryDamageStack();
				}
			}
			else
			{
				if (!skill.skillDef.autoHandleLuminousShot)
				{
					return;
				}
				if ((object)skillLocator.secondary == skill)
				{
					AddIncreasePrimaryDamageStack();
				}
				else if ((object)skillLocator.primary == skill)
				{
					if (GetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff) > 0)
					{
						luminousShotReady = true;
					}
					else
					{
						luminousShotReady = false;
					}
				}
			}
		}
		else
		{
			CallCmdOnSkillActivated((sbyte)skillLocator.FindSkillSlot(skill));
		}
	}

	public void OnDestroy()
	{
		try
		{
			CharacterBody.onBodyDestroyGlobal?.Invoke(this);
		}
		catch (Exception message)
		{
			Debug.LogError(message);
		}
		if ((bool)sfxLocator)
		{
			Util.PlaySound(sfxLocator.aliveLoopStop, base.gameObject);
		}
		if ((object)modelLocator != null)
		{
			modelLocator.onModelChanged -= OnModelChanged;
		}
		if ((bool)inventory)
		{
			inventory.onInventoryChanged -= OnInventoryChanged;
		}
		if ((bool)master)
		{
			master.OnBodyDestroyed(this);
		}
	}

	public float GetNormalizedThreatValue()
	{
		if ((bool)Run.instance)
		{
			return (master ? ((float)master.money) : 0f) * Run.instance.oneOverCompensatedDifficultyCoefficientSquared;
		}
		return 0f;
	}

	private void OnEnable()
	{
		instancesList.Add(this);
	}

	private void OnDisable()
	{
		instancesList.Remove(this);
	}

	private void OnValidate()
	{
		if (autoCalculateLevelStats)
		{
			PerformAutoCalculateLevelStats();
		}
		if (!Application.isPlaying && bodyIndex != BodyIndex.None)
		{
			bodyIndex = BodyIndex.None;
		}
	}

	private void UpdateAuthority()
	{
		hasEffectiveAuthority = Util.HasEffectiveAuthority(base.gameObject);
	}

	public override void OnStartAuthority()
	{
		UpdateAuthority();
	}

	public override void OnStopAuthority()
	{
		UpdateAuthority();
	}

	private void OnSprintStart()
	{
		if ((bool)sfxLocator)
		{
			Util.PlaySound(sfxLocator.sprintLoopStart, base.gameObject);
		}
	}

	private void OnSprintStop()
	{
		if ((bool)sfxLocator)
		{
			Util.PlaySound(sfxLocator.sprintLoopStop, base.gameObject);
		}
	}

	[Command]
	private void CmdUpdateSprint(bool newIsSprinting)
	{
		isSprinting = newIsSprinting;
	}

	[Command]
	private void CmdOnSkillActivated(sbyte skillIndex)
	{
		OnSkillActivated(skillLocator.GetSkill((SkillSlot)skillIndex));
	}

	private void OnOutOfDangerChanged()
	{
		if (outOfDanger && healthComponent.shield != healthComponent.fullShield)
		{
			Util.PlaySound("Play_item_proc_personal_shield_recharge", base.gameObject);
		}
	}

	[Server]
	private void OnOutOfCombatAndDangerServer()
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::OnOutOfCombatAndDangerServer()' called on client");
		}
	}

	[Server]
	public bool GetNotMoving()
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Boolean RoR2.CharacterBody::GetNotMoving()' called on client");
			return false;
		}
		return notMovingStopwatch >= 1f;
	}

	public void PerformAutoCalculateLevelStats()
	{
		levelMaxHealth = Mathf.Round(baseMaxHealth * 0.3f);
		levelMaxShield = Mathf.Round(baseMaxShield * 0.3f);
		levelRegen = baseRegen * 0.2f;
		levelMoveSpeed = 0f;
		levelJumpPower = 0f;
		levelDamage = baseDamage * 0.2f;
		levelAttackSpeed = 0f;
		levelCrit = 0f;
		levelArmor = 0f;
	}

	public void MarkAllStatsDirty()
	{
		statsDirty = true;
	}

	private void UpdateLowerHealthHigherDamageVFX()
	{
		if ((bool)lowerHealthHigherDamageSteam)
		{
			ParticleSystem.EmissionModule emission = lowerHealthHigherDamageSteam.GetComponent<ParticleSystem>().emission;
			emission.rateOverTime = 35f;
		}
	}

	public void UpdateLowerHealthHigherDamage()
	{
		if (!inventory)
		{
			return;
		}
		int itemCount = inventory.GetItemCount(DLC2Content.Items.LowerHealthHigherDamage);
		if (NetworkServer.active)
		{
			if (itemCount > 0)
			{
				if ((bool)inventory && healthComponent.health > 0f && teamComponent.teamIndex == TeamIndex.Player)
				{
					float normalizedHealth = healthComponent.GetNormalizedHealth();
					if ((double)normalizedHealth <= 0.5 && !HasBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff))
					{
						AddBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff);
						Util.PlaySound("Play_item_proc_lowerHealthHigherDamage_proc", base.gameObject);
						TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.LowerHealthHigherDamage.itemIndex, 1f));
					}
					else if (HasBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff) && (double)normalizedHealth > 0.5)
					{
						RemoveBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff);
						TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.LowerHealthHigherDamage.itemIndex, 0f));
					}
				}
			}
			else if (HasBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff))
			{
				RemoveBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff);
				TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.LowerHealthHigherDamage.itemIndex, 0f));
			}
		}
		else if (itemCount == 0 && HasBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff) && healthComponent.health > 0f && teamComponent.teamIndex == TeamIndex.Player && (double)healthComponent.GetNormalizedHealth() > 0.5)
		{
			RemoveBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff);
			TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.LowerHealthHigherDamage.itemIndex, 0f));
		}
	}

	private void SetBoostAllStatsStartTimer(float t)
	{
		if (!boostAllStatsTimerStarted)
		{
			boostAllStatsStartTimer = t;
			boostAllStatsTimer = boostAllStatsStartTimer;
			boostAllStatsTimerStarted = true;
		}
	}

	private void SetBoostAllStatsCoolDownTimer(float t)
	{
		if (boostAllStatsCoolDownTimerStarted)
		{
			boostAllStatsCoolDownStartTimer = t;
			boostAllStatsCoolDownTimer = boostAllStatsCoolDownStartTimer;
		}
	}

	private float CalculateBoostAllStatsTriggerChance(int i)
	{
		boostAllStatsTriggerChance = boostAllStatsDefaultTriggerChance + boostAllStatsTriggerIncrease * (float)(i - 1);
		if ((double)boostAllStatsTriggerChance >= 0.5)
		{
			boostAllStatsTriggerChance = 0.5f;
		}
		return boostAllStatsTriggerChance;
	}

	private void UpdateBoostAllStatsTimer(float t)
	{
		if (!NetworkServer.active || !inventory)
		{
			return;
		}
		int itemCount = inventory.GetItemCount(DLC2Content.Items.BoostAllStats);
		if (!boostAllStatsCoolDownTimerStarted && itemCount > 0)
		{
			SetBoostAllStatsStartTimer(t);
			boostAllStatsTimer += t;
			if (boostAllStatsTimer >= boostAllStatsStartTimer + boostAllStatsTriggerTimer)
			{
				if (RoR2Application.rng.RangeFloat(0f, 1f) <= CalculateBoostAllStatsTriggerChance(inventory.GetItemCount(DLC2Content.Items.BoostAllStats)))
				{
					AddBuff(DLC2Content.Buffs.BoostAllStatsBuff);
					RecalculateStats();
					boostAllStatsTimerStarted = false;
					boostAllStatsCoolDownTimerStarted = true;
					SetBoostAllStatsCoolDownTimer(t);
				}
				else
				{
					boostAllStatsTimerStarted = false;
					boostAllStatsCoolDownTimerStarted = false;
				}
			}
		}
		else if (boostAllStatsCoolDownTimerStarted)
		{
			boostAllStatsCoolDownTimer += t;
			if (boostAllStatsCoolDownTimer >= boostAllStatsStartTimer + boostAllStatsCoolDownTriggerTimer)
			{
				RemoveBuff(DLC2Content.Buffs.BoostAllStatsBuff);
				RecalculateStats();
				boostAllStatsCoolDownTimerStarted = false;
			}
		}
	}

	public void RecalculateStats()
	{
		if (!Run.instance)
		{
			return;
		}
		float num = level;
		TeamManager.instance.GetTeamExperience(teamComponent.teamIndex);
		float num2 = TeamManager.instance.GetTeamLevel(teamComponent.teamIndex);
		int num3 = 0;
		int num4 = 0;
		int num5 = 0;
		int num6 = 0;
		int num7 = 0;
		int num8 = 0;
		int num9 = 0;
		int num10 = 0;
		int num11 = 0;
		int num12 = 0;
		int num13 = 0;
		int num14 = 0;
		int num15 = 0;
		int num16 = 0;
		int num17 = 0;
		int num18 = 0;
		int num19 = 0;
		int num20 = 0;
		int num21 = 0;
		int num22 = 0;
		int num23 = 0;
		int num24 = 0;
		int num25 = 0;
		int num26 = 0;
		int num27 = 0;
		int num28 = 0;
		int num29 = 0;
		int num30 = 0;
		int num31 = 0;
		int num32 = 0;
		int num33 = 0;
		int num34 = 0;
		int num35 = 0;
		int num36 = 0;
		int num37 = 0;
		int num38 = 0;
		int num39 = 0;
		int num40 = 0;
		int num41 = 0;
		int num42 = 0;
		int num43 = 0;
		int num44 = 0;
		int num45 = 0;
		int num46 = 0;
		int num47 = 0;
		int num48 = 0;
		int num49 = 0;
		int num50 = 0;
		EquipmentIndex equipmentIndex = EquipmentIndex.None;
		uint num51 = 0u;
		int num52 = 0;
		int num53 = 0;
		int num54 = 0;
		int num55 = 0;
		if ((bool)inventory)
		{
			num3 = inventory.GetItemCount(RoR2Content.Items.LevelBonus);
			num4 = inventory.GetItemCount(RoR2Content.Items.Infusion);
			num5 = inventory.GetItemCount(RoR2Content.Items.HealWhileSafe);
			num6 = inventory.GetItemCount(RoR2Content.Items.PersonalShield);
			num7 = inventory.GetItemCount(RoR2Content.Items.Hoof);
			num8 = inventory.GetItemCount(RoR2Content.Items.SprintOutOfCombat);
			num9 = inventory.GetItemCount(RoR2Content.Items.Feather);
			num10 = inventory.GetItemCount(RoR2Content.Items.Syringe);
			num11 = inventory.GetItemCount(RoR2Content.Items.CritGlasses);
			num12 = inventory.GetItemCount(RoR2Content.Items.AttackSpeedOnCrit);
			num13 = inventory.GetItemCount(JunkContent.Items.CooldownOnCrit);
			num14 = inventory.GetItemCount(RoR2Content.Items.HealOnCrit);
			num15 = inventory.GetItemCount(RoR2Content.Items.ShieldOnly);
			num16 = inventory.GetItemCount(RoR2Content.Items.AlienHead);
			num17 = inventory.GetItemCount(RoR2Content.Items.Knurl);
			num18 = inventory.GetItemCount(RoR2Content.Items.BoostHp);
			num19 = inventory.GetItemCount(JunkContent.Items.CritHeal);
			num20 = inventory.GetItemCount(RoR2Content.Items.SprintBonus);
			num21 = inventory.GetItemCount(RoR2Content.Items.SecondarySkillMagazine);
			num23 = inventory.GetItemCount(RoR2Content.Items.SprintArmor);
			num24 = inventory.GetItemCount(RoR2Content.Items.UtilitySkillMagazine);
			num25 = inventory.GetItemCount(RoR2Content.Items.HealthDecay);
			num27 = inventory.GetItemCount(RoR2Content.Items.TonicAffliction);
			num28 = inventory.GetItemCount(RoR2Content.Items.LunarDagger);
			num26 = inventory.GetItemCount(RoR2Content.Items.DrizzlePlayerHelper);
			num29 = inventory.GetItemCount(RoR2Content.Items.MonsoonPlayerHelper);
			num30 = inventory.GetItemCount(RoR2Content.Items.Pearl);
			num31 = inventory.GetItemCount(RoR2Content.Items.ShinyPearl);
			num32 = inventory.GetItemCount(RoR2Content.Items.InvadingDoppelganger);
			num33 = inventory.GetItemCount(RoR2Content.Items.CutHp);
			num34 = inventory.GetItemCount(RoR2Content.Items.BoostAttackSpeed);
			num35 = inventory.GetItemCount(RoR2Content.Items.BleedOnHitAndExplode);
			num36 = inventory.GetItemCount(RoR2Content.Items.LunarBadLuck);
			num37 = inventory.GetItemCount(RoR2Content.Items.FlatHealth);
			num38 = inventory.GetItemCount(RoR2Content.Items.TeamSizeDamageBonus);
			num39 = inventory.GetItemCount(RoR2Content.Items.SummonedEcho);
			num40 = inventory.GetItemCount(RoR2Content.Items.UseAmbientLevel);
			num22 = inventory.GetItemCount(DLC1Content.Items.EquipmentMagazineVoid);
			num44 = inventory.GetItemCount(DLC1Content.Items.HalfAttackSpeedHalfCooldowns);
			num45 = inventory.GetItemCount(DLC1Content.Items.HalfSpeedDoubleHealth);
			num41 = inventory.GetItemCount(RoR2Content.Items.BleedOnHit);
			num42 = inventory.GetItemCount(DLC1Content.Items.AttackSpeedAndMoveSpeed);
			num43 = inventory.GetItemCount(DLC1Content.Items.CritDamage);
			num46 = inventory.GetItemCount(DLC1Content.Items.ConvertCritChanceToCritDamage);
			num47 = inventory.GetItemCount(DLC1Content.Items.DroneWeaponsBoost);
			num48 = inventory.GetItemCount(DLC1Content.Items.MissileVoid);
			equipmentIndex = inventory.currentEquipmentIndex;
			num51 = inventory.infusionBonus;
			num49 = ((equipmentIndex == DLC1Content.Equipment.EliteVoidEquipment.equipmentIndex) ? 1 : 0);
			num50 = inventory.GetItemCount(DLC1Content.Items.OutOfCombatArmor);
			inventory.GetItemCount(DLC1Content.Items.VoidmanPassiveItem);
			num52 = inventory.GetItemCount(DLC2Content.Items.LowerHealthHigherDamage);
			num53 = inventory.GetItemCount(DLC2Content.Items.BoostAllStats);
			inventory.GetItemCount(DLC2Content.Items.TeleportOnLowHealth);
			num54 = inventory.GetItemCount(DLC2Content.Items.IncreaseDamageOnMultiKill);
			inventory.GetItemCount(DLC2Content.Items.GoldOnStageStart);
			num55 = inventory.GetItemCount(DLC2Content.Items.ExtraStatsOnLevelUp);
		}
		level = num2;
		if (num40 > 0)
		{
			level = Math.Max(level, Run.instance.ambientLevelFloor);
		}
		level += num3;
		EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(equipmentIndex);
		float num56 = level - 1f;
		isElite = eliteBuffCount > 0;
		bool flag = HasBuff(RoR2Content.Buffs.TonicBuff);
		bool num57 = HasBuff(RoR2Content.Buffs.Entangle);
		bool flag2 = HasBuff(RoR2Content.Buffs.Nullified);
		bool flag3 = HasBuff(RoR2Content.Buffs.LunarSecondaryRoot);
		bool flag4 = teamComponent.teamIndex == TeamIndex.Player && RunArtifactManager.instance.IsArtifactEnabled(RoR2Content.Artifacts.glassArtifactDef);
		bool num58 = num15 > 0 || HasBuff(RoR2Content.Buffs.AffixLunar);
		bool flag5 = (object)equipmentDef != null && (object)equipmentDef == JunkContent.Equipment.EliteYellowEquipment;
		hasOneShotProtection = isPlayerControlled;
		int buffCount = GetBuffCount(RoR2Content.Buffs.BeetleJuice);
		int buffCount2 = GetBuffCount(DLC2Content.Buffs.RevitalizeBuff);
		isGlass = flag4 || num28 > 0;
		canPerformBackstab = (bodyFlags & BodyFlags.HasBackstabPassive) == BodyFlags.HasBackstabPassive;
		canReceiveBackstab = (bodyFlags & BodyFlags.HasBackstabImmunity) != BodyFlags.HasBackstabImmunity;
		float num59 = maxHealth;
		float num60 = maxShield;
		if (num55 > extraStatsOnLevelUpCountModifier && num55 > 0)
		{
			extraStatsOnLevelUpCountModifier = num55;
		}
		if (num55 < extraStatsOnLevelUpCountModifier && (bool)inventory)
		{
			UnityEngine.Object.Instantiate(CommonAssets.prayerBeadEffect, base.gameObject.transform.position, Quaternion.identity).transform.parent = base.gameObject.transform;
			extraStatsOnLevelUpCountModifier -= num55;
			float beadAppliedHealth = inventory.beadAppliedHealth;
			prayerBeadCalculateAppliedStats(levelMaxHealth);
			prayerBeadCalculateAppliedStats(levelMaxShield);
			prayerBeadCalculateAppliedStats(levelRegen);
			prayerBeadCalculateAppliedStats(levelDamage);
			extraStatsOnLevelUpCountModifier = num55;
			if (HasBuff(DLC2Content.Buffs.ExtraStatsOnLevelUpBuff))
			{
				SetBuffCount(DLC2Content.Buffs.ExtraStatsOnLevelUpBuff.buffIndex, 0);
				bool gainedStats = inventory.beadAppliedHealth > beadAppliedHealth;
				master.OnBeadReset(gainedStats);
			}
		}
		HandleDisableAllSkillsDebuff();
		float num61 = baseMaxHealth + levelMaxHealth * num56;
		if (teamComponent.teamIndex == TeamIndex.Player && (bool)inventory && inventory.beadAppliedHealth > 0f)
		{
			num61 += inventory.beadAppliedHealth;
		}
		float num62 = 1f;
		num62 += (float)num18 * 0.1f;
		num62 += (float)(num30 + num31) * 0.1f;
		num62 += (float)buffCount2 * 0.07f;
		num62 += (float)num49 * 0.5f;
		num62 += (float)num45 * 1f;
		if (num4 > 0)
		{
			num61 += (float)num51;
		}
		num61 += (float)num37 * 25f;
		num61 += (float)num17 * 40f;
		num61 *= num62;
		num61 /= (float)(num33 + 1);
		if (num32 > 0)
		{
			num61 *= 10f;
		}
		if (num39 > 0)
		{
			num61 *= 0.1f;
		}
		maxHealth = num61;
		float num63 = baseMaxShield + levelMaxShield * num56;
		if (teamComponent.teamIndex == TeamIndex.Player && (bool)inventory && inventory.beadAppliedShield > 0f)
		{
			num63 += inventory.beadAppliedShield;
		}
		num63 += (float)num6 * 0.08f * maxHealth;
		if (HasBuff(RoR2Content.Buffs.EngiShield))
		{
			num63 += maxHealth * 1f;
		}
		if (HasBuff(JunkContent.Buffs.EngiTeamShield))
		{
			num63 += maxHealth * 0.5f;
		}
		if (num48 > 0)
		{
			num63 += maxHealth * 0.1f;
		}
		if (num58)
		{
			num63 += maxHealth * (1.5f + (float)(num15 - 1) * 0.25f);
			maxHealth = 1f;
		}
		if (HasBuff(RoR2Content.Buffs.AffixBlue))
		{
			float num64 = maxHealth * 0.5f;
			maxHealth -= num64;
			num63 += maxHealth;
		}
		maxShield = num63;
		float num65 = baseRegen + levelRegen * num56;
		if (teamComponent.teamIndex == TeamIndex.Player && (bool)inventory && inventory.beadAppliedRegen > 0f)
		{
			num65 += inventory.beadAppliedRegen;
		}
		float num66 = 1f + num56 * 0.2f;
		float num67 = (float)num17 * 1.6f * num66;
		float num68 = ((outOfDanger && num5 > 0) ? (3f * (float)num5) : 0f) * num66;
		float num69 = (HasBuff(JunkContent.Buffs.MeatRegenBoost) ? 2f : 0f) * num66;
		float num70 = (float)GetBuffCount(RoR2Content.Buffs.CrocoRegen) * maxHealth * 0.1f;
		float num71 = (float)num31 * 0.1f * num66;
		float num72 = (float)buffCount2 * 0.07f * num66;
		float num73 = 1f;
		if (num26 > 0)
		{
			num73 += 0.5f;
		}
		if (num29 > 0)
		{
			num73 -= 0.4f;
		}
		float num74 = (num65 + num67 + num68 + num69 + num71 + num72) * num73;
		if (HasBuff(RoR2Content.Buffs.OnFire) || HasBuff(DLC1Content.Buffs.StrongerBurn))
		{
			num74 = Mathf.Min(0f, num74);
		}
		num74 += num70;
		if (num58)
		{
			num74 = Mathf.Max(num74, 0f);
		}
		if (num25 > 0)
		{
			num74 = Mathf.Min(num74, 0f) - maxHealth / cursePenalty / (float)num25;
		}
		if (tamperedHeartActive)
		{
			num74 += tamperedHeartRegenBonus;
		}
		if (HasBuff(DLC2Content.Buffs.HealAndReviveRegenBuff))
		{
			num74 += num74 * 0.5f;
		}
		regen = num74;
		float num75 = baseMoveSpeed + levelMoveSpeed * num56;
		num75 += surfaceSpeedBoost;
		float num76 = 1f;
		if (flag5)
		{
			num75 += 2f;
		}
		if (isSprinting)
		{
			num75 *= sprintingSpeedMultiplier;
		}
		num76 += (float)num7 * 0.14f;
		num76 += (float)num42 * 0.07f;
		num76 += (float)num31 * 0.1f;
		num76 += (float)buffCount2 * 0.07f;
		num76 += 0.25f * (float)GetBuffCount(DLC1Content.Buffs.KillMoveSpeed);
		if (teamComponent.teamIndex == TeamIndex.Monster && Run.instance.selectedDifficulty >= DifficultyIndex.Eclipse4)
		{
			num76 += 0.4f;
		}
		if (isSprinting && num20 > 0)
		{
			num76 += 0.25f * (float)num20 / sprintingSpeedMultiplier;
		}
		if (num8 > 0 && HasBuff(RoR2Content.Buffs.WhipBoost))
		{
			num76 += (float)num8 * 0.3f;
		}
		if (num39 > 0)
		{
			num76 += 0.66f;
		}
		if (HasBuff(RoR2Content.Buffs.BugWings))
		{
			num76 += 0.2f;
		}
		if (HasBuff(RoR2Content.Buffs.Warbanner))
		{
			num76 += 0.3f;
		}
		if (HasBuff(JunkContent.Buffs.EnrageAncientWisp))
		{
			num76 += 0.4f;
		}
		if (HasBuff(RoR2Content.Buffs.CloakSpeed))
		{
			num76 += 0.4f;
		}
		if (HasBuff(RoR2Content.Buffs.WarCryBuff) || HasBuff(RoR2Content.Buffs.TeamWarCry))
		{
			num76 += 0.5f;
		}
		if (HasBuff(JunkContent.Buffs.EngiTeamShield))
		{
			num76 += 0.3f;
		}
		if (HasBuff(RoR2Content.Buffs.AffixLunar))
		{
			num76 += 0.3f;
		}
		if (tamperedHeartActive)
		{
			num75 += num75 * tamperedHeartMSpeedBonus;
		}
		float num77 = 1f;
		if (HasBuff(RoR2Content.Buffs.Slow50))
		{
			num77 += 0.5f;
		}
		if (HasBuff(RoR2Content.Buffs.Slow60))
		{
			num77 += 0.6f;
		}
		if (HasBuff(RoR2Content.Buffs.Slow80))
		{
			num77 += 0.8f;
		}
		if (HasBuff(RoR2Content.Buffs.ClayGoo))
		{
			num77 += 0.5f;
		}
		if (HasBuff(JunkContent.Buffs.Slow30))
		{
			num77 += 0.3f;
		}
		if (HasBuff(RoR2Content.Buffs.Cripple))
		{
			num77 += 1f;
		}
		if (HasBuff(DLC1Content.Buffs.JailerSlow))
		{
			num77 += 1f;
		}
		num77 += (float)num45 * 1f;
		num75 *= num76 / num77;
		if (buffCount > 0)
		{
			num75 *= 1f - 0.05f * (float)buffCount;
		}
		moveSpeed = num75;
		acceleration = ((baseMoveSpeed == 0f) ? 0f : (moveSpeed / baseMoveSpeed * baseAcceleration));
		if (num57 || flag2 || flag3)
		{
			moveSpeed = 0f;
			acceleration = 80f;
		}
		float num78 = baseJumpPower + levelJumpPower * num56;
		jumpPower = num78;
		maxJumpHeight = Trajectory.CalculateApex(jumpPower);
		maxJumpCount = baseJumpCount + num9;
		oneShotProtectionFraction = 0.1f;
		float num79 = baseDamage + levelDamage * num56;
		if (teamComponent.teamIndex == TeamIndex.Player && (bool)inventory && inventory.beadAppliedDamage > 0f)
		{
			num79 += inventory.beadAppliedDamage;
		}
		float num80 = 1f;
		int num81 = (inventory ? inventory.GetItemCount(RoR2Content.Items.BoostDamage) : 0);
		if (num81 > 0)
		{
			num80 += (float)num81 * 0.1f;
		}
		if (num38 > 0)
		{
			int num82 = Math.Max(TeamComponent.GetTeamMembers(teamComponent.teamIndex).Count - 1, 0);
			num80 += (float)(num82 * num38) * 1f;
		}
		if (buffCount > 0)
		{
			num80 -= 0.05f * (float)buffCount;
		}
		if (HasBuff(JunkContent.Buffs.GoldEmpowered))
		{
			num80 += 1f;
		}
		if (HasBuff(RoR2Content.Buffs.PowerBuff))
		{
			num80 += 0.5f;
		}
		num80 += (float)num31 * 0.1f;
		num80 += (float)buffCount2 * 0.07f;
		num80 += Mathf.Pow(2f, num28) - 1f;
		num80 -= (float)num49 * 0.3f;
		num79 *= num80;
		if (num32 > 0)
		{
			num79 *= 0.04f;
		}
		if (flag4)
		{
			num79 *= 5f;
		}
		damage = num79;
		damageFromRecalculateStats = damage;
		if (HasBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff))
		{
			damage += baseDamage * (float)currentHealthLevel * 0.1f * (float)num52 * 0.5f;
		}
		_ = tamperedHeartActive;
		if (HasBuff(DLC2Content.Buffs.IncreaseDamageBuff))
		{
			int buffCount3 = GetBuffCount(DLC2Content.Buffs.IncreaseDamageBuff);
			float num83 = 0f;
			if (buffCount3 >= 2)
			{
				num83 = (float)(buffCount3 * (buffCount3 + num54 * 5)) * 0.01f;
			}
			else if (buffCount3 == 1)
			{
				num83 = (float)(1 + num54 * 5) * 0.01f;
			}
			damage += baseDamage * num83;
			if (oldComboMeter < buffCount3)
			{
				oldComboMeter = buffCount3;
			}
		}
		float num84 = baseAttackSpeed + levelAttackSpeed * num56;
		float num85 = 1f;
		num85 += (float)num34 * 0.1f;
		num85 += (float)num10 * 0.15f;
		num85 += (float)num42 * 0.075f;
		num85 += (float)num47 * 0.5f;
		if (flag5)
		{
			num85 += 0.5f;
		}
		num85 += (float)GetBuffCount(RoR2Content.Buffs.AttackSpeedOnCrit) * 0.12f;
		if (HasBuff(RoR2Content.Buffs.Warbanner))
		{
			num85 += 0.3f;
		}
		if (HasBuff(RoR2Content.Buffs.Energized))
		{
			num85 += 0.7f;
		}
		if (HasBuff(RoR2Content.Buffs.WarCryBuff) || HasBuff(RoR2Content.Buffs.TeamWarCry))
		{
			num85 += 1f;
		}
		num85 += (float)num31 * 0.1f;
		num85 += (float)buffCount2 * 0.07f;
		num85 /= (float)(num44 + 1);
		num85 = Mathf.Max(num85, 0.1f);
		num84 *= num85;
		if (buffCount > 0)
		{
			num84 *= 1f - 0.05f * (float)buffCount;
		}
		if (tamperedHeartActive)
		{
			num84 += num84 * tamperedHeartAttackSpeedBonus;
		}
		attackSpeed = num84;
		critMultiplier = 2f + 1f * (float)num43;
		float num86 = baseCrit + levelCrit * num56;
		num86 += (float)num11 * 10f;
		if (num12 > 0)
		{
			num86 += 5f;
		}
		if (num35 > 0)
		{
			num86 += 5f;
		}
		if (num13 > 0)
		{
			num86 += 5f;
		}
		if (num14 > 0)
		{
			num86 += 5f;
		}
		if (num19 > 0)
		{
			num86 += 5f;
		}
		if (HasBuff(RoR2Content.Buffs.FullCrit))
		{
			num86 += 100f;
		}
		num86 += (float)num31 * 10f;
		num86 += (float)buffCount2 * 7f;
		if (num46 == 0)
		{
			crit = num86;
		}
		else
		{
			critMultiplier += num86 * 0.01f;
			crit = 0f;
		}
		armor = baseArmor + levelArmor * num56;
		armor *= 1f + 0.1f * (float)num31;
		armor *= 1f + 0.07f * (float)buffCount2;
		armor += (float)num26 * 70f;
		armor += (HasBuff(RoR2Content.Buffs.ArmorBoost) ? 200f : 0f);
		armor += (HasBuff(RoR2Content.Buffs.SmallArmorBoost) ? 100f : 0f);
		armor += (HasBuff(DLC1Content.Buffs.OutOfCombatArmorBuff) ? (100f * (float)num50) : 0f);
		armor += (HasBuff(RoR2Content.Buffs.ElephantArmorBoost) ? 500f : 0f);
		armor += (HasBuff(DLC1Content.Buffs.VoidSurvivorCorruptMode) ? 100f : 0f);
		armor += (HasBuff(DLC2Content.Buffs.AurelioniteBlessing) ? (60f + 0.1f * (float)master.money) : 0f);
		if (HasBuff(RoR2Content.Buffs.Cripple))
		{
			armor -= 20f;
		}
		if (HasBuff(RoR2Content.Buffs.Pulverized))
		{
			armor -= 60f;
		}
		if (isSprinting && num23 > 0)
		{
			armor += num23 * 30;
		}
		if (tamperedHeartActive)
		{
			armor += tamperedHeartArmorBonus;
		}
		int buffCount4 = GetBuffCount(DLC1Content.Buffs.PermanentDebuff);
		armor -= (float)buffCount4 * 2f;
		float num87 = 0f;
		if (num36 > 0)
		{
			num87 += 2f + 1f * (float)(num36 - 1);
		}
		float num88 = 1f;
		if (HasBuff(JunkContent.Buffs.GoldEmpowered))
		{
			num88 *= 0.25f;
		}
		for (int i = 0; i < num16; i++)
		{
			num88 *= 0.75f;
		}
		for (int j = 0; j < num44; j++)
		{
			num88 *= 0.5f;
		}
		for (int k = 0; k < num47; k++)
		{
			num88 *= 0.5f;
		}
		if (teamComponent.teamIndex == TeamIndex.Monster && Run.instance.selectedDifficulty >= DifficultyIndex.Eclipse7)
		{
			num88 *= 0.5f;
		}
		if (HasBuff(RoR2Content.Buffs.NoCooldowns))
		{
			num88 = 0f;
		}
		if ((bool)skillLocator.primary)
		{
			skillLocator.primary.cooldownScale = num88;
			skillLocator.primary.flatCooldownReduction = num87;
		}
		if ((bool)skillLocator.secondaryBonusStockSkill)
		{
			skillLocator.secondaryBonusStockSkill.cooldownScale = num88;
			skillLocator.secondaryBonusStockSkill.SetBonusStockFromBody(num21 + extraSecondaryFromSkill);
			skillLocator.secondaryBonusStockSkill.flatCooldownReduction = num87;
		}
		if ((bool)skillLocator.utilityBonusStockSkill)
		{
			float num89 = num88;
			if (num24 > 0)
			{
				num89 *= 2f / 3f;
			}
			skillLocator.utilityBonusStockSkill.cooldownScale = num89;
			skillLocator.utilityBonusStockSkill.flatCooldownReduction = num87;
			skillLocator.utilityBonusStockSkill.SetBonusStockFromBody(num24 * 2);
		}
		if ((bool)skillLocator.specialBonusStockSkill)
		{
			skillLocator.specialBonusStockSkill.cooldownScale = num88;
			if (num22 > 0)
			{
				skillLocator.specialBonusStockSkill.cooldownScale *= 0.67f;
			}
			skillLocator.specialBonusStockSkill.flatCooldownReduction = num87;
			skillLocator.specialBonusStockSkill.SetBonusStockFromBody(num22 + extraSpecialFromSkill);
		}
		critHeal = 0f;
		if (num19 > 0)
		{
			float num90 = crit;
			crit /= num19 + 1;
			critHeal = num90 - crit;
		}
		cursePenalty = 1f;
		if (num28 > 0)
		{
			cursePenalty = Mathf.Pow(2f, num28);
		}
		if (flag4)
		{
			cursePenalty *= 10f;
		}
		int buffCount5 = GetBuffCount(RoR2Content.Buffs.PermanentCurse);
		if (buffCount5 > 0)
		{
			cursePenalty += (float)buffCount5 * 0.01f;
		}
		if (HasBuff(RoR2Content.Buffs.Weak))
		{
			armor -= 30f;
			damage *= 0.6f;
			moveSpeed *= 0.6f;
		}
		if (HasBuff(DLC2Content.Buffs.lunarruin))
		{
			moveSpeed *= 0.8f;
		}
		if (flag)
		{
			maxHealth *= 1.5f;
			maxShield *= 1.5f;
			attackSpeed *= 1.7f;
			moveSpeed *= 1.3f;
			armor += 20f;
			damage *= 2f;
			regen *= 4f;
		}
		if (HasBuff(DLC2Content.Buffs.BoostAllStatsBuff))
		{
			float num91 = (float)num53 * boostAllStatsMultiplier;
			_ = maxHealth;
			_ = moveSpeed;
			_ = damage;
			_ = attackSpeed;
			_ = crit;
			_ = regen;
			maxHealth += maxHealth * num91;
			moveSpeed += moveSpeed * num91;
			damage += damage * num91;
			attackSpeed += attackSpeed * num91;
			crit += crit * num91;
			regen += regen * num91;
		}
		maxBonusHealth = maxHealth;
		if (num27 > 0 && !flag)
		{
			float num92 = Mathf.Pow(0.95f, num27);
			attackSpeed *= num92;
			moveSpeed *= num92;
			damage *= num92;
			regen *= num92;
			cursePenalty += 0.1f * (float)num27;
		}
		if (HasBuff(DLC2Content.Buffs.SoulCost))
		{
			cursePenalty += 0.1f * (float)GetBuffCount(DLC2Content.Buffs.SoulCost);
		}
		maxHealth /= cursePenalty;
		maxShield /= cursePenalty;
		oneShotProtectionFraction = Mathf.Max(0f, oneShotProtectionFraction - (1f - 1f / cursePenalty));
		maxBarrier = maxHealth + maxShield;
		barrierDecayRate = maxBarrier / 30f;
		if (NetworkServer.active)
		{
			float num93 = maxHealth - num59;
			float num94 = maxShield - num60;
			if (num93 > 0f)
			{
				healthComponent.Heal(num93, default(ProcChainMask), nonRegen: false);
			}
			else if (healthComponent.health > maxHealth)
			{
				healthComponent.Networkhealth = Mathf.Max(healthComponent.health + num93, maxHealth);
			}
			if (num94 > 0f)
			{
				healthComponent.RechargeShield(num94);
			}
			else if (healthComponent.shield > maxShield)
			{
				healthComponent.Networkshield = Mathf.Max(healthComponent.shield + num94, maxShield);
			}
		}
		bleedChance = 10f * (float)num41;
		visionDistance = baseVisionDistance;
		if (HasBuff(DLC1Content.Buffs.Blinded))
		{
			visionDistance = Mathf.Min(visionDistance, 15f);
		}
		if (level != num)
		{
			OnCalculatedLevelChanged(num, level);
		}
		int num95 = 0;
		if (num53 > 0 && !HasBuff(DLC2Content.Buffs.BoostAllStatsBuff))
		{
			BuffIndex[] nonHiddenBuffIndices = BuffCatalog.nonHiddenBuffIndices;
			foreach (BuffIndex buffIndex in nonHiddenBuffIndices)
			{
				if (HasBuff(buffIndex) && buffIndex != DLC2Content.Buffs.BoostAllStatsBuff.buffIndex && !BuffCatalog.ignoreGrowthNectarIndices.Contains(buffIndex))
				{
					num95++;
					if (num95 >= 5 && !HasBuff(DLC2Content.Buffs.BoostAllStatsBuff))
					{
						AddTimedBuff(DLC2Content.Buffs.BoostAllStatsBuff, 5f);
					}
				}
			}
		}
		UpdateAllTemporaryVisualEffects();
		statsDirty = false;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private void HandleDisableAllSkillsDebuff()
	{
		bool flag = HasBuff(DLC2Content.Buffs.DisableAllSkills);
		if (flag != allSkillsDisabled)
		{
			if (flag)
			{
				HandleSkillDisableState(_disable: true);
				allSkillsDisabled = true;
			}
			else
			{
				HandleSkillDisableState(_disable: false);
				allSkillsDisabled = false;
			}
		}
		void HandleSkillDisableState(bool _disable)
		{
			if (base.hasAuthority)
			{
				SkillDef skillDef = LegacyResourcesAPI.Load<SkillDef>("Skills/DisabledSkills");
				if (!skillDef)
				{
					Debug.LogWarning("Could not find disabledSkill for DisableAllSkills.");
				}
				else if (_disable)
				{
					skillLocator.primary.SetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual);
					skillLocator.secondary.SetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual);
					skillLocator.utility.SetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual);
					skillLocator.special.SetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual);
					inventory.SetEquipmentDisabled(_active: true);
					Util.PlaySound("Play_env_meridian_primeDevestator_debuff", base.gameObject);
					screenDamageSkillsDisabled = new ScreenDamageCalculatorDisabledSkills();
					healthComponent.screenDamageCalculator = screenDamageSkillsDisabled;
				}
				else
				{
					skillLocator.primary.UnsetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual);
					skillLocator.secondary.UnsetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual);
					skillLocator.utility.UnsetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual);
					skillLocator.special.UnsetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual);
					inventory.SetEquipmentDisabled(_active: false);
					if (screenDamageSkillsDisabled != null)
					{
						if (healthComponent.screenDamageCalculator == screenDamageSkillsDisabled)
						{
							healthComponent.screenDamageCalculator = null;
						}
						screenDamageSkillsDisabled.End();
					}
				}
			}
		}
	}

	public void OnTeamLevelChanged()
	{
		statsDirty = true;
	}

	private void OnCalculatedLevelChanged(float oldLevel, float newLevel)
	{
		if (newLevel > oldLevel)
		{
			int num = Mathf.FloorToInt(oldLevel);
			if (Mathf.FloorToInt(newLevel) > num && num != 0)
			{
				OnLevelUp();
			}
		}
	}

	private void OnLevelUp()
	{
		GlobalEventManager.OnCharacterLevelUp(this);
		if (inventory.GetItemCount(DLC2Content.Items.OnLevelUpFreeUnlock) > 0)
		{
			solitudeLevelCount++;
			AddFreeChestBuff();
			Util.PlaySound("Play_item_proc_onLevelUpFreeUnlock_activate", base.gameObject);
		}
	}

	public void SetAimTimer(float duration)
	{
		aimTimer = duration;
	}

	public override void OnDeserialize(NetworkReader reader, bool initialState)
	{
		byte num = reader.ReadByte();
		if (((uint)num & (true ? 1u : 0u)) != 0)
		{
			NetworkInstanceId networkInstanceId = reader.ReadNetworkId();
			if (networkInstanceId != masterObjectId)
			{
				masterObjectId = networkInstanceId;
				statsDirty = true;
			}
		}
		if ((num & 2u) != 0)
		{
			ReadBuffs(reader);
		}
		if ((num & 4u) != 0)
		{
			bool flag = reader.ReadBoolean();
			if (!hasEffectiveAuthority && flag != outOfCombat)
			{
				outOfCombat = flag;
				statsDirty = true;
			}
		}
		if ((num & 8u) != 0)
		{
			bool flag2 = reader.ReadBoolean();
			if (flag2 != outOfDanger)
			{
				outOfDanger = flag2;
				statsDirty = true;
			}
		}
		if ((num & 0x10u) != 0)
		{
			bool flag3 = reader.ReadBoolean();
			if (flag3 != isSprinting && !hasEffectiveAuthority)
			{
				statsDirty = true;
				isSprinting = flag3;
			}
		}
	}

	public override bool OnSerialize(NetworkWriter writer, bool initialState)
	{
		uint num = base.syncVarDirtyBits;
		if (initialState)
		{
			num = 31u;
		}
		bool num2 = (num & 1) != 0;
		bool flag = (num & 2) != 0;
		bool flag2 = (num & 4) != 0;
		bool flag3 = (num & 8) != 0;
		bool flag4 = (num & 0x10) != 0;
		writer.Write((byte)num);
		if (num2)
		{
			writer.Write(masterObjectId);
		}
		if (flag)
		{
			WriteBuffs(writer);
		}
		if (flag2)
		{
			writer.Write(outOfCombat);
		}
		if (flag3)
		{
			writer.Write(outOfDanger);
		}
		if (flag4)
		{
			writer.Write(isSprinting);
		}
		if (!initialState)
		{
			return num != 0;
		}
		return false;
	}

	public void TransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData)
	{
		if (!NetworkServer.active)
		{
			InternalTransmitItemBehavior(itemBehaviorData);
			CallCmdTransmitItemBehavior(itemBehaviorData);
		}
		else
		{
			ServerTransmitItemBehavior(itemBehaviorData);
		}
	}

	[Server]
	private void ServerTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::ServerTransmitItemBehavior(RoR2.CharacterBody/NetworkItemBehaviorData)' called on client");
			return;
		}
		CallRpcTransmitItemBehavior(itemBehaviorData);
		InternalTransmitItemBehavior(itemBehaviorData);
	}

	[Command]
	private void CmdTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData)
	{
		ServerTransmitItemBehavior(itemBehaviorData);
	}

	[ClientRpc(channel = 1)]
	private void RpcTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData)
	{
		if (!NetworkServer.active)
		{
			InternalTransmitItemBehavior(itemBehaviorData);
		}
	}

	private void InternalTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData)
	{
		OnNetworkItemBehaviorUpdate?.Invoke(itemBehaviorData);
	}

	public T AddItemBehavior<T>(int stack) where T : ItemBehavior
	{
		T val = GetComponent<T>();
		if (stack > 0)
		{
			if (!val)
			{
				val = base.gameObject.AddComponent<T>();
				val.body = this;
				val.enabled = true;
			}
			val.stack = stack;
			return val;
		}
		if ((bool)val)
		{
			UnityEngine.Object.Destroy(val);
		}
		return null;
	}

	public void HandleOnKillEffectsServer(DamageReport damageReport)
	{
		int num = killCountServer + 1;
		killCountServer = num;
		AddMultiKill(1);
	}

	public void OnKilledOtherServer(DamageReport damageReport)
	{
	}

	public void AddHelfireDuration(float duration)
	{
		helfireLifetime = duration;
	}

	[Server]
	private void UpdateHelfire(float deltaTime)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::UpdateHelfire(System.Single)' called on client");
			return;
		}
		helfireLifetime -= deltaTime;
		bool flag = false;
		if ((bool)inventory)
		{
			flag = itemAvailability.helfireCount > 0 || helfireLifetime > 0f;
		}
		if ((bool)helfireController != flag)
		{
			if (flag)
			{
				helfireController = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/HelfireController")).GetComponent<HelfireController>();
				helfireController.networkedBodyAttachment.AttachToGameObjectAndSpawn(base.gameObject);
			}
			else
			{
				UnityEngine.Object.Destroy(helfireController.gameObject);
				helfireController = null;
			}
		}
	}

	private void UpdateFireTrail()
	{
		bool hasFireTrail = itemAvailability.hasFireTrail;
		if (hasFireTrail != (bool)fireTrail)
		{
			if (hasFireTrail)
			{
				fireTrail = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/FireTrail"), transform).GetComponent<DamageTrail>();
				fireTrail.transform.position = footPosition;
				fireTrail.owner = base.gameObject;
				fireTrail.radius *= radius;
			}
			else
			{
				UnityEngine.Object.Destroy(fireTrail.gameObject);
				fireTrail = null;
			}
		}
		if ((bool)fireTrail)
		{
			fireTrail.damagePerSecond = damage * 1.5f;
		}
	}

	private void UpdateAffixPoison(float deltaTime)
	{
		if (!itemAvailability.hasAffixPoison)
		{
			return;
		}
		poisonballTimer += deltaTime;
		if (poisonballTimer >= 6f)
		{
			int num = 3 + (int)radius;
			poisonballTimer = 0f;
			Vector3 up = Vector3.up;
			float num2 = 360f / (float)num;
			Vector3 normalized = Vector3.ProjectOnPlane(transform.forward, up).normalized;
			Vector3 vector = Vector3.RotateTowards(up, normalized, 0.43633232f, float.PositiveInfinity);
			for (int i = 0; i < num; i++)
			{
				Vector3 forward = Quaternion.AngleAxis(num2 * (float)i, up) * vector;
				ProjectileManager.instance.FireProjectile(LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/PoisonOrbProjectile"), corePosition, Util.QuaternionSafeLookRotation(forward), base.gameObject, damage * 1f, 0f, Util.CheckRoll(crit, master));
			}
		}
	}

	private void UpdateAffixLunar(float deltaTime)
	{
		if (!outOfCombat && itemAvailability.hasAffixLunar)
		{
			lunarMissileRechargeTimer += deltaTime;
			lunarMissileTimerBetweenShots += deltaTime;
			int num = 4;
			if (!lunarMissilePrefab)
			{
				lunarMissilePrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/LunarMissileProjectile");
			}
			if (lunarMissileRechargeTimer >= 10f)
			{
				lunarMissileRechargeTimer = 0f;
				remainingMissilesToFire += num;
			}
			if (remainingMissilesToFire > 0 && lunarMissileTimerBetweenShots > 0.1f)
			{
				lunarMissileTimerBetweenShots = 0f;
				Vector3 vector = (inputBank ? inputBank.aimDirection : transform.forward);
				float num2 = 180f / (float)num;
				float num3 = 3f + (float)(int)radius * 1f;
				float num4 = damage * 0.3f;
				Quaternion rotation = Util.QuaternionSafeLookRotation(vector);
				Vector3 vector2 = Quaternion.AngleAxis((float)(remainingMissilesToFire - 1) * num2 - num2 * (float)(num - 1) / 2f, vector) * Vector3.up * num3;
				Vector3 position = aimOrigin + vector2;
				FireProjectileInfo fireProjectileInfo = default(FireProjectileInfo);
				fireProjectileInfo.projectilePrefab = lunarMissilePrefab;
				fireProjectileInfo.position = position;
				fireProjectileInfo.rotation = rotation;
				fireProjectileInfo.owner = base.gameObject;
				fireProjectileInfo.damage = num4;
				fireProjectileInfo.crit = Util.CheckRoll(crit, master);
				fireProjectileInfo.force = 200f;
				FireProjectileInfo fireProjectileInfo2 = fireProjectileInfo;
				ProjectileManager.instance.FireProjectile(fireProjectileInfo2);
				remainingMissilesToFire--;
			}
		}
	}

	private void UpdateAllTemporaryVisualEffects()
	{
		int buffCount = GetBuffCount(RoR2Content.Buffs.NullifyStack);
		UpdateSingleTemporaryVisualEffect(ref engiShieldTempEffectInstance, AssetReferences.engiShieldTempEffectPrefab, bestFitRadius, healthComponent.shield > 0f && HasBuff(RoR2Content.Buffs.EngiShield));
		ref TemporaryVisualEffect tempEffect = ref bucklerShieldTempEffectInstance;
		GameObject bucklerShieldTempEffectPrefab = AssetReferences.bucklerShieldTempEffectPrefab;
		float effectRadius = radius;
		int active;
		if (isSprinting)
		{
			Inventory obj = inventory;
			active = (((object)obj != null && obj.GetItemCount(RoR2Content.Items.SprintArmor) > 0) ? 1 : 0);
		}
		else
		{
			active = 0;
		}
		UpdateSingleTemporaryVisualEffect(ref tempEffect, bucklerShieldTempEffectPrefab, effectRadius, (byte)active != 0);
		UpdateSingleTemporaryVisualEffect(ref slowDownTimeTempEffectInstance, AssetReferences.slowDownTimeTempEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Slow60));
		UpdateSingleTemporaryVisualEffect(ref crippleEffectInstance, AssetReferences.crippleEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Cripple));
		UpdateSingleTemporaryVisualEffect(ref tonicBuffEffectInstance, AssetReferences.tonicBuffEffectPrefab, radius, HasBuff(RoR2Content.Buffs.TonicBuff));
		UpdateSingleTemporaryVisualEffect(ref weakTempEffectInstance, AssetReferences.weakTempEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Weak));
		UpdateSingleTemporaryVisualEffect(ref energizedTempEffectInstance, AssetReferences.energizedTempEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Energized));
		UpdateSingleTemporaryVisualEffect(ref barrierTempEffectInstance, AssetReferences.barrierTempEffectPrefab, bestFitRadius, healthComponent.barrier > 0f);
		UpdateSingleTemporaryVisualEffect(ref regenBoostEffectInstance, AssetReferences.regenBoostEffectPrefab, bestFitRadius, HasBuff(JunkContent.Buffs.MeatRegenBoost));
		UpdateSingleTemporaryVisualEffect(ref elephantDefenseEffectInstance, AssetReferences.elephantDefenseEffectPrefab, radius, HasBuff(RoR2Content.Buffs.ElephantArmorBoost));
		UpdateSingleTemporaryVisualEffect(ref healingDisabledEffectInstance, AssetReferences.healingDisabledEffectPrefab, radius, HasBuff(RoR2Content.Buffs.HealingDisabled));
		UpdateSingleTemporaryVisualEffect(ref noCooldownEffectInstance, AssetReferences.noCooldownEffectPrefab, radius, HasBuff(RoR2Content.Buffs.NoCooldowns), "Head");
		ref TemporaryVisualEffect tempEffect2 = ref doppelgangerEffectInstance;
		GameObject doppelgangerEffectPrefab = AssetReferences.doppelgangerEffectPrefab;
		float effectRadius2 = radius;
		Inventory obj2 = inventory;
		UpdateSingleTemporaryVisualEffect(ref tempEffect2, doppelgangerEffectPrefab, effectRadius2, (object)obj2 != null && obj2.GetItemCount(RoR2Content.Items.InvadingDoppelganger) > 0, "Head");
		UpdateSingleTemporaryVisualEffect(ref nullifyStack1EffectInstance, AssetReferences.nullifyStack1EffectPrefab, radius, buffCount == 1);
		UpdateSingleTemporaryVisualEffect(ref nullifyStack2EffectInstance, AssetReferences.nullifyStack2EffectPrefab, radius, buffCount == 2);
		UpdateSingleTemporaryVisualEffect(ref nullifyStack3EffectInstance, AssetReferences.nullifyStack3EffectPrefab, radius, HasBuff(RoR2Content.Buffs.Nullified));
		UpdateSingleTemporaryVisualEffect(ref deathmarkEffectInstance, AssetReferences.deathmarkEffectPrefab, radius, HasBuff(RoR2Content.Buffs.DeathMark));
		UpdateSingleTemporaryVisualEffect(ref crocoRegenEffectInstance, AssetReferences.crocoRegenEffectPrefab, bestFitRadius, HasBuff(RoR2Content.Buffs.CrocoRegen));
		UpdateSingleTemporaryVisualEffect(ref mercExposeEffectInstance, AssetReferences.mercExposeEffectPrefab, radius, HasBuff(RoR2Content.Buffs.MercExpose));
		UpdateSingleTemporaryVisualEffect(ref lifestealOnHitEffectInstance, AssetReferences.lifestealOnHitEffectPrefab, bestFitRadius, HasBuff(RoR2Content.Buffs.LifeSteal));
		UpdateSingleTemporaryVisualEffect(ref teamWarCryEffectInstance, AssetReferences.teamWarCryEffectPrefab, bestFitRadius, HasBuff(RoR2Content.Buffs.TeamWarCry), "HeadCenter");
		UpdateSingleTemporaryVisualEffect(ref lunarGolemShieldEffectInstance, AssetReferences.lunarGolemShieldEffectPrefab, bestFitRadius, HasBuff(RoR2Content.Buffs.LunarShell));
		UpdateSingleTemporaryVisualEffect(ref randomDamageEffectInstance, AssetReferences.randomDamageEffectPrefab, radius, HasBuff(RoR2Content.Buffs.PowerBuff));
		UpdateSingleTemporaryVisualEffect(ref warbannerEffectInstance, AssetReferences.warbannerEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Warbanner));
		UpdateSingleTemporaryVisualEffect(ref teslaFieldEffectInstance, AssetReferences.teslaFieldEffectPrefab, bestFitRadius, HasBuff(RoR2Content.Buffs.TeslaField));
		UpdateSingleTemporaryVisualEffect(ref lunarSecondaryRootEffectInstance, AssetReferences.lunarSecondaryRootEffectPrefab, radius, HasBuff(RoR2Content.Buffs.LunarSecondaryRoot));
		UpdateSingleTemporaryVisualEffect(ref lunarDetonatorEffectInstance, AssetReferences.lunarDetonatorEffectPrefab, radius, HasBuff(RoR2Content.Buffs.LunarDetonationCharge));
		UpdateSingleTemporaryVisualEffect(ref fruitingEffectInstance, AssetReferences.fruitingEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Fruiting));
		UpdateSingleTemporaryVisualEffect(ref mushroomVoidTempEffectInstance, AssetReferences.mushroomVoidTempEffectPrefab, radius, HasBuff(DLC1Content.Buffs.MushroomVoidActive));
		UpdateSingleTemporaryVisualEffect(ref bearVoidTempEffectInstance, AssetReferences.bearVoidTempEffectPrefab, radius, HasBuff(DLC1Content.Buffs.BearVoidReady));
		UpdateSingleTemporaryVisualEffect(ref outOfCombatArmorEffectInstance, AssetReferences.outOfCombatArmorEffectPrefab, radius, HasBuff(DLC1Content.Buffs.OutOfCombatArmorBuff));
		UpdateSingleTemporaryVisualEffect(ref voidFogMildEffectInstance, AssetReferences.voidFogMildEffectPrefab, radius, HasBuff(RoR2Content.Buffs.VoidFogMild));
		UpdateSingleTemporaryVisualEffect(ref voidFogStrongEffectInstance, AssetReferences.voidFogStrongEffectPrefab, radius, HasBuff(RoR2Content.Buffs.VoidFogStrong));
		UpdateSingleTemporaryVisualEffect(ref voidRaidcrabWardWipeFogEffectInstance, AssetReferences.voidRaidcrabWardWipeFogEffectPrefab, radius, HasBuff(DLC1Content.Buffs.VoidRaidCrabWardWipeFog));
		UpdateSingleTemporaryVisualEffect(ref voidJailerSlowEffectInstance, AssetReferences.voidJailerSlowEffectPrefab, radius, HasBuff(DLC1Content.Buffs.JailerSlow));
		UpdateSingleTemporaryVisualEffect(ref aurelioniteBlessingEffectInstance, AssetReferences.aurelioniteBlessingEffectInstance, bestFitActualRadius, HasBuff(DLC2Content.Buffs.AurelioniteBlessing), "Pelvis");
		if ((bool)mushroomVoidTempEffectInstance && !HasBuff(DLC1Content.Buffs.MushroomVoidActive))
		{
			UnityEngine.Object.Destroy(mushroomVoidTempEffectInstance.gameObject);
		}
	}

	private void UpdateSingleTemporaryVisualEffect(ref TemporaryVisualEffect tempEffect, string resourceString, float effectRadius, bool active, string childLocatorOverride = "")
	{
		bool flag = tempEffect != null;
		if (flag == active)
		{
			return;
		}
		if (active)
		{
			if (flag)
			{
				return;
			}
			GameObject gameObject = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>(resourceString), corePosition, Quaternion.identity);
			tempEffect = gameObject.GetComponent<TemporaryVisualEffect>();
			tempEffect.parentTransform = coreTransform;
			tempEffect.visualState = TemporaryVisualEffect.VisualState.Enter;
			tempEffect.healthComponent = healthComponent;
			tempEffect.radius = effectRadius;
			LocalCameraEffect component = gameObject.GetComponent<LocalCameraEffect>();
			if ((bool)component)
			{
				component.targetCharacter = base.gameObject;
			}
			if (string.IsNullOrEmpty(childLocatorOverride))
			{
				return;
			}
			ChildLocator childLocator = modelLocator?.modelTransform?.GetComponent<ChildLocator>();
			if ((bool)childLocator)
			{
				Transform transform = childLocator.FindChild(childLocatorOverride);
				if ((bool)transform)
				{
					tempEffect.parentTransform = transform;
				}
			}
		}
		else if ((bool)tempEffect)
		{
			tempEffect.visualState = TemporaryVisualEffect.VisualState.Exit;
		}
	}

	private void UpdateSingleTemporaryVisualEffect(ref TemporaryVisualEffect tempEffect, GameObject tempEffectPrefab, float effectRadius, bool active, string childLocatorOverride = "")
	{
		bool flag = tempEffect != null;
		if (flag == active)
		{
			return;
		}
		if (active)
		{
			if (flag)
			{
				return;
			}
			if ((bool)tempEffectPrefab)
			{
				GameObject gameObject = UnityEngine.Object.Instantiate(tempEffectPrefab, corePosition, Quaternion.identity);
				tempEffect = gameObject.GetComponent<TemporaryVisualEffect>();
				tempEffect.parentTransform = coreTransform;
				tempEffect.visualState = TemporaryVisualEffect.VisualState.Enter;
				tempEffect.healthComponent = healthComponent;
				tempEffect.radius = effectRadius;
				LocalCameraEffect component = gameObject.GetComponent<LocalCameraEffect>();
				if ((bool)component)
				{
					component.targetCharacter = base.gameObject;
				}
				if (string.IsNullOrEmpty(childLocatorOverride))
				{
					return;
				}
				ChildLocator childLocator = modelLocator?.modelTransform?.GetComponent<ChildLocator>();
				if ((bool)childLocator)
				{
					Transform transform = childLocator.FindChild(childLocatorOverride);
					if ((bool)transform)
					{
						tempEffect.parentTransform = transform;
					}
				}
			}
			else
			{
				Debug.LogError("Can't instantiate null temporary visual effect");
			}
		}
		else if ((bool)tempEffect)
		{
			tempEffect.visualState = TemporaryVisualEffect.VisualState.Exit;
		}
	}

	public VisibilityLevel GetVisibilityLevel(CharacterBody observer)
	{
		return GetVisibilityLevel(observer ? observer.teamComponent.teamIndex : TeamIndex.None);
	}

	public VisibilityLevel GetVisibilityLevel(TeamIndex observerTeam)
	{
		if (!hasCloakBuff)
		{
			return VisibilityLevel.Visible;
		}
		if (teamComponent.teamIndex != observerTeam)
		{
			return VisibilityLevel.Cloaked;
		}
		return VisibilityLevel.Revealed;
	}

	public void AddSpreadBloom(float value)
	{
		spreadBloomInternal = Mathf.Min(spreadBloomInternal + value, 1f);
	}

	public void SetSpreadBloom(float value, bool canOnlyIncreaseBloom = true)
	{
		if (canOnlyIncreaseBloom)
		{
			spreadBloomInternal = Mathf.Clamp(value, spreadBloomInternal, 1f);
		}
		else
		{
			spreadBloomInternal = Mathf.Min(value, 1f);
		}
	}

	private void UpdateSpreadBloom(float dt)
	{
		float num = 1f / spreadBloomDecayTime;
		spreadBloomInternal = Mathf.Max(spreadBloomInternal - num * dt, 0f);
	}

	[Client]
	public void SendConstructTurret(CharacterBody builder, Vector3 position, Quaternion rotation, MasterCatalog.MasterIndex masterIndex)
	{
		if (!NetworkClient.active)
		{
			Debug.LogWarning("[Client] function 'System.Void RoR2.CharacterBody::SendConstructTurret(RoR2.CharacterBody,UnityEngine.Vector3,UnityEngine.Quaternion,RoR2.MasterCatalog/MasterIndex)' called on server");
			return;
		}
		ConstructTurretMessage msg = new ConstructTurretMessage
		{
			builder = builder.gameObject,
			position = position,
			rotation = rotation,
			turretMasterIndex = masterIndex
		};
		ClientScene.readyConnection.Send(62, msg);
	}

	[NetworkMessageHandler(msgType = 62, server = true)]
	private static void HandleConstructTurret(NetworkMessage netMsg)
	{
		ConstructTurretMessage constructTurretMessage = netMsg.ReadMessage<ConstructTurretMessage>();
		if (!constructTurretMessage.builder)
		{
			return;
		}
		CharacterBody component = constructTurretMessage.builder.GetComponent<CharacterBody>();
		if ((bool)component)
		{
			CharacterMaster characterMaster = component.master;
			if ((bool)characterMaster)
			{
				CharacterMaster characterMaster2 = new MasterSummon
				{
					masterPrefab = MasterCatalog.GetMasterPrefab(constructTurretMessage.turretMasterIndex),
					position = constructTurretMessage.position,
					rotation = constructTurretMessage.rotation,
					summonerBodyObject = component.gameObject,
					ignoreTeamMemberLimit = true,
					inventoryToCopy = characterMaster.inventory
				}.Perform();
				Deployable deployable = characterMaster2.gameObject.AddComponent<Deployable>();
				deployable.onUndeploy = new UnityEvent();
				deployable.onUndeploy.AddListener(characterMaster2.TrueKill);
				characterMaster.AddDeployable(deployable, DeployableSlot.EngiTurret);
			}
		}
	}

	public void AddIncreasedDamageMultiKillTime()
	{
		increasedDamageKillTimer = 5f;
	}

	[Server]
	public void AddMultiKill(int kills)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddMultiKill(System.Int32)' called on client");
			return;
		}
		multiKillTimer = 1f;
		multiKillCount += kills;
		int num = (inventory ? inventory.GetItemCount(RoR2Content.Items.WarCryOnMultiKill) : 0);
		if (num > 0 && multiKillCount >= 4)
		{
			AddTimedBuff(RoR2Content.Buffs.WarCryBuff, 2f + 4f * (float)num);
		}
		increasedDamageKillTimer = 5f;
		increasedDamageKillCount += kills;
		increasedDamageKillCountBuff += kills;
		if ((((bool)inventory && inventory.GetItemCount(DLC2Content.Items.IncreaseDamageOnMultiKill) != 0) ? 1 : 0) > (false ? 1 : 0))
		{
			if (increasedDamageKillCountBuff >= 5)
			{
				AddBuff(DLC2Content.Buffs.IncreaseDamageBuff);
				EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/IncreaseDamageOnMultiKillVFX"), new EffectData
				{
					origin = base.gameObject.transform.position
				}, transmit: true);
				increasedDamageKillCountBuff = 0;
			}
			if (increasedDamageKillCount > oldKillcount)
			{
				oldKillcount = increasedDamageKillCount;
			}
		}
	}

	[Server]
	private void UpdateMultiKill(float deltaTime)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::UpdateMultiKill(System.Single)' called on client");
			return;
		}
		multiKillTimer -= deltaTime;
		if (multiKillTimer <= 0f)
		{
			multiKillTimer = 0f;
			multiKillCount = 0;
		}
		increasedDamageKillTimer -= deltaTime;
		if (increasedDamageKillTimer <= 0f)
		{
			increasedDamageKillTimer = 0f;
			increasedDamageKillCount = 0;
			increasedDamageKillCountBuff = 0;
			oldKillcount = 0;
			oldComboMeter = 0;
			if (HasBuff(DLC2Content.Buffs.IncreaseDamageBuff))
			{
				RemoveBuff(DLC2Content.Buffs.IncreaseDamageBuff);
			}
		}
	}

	public void AddIncreasePrimaryDamageStack()
	{
		int buffCount = GetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff);
		int itemCount = inventory.GetItemCount(DLC2Content.Items.IncreasePrimaryDamage);
		int num = 4 + itemCount;
		if (buffCount < num)
		{
			AddBuff(DLC2Content.Buffs.IncreasePrimaryDamageBuff);
		}
		buffCount = GetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff);
		TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.IncreasePrimaryDamage.itemIndex, buffCount));
		float num2 = baseDamage + levelDamage * (level - 1f);
		luminousShotDamage = num2 * (1.25f + 0.25f * (float)itemCount) * (float)buffCount;
	}

	public void IncreasePrimaryDamageReset()
	{
		if (GetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff) > 0)
		{
			SetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff.buffIndex, 0);
			TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.IncreasePrimaryDamage.itemIndex, 0f));
		}
		luminousShotReady = false;
	}

	[Server]
	private void UpdateDelayedDamage(float deltaTime)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::UpdateDelayedDamage(System.Single)' called on client");
			return;
		}
		int num = (inventory ? inventory.GetItemCount(DLC2Content.Items.DelayedDamage) : 0);
		if (num > 0)
		{
			int buffCount = GetBuffCount(DLC2Content.Buffs.DelayedDamageBuff);
			if (oldDelayedDamageCount < num)
			{
				int num2 = num - oldDelayedDamageCount;
				for (int i = 0; i < num2; i++)
				{
					AddBuff(DLC2Content.Buffs.DelayedDamageBuff);
				}
				oldDelayedDamageCount = num;
			}
			else if (oldDelayedDamageCount > num)
			{
				oldDelayedDamageCount = num;
			}
			if (buffCount < num)
			{
				delayedDamageRefreshTime -= deltaTime;
				if (delayedDamageRefreshTime <= 0f)
				{
					AddBuff(DLC2Content.Buffs.DelayedDamageBuff);
					delayedDamageRefreshTime = 10f;
				}
			}
		}
		else
		{
			delayedDamageRefreshTime = 10f;
			oldDelayedDamageCount = 0;
			RemoveBuff(DLC2Content.Buffs.DelayedDamageBuff);
			RemoveBuff(DLC2Content.Buffs.DelayedDamageDebuff);
			RemoveOldestTimedBuff(DLC2Content.Buffs.DelayedDamageDebuff);
		}
	}

	public void SpawnDelayedDamageEffect()
	{
		if (NetworkServer.active)
		{
			ServerSpawnDelayedDamageEffect();
		}
		else
		{
			CallCmdSpawnDelayedDamageEffect();
		}
	}

	[Server]
	private void ServerSpawnDelayedDamageEffect()
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::ServerSpawnDelayedDamageEffect()' called on client");
		}
		else
		{
			UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/DelayedDamageIndicator"), mainHurtBox ? mainHurtBox.transform.position : transform.position, Quaternion.identity, mainHurtBox ? mainHurtBox.transform : transform);
		}
	}

	[Command]
	private void CmdSpawnDelayedDamageEffect()
	{
		ServerSpawnDelayedDamageEffect();
	}

	public void SecondHalfOfDelayedDamage(DamageInfo halfDamage)
	{
		RemoveBuff(DLC2Content.Buffs.DelayedDamageBuff);
		AddBuff(DLC2Content.Buffs.DelayedDamageDebuff);
		TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.DelayedDamage.itemIndex, 0f));
		DelayedDamageInfo delayedDamageInfo = new DelayedDamageInfo();
		delayedDamageInfo.halfDamage = halfDamage;
		incomingDamageList.Add(delayedDamageInfo);
		if (incomingDamageList.Count == 0)
		{
			halfDamageReady = false;
		}
		else
		{
			halfDamageReady = true;
		}
	}

	[Server]
	private void UpdateSecondHalfOfDamage(float deltaTime)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::UpdateSecondHalfOfDamage(System.Single)' called on client");
		}
		else
		{
			if (!halfDamageReady)
			{
				return;
			}
			for (int i = 0; i < incomingDamageList.Count; i++)
			{
				DelayedDamageInfo delayedDamageInfo = incomingDamageList[i];
				DamageInfo halfDamage = delayedDamageInfo.halfDamage;
				halfDamage.position = GetBody().corePosition;
				if (protectFromOneShot)
				{
					halfDamage.damageType = DamageType.NonLethal;
				}
				delayedDamageInfo.timeUntilDamage -= deltaTime;
				if (delayedDamageInfo.timeUntilDamage <= 0f)
				{
					Util.PlaySound("Play_item_proc_delayedDamage_2ndHit", base.gameObject);
					healthComponent.TakeDamage(halfDamage);
					RemoveBuff(DLC2Content.Buffs.DelayedDamageDebuff);
					incomingDamageList.RemoveAt(i);
					protectFromOneShot = false;
				}
			}
		}
	}

	[ClientRpc]
	public void RpcTeleportCharacterToSafety()
	{
		if (!hasEffectiveAuthority)
		{
			return;
		}
		Transform transform = modelLocator?.modelTransform;
		if (!(transform == null))
		{
			CharacterModel component = transform.GetComponent<CharacterModel>();
			Vector3 position = coreTransform.position;
			int itemCount = inventory.GetItemCount(DLC2Content.Items.TeleportOnLowHealth);
			BlastAttack blastAttack = new BlastAttack();
			blastAttack.attacker = base.gameObject;
			blastAttack.baseDamage = damage * ((float)itemCount * 3.5f);
			blastAttack.baseForce = 2000f;
			blastAttack.bonusForce = Vector3.zero;
			blastAttack.attackerFiltering = AttackerFiltering.NeverHitSelf;
			blastAttack.crit = RollCrit();
			blastAttack.damageColorIndex = DamageColorIndex.Item;
			blastAttack.damageType = DamageType.Generic;
			blastAttack.falloffModel = BlastAttack.FalloffModel.None;
			blastAttack.inflictor = base.gameObject;
			blastAttack.position = position;
			blastAttack.procChainMask = default(ProcChainMask);
			blastAttack.procCoefficient = 1f;
			blastAttack.radius = 25f;
			blastAttack.losType = BlastAttack.LoSType.None;
			blastAttack.teamIndex = TeamIndex.Player;
			blastAttack.Fire();
			EffectManager.SpawnEffect(CommonAssets.teleportOnLowHealthExplosion, new EffectData
			{
				origin = position,
				scale = 50f,
				rotation = Quaternion.identity
			}, transmit: true);
			Util.PlaySound("Play_item_proc_teleportOnLowHealth", base.gameObject);
			NodeGraph nodeGraph = SceneInfo.instance.GetNodeGraph(MapNodeGroup.GraphType.Ground);
			List<NodeGraph.NodeIndex> source = nodeGraph.FindNodesInRange(corePosition, 100f, 200f, HullMask.Human);
			nodeGraph.GetNodePosition(source.First(), out var position2);
			TeleportHelper.TeleportBody(this, position2);
			TeleportOutController.AddTPOutEffect(component, 1f, 0f, 1f);
			EffectManager.SpawnEffect(CommonAssets.teleportOnLowHealthVFX, new EffectData
			{
				origin = this.transform.position,
				rotation = Quaternion.identity
			}, transmit: true);
			Vector3 normalized = (position - position2).normalized;
			if ((bool)characterDirection)
			{
				characterDirection.forward = normalized;
			}
			if ((bool)master && (bool)master.playerCharacterMasterController)
			{
				master.playerCharacterMasterController.RedirectCamera(Quaternion.LookRotation(normalized).eulerAngles);
			}
		}
	}

	private void prayerBeadCalculateAppliedStats(float levelStat)
	{
		if (teamComponent.teamIndex == TeamIndex.Player)
		{
			float num = (float)GetBuffCount(DLC2Content.Buffs.ExtraStatsOnLevelUpBuff) * levelStat * (0.2f + 0.05f * (float)(inventory.GetItemCount(DLC2Content.Items.ExtraStatsOnLevelUp) - 1));
			if (levelStat == levelMaxHealth)
			{
				_ = inventory.beadAppliedHealth;
				inventory.beadAppliedHealth += num;
			}
			else if (levelStat == levelMaxShield)
			{
				_ = inventory.beadAppliedShield;
				inventory.beadAppliedShield += num;
			}
			else if (levelStat == levelRegen)
			{
				_ = inventory.beadAppliedRegen;
				inventory.beadAppliedRegen += num;
			}
			else if (levelStat == levelDamage)
			{
				_ = inventory.beadAppliedDamage;
				inventory.beadAppliedDamage += num;
			}
		}
	}

	[HideInInspector]
	public void runicLensUpdateVariables(float damage, Vector3 position, DamageInfo damageInfo, float blastForce, float blastRadius)
	{
		runicLensPosition = position;
		runicLensImpactTime = Run.instance.time + 2f;
		runicLensMeteorReady = true;
		runicLensDamage = damage;
		runicLensDamageInfo = damageInfo;
		runicLensBlastForce = blastForce;
		runicLensBlastRadius = blastRadius;
	}

	public void detonateRunicLensMeteor()
	{
		GameObject gameObject = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/RunicMeteorStrikeImpact");
		Util.PlaySound("Play_item_proc_meteorAttackOnHighDamage_impact", base.gameObject);
		EffectData effectData = new EffectData
		{
			origin = runicLensPosition
		};
		EffectManager.SpawnEffect(gameObject, effectData, transmit: true);
		BlastAttack blastAttack = new BlastAttack();
		blastAttack.falloffModel = BlastAttack.FalloffModel.None;
		blastAttack.inflictor = gameObject;
		blastAttack.baseDamage = runicLensDamage;
		blastAttack.baseForce = runicLensBlastForce;
		blastAttack.attackerFiltering = AttackerFiltering.Default;
		blastAttack.crit = runicLensDamageInfo.crit;
		blastAttack.attacker = runicLensDamageInfo.attacker;
		blastAttack.bonusForce = Vector3.zero;
		blastAttack.damageColorIndex = DamageColorIndex.Item;
		blastAttack.position = runicLensPosition;
		blastAttack.procChainMask = default(ProcChainMask);
		blastAttack.procCoefficient = 0.5f;
		blastAttack.teamIndex = TeamIndex.Player;
		blastAttack.radius = runicLensBlastRadius;
		blastAttack.Fire();
	}

	public void TriggerEnemyDebuffs(DamageInfo damageInfo)
	{
		SphereSearch sphereSearch = new SphereSearch();
		List<HurtBox> list = CollectionPool<HurtBox, List<HurtBox>>.RentCollection();
		sphereSearch.mask = LayerIndex.entityPrecise.mask;
		sphereSearch.origin = base.gameObject.transform.position;
		sphereSearch.radius = 30f;
		sphereSearch.queryTriggerInteraction = QueryTriggerInteraction.UseGlobal;
		sphereSearch.RefreshCandidates();
		sphereSearch.FilterCandidatesByHurtBoxTeam(TeamMask.GetEnemyTeams(teamComponent.teamIndex));
		sphereSearch.OrderCandidatesByDistance();
		sphereSearch.FilterCandidatesByDistinctHurtBoxEntities();
		sphereSearch.GetHurtBoxes(list);
		sphereSearch.ClearCandidates();
		EffectManager.SpawnEffect(CommonAssets.thornExplosionEffect, new EffectData
		{
			origin = coreTransform.position,
			scale = 60f,
			rotation = Quaternion.identity
		}, transmit: true);
		Util.PlaySound("Play_item_proc_triggerEnemyDebuffs", base.gameObject);
		for (int i = 0; i < list.Count; i++)
		{
			HurtBox hurtBox = list[i];
			if (!hurtBox || !hurtBox.healthComponent || !hurtBox.healthComponent.alive)
			{
				continue;
			}
			CharacterBody body = hurtBox.healthComponent.body;
			int itemCount = inventory.GetItemCount(DLC2Content.Items.TriggerEnemyDebuffs);
			int num = 1;
			if (!body.hasStackableDebuff)
			{
				DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.Bleed, 3f * damageInfo.procCoefficient);
				continue;
			}
			int buffCount = body.GetBuffCount(RoR2Content.Buffs.OnFire);
			if (buffCount > 0)
			{
				float num2 = 0.5f;
				int num3 = num * itemCount;
				InflictDotInfo inflictDotInfo = default(InflictDotInfo);
				inflictDotInfo.attackerObject = damageInfo.attacker;
				inflictDotInfo.victimObject = body.gameObject;
				inflictDotInfo.totalDamage = damageInfo.damage * num2;
				inflictDotInfo.damageMultiplier = 1f;
				inflictDotInfo.dotIndex = DotController.DotIndex.Burn;
				InflictDotInfo inflictDotInfo2 = inflictDotInfo;
				for (int j = 0; j < num3; j++)
				{
					DotController.InflictDot(ref inflictDotInfo2);
				}
			}
			buffCount = body.GetBuffCount(RoR2Content.Buffs.BeetleJuice);
			if (buffCount > 0)
			{
				int newCount = buffCount + num * itemCount;
				body.SetBuffCount(RoR2Content.Buffs.BeetleJuice.buffIndex, newCount);
			}
			buffCount = body.GetBuffCount(RoR2Content.Buffs.NullifyStack);
			if (buffCount > 0)
			{
				int newCount2 = buffCount + num * itemCount;
				body.SetBuffCount(RoR2Content.Buffs.NullifyStack.buffIndex, newCount2);
			}
			buffCount = body.GetBuffCount(RoR2Content.Buffs.Bleeding);
			if (buffCount > 0)
			{
				int num4 = num * itemCount;
				for (int k = 0; k < num4; k++)
				{
					DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.Bleed, 3f * damageInfo.procCoefficient);
				}
			}
			buffCount = body.GetBuffCount(RoR2Content.Buffs.SuperBleed);
			if (buffCount > 0)
			{
				int num5 = num * itemCount;
				for (int l = 0; l < num5; l++)
				{
					DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.SuperBleed, 15f * damageInfo.procCoefficient);
				}
			}
			buffCount = body.GetBuffCount(RoR2Content.Buffs.Blight);
			if (buffCount > 0)
			{
				int num6 = num * itemCount;
				for (int m = 0; m < num6; m++)
				{
					DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.Blight, 5f * damageInfo.procCoefficient);
				}
			}
			buffCount = body.GetBuffCount(RoR2Content.Buffs.Overheat);
			if (buffCount > 0)
			{
				int newCount3 = buffCount + num * itemCount;
				body.SetBuffCount(RoR2Content.Buffs.Overheat.buffIndex, newCount3);
			}
			buffCount = body.GetBuffCount(RoR2Content.Buffs.PulverizeBuildup);
			if (buffCount > 0)
			{
				int newCount4 = buffCount + num * itemCount;
				body.SetBuffCount(RoR2Content.Buffs.PulverizeBuildup.buffIndex, newCount4);
			}
			buffCount = body.GetBuffCount(DLC1Content.Buffs.StrongerBurn);
			if (buffCount > 0)
			{
				int num7 = num * itemCount;
				for (int n = 0; n < num7; n++)
				{
					DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.StrongerBurn, 3f * damageInfo.procCoefficient);
				}
			}
			buffCount = body.GetBuffCount(DLC1Content.Buffs.Fracture);
			if (buffCount > 0)
			{
				int num8 = num * itemCount;
				DotController.DotDef dotDef = DotController.GetDotDef(DotController.DotIndex.Fracture);
				for (int num9 = 0; num9 < num8; num9++)
				{
					DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.Fracture, dotDef.interval);
				}
			}
			buffCount = body.GetBuffCount(DLC1Content.Buffs.PermanentDebuff);
			if (buffCount > 0)
			{
				int newCount5 = buffCount + num * itemCount;
				body.SetBuffCount(DLC1Content.Buffs.PermanentDebuff.buffIndex, newCount5);
			}
			buffCount = body.GetBuffCount(DLC2Content.Buffs.lunarruin);
			if (buffCount > 0)
			{
				int num10 = buffCount + num * itemCount;
				body.SetBuffCount(DLC2Content.Buffs.lunarruin.buffIndex, num10);
				for (int num11 = 0; num11 < num10; num11++)
				{
					DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.LunarRuin, 5f);
				}
			}
		}
	}

	private void IncreaseStunPierceDamage(int kills)
	{
	}

	public void ApplyTamperedHeartPassive(float heartRegen, float heartMSpeed, float heartDamage, float armor, float attackSpeed)
	{
		tamperedHeartActive = true;
		tamperedHeartRegenBonus = heartRegen;
		tamperedHeartMSpeedBonus = heartMSpeed;
		tamperedHeartDamageBonus = heartDamage;
		tamperedHeartAttackSpeedBonus = attackSpeed;
		tamperedHeartArmorBonus = armor;
	}

	public void AddFreeChestBuff()
	{
		int itemCount = inventory.GetItemCount(DLC2Content.Items.OnLevelUpFreeUnlock);
		for (int i = 0; i < itemCount; i++)
		{
			AddBuff(DLC2Content.Buffs.FreeUnlocks.buffIndex);
		}
	}

	[ClientRpc]
	public void RpcBark()
	{
		if ((bool)sfxLocator)
		{
			Util.PlaySound(sfxLocator.barkSound, base.gameObject);
		}
	}

	[Command]
	public void CmdRequestVehicleEjection()
	{
		if ((bool)currentVehicle)
		{
			currentVehicle.EjectPassenger(base.gameObject);
		}
	}

	public bool RollCrit()
	{
		if ((bool)master)
		{
			return Util.CheckRoll(crit, master);
		}
		return false;
	}

	public bool IsCullable()
	{
		if (!dontCull && Importance - TeamComponent.GetTeamAverageImportance(teamComponent) < 3 && teamComponent.teamIndex != TeamIndex.Player && !isBoss)
		{
			return TeamComponent.GetTeamMembers(TeamIndex.Monster).Count >= 10;
		}
		return false;
	}

	public bool IsActivelyCullable()
	{
		if (!isBoss)
		{
			if (!NearAnyPlayers(75f))
			{
				return !CharacterIsVisible;
			}
			return false;
		}
		return false;
	}

	public bool NearAnyPlayers(float checkRadius)
	{
		float num = checkRadius * checkRadius;
		foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
		{
			if ((bool)instance.master && (bool)instance.master.GetBody() && (transform.position - instance.master.GetBody().transform.position).sqrMagnitude < num)
			{
				return true;
			}
		}
		return false;
	}

	[ClientRpc]
	private void RpcUsePreferredInitialStateType()
	{
		if (hasEffectiveAuthority)
		{
			SetBodyStateToPreferredInitialState();
		}
	}

	public void SetBodyStateToPreferredInitialState()
	{
		if (!hasEffectiveAuthority)
		{
			if (NetworkServer.active)
			{
				CallRpcUsePreferredInitialStateType();
			}
			return;
		}
		Type stateType = preferredInitialStateType.stateType;
		if (!(stateType == null) && !(stateType == typeof(Uninitialized)))
		{
			EntityStateMachine.FindByCustomName(base.gameObject, "Body")?.SetState(EntityStateCatalog.InstantiateState(stateType));
		}
	}

	[Server]
	public void SetLoadoutServer(Loadout loadout)
	{
		if (!NetworkServer.active)
		{
			Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::SetLoadoutServer(RoR2.Loadout)' called on client");
		}
		else
		{
			skillLocator.ApplyLoadoutServer(loadout, bodyIndex);
		}
	}

	static CharacterBody()
	{
		instancesList = new List<CharacterBody>();
		readOnlyInstancesList = new ReadOnlyCollection<CharacterBody>(instancesList);
		kCmdCmdAddTimedBuff = -160178508;
		NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdAddTimedBuff, InvokeCmdCmdAddTimedBuff);
		kCmdCmdSetInLava = 234733148;
		NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdSetInLava, InvokeCmdCmdSetInLava);
		kCmdCmdUpdateSprint = -1006016914;
		NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdUpdateSprint, InvokeCmdCmdUpdateSprint);
		kCmdCmdOnSkillActivated = 384138986;
		NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdOnSkillActivated, InvokeCmdCmdOnSkillActivated);
		kCmdCmdTransmitItemBehavior = 394448000;
		NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdTransmitItemBehavior, InvokeCmdCmdTransmitItemBehavior);
		kCmdCmdSpawnDelayedDamageEffect = 1860577938;
		NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdSpawnDelayedDamageEffect, InvokeCmdCmdSpawnDelayedDamageEffect);
		kCmdCmdRequestVehicleEjection = 1803737791;
		NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdRequestVehicleEjection, InvokeCmdCmdRequestVehicleEjection);
		kRpcRpcTransmitItemBehavior = -729896618;
		NetworkBehaviour.RegisterRpcDelegate(typeof(CharacterBody), kRpcRpcTransmitItemBehavior, InvokeRpcRpcTransmitItemBehavior);
		kRpcRpcTeleportCharacterToSafety = -245876694;
		NetworkBehaviour.RegisterRpcDelegate(typeof(CharacterBody), kRpcRpcTeleportCharacterToSafety, InvokeRpcRpcTeleportCharacterToSafety);
		kRpcRpcBark = -76716871;
		NetworkBehaviour.RegisterRpcDelegate(typeof(CharacterBody), kRpcRpcBark, InvokeRpcRpcBark);
		kRpcRpcUsePreferredInitialStateType = 638695010;
		NetworkBehaviour.RegisterRpcDelegate(typeof(CharacterBody), kRpcRpcUsePreferredInitialStateType, InvokeRpcRpcUsePreferredInitialStateType);
		NetworkCRC.RegisterBehaviour("CharacterBody", 0);
	}

	private void UNetVersion()
	{
	}

	protected static void InvokeCmdCmdAddTimedBuff(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkServer.active)
		{
			Debug.LogError("Command CmdAddTimedBuff called on client.");
		}
		else
		{
			((CharacterBody)obj).CmdAddTimedBuff((BuffIndex)reader.ReadInt32(), reader.ReadSingle());
		}
	}

	protected static void InvokeCmdCmdSetInLava(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkServer.active)
		{
			Debug.LogError("Command CmdSetInLava called on client.");
		}
		else
		{
			((CharacterBody)obj).CmdSetInLava(reader.ReadBoolean());
		}
	}

	protected static void InvokeCmdCmdUpdateSprint(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkServer.active)
		{
			Debug.LogError("Command CmdUpdateSprint called on client.");
		}
		else
		{
			((CharacterBody)obj).CmdUpdateSprint(reader.ReadBoolean());
		}
	}

	protected static void InvokeCmdCmdOnSkillActivated(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkServer.active)
		{
			Debug.LogError("Command CmdOnSkillActivated called on client.");
		}
		else
		{
			((CharacterBody)obj).CmdOnSkillActivated((sbyte)reader.ReadPackedUInt32());
		}
	}

	protected static void InvokeCmdCmdTransmitItemBehavior(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkServer.active)
		{
			Debug.LogError("Command CmdTransmitItemBehavior called on client.");
		}
		else
		{
			((CharacterBody)obj).CmdTransmitItemBehavior(GeneratedNetworkCode._ReadNetworkItemBehaviorData_CharacterBody(reader));
		}
	}

	protected static void InvokeCmdCmdSpawnDelayedDamageEffect(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkServer.active)
		{
			Debug.LogError("Command CmdSpawnDelayedDamageEffect called on client.");
		}
		else
		{
			((CharacterBody)obj).CmdSpawnDelayedDamageEffect();
		}
	}

	protected static void InvokeCmdCmdRequestVehicleEjection(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkServer.active)
		{
			Debug.LogError("Command CmdRequestVehicleEjection called on client.");
		}
		else
		{
			((CharacterBody)obj).CmdRequestVehicleEjection();
		}
	}

	public void CallCmdAddTimedBuff(BuffIndex buffType, float duration)
	{
		if (!NetworkClient.active)
		{
			Debug.LogError("Command function CmdAddTimedBuff called on server.");
			return;
		}
		if (base.isServer)
		{
			CmdAddTimedBuff(buffType, duration);
			return;
		}
		NetworkWriter networkWriter = new NetworkWriter();
		networkWriter.Write((short)0);
		networkWriter.Write((short)5);
		networkWriter.WritePackedUInt32((uint)kCmdCmdAddTimedBuff);
		networkWriter.Write(GetComponent<NetworkIdentity>().netId);
		networkWriter.Write((int)buffType);
		networkWriter.Write(duration);
		SendCommandInternal(networkWriter, 0, "CmdAddTimedBuff");
	}

	public void CallCmdSetInLava(bool b)
	{
		if (!NetworkClient.active)
		{
			Debug.LogError("Command function CmdSetInLava called on server.");
			return;
		}
		if (base.isServer)
		{
			CmdSetInLava(b);
			return;
		}
		NetworkWriter networkWriter = new NetworkWriter();
		networkWriter.Write((short)0);
		networkWriter.Write((short)5);
		networkWriter.WritePackedUInt32((uint)kCmdCmdSetInLava);
		networkWriter.Write(GetComponent<NetworkIdentity>().netId);
		networkWriter.Write(b);
		SendCommandInternal(networkWriter, 0, "CmdSetInLava");
	}

	public void CallCmdUpdateSprint(bool newIsSprinting)
	{
		if (!NetworkClient.active)
		{
			Debug.LogError("Command function CmdUpdateSprint called on server.");
			return;
		}
		if (base.isServer)
		{
			CmdUpdateSprint(newIsSprinting);
			return;
		}
		NetworkWriter networkWriter = new NetworkWriter();
		networkWriter.Write((short)0);
		networkWriter.Write((short)5);
		networkWriter.WritePackedUInt32((uint)kCmdCmdUpdateSprint);
		networkWriter.Write(GetComponent<NetworkIdentity>().netId);
		networkWriter.Write(newIsSprinting);
		SendCommandInternal(networkWriter, 0, "CmdUpdateSprint");
	}

	public void CallCmdOnSkillActivated(sbyte skillIndex)
	{
		if (!NetworkClient.active)
		{
			Debug.LogError("Command function CmdOnSkillActivated called on server.");
			return;
		}
		if (base.isServer)
		{
			CmdOnSkillActivated(skillIndex);
			return;
		}
		NetworkWriter networkWriter = new NetworkWriter();
		networkWriter.Write((short)0);
		networkWriter.Write((short)5);
		networkWriter.WritePackedUInt32((uint)kCmdCmdOnSkillActivated);
		networkWriter.Write(GetComponent<NetworkIdentity>().netId);
		networkWriter.WritePackedUInt32((uint)skillIndex);
		SendCommandInternal(networkWriter, 0, "CmdOnSkillActivated");
	}

	public void CallCmdTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData)
	{
		if (!NetworkClient.active)
		{
			Debug.LogError("Command function CmdTransmitItemBehavior called on server.");
			return;
		}
		if (base.isServer)
		{
			CmdTransmitItemBehavior(itemBehaviorData);
			return;
		}
		NetworkWriter networkWriter = new NetworkWriter();
		networkWriter.Write((short)0);
		networkWriter.Write((short)5);
		networkWriter.WritePackedUInt32((uint)kCmdCmdTransmitItemBehavior);
		networkWriter.Write(GetComponent<NetworkIdentity>().netId);
		GeneratedNetworkCode._WriteNetworkItemBehaviorData_CharacterBody(networkWriter, itemBehaviorData);
		SendCommandInternal(networkWriter, 0, "CmdTransmitItemBehavior");
	}

	public void CallCmdSpawnDelayedDamageEffect()
	{
		if (!NetworkClient.active)
		{
			Debug.LogError("Command function CmdSpawnDelayedDamageEffect called on server.");
			return;
		}
		if (base.isServer)
		{
			CmdSpawnDelayedDamageEffect();
			return;
		}
		NetworkWriter networkWriter = new NetworkWriter();
		networkWriter.Write((short)0);
		networkWriter.Write((short)5);
		networkWriter.WritePackedUInt32((uint)kCmdCmdSpawnDelayedDamageEffect);
		networkWriter.Write(GetComponent<NetworkIdentity>().netId);
		SendCommandInternal(networkWriter, 0, "CmdSpawnDelayedDamageEffect");
	}

	public void CallCmdRequestVehicleEjection()
	{
		if (!NetworkClient.active)
		{
			Debug.LogError("Command function CmdRequestVehicleEjection called on server.");
			return;
		}
		if (base.isServer)
		{
			CmdRequestVehicleEjection();
			return;
		}
		NetworkWriter networkWriter = new NetworkWriter();
		networkWriter.Write((short)0);
		networkWriter.Write((short)5);
		networkWriter.WritePackedUInt32((uint)kCmdCmdRequestVehicleEjection);
		networkWriter.Write(GetComponent<NetworkIdentity>().netId);
		SendCommandInternal(networkWriter, 0, "CmdRequestVehicleEjection");
	}

	protected static void InvokeRpcRpcTransmitItemBehavior(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkClient.active)
		{
			Debug.LogError("RPC RpcTransmitItemBehavior called on server.");
		}
		else
		{
			((CharacterBody)obj).RpcTransmitItemBehavior(GeneratedNetworkCode._ReadNetworkItemBehaviorData_CharacterBody(reader));
		}
	}

	protected static void InvokeRpcRpcTeleportCharacterToSafety(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkClient.active)
		{
			Debug.LogError("RPC RpcTeleportCharacterToSafety called on server.");
		}
		else
		{
			((CharacterBody)obj).RpcTeleportCharacterToSafety();
		}
	}

	protected static void InvokeRpcRpcBark(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkClient.active)
		{
			Debug.LogError("RPC RpcBark called on server.");
		}
		else
		{
			((CharacterBody)obj).RpcBark();
		}
	}

	protected static void InvokeRpcRpcUsePreferredInitialStateType(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkClient.active)
		{
			Debug.LogError("RPC RpcUsePreferredInitialStateType called on server.");
		}
		else
		{
			((CharacterBody)obj).RpcUsePreferredInitialStateType();
		}
	}

	public void CallRpcTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData)
	{
		if (!NetworkServer.active)
		{
			Debug.LogError("RPC Function RpcTransmitItemBehavior called on client.");
			return;
		}
		NetworkWriter networkWriter = new NetworkWriter();
		networkWriter.Write((short)0);
		networkWriter.Write((short)2);
		networkWriter.WritePackedUInt32((uint)kRpcRpcTransmitItemBehavior);
		networkWriter.Write(GetComponent<NetworkIdentity>().netId);
		GeneratedNetworkCode._WriteNetworkItemBehaviorData_CharacterBody(networkWriter, itemBehaviorData);
		SendRPCInternal(networkWriter, 1, "RpcTransmitItemBehavior");
	}

	public void CallRpcTeleportCharacterToSafety()
	{
		if (!NetworkServer.active)
		{
			Debug.LogError("RPC Function RpcTeleportCharacterToSafety called on client.");
			return;
		}
		NetworkWriter networkWriter = new NetworkWriter();
		networkWriter.Write((short)0);
		networkWriter.Write((short)2);
		networkWriter.WritePackedUInt32((uint)kRpcRpcTeleportCharacterToSafety);
		networkWriter.Write(GetComponent<NetworkIdentity>().netId);
		SendRPCInternal(networkWriter, 0, "RpcTeleportCharacterToSafety");
	}

	public void CallRpcBark()
	{
		if (!NetworkServer.active)
		{
			Debug.LogError("RPC Function RpcBark called on client.");
			return;
		}
		NetworkWriter networkWriter = new NetworkWriter();
		networkWriter.Write((short)0);
		networkWriter.Write((short)2);
		networkWriter.WritePackedUInt32((uint)kRpcRpcBark);
		networkWriter.Write(GetComponent<NetworkIdentity>().netId);
		SendRPCInternal(networkWriter, 0, "RpcBark");
	}

	public void CallRpcUsePreferredInitialStateType()
	{
		if (!NetworkServer.active)
		{
			Debug.LogError("RPC Function RpcUsePreferredInitialStateType called on client.");
			return;
		}
		NetworkWriter networkWriter = new NetworkWriter();
		networkWriter.Write((short)0);
		networkWriter.Write((short)2);
		networkWriter.WritePackedUInt32((uint)kRpcRpcUsePreferredInitialStateType);
		networkWriter.Write(GetComponent<NetworkIdentity>().netId);
		SendRPCInternal(networkWriter, 0, "RpcUsePreferredInitialStateType");
	}

	public override void PreStartClient()
	{
	}
}
