Decompiled source of soldier76 v1.0.2

plugins/LittleFight-soldier76mod/Soldier76Mod.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.AI.Walker;
using EntityStates.Commando.CommandoWeapon;
using HG;
using HG.BlendableTypes;
using On.RoR2;
using On.RoR2.Projectile;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.Achievements;
using RoR2.Audio;
using RoR2.CharacterAI;
using RoR2.ContentManagement;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.UI;
using Soldier76Mod.Components;
using Soldier76Mod.Modules;
using Soldier76Mod.Modules.Achievements;
using Soldier76Mod.Modules.Characters;
using Soldier76Mod.Survivors.Soldier76;
using Soldier76Mod.Survivors.Soldier76.Components;
using Soldier76Mod.Survivors.Soldier76.SkillStates;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Soldier76Mod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Soldier76Mod")]
[assembly: AssemblyTitle("Soldier76Mod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Soldier76Mod
{
	public class VisorOverlayController : MonoBehaviour
	{
		private class BracketInfo
		{
			public GameObject uiObject;

			public Image image;

			public RectTransform rectTransform;

			public CharacterBody trackedBody;

			public float currentAlpha;

			public float targetAlpha;

			public float hitAnimTimer;
		}

		[CompilerGenerated]
		private sealed class <DelayedVisorDuringSound>d__28 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public VisorOverlayController <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedVisorDuringSound>d__28(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.8f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					break;
				case 2:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)<>4__this.body != (Object)null && <>4__this.body.HasBuff(Soldier76Buffs.tacticalVisorBuff))
				{
					Soldier76Plugin.PlayVoiceWithVolume(((Component)<>4__this).gameObject, "Play_skill4_during", 0.3f);
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 2;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <FadeVisor>d__29 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public bool show;

			public bool enhanced;

			public VisorOverlayController <>4__this;

			private float <duration>5__1;

			private float <elapsed>5__2;

			private float <t>5__3;

			private float <t>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FadeVisor>d__29(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_011d: Unknown result type (might be due to invalid IL or missing references)
				//IL_01de: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_016f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0229: Unknown result type (might be due to invalid IL or missing references)
				//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<duration>5__1 = 0.3f;
					<elapsed>5__2 = 0f;
					if (show)
					{
						if (Object.op_Implicit((Object)(object)<>4__this.visorImage))
						{
							((Component)<>4__this.visorImage).gameObject.SetActive(true);
						}
						if (enhanced && Object.op_Implicit((Object)(object)<>4__this.blueTint))
						{
							((Component)<>4__this.blueTint).gameObject.SetActive(true);
						}
						goto IL_0192;
					}
					goto IL_031d;
				case 1:
					<>1__state = -1;
					goto IL_0192;
				case 2:
					{
						<>1__state = -1;
						goto IL_031d;
					}
					IL_031d:
					if (<elapsed>5__2 < <duration>5__1)
					{
						<elapsed>5__2 += Time.deltaTime;
						<t>5__4 = 1f - <elapsed>5__2 / <duration>5__1;
						if (Object.op_Implicit((Object)(object)<>4__this.visorImage))
						{
							((Graphic)<>4__this.visorImage).color = new Color(1f, 1f, 1f, <t>5__4 * 0.07f);
						}
						if (enhanced && Object.op_Implicit((Object)(object)<>4__this.blueTint))
						{
							((Graphic)<>4__this.blueTint).color = new Color(1f, 0f, 0f, <t>5__4 * 0.05f);
						}
						<>2__current = null;
						<>1__state = 2;
						return true;
					}
					if (Object.op_Implicit((Object)(object)<>4__this.visorImage))
					{
						((Component)<>4__this.visorImage).gameObject.SetActive(false);
					}
					if (Object.op_Implicit((Object)(object)<>4__this.blueTint))
					{
						((Component)<>4__this.blueTint).gameObject.SetActive(false);
					}
					break;
					IL_0192:
					if (<elapsed>5__2 < <duration>5__1)
					{
						<elapsed>5__2 += Time.deltaTime;
						<t>5__3 = <elapsed>5__2 / <duration>5__1;
						if (Object.op_Implicit((Object)(object)<>4__this.visorImage))
						{
							((Graphic)<>4__this.visorImage).color = new Color(1f, 1f, 1f, <t>5__3 * 0.07f);
						}
						if (enhanced && Object.op_Implicit((Object)(object)<>4__this.blueTint))
						{
							((Graphic)<>4__this.blueTint).color = new Color(1f, 0f, 0f, <t>5__3 * 0.05f);
						}
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					if (Object.op_Implicit((Object)(object)<>4__this.visorImage))
					{
						((Graphic)<>4__this.visorImage).color = new Color(1f, 1f, 1f, 0.07f);
					}
					if (enhanced && Object.op_Implicit((Object)(object)<>4__this.blueTint))
					{
						((Graphic)<>4__this.blueTint).color = new Color(1f, 0f, 0f, 0.05f);
					}
					break;
				}
				<>4__this.fadeRoutine = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private CharacterBody body;

		private RawImage visorImage;

		private RawImage blueTint;

		private Texture2D visorTexture;

		private Coroutine fadeRoutine;

		private bool isVisorActive;

		private bool hudReady;

		private List<BracketInfo> bracketPool = new List<BracketInfo>();

		private Dictionary<CharacterBody, BracketInfo> activeBrackets = new Dictionary<CharacterBody, BracketInfo>();

		private Texture2D bracketTexture;

		private Transform bracketParent;

		private float enemySearchTimer;

		private bool hooksRegistered;

		private const float BRACKET_SEARCH_INTERVAL = 0.2f;

		private const float BRACKET_FADE_SPEED = 8f;

		private const float BRACKET_HIT_SCALE = 1.7f;

		private const float BRACKET_HIT_DURATION = 0.2f;

		private const float BRACKET_UI_SIZE = 80f;

		private const float VISOR_SEARCH_RANGE = 200f;

		private const float VISOR_SEARCH_ANGLE = 55f;

		private const int MAX_BRACKETS = 25;

		private Canvas visorCanvas;

		private void Awake()
		{
			body = ((Component)this).GetComponent<CharacterBody>();
			visorTexture = Soldier76Assets._cachedVisorTexture;
			if ((Object)(object)visorTexture == (Object)null)
			{
				visorTexture = GenerateBorderTexture();
			}
			bracketTexture = GenerateBracketTexture();
		}

		private Texture2D LoadBracketTexture()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Soldier76Plugin.instance).Info.Location);
			string path = Path.Combine(directoryName, "texBracket.png");
			if (File.Exists(path))
			{
				try
				{
					byte[] array = File.ReadAllBytes(path);
					Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
					ImageConversion.LoadImage(val, array);
					val.Apply();
					Log.Info("Visor: 加载瞄准框贴图 texBracket.png");
					return val;
				}
				catch
				{
				}
			}
			return GenerateBracketTexture();
		}

		private bool EnsureHudSetup()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Expected O, but got Unknown
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			if (hudReady)
			{
				return true;
			}
			GameObject val = new GameObject("VisorCanvas", new Type[3]
			{
				typeof(Canvas),
				typeof(CanvasScaler),
				typeof(GraphicRaycaster)
			});
			Object.DontDestroyOnLoad((Object)(object)val);
			Canvas component = val.GetComponent<Canvas>();
			component.renderMode = (RenderMode)0;
			component.sortingOrder = 200;
			visorCanvas = component;
			CanvasScaler component2 = val.GetComponent<CanvasScaler>();
			component2.uiScaleMode = (ScaleMode)0;
			RectTransform component3 = val.GetComponent<RectTransform>();
			component3.anchorMin = Vector2.zero;
			component3.anchorMax = Vector2.one;
			component3.offsetMin = Vector2.zero;
			component3.offsetMax = Vector2.zero;
			GameObject val2 = new GameObject("VisorBlueTint", new Type[1] { typeof(RawImage) });
			val2.transform.SetParent(val.transform, false);
			blueTint = val2.GetComponent<RawImage>();
			((Graphic)blueTint).color = new Color(1f, 0f, 0f, 0f);
			((Graphic)blueTint).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)blueTint).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.offsetMin = Vector2.zero;
			rectTransform.offsetMax = Vector2.zero;
			val2.SetActive(false);
			GameObject val3 = new GameObject("VisorOverlay", new Type[1] { typeof(RawImage) });
			val3.transform.SetParent(val.transform, false);
			visorImage = val3.GetComponent<RawImage>();
			visorImage.texture = (Texture)(object)visorTexture;
			((Graphic)visorImage).color = new Color(1f, 1f, 1f, 0f);
			((Graphic)visorImage).raycastTarget = false;
			RectTransform rectTransform2 = ((Graphic)visorImage).rectTransform;
			rectTransform2.anchorMin = Vector2.zero;
			rectTransform2.anchorMax = Vector2.one;
			rectTransform2.offsetMin = Vector2.zero;
			rectTransform2.offsetMax = Vector2.zero;
			val3.SetActive(false);
			GameObject val4 = new GameObject("VisorBrackets", new Type[1] { typeof(RectTransform) });
			val4.transform.SetParent(val.transform, false);
			bracketParent = val4.transform;
			RectTransform component4 = val4.GetComponent<RectTransform>();
			component4.anchorMin = Vector2.zero;
			component4.anchorMax = Vector2.one;
			component4.offsetMin = Vector2.zero;
			component4.offsetMax = Vector2.zero;
			if (Object.op_Implicit((Object)(object)bracketTexture))
			{
				Object.Destroy((Object)(object)bracketTexture);
			}
			bracketTexture = LoadBracketTexture();
			RegisterHooks();
			hudReady = true;
			Log.Info("VisorOverlayController: 独立 Canvas 初始化完成");
			return true;
		}

		private void OnDestroy()
		{
			UnregisterHooks();
			foreach (KeyValuePair<CharacterBody, BracketInfo> activeBracket in activeBrackets)
			{
				if (Object.op_Implicit((Object)(object)activeBracket.Value.uiObject))
				{
					Object.Destroy((Object)(object)activeBracket.Value.uiObject);
				}
			}
			activeBrackets.Clear();
			foreach (BracketInfo item in bracketPool)
			{
				if (Object.op_Implicit((Object)(object)item.uiObject))
				{
					Object.Destroy((Object)(object)item.uiObject);
				}
			}
			bracketPool.Clear();
			if (Object.op_Implicit((Object)(object)bracketTexture))
			{
				Object.Destroy((Object)(object)bracketTexture);
			}
			if (Object.op_Implicit((Object)(object)bracketParent))
			{
				Object.Destroy((Object)(object)((Component)bracketParent).gameObject);
			}
			if (Object.op_Implicit((Object)(object)visorTexture))
			{
				Object.Destroy((Object)(object)visorTexture);
			}
			if (Object.op_Implicit((Object)(object)visorCanvas))
			{
				Object.Destroy((Object)(object)((Component)visorCanvas).gameObject);
			}
		}

		private void Update()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)body == (Object)null)
			{
				return;
			}
			bool flag = body.HasBuff(Soldier76Buffs.tacticalVisorBuff);
			if (flag != isVisorActive)
			{
				if (flag)
				{
					if (!EnsureHudSetup())
					{
						return;
					}
					((MonoBehaviour)this).StartCoroutine(DelayedVisorDuringSound());
				}
				else
				{
					Transform val = ((Component)this).transform.Find("S76Vol_30");
					if (Object.op_Implicit((Object)(object)val))
					{
						AkSoundEngine.ExecuteActionOnEvent("Play_skill4_during", (AkActionOnEventType)0, ((Component)val).gameObject);
					}
					Soldier76Plugin.PlayVoiceWithVolume(((Component)this).gameObject, "Play_skill4_end", 0.5f);
				}
				isVisorActive = flag;
				if (fadeRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(fadeRoutine);
				}
				bool enhanced = body.HasBuff(Soldier76Buffs.enhancedVisorBuff);
				fadeRoutine = ((MonoBehaviour)this).StartCoroutine(FadeVisor(flag, enhanced));
			}
			if (hudReady)
			{
				UpdateBrackets();
			}
		}

		[IteratorStateMachine(typeof(<DelayedVisorDuringSound>d__28))]
		private IEnumerator DelayedVisorDuringSound()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedVisorDuringSound>d__28(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<FadeVisor>d__29))]
		private IEnumerator FadeVisor(bool show, bool enhanced)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FadeVisor>d__29(0)
			{
				<>4__this = this,
				show = show,
				enhanced = enhanced
			};
		}

		private Texture2D GenerateBracketTexture()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			int num = 128;
			Texture2D val = new Texture2D(num, num, (TextureFormat)4, false);
			Color clear = Color.clear;
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(1f, 0.15f, 0.15f, 1f);
			int num2 = 7;
			int num3 = 25;
			int num4 = 2;
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					bool flag = false;
					if (j >= num4 && j < num4 + num3 && i >= num4 && i < num4 + num2)
					{
						flag = true;
					}
					if (j >= num4 && j < num4 + num2 && i >= num4 && i < num4 + num3)
					{
						flag = true;
					}
					if (j >= num - num4 - num3 && j < num - num4 && i >= num4 && i < num4 + num2)
					{
						flag = true;
					}
					if (j >= num - num4 - num2 && j < num - num4 && i >= num4 && i < num4 + num3)
					{
						flag = true;
					}
					if (j >= num4 && j < num4 + num3 && i >= num - num4 - num2 && i < num - num4)
					{
						flag = true;
					}
					if (j >= num4 && j < num4 + num2 && i >= num - num4 - num3 && i < num - num4)
					{
						flag = true;
					}
					if (j >= num - num4 - num3 && j < num - num4 && i >= num - num4 - num2 && i < num - num4)
					{
						flag = true;
					}
					if (j >= num - num4 - num2 && j < num - num4 && i >= num - num4 - num3 && i < num - num4)
					{
						flag = true;
					}
					val.SetPixel(j, i, flag ? val2 : clear);
				}
			}
			val.Apply();
			return val;
		}

		private Texture2D GenerateBorderTexture()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			int num = 512;
			int num2 = 512;
			Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.2f, 0.6f, 1f, 0.5f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0f, 0f, 0f, 0f);
			for (int i = 0; i < num2; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num3 = (float)j / (float)num;
					float num4 = (float)i / (float)num2;
					bool flag = num3 < 0.03f || num3 > 0.97f || num4 < 0.03f || num4 > 0.97f;
					val.SetPixel(j, i, flag ? val2 : val3);
				}
			}
			val.Apply();
			return val;
		}

		private void UpdateBrackets()
		{
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			if (!isVisorActive)
			{
				bool flag = false;
				foreach (BracketInfo item in activeBrackets.Values.ToList())
				{
					item.targetAlpha = 0f;
					ApplyBracketAlpha(item);
					if (item.currentAlpha <= 0.001f)
					{
						ReturnBracketToPool(item);
					}
					else
					{
						flag = true;
					}
				}
				if (!flag)
				{
					activeBrackets.Clear();
				}
			}
			else
			{
				if ((Object)(object)bracketParent == (Object)null)
				{
					return;
				}
				Camera main = Camera.main;
				if ((Object)(object)main == (Object)null)
				{
					return;
				}
				enemySearchTimer -= Time.deltaTime;
				if (enemySearchTimer <= 0f)
				{
					enemySearchTimer = 0.2f;
					RefreshEnemyList();
				}
				List<CharacterBody> list = new List<CharacterBody>();
				foreach (KeyValuePair<CharacterBody, BracketInfo> activeBracket in activeBrackets)
				{
					CharacterBody key = activeBracket.Key;
					BracketInfo value = activeBracket.Value;
					if ((Object)(object)key == (Object)null || !Object.op_Implicit((Object)(object)key.healthComponent) || !key.healthComponent.alive)
					{
						value.targetAlpha = 0f;
						ApplyBracketAlpha(value);
						if (value.currentAlpha <= 0.001f)
						{
							list.Add(key);
						}
						continue;
					}
					Vector3 corePosition = key.corePosition;
					Vector3 val = main.WorldToScreenPoint(corePosition);
					if (val.z <= 0f)
					{
						value.uiObject.SetActive(false);
						continue;
					}
					value.uiObject.SetActive(true);
					((Transform)value.rectTransform).position = new Vector3(val.x, val.y, 0f);
					float num = Vector3.Distance(((Component)main).transform.position, corePosition);
					float num2 = Mathf.Clamp(80f * (20f / Mathf.Max(num, 5f)), 35f, 80f);
					value.rectTransform.SetSizeWithCurrentAnchors((Axis)0, num2);
					value.rectTransform.SetSizeWithCurrentAnchors((Axis)1, num2);
					if (value.hitAnimTimer > 0f)
					{
						value.hitAnimTimer -= Time.deltaTime;
						float num3 = value.hitAnimTimer / 0.2f;
						float num4 = 1f + Mathf.Sin(num3 * MathF.PI) * 0.70000005f;
						((Transform)value.rectTransform).localScale = Vector3.one * num4;
						((Graphic)value.image).color = new Color(1f, 0.3f, 0.05f, value.currentAlpha);
					}
					else
					{
						((Transform)value.rectTransform).localScale = Vector3.one;
						((Graphic)value.image).color = new Color(1f, 0f, 0f, value.currentAlpha);
					}
					ApplyBracketAlpha(value);
				}
				foreach (CharacterBody item2 in list)
				{
					if (activeBrackets.TryGetValue(item2, out var value2))
					{
						ReturnBracketToPool(value2);
						activeBrackets.Remove(item2);
					}
				}
			}
		}

		private void RefreshEnemyList()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)body == (Object)null || !Object.op_Implicit((Object)(object)body.healthComponent) || !body.healthComponent.alive || (Object)(object)body.teamComponent == (Object)null)
			{
				return;
			}
			TeamIndex teamIndex = body.teamComponent.teamIndex;
			TeamMask enemyTeams = TeamMask.GetEnemyTeams(teamIndex);
			InputBankTest inputBank = body.inputBank;
			Vector3 val = (Object.op_Implicit((Object)(object)inputBank) ? inputBank.aimOrigin : body.corePosition);
			Vector3 val2 = (Object.op_Implicit((Object)(object)inputBank) ? inputBank.aimDirection : (Object.op_Implicit((Object)(object)Camera.main) ? ((Component)Camera.main).transform.forward : ((Component)this).transform.forward));
			HashSet<CharacterBody> hashSet = new HashSet<CharacterBody>();
			foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList)
			{
				if ((Object)(object)readOnlyInstances == (Object)null || (Object)(object)readOnlyInstances == (Object)(object)body || !Object.op_Implicit((Object)(object)readOnlyInstances.healthComponent) || !readOnlyInstances.healthComponent.alive || (Object)(object)readOnlyInstances.teamComponent == (Object)null || !((TeamMask)(ref enemyTeams)).HasTeam(readOnlyInstances.teamComponent.teamIndex))
				{
					continue;
				}
				Vector3 val3 = readOnlyInstances.corePosition - val;
				float magnitude = ((Vector3)(ref val3)).magnitude;
				if (!(magnitude > 200f))
				{
					float num = Vector3.Angle(val2, ((Vector3)(ref val3)).normalized);
					if (!(num > 55f))
					{
						hashSet.Add(readOnlyInstances);
					}
				}
			}
			foreach (CharacterBody item in activeBrackets.Keys.ToList())
			{
				if (((Object)(object)item == (Object)null || !hashSet.Contains(item)) && activeBrackets.TryGetValue(item, out var value))
				{
					value.targetAlpha = 0f;
					ApplyBracketAlpha(value);
					if (value.currentAlpha <= 0.001f)
					{
						ReturnBracketToPool(value);
						activeBrackets.Remove(item);
					}
				}
			}
			foreach (CharacterBody item2 in hashSet)
			{
				if (activeBrackets.TryGetValue(item2, out var value2))
				{
					value2.targetAlpha = 1f;
					continue;
				}
				BracketInfo bracketFromPool = GetBracketFromPool();
				if (bracketFromPool != null)
				{
					bracketFromPool.trackedBody = item2;
					bracketFromPool.currentAlpha = 0f;
					bracketFromPool.targetAlpha = 1f;
					bracketFromPool.hitAnimTimer = 0f;
					((Transform)bracketFromPool.rectTransform).localScale = Vector3.one;
					activeBrackets[item2] = bracketFromPool;
				}
			}
			if (hashSet.Count > 0 && !activeBrackets.Any())
			{
				Log.Info($"Visor: 找到 {hashSet.Count} 个敌人, 但 bracket 池为空");
			}
		}

		private BracketInfo GetBracketFromPool()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			if (bracketPool.Count > 0)
			{
				BracketInfo bracketInfo = bracketPool[bracketPool.Count - 1];
				bracketPool.RemoveAt(bracketPool.Count - 1);
				bracketInfo.uiObject.SetActive(true);
				return bracketInfo;
			}
			if (activeBrackets.Count + bracketPool.Count >= 25)
			{
				return null;
			}
			GameObject val = new GameObject("EnemyBracket", new Type[1] { typeof(Image) });
			val.transform.SetParent(bracketParent, false);
			Image component = val.GetComponent<Image>();
			component.sprite = Sprite.Create(bracketTexture, new Rect(0f, 0f, (float)((Texture)bracketTexture).width, (float)((Texture)bracketTexture).height), new Vector2(0.5f, 0.5f), 100f);
			((Graphic)component).raycastTarget = false;
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.5f, 0.5f);
			component2.anchorMax = new Vector2(0.5f, 0.5f);
			component2.pivot = new Vector2(0.5f, 0.5f);
			component2.sizeDelta = new Vector2(80f, 80f);
			return new BracketInfo
			{
				uiObject = val,
				image = component,
				rectTransform = component2,
				currentAlpha = 0f,
				targetAlpha = 0f
			};
		}

		private void ReturnBracketToPool(BracketInfo bracket)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)bracket.uiObject))
			{
				bracket.uiObject.SetActive(false);
				((Transform)bracket.rectTransform).localScale = Vector3.one;
			}
			bracket.trackedBody = null;
			bracket.currentAlpha = 0f;
			bracket.targetAlpha = 0f;
			bracket.hitAnimTimer = 0f;
			if (!bracketPool.Contains(bracket))
			{
				bracketPool.Add(bracket);
			}
		}

		private void ApplyBracketAlpha(BracketInfo bracket)
		{
			float num = bracket.targetAlpha - bracket.currentAlpha;
			if (Mathf.Abs(num) < 0.001f)
			{
				bracket.currentAlpha = bracket.targetAlpha;
			}
			else
			{
				bracket.currentAlpha = Mathf.MoveTowards(bracket.currentAlpha, bracket.targetAlpha, 8f * Time.deltaTime);
			}
		}

		private void RegisterHooks()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if (!hooksRegistered)
			{
				hooksRegistered = true;
				HealthComponent.TakeDamage += new hook_TakeDamage(OnTakeDamageHook);
				Log.Info("VisorOverlayController: 伤害钩子已注册");
			}
		}

		private void UnregisterHooks()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if (hooksRegistered)
			{
				hooksRegistered = false;
				HealthComponent.TakeDamage -= new hook_TakeDamage(OnTakeDamageHook);
			}
		}

		private void OnTakeDamageHook(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
		{
			orig.Invoke(self, damageInfo);
			if (!((Object)(object)body == (Object)null) && body.HasBuff(Soldier76Buffs.tacticalVisorBuff) && !((Object)(object)damageInfo.attacker == (Object)null) && !((Object)(object)damageInfo.attacker != (Object)(object)((Component)this).gameObject))
			{
				CharacterBody val = self.body;
				if (!((Object)(object)val == (Object)null) && activeBrackets.TryGetValue(val, out var value))
				{
					value.hitAnimTimer = 0.2f;
				}
			}
		}
	}
	internal static class Log
	{
		internal static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void ErrorAssetBundle(string assetName, string bundleName)
		{
			Error("failed to load asset, " + assetName + ", because it does not exist in asset bundle, " + bundleName);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.littlefight.soldier76", "soldier76", "1.0.2")]
	public class Soldier76Plugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_Start <>9__15_0;

			internal void <Awake>b__15_0(orig_Start orig, CharacterBody self)
			{
				orig.Invoke(self);
				if (!_hasPlayedSelectVoice && ((Object)self).name.Contains("Soldier76"))
				{
					_hasPlayedSelectVoice = true;
					((MonoBehaviour)self).StartCoroutine(PlaySelectVoiceWhenReady());
				}
			}
		}

		[CompilerGenerated]
		private sealed class <LoadSoundBankDelayed>d__16 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Soldier76Plugin <>4__this;

			private string <soundDir>5__1;

			private AKRESULT <result>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadSoundBankDelayed>d__16(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<soundDir>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: Invalid comparison between Unknown and I4
				//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<soundDir>5__1 = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)<>4__this).Info.Location), "sound");
					AkSoundEngine.AddBasePath(<soundDir>5__1);
					<result>5__2 = AkSoundEngine.LoadBank("Soldier76_Voices.bnk", ref _bankId);
					if ((int)<result>5__2 == 1)
					{
						_soundBankLoaded = true;
						Log.Info("SoundBank加载成功: Soldier76_Voices.bnk");
					}
					else
					{
						Log.Warning($"SoundBank加载失败: {<result>5__2}, 尝试备用加载方式...");
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <PlaySelectVoiceWhenReady>d__17 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <PlaySelectVoiceWhenReady>d__17(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Expected O, but got Unknown
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					goto IL_004d;
				case 1:
					<>1__state = -1;
					goto IL_004d;
				case 2:
					{
						<>1__state = -1;
						PlayVoice(((Component)RoR2Application.instance).gameObject, "Play_select_76voice");
						return false;
					}
					IL_004d:
					if (!_soundBankLoaded)
					{
						<>2__current = (object)new WaitForSeconds(0.3f);
						<>1__state = 1;
						return true;
					}
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 2;
					return true;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string MODUID = "com.littlefight.soldier76";

		public const string MODNAME = "soldier76";

		public const string MODVERSION = "1.0.2";

		public const string DEVELOPER_PREFIX = "S76";

		public static Soldier76Plugin instance;

		private static uint _bankId;

		private static bool _soundBankLoaded;

		private static bool _hasPlayedSelectVoice;

		public static void PlayVoice(GameObject source, string eventName)
		{
			if (!((Object)(object)source == (Object)null) && !string.IsNullOrEmpty(eventName))
			{
				AkSoundEngine.PostEvent(eventName, source);
			}
		}

		public static void PlayVoiceWithVolume(GameObject source, string eventName, float volume)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)source == (Object)null) && !string.IsNullOrEmpty(eventName))
			{
				string text = $"S76Vol_{(int)(volume * 100f):D2}";
				Transform val = source.transform.Find(text);
				GameObject val2;
				if ((Object)(object)val == (Object)null)
				{
					val2 = new GameObject(text);
					val2.transform.SetParent(source.transform);
					val2.AddComponent<AkGameObj>();
					AkSoundEngine.SetGameObjectOutputBusVolume(val2, (GameObject)null, volume);
				}
				else
				{
					val2 = ((Component)val).gameObject;
				}
				AkSoundEngine.PostEvent(eventName, val2);
			}
		}

		public static Texture2D LoadTexture(string fileName)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)instance).Info.Location), fileName);
			if (!File.Exists(path))
			{
				return null;
			}
			byte[] array = File.ReadAllBytes(path);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, array);
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			val.Apply();
			return val;
		}

		public static Texture2D LoadTextureFromAssetBundle(AssetBundle bundle, string assetName)
		{
			Texture2D val = bundle.LoadAsset<Texture2D>(assetName);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Texture2D val2 = DecompressTexture(val);
			((Texture)val2).filterMode = (FilterMode)1;
			((Texture)val2).wrapMode = (TextureWrapMode)1;
			return val2;
		}

		public static Sprite LoadSpriteFromAssetBundle(AssetBundle bundle, string assetName)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = bundle.LoadAsset<Texture2D>(assetName);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Texture2D val2 = DecompressTexture(val);
			((Texture)val2).filterMode = (FilterMode)1;
			((Texture)val2).wrapMode = (TextureWrapMode)1;
			return Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f);
		}

		public static Texture2D DecompressTexture(Texture2D source)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)2);
			Graphics.Blit((Texture)(object)source, temporary);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)4, false);
			val.ReadPixels(new Rect(0f, 0f, (float)((Texture)source).width, (float)((Texture)source).height), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			return val;
		}

		public static Sprite LoadSprite(string fileName)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)instance).Info.Location), fileName);
			if (!File.Exists(path))
			{
				return null;
			}
			byte[] array = File.ReadAllBytes(path);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, array);
			((Texture)val).filterMode = (FilterMode)0;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			val.Apply();
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			((Object)val2).name = fileName;
			return val2;
		}

		private void Awake()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			((MonoBehaviour)this).StartCoroutine(LoadSoundBankDelayed());
			object obj = <>c.<>9__15_0;
			if (obj == null)
			{
				hook_Start val = delegate(orig_Start orig, CharacterBody self)
				{
					orig.Invoke(self);
					if (!_hasPlayedSelectVoice && ((Object)self).name.Contains("Soldier76"))
					{
						_hasPlayedSelectVoice = true;
						((MonoBehaviour)self).StartCoroutine(PlaySelectVoiceWhenReady());
					}
				};
				<>c.<>9__15_0 = val;
				obj = (object)val;
			}
			CharacterBody.Start += (hook_Start)obj;
			Log.Info("=== 士兵76 v1.0.0 by littlefight ===");
			Log.Info("主武器: 50%伤害, 5发/秒");
			Log.Info("副武器: 200%伤害, CD=10s, 2层充能, 追踪+火箭跳");
			Log.Info("辅助:   10秒, +50%速/+300甲/+100%攻速, 扣20%HP/+15%盾, 禁止治疗, CD=20s");
			Log.Info("特殊:   10秒, +50%攻速, 子弹追踪, CD=30s | 强化: +50%暴击+100%暴伤");
			Log.Info("被动:   击杀+5%, 满100%强化目镜");
			Log.Info("==============================");
			Language.Init();
			new Soldier76Survivor().Initialize();
			new ContentPacks().Initialize();
		}

		[IteratorStateMachine(typeof(<LoadSoundBankDelayed>d__16))]
		private IEnumerator LoadSoundBankDelayed()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadSoundBankDelayed>d__16(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<PlaySelectVoiceWhenReady>d__17))]
		private static IEnumerator PlaySelectVoiceWhenReady()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <PlaySelectVoiceWhenReady>d__17(0);
		}
	}
}
namespace Soldier76Mod.Modules
{
	internal static class Asset
	{
		internal static Dictionary<string, AssetBundle> loadedBundles = new Dictionary<string, AssetBundle>();

		internal static AssetBundle LoadAssetBundle(string bundleName)
		{
			if (bundleName == "myassetbundle")
			{
				Log.Error("AssetBundle name hasn't been changed. not loading any assets to avoid conflicts.\nMake sure to rename your assetbundle filename and rename the AssetBundleName field in your character setup code ");
				return null;
			}
			if (loadedBundles.ContainsKey(bundleName))
			{
				return loadedBundles[bundleName];
			}
			AssetBundle val = null;
			try
			{
				val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Soldier76Plugin.instance).Info.Location), "AssetBundles", bundleName));
			}
			catch (Exception arg)
			{
				Log.Error($"Error loading asset bundle, {bundleName}. Your asset bundle must be in a folder next to your mod dll called 'AssetBundles'. Follow the guide to build and install your mod correctly!\n{arg}");
			}
			loadedBundles[bundleName] = val;
			return val;
		}

		internal static GameObject CloneTracer(string originalTracerName, string newTracerName)
		{
			if ((Object)(object)LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/Tracers/" + originalTracerName) == (Object)null)
			{
				return null;
			}
			GameObject val = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/Tracers/" + originalTracerName), newTracerName, true);
			if (!Object.op_Implicit((Object)(object)val.GetComponent<EffectComponent>()))
			{
				val.AddComponent<EffectComponent>();
			}
			if (!Object.op_Implicit((Object)(object)val.GetComponent<VFXAttributes>()))
			{
				val.AddComponent<VFXAttributes>();
			}
			if (!Object.op_Implicit((Object)(object)val.GetComponent<NetworkIdentity>()))
			{
				val.AddComponent<NetworkIdentity>();
			}
			val.GetComponent<Tracer>().speed = 250f;
			val.GetComponent<Tracer>().length = 50f;
			Content.CreateAndAddEffectDef(val);
			return val;
		}

		internal static void ConvertAllRenderersToHopooShader(GameObject objectToConvert)
		{
			if (!Object.op_Implicit((Object)(object)objectToConvert))
			{
				return;
			}
			MeshRenderer[] componentsInChildren = objectToConvert.GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)((Renderer)val).sharedMaterial))
				{
					((Renderer)val).sharedMaterial.ConvertDefaultShaderToHopoo();
				}
			}
			SkinnedMeshRenderer[] componentsInChildren2 = objectToConvert.GetComponentsInChildren<SkinnedMeshRenderer>();
			foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
			{
				if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)((Renderer)val2).sharedMaterial))
				{
					((Renderer)val2).sharedMaterial.ConvertDefaultShaderToHopoo();
				}
			}
		}

		internal static GameObject LoadCrosshair(string crosshairName)
		{
			GameObject val = LegacyResourcesAPI.Load<GameObject>("Prefabs/Crosshair/" + crosshairName + "Crosshair");
			if ((Object)(object)val == (Object)null)
			{
				Log.Error("could not load crosshair with the name " + crosshairName + ". defaulting to Standard");
				return LegacyResourcesAPI.Load<GameObject>("Prefabs/Crosshair/StandardCrosshair");
			}
			return val;
		}

		internal static GameObject LoadEffect(this AssetBundle assetBundle, string resourceName, bool parentToTransform)
		{
			return assetBundle.LoadEffect(resourceName, "", parentToTransform);
		}

		internal static GameObject LoadEffect(this AssetBundle assetBundle, string resourceName, string soundName = "", bool parentToTransform = false)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = assetBundle.LoadAsset<GameObject>(resourceName);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Log.ErrorAssetBundle(resourceName, ((Object)assetBundle).name);
				return null;
			}
			val.AddComponent<DestroyOnTimer>().duration = 12f;
			val.AddComponent<NetworkIdentity>();
			val.AddComponent<VFXAttributes>().vfxPriority = (VFXPriority)2;
			EffectComponent val2 = val.AddComponent<EffectComponent>();
			val2.applyScale = false;
			val2.effectIndex = (EffectIndex)(-1);
			val2.parentToReferencedTransform = parentToTransform;
			val2.positionAtReferencedTransform = true;
			val2.soundName = soundName;
			Content.CreateAndAddEffectDef(val);
			return val;
		}

		internal static GameObject CreateProjectileGhostPrefab(this AssetBundle assetBundle, string ghostName)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(ghostName);
			if ((Object)(object)val == (Object)null)
			{
				Log.Error("Failed to load ghost prefab " + ghostName);
			}
			if (!Object.op_Implicit((Object)(object)val.GetComponent<NetworkIdentity>()))
			{
				val.AddComponent<NetworkIdentity>();
			}
			if (!Object.op_Implicit((Object)(object)val.GetComponent<ProjectileGhostController>()))
			{
				val.AddComponent<ProjectileGhostController>();
			}
			ConvertAllRenderersToHopooShader(val);
			return val;
		}

		internal static GameObject CloneProjectilePrefab(string prefabName, string newPrefabName)
		{
			return PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/" + prefabName), newPrefabName);
		}

		internal static GameObject LoadAndAddProjectilePrefab(this AssetBundle assetBundle, string newPrefabName)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(newPrefabName);
			if ((Object)(object)val == (Object)null)
			{
				Log.ErrorAssetBundle(newPrefabName, ((Object)assetBundle).name);
				return null;
			}
			Content.AddProjectilePrefab(val);
			return val;
		}
	}
	public static class Config
	{
		public static ConfigFile MyConfig = ((BaseUnityPlugin)Soldier76Plugin.instance).Config;

		public static ConfigEntry<bool> CharacterEnableConfig(string section, string characterName, string description = "", bool enabledByDefault = true)
		{
			if (string.IsNullOrEmpty(description))
			{
				description = "Set to false to disable this character and as much of its code and content as possible";
			}
			return BindAndOptions(section, "Enable " + characterName, enabledByDefault, description, restartRequired: true);
		}

		public static ConfigEntry<T> BindAndOptions<T>(string section, string name, T defaultValue, string description = "", bool restartRequired = false)
		{
			return BindAndOptions(section, name, defaultValue, 0f, 20f, description, restartRequired);
		}

		public static ConfigEntry<T> BindAndOptions<T>(string section, string name, T defaultValue, float min, float max, string description = "", bool restartRequired = false)
		{
			if (string.IsNullOrEmpty(description))
			{
				description = name;
			}
			if (restartRequired)
			{
				description += " (restart required)";
			}
			ConfigEntry<T> result = MyConfig.Bind<T>(section, name, defaultValue, description);
			if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
			{
			}
			return result;
		}

		public static ConfigEntry<float> BindAndOptionsSlider(string section, string name, float defaultValue, string description, float min = 0f, float max = 20f, bool restartRequired = false)
		{
			return BindAndOptions(section, name, defaultValue, min, max, description, restartRequired);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void TryRegisterOption<T>(ConfigEntry<T> entry, float min, float max, bool restartRequired)
		{
		}

		public static bool GetKeyPressed(KeyboardShortcut entry)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref entry)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			return Input.GetKeyDown(((KeyboardShortcut)(ref entry)).MainKey);
		}
	}
	internal class Content
	{
		internal static void AddCharacterBodyPrefab(GameObject bprefab)
		{
			ContentPacks.bodyPrefabs.Add(bprefab);
		}

		internal static void AddMasterPrefab(GameObject prefab)
		{
			ContentPacks.masterPrefabs.Add(prefab);
		}

		internal static void AddProjectilePrefab(GameObject prefab)
		{
			ContentPacks.projectilePrefabs.Add(prefab);
		}

		internal static void AddSurvivorDef(SurvivorDef survivorDef)
		{
			ContentPacks.survivorDefs.Add(survivorDef);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			CreateSurvivor(bodyPrefab, displayPrefab, charColor, tokenPrefix, null, 100f);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix, float sortPosition)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			CreateSurvivor(bodyPrefab, displayPrefab, charColor, tokenPrefix, null, sortPosition);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix, UnlockableDef unlockableDef)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			CreateSurvivor(bodyPrefab, displayPrefab, charColor, tokenPrefix, unlockableDef, 100f);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix, UnlockableDef unlockableDef, float sortPosition)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			SurvivorDef val = ScriptableObject.CreateInstance<SurvivorDef>();
			val.bodyPrefab = bodyPrefab;
			val.displayPrefab = displayPrefab;
			val.primaryColor = charColor;
			val.cachedName = ((Object)bodyPrefab).name.Replace("Body", "");
			val.displayNameToken = tokenPrefix + "NAME";
			val.descriptionToken = tokenPrefix + "DESCRIPTION";
			val.outroFlavorToken = tokenPrefix + "OUTRO_FLAVOR";
			val.mainEndingEscapeFailureFlavorToken = tokenPrefix + "OUTRO_FAILURE";
			val.desiredSortPosition = sortPosition;
			val.unlockableDef = unlockableDef;
			AddSurvivorDef(val);
		}

		internal static void AddUnlockableDef(UnlockableDef unlockableDef)
		{
			ContentPacks.unlockableDefs.Add(unlockableDef);
		}

		internal static UnlockableDef CreateAndAddUnlockbleDef(string identifier, string nameToken, Sprite achievementIcon)
		{
			UnlockableDef val = ScriptableObject.CreateInstance<UnlockableDef>();
			val.cachedName = identifier;
			val.nameToken = nameToken;
			val.achievementIcon = achievementIcon;
			AddUnlockableDef(val);
			return val;
		}

		internal static void AddSkillDef(SkillDef skillDef)
		{
			ContentPacks.skillDefs.Add(skillDef);
		}

		internal static void AddSkillFamily(SkillFamily skillFamily)
		{
			ContentPacks.skillFamilies.Add(skillFamily);
		}

		internal static void AddEntityState(Type entityState)
		{
			ContentPacks.entityStates.Add(entityState);
		}

		internal static void AddBuffDef(BuffDef buffDef)
		{
			ContentPacks.buffDefs.Add(buffDef);
		}

		internal static BuffDef CreateAndAddBuff(string buffName, Sprite buffIcon, Color buffColor, bool canStack, bool isDebuff)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			BuffDef val = ScriptableObject.CreateInstance<BuffDef>();
			((Object)val).name = buffName;
			val.buffColor = buffColor;
			val.canStack = canStack;
			val.isDebuff = isDebuff;
			val.eliteDef = null;
			val.iconSprite = buffIcon;
			AddBuffDef(val);
			return val;
		}

		internal static void AddEffectDef(EffectDef effectDef)
		{
			ContentPacks.effectDefs.Add(effectDef);
		}

		internal static EffectDef CreateAndAddEffectDef(GameObject effectPrefab)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			EffectDef val = new EffectDef(effectPrefab);
			AddEffectDef(val);
			return val;
		}

		internal static void AddNetworkSoundEventDef(NetworkSoundEventDef networkSoundEventDef)
		{
			ContentPacks.networkSoundEventDefs.Add(networkSoundEventDef);
		}

		internal static NetworkSoundEventDef CreateAndAddNetworkSoundEventDef(string eventName)
		{
			NetworkSoundEventDef val = ScriptableObject.CreateInstance<NetworkSoundEventDef>();
			val.akId = AkSoundEngine.GetIDFromString(eventName);
			val.eventName = eventName;
			AddNetworkSoundEventDef(val);
			return val;
		}
	}
	internal class ContentPacks : IContentPackProvider
	{
		[CompilerGenerated]
		private sealed class <FinalizeAsync>d__18 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public FinalizeAsyncArgs args;

			public ContentPacks <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FinalizeAsync>d__18(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				args.ReportProgress(1f);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <GenerateContentPackAsync>d__17 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public GetContentPackAsyncArgs args;

			public ContentPacks <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GenerateContentPackAsync>d__17(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				ContentPack.Copy(<>4__this.contentPack, args.output);
				args.ReportProgress(1f);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <LoadStaticContentAsync>d__16 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public LoadStaticContentAsyncArgs args;

			public ContentPacks <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadStaticContentAsync>d__16(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				<>4__this.contentPack.identifier = <>4__this.identifier;
				<>4__this.contentPack.bodyPrefabs.Add(bodyPrefabs.ToArray());
				<>4__this.contentPack.masterPrefabs.Add(masterPrefabs.ToArray());
				<>4__this.contentPack.projectilePrefabs.Add(projectilePrefabs.ToArray());
				<>4__this.contentPack.survivorDefs.Add(survivorDefs.ToArray());
				<>4__this.contentPack.unlockableDefs.Add(unlockableDefs.ToArray());
				<>4__this.contentPack.skillDefs.Add(skillDefs.ToArray());
				<>4__this.contentPack.skillFamilies.Add(skillFamilies.ToArray());
				<>4__this.contentPack.entityStateTypes.Add(entityStates.ToArray());
				<>4__this.contentPack.buffDefs.Add(buffDefs.ToArray());
				<>4__this.contentPack.effectDefs.Add(effectDefs.ToArray());
				<>4__this.contentPack.networkSoundEventDefs.Add(networkSoundEventDefs.ToArray());
				args.ReportProgress(1f);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		internal ContentPack contentPack = new ContentPack();

		public static List<GameObject> bodyPrefabs = new List<GameObject>();

		public static List<GameObject> masterPrefabs = new List<GameObject>();

		public static List<GameObject> projectilePrefabs = new List<GameObject>();

		public static List<SurvivorDef> survivorDefs = new List<SurvivorDef>();

		public static List<UnlockableDef> unlockableDefs = new List<UnlockableDef>();

		public static List<SkillFamily> skillFamilies = new List<SkillFamily>();

		public static List<SkillDef> skillDefs = new List<SkillDef>();

		public static List<Type> entityStates = new List<Type>();

		public static List<BuffDef> buffDefs = new List<BuffDef>();

		public static List<EffectDef> effectDefs = new List<EffectDef>();

		public static List<NetworkSoundEventDef> networkSoundEventDefs = new List<NetworkSoundEventDef>();

		public string identifier => "com.littlefight.soldier76";

		public void Initialize()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			ContentManager.collectContentPackProviders += new CollectContentPackProvidersDelegate(ContentManager_collectContentPackProviders);
		}

		private void ContentManager_collectContentPackProviders(AddContentPackProviderDelegate addContentPackProvider)
		{
			addContentPackProvider.Invoke((IContentPackProvider)(object)this);
		}

		[IteratorStateMachine(typeof(<LoadStaticContentAsync>d__16))]
		public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadStaticContentAsync>d__16(0)
			{
				<>4__this = this,
				args = args
			};
		}

		[IteratorStateMachine(typeof(<GenerateContentPackAsync>d__17))]
		public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GenerateContentPackAsync>d__17(0)
			{
				<>4__this = this,
				args = args
			};
		}

		[IteratorStateMachine(typeof(<FinalizeAsync>d__18))]
		public IEnumerator FinalizeAsync(FinalizeAsyncArgs args)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FinalizeAsync>d__18(0)
			{
				<>4__this = this,
				args = args
			};
		}
	}
	internal static class ItemDisplayCheck
	{
		public static List<Object> allDisplayedItems;

		public static void PrintUnused(ItemDisplayRuleSet itemDisplayRuleSet, string bodyName = "")
		{
			PrintUnused((IEnumerable<KeyAssetRuleGroup>)itemDisplayRuleSet.keyAssetRuleGroups.ToList(), bodyName);
		}

		public static void PrintUnused(IEnumerable<KeyAssetRuleGroup> ruleSet = null, string bodyName = "")
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			string text = "generating item displays for " + bodyName;
			if (allDisplayedItems == null)
			{
				LazyGatherAllItems();
			}
			List<Object> list = new List<Object>(allDisplayedItems);
			string text2 = "";
			if (ruleSet != null)
			{
				foreach (KeyAssetRuleGroup item in ruleSet)
				{
					if (item.displayRuleGroup.rules.Length != 0)
					{
						list.Remove(item.keyAsset);
						if (string.IsNullOrEmpty(text2))
						{
							text2 = item.displayRuleGroup.rules[0].childName;
						}
					}
				}
			}
			if (string.IsNullOrEmpty(text2))
			{
				text2 = "Chest";
			}
			foreach (Object item2 in list)
			{
				string text3 = "";
				if (ItemDisplays.KeyAssetDisplayPrefabs.ContainsKey(item2))
				{
					text3 += SpitOutNewRule(item2, text2, ItemDisplays.KeyAssetDisplayPrefabs[item2]);
				}
				else
				{
					Log.Error($"COULD NOT FIND DISPLAY PREFABS FOR KEYASSET {item2}");
				}
				text += text3;
			}
			Log.Message(text);
		}

		private static void LazyGatherAllItems()
		{
			allDisplayedItems = new List<Object>(ItemDisplays.KeyAssetDisplayPrefabs.Keys);
			allDisplayedItems.Sort(delegate(Object item1, Object item2)
			{
				if (item1 is ItemDef && item2 is ItemDef)
				{
					return item1.name.CompareTo(item2.name);
				}
				if (item1 is EquipmentDef && item2 is EquipmentDef)
				{
					return item1.name.CompareTo(item2.name);
				}
				if (item1 is ItemDef && item2 is EquipmentDef)
				{
					return -1;
				}
				return (item1 is EquipmentDef && item2 is ItemDef) ? 1 : 0;
			});
		}

		private static string SpitOutNewRule(Object asset, string firstCompatibleChild, ItemDisplayRule[] displayRules)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if (displayRules.Length == 0)
			{
				return $"\n[NO DISPLAY RULES FOUND FOR THE KEYASSET {asset}";
			}
			string text = "\n            itemDisplayRules.Add(ItemDisplays.CreateDisplayRuleGroupWithRules(ItemDisplays.KeyAssets[\"" + asset.name + "\"]";
			for (int i = 0; i < displayRules.Length; i++)
			{
				text = (((int)displayRules[i].limbMask != 0) ? (text + ",\n" + $"                ItemDisplays.CreateLimbMaskDisplayRule(LimbFlags.{displayRules[i].limbMask})") : (text + ",\n                ItemDisplays.CreateDisplayRule(ItemDisplays.LoadDisplay(\"" + ((Object)displayRules[i].followerPrefab).name + "\"),\n                    \"" + firstCompatibleChild + "\",\n                    new Vector3(2, 2, 2),\n                    new Vector3(0, 0, 0),\n                    new Vector3(1, 1, 1)\n                    )"));
			}
			return text + "\n                ));";
		}
	}
	internal static class ItemDisplays
	{
		private static Dictionary<string, GameObject> itemDisplayPrefabs = new Dictionary<string, GameObject>();

		public static Dictionary<Object, ItemDisplayRule[]> KeyAssetDisplayPrefabs = new Dictionary<Object, ItemDisplayRule[]>();

		public static Dictionary<string, Object> KeyAssets = new Dictionary<string, Object>();

		public static int queuedDisplays;

		public static bool initialized = false;

		public static void LazyInit()
		{
			if (!initialized)
			{
				initialized = true;
				PopulateDisplays();
			}
		}

		internal static void DisposeWhenDone()
		{
			queuedDisplays--;
			if (queuedDisplays <= 0 && initialized)
			{
				initialized = false;
				itemDisplayPrefabs = null;
				KeyAssetDisplayPrefabs = null;
				KeyAssets = null;
			}
		}

		internal static void PopulateDisplays()
		{
			PopulateFromBody("LoaderBody");
		}

		private static void PopulateFromBody(string bodyName)
		{
			ItemDisplayRuleSet itemDisplayRuleSet = ((Component)LegacyResourcesAPI.Load<GameObject>("Prefabs/CharacterBodies/" + bodyName).GetComponent<ModelLocator>().modelTransform).GetComponent<CharacterModel>().itemDisplayRuleSet;
			KeyAssetRuleGroup[] keyAssetRuleGroups = itemDisplayRuleSet.keyAssetRuleGroups;
			for (int i = 0; i < keyAssetRuleGroups.Length; i++)
			{
				ItemDisplayRule[] rules = keyAssetRuleGroups[i].displayRuleGroup.rules;
				KeyAssetDisplayPrefabs[keyAssetRuleGroups[i].keyAsset] = rules;
				KeyAssets[keyAssetRuleGroups[i].keyAsset.name] = keyAssetRuleGroups[i].keyAsset;
				for (int j = 0; j < rules.Length; j++)
				{
					GameObject followerPrefab = rules[j].followerPrefab;
					if (Object.op_Implicit((Object)(object)followerPrefab))
					{
						string key = ((Object)followerPrefab).name?.ToLowerInvariant();
						if (!itemDisplayPrefabs.ContainsKey(key))
						{
							itemDisplayPrefabs[key] = followerPrefab;
						}
					}
				}
			}
		}

		private static void PopulateCustomLightningArm()
		{
			GameObject val = PrefabAPI.InstantiateClone(itemDisplayPrefabs["displaylightningarmright"], "DisplayLightningCustom", false);
			LimbMatcher component = val.GetComponent<LimbMatcher>();
			component.limbPairs[0].targetChildLimb = "LightningArm1";
			component.limbPairs[1].targetChildLimb = "LightningArm2";
			component.limbPairs[2].targetChildLimb = "LightningArmEnd";
			itemDisplayPrefabs["displaylightningarmcustom"] = val;
		}

		public static GameObject LoadDisplay(string name)
		{
			if (itemDisplayPrefabs.ContainsKey(name.ToLowerInvariant()) && Object.op_Implicit((Object)(object)itemDisplayPrefabs[name.ToLowerInvariant()]))
			{
				return itemDisplayPrefabs[name.ToLowerInvariant()];
			}
			Log.Error("item display " + name + " returned null");
			return null;
		}

		public static KeyAssetRuleGroup CreateDisplayRuleGroupWithRules(string itemName, params ItemDisplayRule[] rules)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return CreateDisplayRuleGroupWithRules(GetKeyAssetFromString(itemName), rules);
		}

		public static KeyAssetRuleGroup CreateDisplayRuleGroupWithRules(Object keyAsset_, params ItemDisplayRule[] rules)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (keyAsset_ == (Object)null)
			{
				Log.Error("could not find keyasset");
			}
			KeyAssetRuleGroup result = default(KeyAssetRuleGroup);
			result.keyAsset = keyAsset_;
			result.displayRuleGroup = new DisplayRuleGroup
			{
				rules = rules
			};
			return result;
		}

		public static ItemDisplayRule CreateDisplayRule(string prefabName, string childName, Vector3 position, Vector3 rotation, Vector3 scale)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return CreateDisplayRule(LoadDisplay(prefabName), childName, position, rotation, scale);
		}

		public static ItemDisplayRule CreateDisplayRule(GameObject itemPrefab, string childName, Vector3 position, Vector3 rotation, Vector3 scale)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			ItemDisplayRule result = default(ItemDisplayRule);
			result.ruleType = (ItemDisplayRuleType)0;
			result.childName = childName;
			result.followerPrefab = itemPrefab;
			result.limbMask = (LimbFlags)0;
			result.localPos = position;
			result.localAngles = rotation;
			result.localScale = scale;
			return result;
		}

		public static ItemDisplayRule CreateLimbMaskDisplayRule(LimbFlags limb)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			ItemDisplayRule result = default(ItemDisplayRule);
			result.ruleType = (ItemDisplayRuleType)1;
			result.limbMask = limb;
			result.childName = "";
			result.followerPrefab = null;
			return result;
		}

		private static Object GetKeyAssetFromString(string itemName)
		{
			Object val = (Object)(object)LegacyResourcesAPI.Load<ItemDef>("ItemDefs/" + itemName);
			if (val == (Object)null)
			{
				val = (Object)(object)LegacyResourcesAPI.Load<EquipmentDef>("EquipmentDefs/" + itemName);
			}
			if (val == (Object)null)
			{
				Log.Error("Could not load keyasset for " + itemName);
			}
			return val;
		}
	}
	internal static class Language
	{
		public static string TokensOutput = "";

		public static bool usingLanguageFolder = false;

		public static bool printingEnabled = false;

		public static void Init()
		{
			if (usingLanguageFolder)
			{
				Language.collectLanguageRootFolders += Language_collectLanguageRootFolders;
			}
		}

		private static void Language_collectLanguageRootFolders(List<string> obj)
		{
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Soldier76Plugin.instance).Info.Location), "Language");
			if (Directory.Exists(text))
			{
				obj.Add(text);
			}
		}

		public static void Add(string token, string text)
		{
			if (!usingLanguageFolder)
			{
				LanguageAPI.Add(token, text);
			}
			if (printingEnabled)
			{
				TokensOutput = TokensOutput + "\n    \"" + token + "\" : \"" + text.Replace(Environment.NewLine, "\\n").Replace("\n", "\\n") + "\",";
			}
		}

		public static void PrintOutput(string fileName = "")
		{
			if (printingEnabled)
			{
				string text = "{\n    strings:\n    {" + TokensOutput + "\n    }\n}";
				Log.Message(fileName + ": \n" + text);
				if (!string.IsNullOrEmpty(fileName))
				{
					string path = Path.Combine(Directory.GetParent(((BaseUnityPlugin)Soldier76Plugin.instance).Info.Location).FullName, "Language", "en", fileName);
					File.WriteAllText(path, text);
				}
				TokensOutput = "";
			}
		}
	}
	internal static class Materials
	{
		private static List<Material> cachedMaterials = new List<Material>();

		internal static Shader hotpoo = LegacyResourcesAPI.Load<Shader>("Shaders/Deferred/HGStandard");

		public static Material LoadMaterial(this AssetBundle assetBundle, string materialName)
		{
			return assetBundle.CreateHopooMaterialFromBundle(materialName);
		}

		public static Material CreateHopooMaterialFromBundle(this AssetBundle assetBundle, string materialName)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			Material val = cachedMaterials.Find(delegate(Material mat)
			{
				materialName.Replace(" (Instance)", "");
				return ((Object)mat).name.Contains(materialName);
			});
			if (Object.op_Implicit((Object)(object)val))
			{
				Log.Debug(((Object)val).name + " has already been loaded. returning cached");
				return val;
			}
			val = assetBundle.LoadAsset<Material>(materialName);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Log.ErrorAssetBundle(materialName, ((Object)assetBundle).name);
				return new Material(hotpoo);
			}
			return val.ConvertDefaultShaderToHopoo();
		}

		public static Material SetHopooMaterial(this Material tempMat)
		{
			return tempMat.ConvertDefaultShaderToHopoo();
		}

		public static Material ConvertDefaultShaderToHopoo(this Material tempMat)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			if (cachedMaterials.Contains(tempMat))
			{
				Log.Debug(((Object)tempMat).name + " has already been converted. returning cached");
				return tempMat;
			}
			string text = ((Object)tempMat.shader).name.ToLowerInvariant();
			if (!text.StartsWith("standard") && !text.StartsWith("autodesk"))
			{
				Log.Debug(((Object)tempMat).name + " is not unity standard shader. aborting material conversion");
				return tempMat;
			}
			float? num = null;
			Color? val = null;
			if (tempMat.IsKeywordEnabled("_NORMALMAP"))
			{
				num = tempMat.GetFloat("_BumpScale");
			}
			if (tempMat.IsKeywordEnabled("_EMISSION"))
			{
				val = tempMat.GetColor("_EmissionColor");
			}
			tempMat.shader = hotpoo;
			tempMat.SetTexture("_EmTex", tempMat.GetTexture("_EmissionMap"));
			tempMat.EnableKeyword("DITHER");
			if (num.HasValue)
			{
				tempMat.SetFloat("_NormalStrength", num.Value);
				tempMat.SetTexture("_NormalTex", tempMat.GetTexture("_BumpMap"));
			}
			if (val.HasValue)
			{
				tempMat.SetColor("_EmColor", val.Value);
				tempMat.SetFloat("_EmPower", 1f);
			}
			if (tempMat.IsKeywordEnabled("NOCULL"))
			{
				tempMat.SetInt("_Cull", 0);
			}
			if (tempMat.IsKeywordEnabled("LIMBREMOVAL"))
			{
				tempMat.SetInt("_LimbRemovalOn", 1);
			}
			cachedMaterials.Add(tempMat);
			return tempMat;
		}

		public static Material MakeUnique(this Material material)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (cachedMaterials.Contains(material))
			{
				return new Material(material);
			}
			return material;
		}

		public static Material SetColor(this Material material, Color color)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			material.SetColor("_Color", color);
			return material;
		}

		public static Material SetNormal(this Material material, float normalStrength = 1f)
		{
			material.SetFloat("_NormalStrength", normalStrength);
			return material;
		}

		public static Material SetEmission(this Material material)
		{
			return material.SetEmission(1f);
		}

		public static Material SetEmission(this Material material, float emission)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return material.SetEmission(emission, Color.white);
		}

		public static Material SetEmission(this Material material, float emission, Color emissionColor)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			material.SetFloat("_EmPower", emission);
			material.SetColor("_EmColor", emissionColor);
			return material;
		}

		public static Material SetCull(this Material material, bool cull = false)
		{
			material.SetInt("_Cull", cull ? 1 : 0);
			return material;
		}

		public static Material SetSpecular(this Material material, float strength)
		{
			material.SetFloat("_SpecularStrength", strength);
			return material;
		}

		public static Material SetSpecular(this Material material, float strength, float exponent)
		{
			material.SetFloat("_SpecularStrength", strength);
			material.SetFloat("SpecularExponent", exponent);
			return material;
		}
	}
	internal static class Prefabs
	{
		private static PhysicMaterial ragdollMaterial;

		public static GameObject CreateDisplayPrefab(AssetBundle assetBundle, string displayPrefabName, GameObject prefab)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(displayPrefabName);
			if ((Object)(object)val == (Object)null)
			{
				Log.Error("could not load display prefab " + displayPrefabName + ". Make sure this prefab exists in assetbundle " + ((Object)assetBundle).name);
				return null;
			}
			CharacterModel val2 = val.GetComponent<CharacterModel>();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = val.AddComponent<CharacterModel>();
			}
			val2.baseRendererInfos = prefab.GetComponentInChildren<CharacterModel>().baseRendererInfos;
			Asset.ConvertAllRenderersToHopooShader(val);
			return val;
		}

		public static GameObject LoadCharacterModel(AssetBundle assetBundle, string modelName)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(modelName);
			if ((Object)(object)val == (Object)null)
			{
				Log.Error("could not load model prefab " + modelName + ". Make sure this prefab exists in assetbundle " + ((Object)assetBundle).name);
				return null;
			}
			return val;
		}

		public static GameObject LoadCharacterBody(AssetBundle assetBundle, string bodyName)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(bodyName);
			if ((Object)(object)val == (Object)null)
			{
				Log.Error("could not load body prefab " + bodyName + ". Make sure this prefab exists in assetbundle " + ((Object)assetBundle).name);
				return null;
			}
			return val;
		}

		public static GameObject CloneCharacterBody(BodyInfo bodyInfo)
		{
			GameObject val = LegacyResourcesAPI.Load<GameObject>("Prefabs/CharacterBodies/" + bodyInfo.bodyNameToClone + "Body");
			if (!Object.op_Implicit((Object)(object)val))
			{
				Log.Error(bodyInfo.bodyNameToClone + " Body to clone is not a valid body, character creation failed");
				return null;
			}
			GameObject val2 = PrefabAPI.InstantiateClone(val, bodyInfo.bodyName);
			for (int num = val2.transform.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)val2.transform.GetChild(num)).gameObject);
			}
			return val2;
		}

		public static GameObject CreateBodyPrefab(AssetBundle assetBundle, string modelPrefabName, BodyInfo bodyInfo)
		{
			return CreateBodyPrefab(LoadCharacterModel(assetBundle, modelPrefabName), bodyInfo);
		}

		public static GameObject CreateBodyPrefab(GameObject model, BodyInfo bodyInfo)
		{
			return CreateBodyPrefab(CloneCharacterBody(bodyInfo), model, bodyInfo);
		}

		public static GameObject CreateBodyPrefab(GameObject newBodyPrefab, AssetBundle assetBundle, string modelName, BodyInfo bodyInfo)
		{
			return CreateBodyPrefab(newBodyPrefab, LoadCharacterModel(assetBundle, modelName), bodyInfo);
		}

		public static GameObject CreateBodyPrefab(AssetBundle assetBundle, string bodyPrefabName, string modelPrefabName, BodyInfo bodyInfo)
		{
			return CreateBodyPrefab(LoadCharacterBody(assetBundle, bodyPrefabName), LoadCharacterModel(assetBundle, modelPrefabName), bodyInfo);
		}

		public static GameObject CreateBodyPrefab(GameObject newBodyPrefab, GameObject model, BodyInfo bodyInfo)
		{
			if ((Object)(object)model == (Object)null || (Object)(object)newBodyPrefab == (Object)null)
			{
				Log.Error($"Character creation failed. Model: {model}, Body: {newBodyPrefab}");
				return null;
			}
			SetupCharacterBody(newBodyPrefab, bodyInfo);
			Transform modelBaseTransform = AddCharacterModelToSurvivorBody(newBodyPrefab, model.transform, bodyInfo);
			SetupModelLocator(newBodyPrefab, modelBaseTransform, model.transform);
			SetupCharacterDirection(newBodyPrefab, modelBaseTransform, model.transform);
			SetupCameraTargetParams(newBodyPrefab, bodyInfo);
			SetupCapsuleCollider(newBodyPrefab);
			Content.AddCharacterBodyPrefab(newBodyPrefab);
			return newBodyPrefab;
		}

		private static void SetupCharacterBody(GameObject newBodyPrefab, BodyInfo bodyInfo)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody component = newBodyPrefab.GetComponent<CharacterBody>();
			component.baseNameToken = bodyInfo.bodyNameToken;
			component.subtitleNameToken = bodyInfo.subtitleNameToken;
			component.portraitIcon = bodyInfo.characterPortrait;
			component.bodyColor = bodyInfo.bodyColor;
			component._defaultCrosshairPrefab = bodyInfo.crosshair;
			component.hideCrosshair = false;
			component.preferredPodPrefab = bodyInfo.podPrefab;
			component.baseMaxHealth = bodyInfo.maxHealth;
			component.baseRegen = bodyInfo.healthRegen;
			component.baseArmor = bodyInfo.armor;
			component.baseMaxShield = bodyInfo.shield;
			component.baseDamage = bodyInfo.damage;
			component.baseAttackSpeed = bodyInfo.attackSpeed;
			component.baseCrit = bodyInfo.crit;
			component.baseMoveSpeed = bodyInfo.moveSpeed;
			component.baseJumpPower = bodyInfo.jumpPower;
			component.autoCalculateLevelStats = bodyInfo.autoCalculateLevelStats;
			if (bodyInfo.autoCalculateLevelStats)
			{
				component.levelMaxHealth = Mathf.Round(component.baseMaxHealth * 0.3f);
				component.levelMaxShield = Mathf.Round(component.baseMaxShield * 0.3f);
				component.levelRegen = component.baseRegen * 0.2f;
				component.levelMoveSpeed = 0f;
				component.levelJumpPower = 0f;
				component.levelDamage = component.baseDamage * 0.2f;
				component.levelAttackSpeed = 0f;
				component.levelCrit = 0f;
				component.levelArmor = 0f;
			}
			else
			{
				component.levelMaxHealth = bodyInfo.healthGrowth;
				component.levelMaxShield = bodyInfo.shieldGrowth;
				component.levelRegen = bodyInfo.regenGrowth;
				component.levelMoveSpeed = bodyInfo.moveSpeedGrowth;
				component.levelJumpPower = bodyInfo.jumpPowerGrowth;
				component.levelDamage = bodyInfo.damageGrowth;
				component.levelAttackSpeed = bodyInfo.attackSpeedGrowth;
				component.levelCrit = bodyInfo.critGrowth;
				component.levelArmor = bodyInfo.armorGrowth;
			}
			component.baseAcceleration = bodyInfo.acceleration;
			component.baseJumpCount = bodyInfo.jumpCount;
			component.sprintingSpeedMultiplier = 1.45f;
			component.bodyFlags = (BodyFlags)16;
			component.rootMotionInMainState = false;
			component.hullClassification = (HullClassification)0;
			component.isChampion = false;
		}

		private static Transform AddCharacterModelToSurvivorBody(GameObject bodyPrefab, Transform modelTransform, BodyInfo bodyInfo)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			Transform val = bodyPrefab.transform.Find("ModelBase");
			if ((Object)(object)val == (Object)null)
			{
				val = new GameObject("ModelBase").transform;
				val.parent = bodyPrefab.transform;
				val.localPosition = bodyInfo.modelBasePosition;
				val.localRotation = Quaternion.identity;
			}
			modelTransform.parent = ((Component)val).transform;
			modelTransform.localPosition = Vector3.zero;
			modelTransform.localRotation = Quaternion.identity;
			Transform val2 = bodyPrefab.transform.Find("CameraPivot");
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = new GameObject("CameraPivot").transform;
				val2.parent = bodyPrefab.transform;
				val2.localPosition = bodyInfo.cameraPivotPosition;
				val2.localRotation = Quaternion.identity;
			}
			Transform val3 = bodyPrefab.transform.Find("AimOrigin");
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = new GameObject("AimOrigin").transform;
				val3.parent = bodyPrefab.transform;
				val3.localPosition = bodyInfo.aimOriginPosition;
				val3.localRotation = Quaternion.identity;
			}
			bodyPrefab.GetComponent<CharacterBody>().aimOriginTransform = val3;
			return ((Component)val).transform;
		}

		private static void SetupCharacterDirection(GameObject prefab, Transform modelBaseTransform, Transform modelTransform)
		{
			if (Object.op_Implicit((Object)(object)prefab.GetComponent<CharacterDirection>()))
			{
				CharacterDirection component = prefab.GetComponent<CharacterDirection>();
				component.targetTransform = modelBaseTransform;
				component.overrideAnimatorForwardTransform = null;
				component.rootMotionAccumulator = null;
				component.modelAnimator = ((Component)modelTransform).GetComponent<Animator>();
				component.driveFromRootRotation = false;
				component.turnSpeed = 720f;
			}
		}

		private static void SetupCameraTargetParams(GameObject prefab, BodyInfo bodyInfo)
		{
			CameraTargetParams component = prefab.GetComponent<CameraTargetParams>();
			component.cameraParams = bodyInfo.cameraParams;
			component.cameraPivotTransform = prefab.transform.Find("CameraPivot");
		}

		private static void SetupModelLocator(GameObject prefab, Transform modelBaseTransform, Transform modelTransform)
		{
			ModelLocator component = prefab.GetComponent<ModelLocator>();
			component.modelTransform = modelTransform;
			component.modelBaseTransform = modelBaseTransform;
		}

		private static void SetupCapsuleCollider(GameObject prefab)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			CapsuleCollider component = prefab.GetComponent<CapsuleCollider>();
			component.center = new Vector3(0f, 0f, 0f);
			component.radius = 0.5f;
			component.height = 1.82f;
			component.direction = 1;
		}

		public static CharacterModel SetupCharacterModel(GameObject bodyPrefab, CustomRendererInfo[] customInfos = null)
		{
			CharacterModel val = ((Component)bodyPrefab.GetComponent<ModelLocator>().modelTransform).gameObject.GetComponent<CharacterModel>();
			bool flag = (Object)(object)val != (Object)null;
			if (!flag)
			{
				val = ((Component)bodyPrefab.GetComponent<ModelLocator>().modelTransform).gameObject.AddComponent<CharacterModel>();
			}
			val.body = bodyPrefab.GetComponent<CharacterBody>();
			val.autoPopulateLightInfos = true;
			val.invisibilityCount = 0;
			val.temporaryOverlays = new List<TemporaryOverlayInstance>();
			if (!flag)
			{
				SetupCustomRendererInfos(val, customInfos);
			}
			else
			{
				SetupPreAttachedRendererInfos(val);
			}
			SetupHurtboxGroup(bodyPrefab, ((Component)val).gameObject);
			SetupAimAnimator(bodyPrefab, ((Component)val).gameObject);
			SetupFootstepController(((Component)val).gameObject);
			SetupRagdoll(((Component)val).gameObject);
			return val;
		}

		public static void SetupPreAttachedRendererInfos(CharacterModel characterModel)
		{
			for (int i = 0; i < characterModel.baseRendererInfos.Length; i++)
			{
				if ((Object)(object)characterModel.baseRendererInfos[i].defaultMaterial == (Object)null)
				{
					characterModel.baseRendererInfos[i].defaultMaterial = characterModel.baseRendererInfos[i].renderer.sharedMaterial;
				}
				if ((Object)(object)characterModel.baseRendererInfos[i].defaultMaterial == (Object)null)
				{
					Log.Error($"no material for rendererinfo of this renderer: {characterModel.baseRendererInfos[i].renderer}");
				}
				characterModel.baseRendererInfos[i].defaultMaterial.ConvertDefaultShaderToHopoo();
			}
		}

		public static void SetupCustomRendererInfos(CharacterModel characterModel, CustomRendererInfo[] customInfos)
		{
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			ChildLocator component = ((Component)characterModel).GetComponent<ChildLocator>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				Log.Error("Failed CharacterModel setup: ChildLocator component does not exist on the model");
				return;
			}
			List<RendererInfo> list = new List<RendererInfo>();
			for (int i = 0; i < customInfos.Length; i++)
			{
				if (!Object.op_Implicit((Object)(object)component.FindChild(customInfos[i].childName)))
				{
					Log.Error("Trying to add a RendererInfo for a renderer that does not exist: " + customInfos[i].childName);
					continue;
				}
				Renderer component2 = ((Component)component.FindChild(customInfos[i].childName)).GetComponent<Renderer>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					Material val = customInfos[i].material;
					if ((Object)(object)val == (Object)null)
					{
						val = ((!customInfos[i].dontHotpoo) ? component2.sharedMaterial.ConvertDefaultShaderToHopoo() : component2.sharedMaterial);
					}
					list.Add(new RendererInfo
					{
						renderer = component2,
						defaultMaterial = val,
						ignoreOverlays = customInfos[i].ignoreOverlays,
						defaultShadowCastingMode = (ShadowCastingMode)1
					});
				}
			}
			characterModel.baseRendererInfos = list.ToArray();
		}

		private static void SetupHurtboxGroup(GameObject bodyPrefab, GameObject model)
		{
			SetupMainHurtboxesFromChildLocator(bodyPrefab, model);
			SetHurtboxesHealthComponents(bodyPrefab);
		}

		private static void SetupMainHurtboxesFromChildLocator(GameObject bodyPrefab, GameObject model)
		{
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)bodyPrefab.GetComponent<HurtBoxGroup>() != (Object)null)
			{
				Log.Debug("Hitboxgroup already exists on model prefab. aborting code setup");
				return;
			}
			ChildLocator component = model.GetComponent<ChildLocator>();
			if (string.IsNullOrEmpty(component.FindChildNameInsensitive("MainHurtbox")))
			{
				Log.Error("Could not set up main hurtbox: make sure you have a transform pair in your prefab's ChildLocator called 'MainHurtbox'");
				return;
			}
			HurtBoxGroup val = model.AddComponent<HurtBoxGroup>();
			HurtBox val2 = null;
			GameObject val3 = component.FindChildGameObjectInsensitive("HeadHurtbox");
			if (Object.op_Implicit((Object)(object)val3))
			{
				Log.Debug("HeadHurtboxFound. Setting up");
				val2 = val3.AddComponent<HurtBox>();
				((Component)val2).gameObject.layer = LayerIndex.entityPrecise.intVal;
				val2.healthComponent = bodyPrefab.GetComponent<HealthComponent>();
				val2.isBullseye = false;
				val2.isSniperTarget = true;
				val2.damageModifier = (DamageModifier)0;
				val2.hurtBoxGroup = val;
				val2.indexInGroup = 1;
			}
			HurtBox val4 = component.FindChildGameObjectInsensitive("MainHurtbox").AddComponent<HurtBox>();
			((Component)val4).gameObject.layer = LayerIndex.entityPrecise.intVal;
			val4.healthComponent = bodyPrefab.GetComponent<HealthComponent>();
			val4.isBullseye = true;
			val4.isSniperTarget = (Object)(object)val2 == (Object)null;
			val4.damageModifier = (DamageModifier)0;
			val4.hurtBoxGroup = val;
			val4.indexInGroup = 0;
			if (Object.op_Implicit((Object)(object)val2))
			{
				val.hurtBoxes = (HurtBox[])(object)new HurtBox[2] { val4, val2 };
			}
			else
			{
				val.hurtBoxes = (HurtBox[])(object)new HurtBox[1] { val4 };
			}
			val.mainHurtBox = val4;
			val.bullseyeCount = 1;
		}

		private static string FindChildNameInsensitive(this ChildLocator childLocator, string child)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			return childLocator.transformPairs.Where((NameTransformPair pair) => pair.name.ToLowerInvariant() == child.ToLowerInvariant()).FirstOrDefault().name;
		}

		private static Transform FindChildInsensitive(this ChildLocator childLocator, string child)
		{
			return childLocator.FindChild(childLocator.FindChildNameInsensitive(child));
		}

		private static GameObject FindChildGameObjectInsensitive(this ChildLocator childLocator, string child)
		{
			return childLocator.FindChildGameObject(childLocator.FindChildNameInsensitive(child));
		}

		public static void SetHurtboxesHealthComponents(GameObject bodyPrefab)
		{
			HealthComponent component = bodyPrefab.GetComponent<HealthComponent>();
			HurtBoxGroup[] componentsInChildren = bodyPrefab.GetComponentsInChildren<HurtBoxGroup>();
			foreach (HurtBoxGroup val in componentsInChildren)
			{
				val.mainHurtBox.healthComponent = component;
				for (int j = 0; j < val.hurtBoxes.Length; j++)
				{
					val.hurtBoxes[j].healthComponent = component;
				}
			}
		}

		private static void SetupFootstepController(GameObject model)
		{
			FootstepHandler val = model.AddComponent<FootstepHandler>();
			val.baseFootstepString = "Play_player_footstep";
			val.sprintFootstepOverrideString = "";
			val.enableFootstepDust = true;
			val.footstepDustPrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/GenericFootstepDust");
		}

		private static void SetupRagdoll(GameObject model)
		{
			RagdollController component = model.GetComponent<RagdollController>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			if ((Object)(object)ragdollMaterial == (Object)null)
			{
				ragdollMaterial = ((Component)LegacyResourcesAPI.Load<GameObject>("Prefabs/CharacterBodies/CommandoBody").GetComponentInChildren<RagdollController>().bones[1]).GetComponent<Collider>().material;
			}
			Transform[] bones = component.bones;
			foreach (Transform val in bones)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					((Component)val).gameObject.layer = LayerIndex.ragdoll.intVal;
					Collider component2 = ((Component)val).GetComponent<Collider>();
					if (Object.op_Implicit((Object)(object)component2))
					{
						component2.sharedMaterial = ragdollMaterial;
					}
					else
					{
						Log.Error($"Ragdoll bone {((Component)val).gameObject} doesn't have a collider. Ragdoll will break.");
					}
				}
			}
		}

		private static void SetupAimAnimator(GameObject prefab, GameObject model)
		{
			AimAnimator val = model.AddComponent<AimAnimator>();
			val.directionComponent = prefab.GetComponent<CharacterDirection>();
			val.pitchRangeMax = 60f;
			val.pitchRangeMin = -60f;
			val.yawRangeMin = -80f;
			val.yawRangeMax = 80f;
			val.pitchGiveupRange = 30f;
			val.yawGiveupRange = 10f;
			val.giveupDuration = 3f;
			val.inputBank = prefab.GetComponent<InputBankTest>();
		}

		public static void CreateGenericDoppelganger(GameObject bodyPrefab, string masterName, string masterToCopy)
		{
			CloneDopplegangerMaster(bodyPrefab, masterName, masterToCopy);
		}

		public static GameObject CloneDopplegangerMaster(GameObject bodyPrefab, string masterName, string masterToCopy)
		{
			GameObject val = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load<GameObject>("Prefabs/CharacterMasters/" + masterToCopy + "MonsterMaster"), masterName, true);
			val.GetComponent<CharacterMaster>().bodyPrefab = bodyPrefab;
			Conten