Decompiled source of SasukeRinneganMod v0.14.1

plugins/SasukeRinneganMod.dll

Decompiled 19 hours 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.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.AI.Walker;
using EntityStates.Commando;
using HG;
using HG.BlendableTypes;
using KinematicCharacterController;
using KizunaMod;
using Microsoft.CodeAnalysis;
using On.RoR2;
using On.RoR2.UI;
using R2API;
using R2API.Utils;
using Rewired;
using RoR2;
using RoR2.Achievements;
using RoR2.Audio;
using RoR2.CharacterAI;
using RoR2.ContentManagement;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.SurvivorMannequins;
using RoR2.UI;
using RoR2.WwiseUtils;
using SasukeRinneganMod.Modules;
using SasukeRinneganMod.Modules.Achievements;
using SasukeRinneganMod.Modules.BaseStates;
using SasukeRinneganMod.Modules.Characters;
using SasukeRinneganMod.Ogi;
using SasukeRinneganMod.Survivors.SasukeRinnegan;
using SasukeRinneganMod.Survivors.SasukeRinnegan.Bonds;
using SasukeRinneganMod.Survivors.SasukeRinnegan.Components;
using SasukeRinneganMod.Survivors.SasukeRinnegan.SkillStates;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SasukeRinneganMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SasukeRinneganMod")]
[assembly: AssemblyTitle("SasukeRinneganMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace SasukeRinneganMod
{
	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);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.Zerneas.SasukeRinneganMod", "SasukeRinneganMod", "0.14.1")]
	public class SasukeRinneganPlugin : BaseUnityPlugin
	{
		public const string MODUID = "com.Zerneas.SasukeRinneganMod";

		public const string MODNAME = "SasukeRinneganMod";

		public const string MODVERSION = "0.14.1";

		public const string DEVELOPER_PREFIX = "ZERNEAS";

		public static SasukeRinneganPlugin instance;

		private void Awake()
		{
			instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			Language.Init();
			new SasukeRinneganSurvivor().Initialize();
			new ContentPacks().Initialize();
		}
	}
}
namespace SasukeRinneganMod.Ogi
{
	public class OgiController : MonoBehaviour
	{
		private static readonly Dictionary<string, OgiDefinition> definitions = new Dictionary<string, OgiDefinition>();

		public OgiDefinition definition;

		private CharacterBody body;

		private EntityStateMachine machine;

		private EntityStateMachine bodyMachine;

		public static void Register(OgiDefinition definition)
		{
			definitions[definition.bodyName] = definition;
			KizunaSkillList.Register(definition.bodyName, (Func<IEnumerable<Row>>)delegate
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				Row[] array = new Row[1];
				Sprite icon = definition.icon;
				string nameToken = definition.nameToken;
				string descriptionToken = definition.descriptionToken;
				Color color = definition.color;
				object keyText;
				if (definition.key == null)
				{
					keyText = "X";
				}
				else
				{
					KeyboardShortcut value = definition.key.Value;
					keyText = ((object)((KeyboardShortcut)(ref value)).MainKey/*cast due to .constrained prefix*/).ToString();
				}
				array[0] = KizunaSkillList.Key(icon, nameToken, descriptionToken, color, Config.KeyLabel((string)keyText, left: true));
				return (IEnumerable<Row>)(object)array;
			});
		}

		public static OgiDefinition DefinitionOf(CharacterBody body)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)body) || (int)body.bodyIndex == -1)
			{
				return null;
			}
			string bodyName = BodyCatalog.GetBodyName(body.bodyIndex);
			if (bodyName == null || !definitions.TryGetValue(bodyName, out var value))
			{
				return null;
			}
			return value;
		}

		public static int Gauge(CharacterBody body)
		{
			OgiDefinition ogiDefinition = DefinitionOf(body);
			if (ogiDefinition == null || !Object.op_Implicit((Object)(object)ogiDefinition.gaugeBuff))
			{
				return 0;
			}
			return body.GetBuffCount(ogiDefinition.gaugeBuff);
		}

		public static float Power(CharacterBody body, float gauge)
		{
			OgiDefinition ogiDefinition = DefinitionOf(body);
			if (ogiDefinition == null)
			{
				return 0f;
			}
			return Mathf.Clamp01((gauge - ogiDefinition.powerFloor) / Mathf.Max(1f, ogiDefinition.gaugeMax - ogiDefinition.powerFloor));
		}

		public static bool Busy(CharacterBody body)
		{
			OgiController ogiController = (Object.op_Implicit((Object)(object)body) ? ((Component)body).GetComponent<OgiController>() : null);
			if (Object.op_Implicit((Object)(object)ogiController) && Object.op_Implicit((Object)(object)ogiController.machine))
			{
				return ogiController.machine.state is IOgiState;
			}
			return false;
		}

		public static bool CanCast(CharacterBody body)
		{
			OgiDefinition ogiDefinition = DefinitionOf(body);
			if (ogiDefinition != null && Object.op_Implicit((Object)(object)body.healthComponent) && body.healthComponent.alive && !Busy(body))
			{
				return (float)body.GetBuffCount(ogiDefinition.gaugeBuff) >= ogiDefinition.castThreshold;
			}
			return false;
		}

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

		private void Start()
		{
			definition = DefinitionOf(body);
			if (definition != null)
			{
				machine = EntityStateMachine.FindByCustomName(((Component)this).gameObject, definition.machineName);
			}
			bodyMachine = EntityStateMachine.FindByCustomName(((Component)this).gameObject, "Body");
		}

		private void Update()
		{
			if (definition != null && Object.op_Implicit((Object)(object)body) && body.hasEffectiveAuthority && KeyPressed())
			{
				if (Object.op_Implicit((Object)(object)machine) && machine.state is IOgiState ogiState)
				{
					ogiState.Again();
				}
				else if (CanCast(body))
				{
					Cast();
				}
			}
		}

		private void Cast()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (definition.castState != null && Object.op_Implicit((Object)(object)machine))
			{
				machine.SetInterruptState(definition.castState(), definition.priority);
			}
		}

		private void FixedUpdate()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || definition == null || !Object.op_Implicit((Object)(object)body))
			{
				return;
			}
			OgiGauge ogiGauge = OgiGauge.Of(body);
			if (!Object.op_Implicit((Object)(object)ogiGauge))
			{
				return;
			}
			int num = Mathf.FloorToInt(ogiGauge.value);
			if (body.GetBuffCount(definition.gaugeBuff) != num)
			{
				body.SetBuffCount(definition.gaugeBuff.buffIndex, num);
			}
			CharacterMaster master = body.master;
			if (Object.op_Implicit((Object)(object)master) && !Object.op_Implicit((Object)(object)master.playerCharacterMasterController) && ogiGauge.value >= definition.gaugeMax && !body.outOfCombat && body.hasEffectiveAuthority && CanCast(body) && Object.op_Implicit((Object)(object)bodyMachine) && bodyMachine.IsInMainState())
			{
				BaseAI component = ((Component)master).GetComponent<BaseAI>();
				if (Object.op_Implicit((Object)(object)component) && component.currentEnemy != null && Object.op_Implicit((Object)(object)component.currentEnemy.gameObject))
				{
					Cast();
				}
			}
		}

		private bool KeyPressed()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (definition.key == null)
			{
				return false;
			}
			CharacterMaster master = body.master;
			PlayerCharacterMasterController val = (Object.op_Implicit((Object)(object)master) ? master.playerCharacterMasterController : null);
			LocalUser val2 = ((Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.networkUser)) ? val.networkUser.localUser : null);
			if (val2 == null)
			{
				return false;
			}
			if (!Config.GetKeyPressed(definition.key.Value) && !Config.DPadPressed(val2, left: true))
			{
				return false;
			}
			if (Object.op_Implicit((Object)(object)val2.eventSystem) && Object.op_Implicit((Object)(object)((EventSystem)val2.eventSystem).currentSelectedGameObject))
			{
				return false;
			}
			return !PauseManager.PauseScreenIsOpen();
		}
	}
	public class OgiDefinition
	{
		public string bodyName;

		public BuffDef gaugeBuff;

		public float gaugeMax = 100f;

		public float castThreshold = 50f;

		public float powerFloor = 25f;

		public ConfigEntry<KeyboardShortcut> key;

		public Func<EntityState> castState;

		public string machineName = "Weapon";

		public InterruptPriority priority = (InterruptPriority)2;

		public string nameToken;

		public string descriptionToken;

		public Sprite icon;

		public Color color = Color.white;
	}
	public interface IOgiState
	{
		void Again();
	}
	public class OgiGauge : MonoBehaviour
	{
		public float value;

		public static OgiGauge Of(CharacterBody body)
		{
			CharacterMaster val = (Object.op_Implicit((Object)(object)body) ? body.master : null);
			if (!Object.op_Implicit((Object)(object)val) || !NetworkServer.active)
			{
				return null;
			}
			OgiGauge component = ((Component)val).GetComponent<OgiGauge>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return ((Component)val).gameObject.AddComponent<OgiGauge>();
			}
			return component;
		}

		public static void Add(CharacterBody body, float amount)
		{
			OgiGauge ogiGauge = Of(body);
			OgiDefinition ogiDefinition = OgiController.DefinitionOf(body);
			if (Object.op_Implicit((Object)(object)ogiGauge) && ogiDefinition != null && !(amount <= 0f))
			{
				ogiGauge.value = Mathf.Clamp(ogiGauge.value + amount * OgiMastery.GainScale(body), 0f, ogiDefinition.gaugeMax);
			}
		}

		public static float SpendAll(CharacterBody body)
		{
			OgiGauge ogiGauge = Of(body);
			if (!Object.op_Implicit((Object)(object)ogiGauge))
			{
				return 0f;
			}
			float result = ogiGauge.value;
			ogiGauge.value = 0f;
			return result;
		}
	}
	public class OgiHud : MonoBehaviour
	{
		private static readonly Color unusableColor = new Color(0.45f, 0.45f, 0.45f);

		private const float slotGap = 0.75f;

		private const float glowMargin = 0.12f;

		private HUD hud;

		private Transform panel;

		private bool built;

		private GameObject lastTarget;

		private CharacterBody targetBody;

		private OgiDefinition definition;

		private readonly Vector3[] corners = (Vector3[])(object)new Vector3[4];

		private RectTransform root;

		private SkillIcon source;

		private Image picture;

		private RawImage sweep;

		private TextMeshProUGUI cooldownText;

		private TextMeshProUGUI keyText;

		private GameObject readyPanel;

		private GameObject flashPanel;

		private TooltipProvider tooltip;

		private Image glow;

		private bool wasUsable;

		private bool primed;

		private string key;

		public static void Init()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			HUD.Awake += new hook_Awake(HUD_Awake);
		}

		private static void HUD_Awake(orig_Awake orig, HUD self)
		{
			orig.Invoke(self);
			((Component)self).gameObject.AddComponent<OgiHud>().hud = self;
		}

		private void Update()
		{
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (Object.op_Implicit((Object)(object)hud) ? hud.targetBodyObject : null);
			if ((Object)(object)val != (Object)(object)lastTarget)
			{
				lastTarget = val;
				targetBody = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<CharacterBody>() : null);
				definition = OgiController.DefinitionOf(targetBody);
				primed = false;
			}
			if (definition == null)
			{
				if (Object.op_Implicit((Object)(object)root))
				{
					((Component)root).gameObject.SetActive(false);
				}
			}
			else
			{
				if (!built && !Build())
				{
					return;
				}
				((Component)root).gameObject.SetActive(true);
				if (!Place())
				{
					return;
				}
				int buffCount = targetBody.GetBuffCount(definition.gaugeBuff);
				float num = Mathf.Clamp01((float)buffCount / definition.gaugeMax);
				bool flag = OgiController.Busy(targetBody);
				bool flag2 = !flag && (float)buffCount >= definition.castThreshold;
				bool flag3 = (float)buffCount >= definition.gaugeMax;
				float num2 = 0.5f + 0.5f * Mathf.Sin(Time.unscaledTime * 8f);
				if (!primed)
				{
					primed = true;
					wasUsable = flag2;
				}
				if (flag2 && !wasUsable)
				{
					if (Object.op_Implicit((Object)(object)flashPanel))
					{
						flashPanel.SetActive(true);
					}
					Util.PlaySound("Play_UI_cooldownRefresh", ((Component)RoR2Application.instance).gameObject);
				}
				wasUsable = flag2;
				SetKey(Config.KeyLabel((definition.key != null) ? ((object)definition.key.Value/*cast due to .constrained prefix*/).ToString() : "X", left: true) + OgiMastery.HudSuffix(targetBody));
				if (Object.op_Implicit((Object)(object)tooltip))
				{
					tooltip.overrideBodyText = OgiMastery.Tooltip(targetBody, definition);
				}
				((Behaviour)picture).enabled = true;
				picture.sprite = definition.icon;
				((Graphic)picture).color = ((flag || flag2) ? Color.white : unusableColor);
				if (Object.op_Implicit((Object)(object)readyPanel))
				{
					readyPanel.SetActive(flag2);
				}
				if (Object.op_Implicit((Object)(object)sweep))
				{
					((Behaviour)sweep).enabled = num < 1f;
					((Graphic)sweep).color = new Color(1f, 1f, 1f, num);
				}
				if (Object.op_Implicit((Object)(object)cooldownText))
				{
					((TMP_Text)cooldownText).text = ((flag3 && !flag) ? "" : Mathf.RoundToInt(100f * num).ToString());
				}
				if (Object.op_Implicit((Object)(object)glow))
				{
					Color color = definition.color;
					color.a = (flag ? 0.6f : (flag3 ? Mathf.Lerp(0.3f, 0.85f, num2) : 0f));
					((Graphic)glow).color = color;
					((Behaviour)glow).enabled = color.a > 0f;
				}
			}
		}

		private void SetKey(string text)
		{
			if (Object.op_Implicit((Object)(object)keyText) && text != key)
			{
				key = text;
				((TMP_Text)keyText).text = text;
			}
		}

		private bool Build()
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			SkillIcon[] array = (Object.op_Implicit((Object)(object)hud) ? hud.skillIcons : null);
			if (array == null || array.Length < 4 || !Object.op_Implicit((Object)(object)array[0]) || !Object.op_Implicit((Object)(object)array[3]))
			{
				return false;
			}
			panel = IconsPanel(array);
			if (!Object.op_Implicit((Object)(object)panel))
			{
				return false;
			}
			source = array[3];
			GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, ((Component)source).transform.parent, false);
			((Object)val).name = "OgiSlot";
			LayoutElement val2 = val.GetComponent<LayoutElement>();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = val.AddComponent<LayoutElement>();
			}
			val2.ignoreLayout = true;
			SkillIcon component = val.GetComponent<SkillIcon>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				Object.Destroy((Object)(object)val);
				return false;
			}
			root = (RectTransform)val.transform;
			picture = component.iconImage;
			sweep = component.cooldownRemapPanel;
			cooldownText = component.cooldownText;
			readyPanel = component.isReadyPanelObject;
			flashPanel = component.flashPanelObject;
			tooltip = (Object.op_Implicit((Object)(object)component.tooltipProvider) ? component.tooltipProvider : val.GetComponentInChildren<TooltipProvider>(true));
			if (Object.op_Implicit((Object)(object)component.stockText))
			{
				((Component)component.stockText).gameObject.SetActive(false);
			}
			component.targetSkill = null;
			Object.Destroy((Object)(object)component);
			InputBindingDisplayController[] componentsInChildren = val.GetComponentsInChildren<InputBindingDisplayController>(true);
			foreach (InputBindingDisplayController val3 in componentsInChildren)
			{
				if (!Object.op_Implicit((Object)(object)keyText))
				{
					keyText = ((Component)val3).GetComponent<TextMeshProUGUI>();
				}
				Object.Destroy((Object)(object)val3);
			}
			if (!Object.op_Implicit((Object)(object)picture))
			{
				return false;
			}
			if (Object.op_Implicit((Object)(object)tooltip))
			{
				tooltip.titleToken = definition.nameToken;
				tooltip.bodyToken = definition.descriptionToken;
				tooltip.titleColor = definition.color;
			}
			glow = Glow(picture);
			built = true;
			return true;
		}

		private static Image Glow(Image picture)
		{
			//IL_001f: 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_0038: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = ((Graphic)picture).rectTransform;
			GameObject val = new GameObject("OgiGlow", new Type[1] { typeof(RectTransform) });
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent(((Transform)rectTransform).parent, false);
			val.AddComponent<LayoutElement>().ignoreLayout = true;
			((Transform)component).SetSiblingIndex(((Transform)rectTransform).GetSiblingIndex());
			component.anchorMin = rectTransform.anchorMin;
			component.anchorMax = rectTransform.anchorMax;
			component.pivot = rectTransform.pivot;
			component.anchoredPosition = rectTransform.anchoredPosition;
			Rect rect = rectTransform.rect;
			float num = ((Rect)(ref rect)).height * 0.12f;
			component.sizeDelta = rectTransform.sizeDelta + new Vector2(num, num) * 2f;
			((Transform)component).localRotation = ((Transform)rectTransform).localRotation;
			((Transform)component).localScale = ((Transform)rectTransform).localScale;
			Image obj = val.AddComponent<Image>();
			((Graphic)obj).raycastTarget = false;
			((Behaviour)obj).enabled = false;
			return obj;
		}

		private static Transform IconsPanel(SkillIcon[] icons)
		{
			Transform found = ((Component)icons[0]).transform.parent;
			while (Object.op_Implicit((Object)(object)found) && !Array.TrueForAll(icons, (SkillIcon icon) => !Object.op_Implicit((Object)(object)icon) || ((Component)icon).transform.IsChildOf(found)))
			{
				found = found.parent;
			}
			return found;
		}

		private bool Place()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			float num = float.MinValue;
			float num2 = 0f;
			SkillIcon[] skillIcons = hud.skillIcons;
			foreach (SkillIcon val in skillIcons)
			{
				if (Object.op_Implicit((Object)(object)val) && ((Component)val).gameObject.activeInHierarchy)
				{
					PictureBounds(val, panel, out var bottomLeft, out var topRight);
					num = Mathf.Max(num, topRight.y);
					num2 = Mathf.Max(num2, topRight.y - bottomLeft.y);
				}
			}
			if (num2 <= 0f)
			{
				return false;
			}
			float num3 = num + num2 * 0.75f;
			Transform transform = ((Component)source).transform;
			Transform parent = transform.parent;
			PictureBounds(source, panel, out var bottomLeft2, out var _);
			Vector3 val2 = parent.InverseTransformPoint(panel.TransformPoint(bottomLeft2));
			Vector3 val3 = parent.InverseTransformPoint(panel.TransformPoint(new Vector3(bottomLeft2.x, num3, bottomLeft2.z)));
			((Transform)root).localRotation = transform.localRotation;
			((Transform)root).localScale = transform.localScale;
			((Transform)root).localPosition = transform.localPosition + (val3 - val2);
			return true;
		}

		private void PictureBounds(SkillIcon icon, Transform parent, out Vector3 bottomLeft, out Vector3 topRight)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			((RectTransform)(Object.op_Implicit((Object)(object)icon.iconImage) ? ((object)((Graphic)icon.iconImage).rectTransform) : ((object)(RectTransform)((Component)icon).transform))).GetWorldCorners(corners);
			bottomLeft = parent.InverseTransformPoint(corners[0]);
			topRight = parent.InverseTransformPoint(corners[2]);
		}
	}
	public class OgiMastery : MonoBehaviour
	{
		public const int maxLevel = 40;

		public const float damageShare = 0.05f;

		public const float levelBase = 125f;

		public const float levelStep = 75f;

		public const float damagePerLevel = 0.04f;

		public const float gainPerLevel = 0.0125f;

		public const float maxGainBonus = 0.5f;

		public static BuffDef levelBuff;

		public float experience;

		public int level;

		private CharacterMaster master;

		public static void Init()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			levelBuff = Content.CreateAndAddBuff(typeof(OgiMastery).Namespace.Replace(".", "") + "Mastery", null, Color.white, canStack: true, isDebuff: false);
			levelBuff.isHidden = true;
		}

		public static void AddHooks()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			GlobalEventManager.onServerDamageDealt += OnServerDamageDealt;
			RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(OnGetStatCoefficients);
		}

		private static void OnGetStatCoefficients(CharacterBody sender, StatHookEventArgs args)
		{
			if (OgiController.DefinitionOf(sender) != null)
			{
				args.damageMultAdd += (float)Level(sender) * 0.04f;
			}
		}

		public static int Level(CharacterBody body)
		{
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)levelBuff))
			{
				return 0;
			}
			return body.GetBuffCount(levelBuff);
		}

		public static float DamageScale(CharacterBody body)
		{
			return 1f + (float)Level(body) * 0.04f;
		}

		public static float GainScale(CharacterBody body)
		{
			return 1f + Mathf.Min(0.5f, (float)Level(body) * 0.0125f);
		}

		public static float Needed(int level)
		{
			return 125f + 75f * (float)level;
		}

		public static OgiMastery Of(CharacterBody body)
		{
			CharacterMaster val = (Object.op_Implicit((Object)(object)body) ? body.master : null);
			if (!Object.op_Implicit((Object)(object)val) || !NetworkServer.active)
			{
				return null;
			}
			OgiMastery ogiMastery = ((Component)val).GetComponent<OgiMastery>();
			if (!Object.op_Implicit((Object)(object)ogiMastery))
			{
				ogiMastery = ((Component)val).gameObject.AddComponent<OgiMastery>();
				ogiMastery.master = val;
			}
			return ogiMastery;
		}

		private static CharacterBody Owner(CharacterBody attacker)
		{
			if (!Object.op_Implicit((Object)(object)attacker))
			{
				return null;
			}
			if (OgiController.DefinitionOf(attacker) != null)
			{
				return attacker;
			}
			CharacterMaster val = attacker.master;
			CharacterMaster val2 = ((Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.minionOwnership)) ? val.minionOwnership.ownerMaster : null);
			CharacterBody val3 = (Object.op_Implicit((Object)(object)val2) ? val2.GetBody() : null);
			if (OgiController.DefinitionOf(val3) == null)
			{
				return null;
			}
			return val3;
		}

		private static void OnServerDamageDealt(DamageReport report)
		{
			if (!NetworkServer.active || report == null || report.damageDealt <= 0f || !Object.op_Implicit((Object)(object)report.victim))
			{
				return;
			}
			CharacterBody val = Owner(report.attackerBody);
			if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val == (Object)(object)report.victimBody) && !((Object)(object)report.attackerBody == (Object)(object)report.victimBody))
			{
				OgiMastery ogiMastery = Of(val);
				if (Object.op_Implicit((Object)(object)ogiMastery))
				{
					ogiMastery.Gain(Mathf.Min(report.damageDealt, report.victim.fullCombinedHealth) * 0.05f);
				}
			}
		}

		private void Gain(float amount)
		{
			if (level < 40)
			{
				experience += amount;
				while (level < 40 && experience >= Needed(level))
				{
					experience -= Needed(level);
					level++;
				}
			}
		}

		private void FixedUpdate()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				if (!Object.op_Implicit((Object)(object)master))
				{
					master = ((Component)this).GetComponent<CharacterMaster>();
				}
				CharacterBody val = (Object.op_Implicit((Object)(object)master) ? master.GetBody() : null);
				if (OgiController.DefinitionOf(val) != null && val.GetBuffCount(levelBuff) != level)
				{
					val.SetBuffCount(levelBuff.buffIndex, level);
				}
			}
		}

		public static string HudSuffix(CharacterBody body)
		{
			int num = Level(body);
			if (num <= 0)
			{
				return "";
			}
			return "  Lv" + num;
		}

		public static string Tooltip(CharacterBody body, OgiDefinition definition)
		{
			int num = Level(body);
			bool num2 = Language.currentLanguageName != null && Language.currentLanguageName.StartsWith("es");
			string text = Language.GetString(definition.descriptionToken);
			int num3 = Mathf.RoundToInt(100f * (DamageScale(body) - 1f));
			int num4 = Mathf.RoundToInt(100f * (GainScale(body) - 1f));
			string text2 = (num2 ? $"<style=cIsUtility>Maestría {num}/{40}</style>: <style=cIsDamage>+{num3}% de daño</style> en todo tu kit y la barra se llena un {num4}% más rápido. Sube con el daño que haces en la partida." : $"<style=cIsUtility>Mastery {num}/{40}</style>: <style=cIsDamage>+{num3}% damage</style> in your whole kit and the gauge fills {num4}% faster. It grows with the damage you deal this run.");
			return text + "\n\n" + text2;
		}
	}
}
namespace SasukeRinneganMod.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)SasukeRinneganPlugin.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_003d: 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)
			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>();
			VFXAttributes obj = val.AddComponent<VFXAttributes>();
			obj.vfxPriority = (VFXPriority)2;
			obj.DoNotPool = true;
			EffectComponent obj2 = val.AddComponent<EffectComponent>();
			obj2.applyScale = false;
			obj2.effectIndex = (EffectIndex)(-1);
			obj2.parentToReferencedTransform = parentToTransform;
			obj2.positionAtReferencedTransform = true;
			obj2.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)SasukeRinneganPlugin.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);
			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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref entry)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			return Input.GetKeyDown(((KeyboardShortcut)(ref entry)).MainKey);
		}

		public static bool DPadPressed(LocalUser user, bool left)
		{
			Player val = ((user != null) ? user.inputPlayer : null);
			if (val == null)
			{
				return false;
			}
			foreach (Joystick joystick in val.controllers.Joysticks)
			{
				IGamepadTemplate template = ((Controller)joystick).GetTemplate<IGamepadTemplate>();
				if (template != null && ((IControllerTemplate)template).GetElement<IControllerTemplateButton>(left ? 22 : 21).justPressed)
				{
					return true;
				}
			}
			return false;
		}

		public static string KeyLabel(string keyText, bool left)
		{
			return KizunaPad.Label(keyText, left);
		}
	}
	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_0002: 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_0002: 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_0002: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			SurvivorDef obj = ScriptableObject.CreateInstance<SurvivorDef>();
			obj.bodyPrefab = bodyPrefab;
			obj.displayPrefab = displayPrefab;
			obj.primaryColor = charColor;
			obj.cachedName = ((Object)bodyPrefab).name.Replace("Body", "");
			obj.displayNameToken = tokenPrefix + "NAME";
			obj.descriptionToken = tokenPrefix + "DESCRIPTION";
			obj.outroFlavorToken = tokenPrefix + "OUTRO_FLAVOR";
			obj.mainEndingEscapeFailureFlavorToken = tokenPrefix + "OUTRO_FAILURE";
			obj.desiredSortPosition = sortPosition;
			obj.unlockableDef = unlockableDef;
			AddSurvivorDef(obj);
		}

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

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

		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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			BuffDef obj = ScriptableObject.CreateInstance<BuffDef>();
			((Object)obj).name = buffName;
			obj.buffColor = buffColor;
			obj.canStack = canStack;
			obj.isDebuff = isDebuff;
			obj.eliteDef = null;
			obj.iconSprite = buffIcon;
			AddBuffDef(obj);
			return obj;
		}

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

		internal static EffectDef CreateAndAddEffectDef(GameObject effectPrefab)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_000d: 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 NetworkSounds CreateAndAddNetworkSounds(string eventName)
		{
			string[] array = StormVoice.VariantsOf(eventName);
			NetworkSoundEventDef[] array2 = (NetworkSoundEventDef[])(object)new NetworkSoundEventDef[array.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array2[i] = CreateAndAddNetworkSoundEventDef(array[i]);
			}
			return new NetworkSounds(array2);
		}

		internal static NetworkSoundEventDef CreateAndAddNetworkSoundEventDef(string eventName)
		{
			NetworkSoundEventDef obj = ScriptableObject.CreateInstance<NetworkSoundEventDef>();
			obj.akId = AkSoundEngine.GetIDFromString(eventName);
			obj.eventName = eventName;
			AddNetworkSoundEventDef(obj);
			return obj;
		}
	}
	public class NetworkSounds
	{
		private readonly NetworkSoundEventDef[] defs;

		public NetworkSoundEventIndex index
		{
			get
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				if (defs.Length == 0)
				{
					return (NetworkSoundEventIndex)(-1);
				}
				return defs[Random.Range(0, defs.Length)].index;
			}
		}

		public NetworkSounds(NetworkSoundEventDef[] defs)
		{
			this.defs = defs;
		}

		public static implicit operator bool(NetworkSounds sounds)
		{
			if (sounds != null)
			{
				return sounds.defs.Length != 0;
			}
			return false;
		}
	}
	internal class ContentPacks : IContentPackProvider
	{
		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.Zerneas.SasukeRinneganMod";

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

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

		public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
		{
			contentPack.identifier = identifier;
			contentPack.bodyPrefabs.Add(bodyPrefabs.ToArray());
			contentPack.masterPrefabs.Add(masterPrefabs.ToArray());
			contentPack.projectilePrefabs.Add(projectilePrefabs.ToArray());
			contentPack.survivorDefs.Add(survivorDefs.ToArray());
			contentPack.unlockableDefs.Add(unlockableDefs.ToArray());
			contentPack.skillDefs.Add(skillDefs.ToArray());
			contentPack.skillFamilies.Add(skillFamilies.ToArray());
			contentPack.entityStateTypes.Add(entityStates.ToArray());
			contentPack.buffDefs.Add(buffDefs.ToArray());
			contentPack.effectDefs.Add(effectDefs.ToArray());
			contentPack.networkSoundEventDefs.Add(networkSoundEventDefs.ToArray());
			args.ReportProgress(1f);
			yield break;
		}

		public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args)
		{
			ContentPack.Copy(contentPack, args.output);
			args.ReportProgress(1f);
			yield break;
		}

		public IEnumerator FinalizeAsync(FinalizeAsyncArgs args)
		{
			args.ReportProgress(1f);
			yield break;
		}
	}
	public static class DamageMeter
	{
		private class Tally
		{
			public readonly Dictionary<string, float> bySource = new Dictionary<string, float>();

			public float total;

			public float startTime = -1f;

			public float lastTime;

			public string victimName;

			public int victimLevel;

			public float victimHealth;

			public void Add(string source, float amount, float time)
			{
				if (startTime < 0f)
				{
					startTime = time;
				}
				lastTime = time;
				total += amount;
				bySource.TryGetValue(source, out var value);
				bySource[source] = value + amount;
			}
		}

		private static Func<CharacterBody, bool> isHim;

		private static string label;

		public static Func<DamageInfo, string> tag;

		public static Func<string> stageNote;

		private static readonly Dictionary<NetworkInstanceId, Tally> stage = new Dictionary<NetworkInstanceId, Tally>();

		private static readonly Dictionary<HealthComponent, Dictionary<NetworkInstanceId, Tally>> bosses = new Dictionary<HealthComponent, Dictionary<NetworkInstanceId, Tally>>();

		private static float Now
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)Run.instance))
				{
					return Time.time;
				}
				return Run.instance.GetRunStopwatch();
			}
		}

		public static void Init(string survivorLabel, Func<CharacterBody, bool> isSurvivor)
		{
			label = survivorLabel;
			isHim = isSurvivor;
			GlobalEventManager.onServerDamageDealt += OnServerDamageDealt;
			GlobalEventManager.onCharacterDeathGlobal += OnCharacterDeath;
			Stage.onServerStageComplete += OnStageComplete;
			Run.onRunDestroyGlobal += delegate
			{
				stage.Clear();
				bosses.Clear();
			};
		}

		private static CharacterBody Owner(CharacterBody attacker, out bool minion)
		{
			minion = false;
			if (!Object.op_Implicit((Object)(object)attacker))
			{
				return null;
			}
			if (isHim(attacker))
			{
				return attacker;
			}
			CharacterMaster master = attacker.master;
			CharacterMaster val = ((Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.minionOwnership)) ? master.minionOwnership.ownerMaster : null);
			CharacterBody val2 = (Object.op_Implicit((Object)(object)val) ? val.GetBody() : null);
			minion = Object.op_Implicit((Object)(object)val2) && isHim(val2);
			if (!minion)
			{
				return null;
			}
			return val2;
		}

		private static string Source(DamageReport report, CharacterBody owner, bool minion)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0079: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			if (minion)
			{
				return "Minions";
			}
			DamageInfo damageInfo = report.damageInfo;
			string text = "";
			if ((int)report.dotType != -1)
			{
				return text + "DoT " + ((object)Unsafe.As<DotIndex, DotIndex>(ref report.dotType)/*cast due to .constrained prefix*/).ToString();
			}
			string text2 = ((tag != null) ? tag(damageInfo) : null);
			if (text2 != null)
			{
				return text + text2;
			}
			DamageSource damageSource = damageInfo.damageType.damageSource;
			if ((damageInfo.damageType.damageType & 0x4000000) != 0 || (damageSource & 0x20) != 0)
			{
				return text + "DoT (own)";
			}
			if ((damageSource & 1) != 0)
			{
				return text + "M1";
			}
			if ((damageSource & 2) != 0)
			{
				return text + "M2";
			}
			if ((damageSource & 4) != 0)
			{
				return text + "Utility";
			}
			if ((damageSource & 8) != 0)
			{
				return text + "Special";
			}
			if ((damageSource & 0x40) != 0)
			{
				return "Equipment";
			}
			if (!((ProcChainMask)(ref damageInfo.procChainMask)).Equals(default(ProcChainMask)))
			{
				return text + "Items/other";
			}
			if (Object.op_Implicit((Object)(object)damageInfo.inflictor) && (Object)(object)damageInfo.inflictor != (Object)(object)((Component)owner).gameObject)
			{
				return text + "Untagged " + Clean(((Object)damageInfo.inflictor).name);
			}
			return text + Guess(owner);
		}

		private static string Clean(string name)
		{
			return name.Replace("(Clone)", "").Trim();
		}

		private static string Guess(CharacterBody owner)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Invalid comparison between Unknown and I4
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Invalid comparison between Unknown and I4
			SkillLocator skillLocator = owner.skillLocator;
			if (Object.op_Implicit((Object)(object)skillLocator))
			{
				GenericSkill[] allSkills = skillLocator.allSkills;
				foreach (GenericSkill val in allSkills)
				{
					EntityStateMachine val2 = (Object.op_Implicit((Object)(object)val) ? val.stateMachine : null);
					if (!Object.op_Implicit((Object)(object)val2) || val2.state == null || !Object.op_Implicit((Object)(object)val.skillDef) || !(((SerializableEntityStateType)(ref val.skillDef.activationState)).stateType == ((object)val2.state).GetType()))
					{
						continue;
					}
					SkillSlot val3 = skillLocator.FindSkillSlot(val);
					if ((int)val3 != 0)
					{
						if ((int)val3 != 1)
						{
							if ((int)val3 != 2)
							{
								if ((int)val3 != 3)
								{
									return "Untagged " + ((object)val2.state).GetType().Name;
								}
								return "Special";
							}
							return "Utility";
						}
						return "M2";
					}
					return "M1";
				}
			}
			EntityStateMachine val4 = EntityStateMachine.FindByCustomName(((Component)owner).gameObject, "Body");
			return "Untagged " + ((Object.op_Implicit((Object)(object)val4) && val4.state != null) ? ((object)val4.state).GetType().Name : "?");
		}

		private static void OnServerDamageDealt(DamageReport report)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || report == null || report.damageInfo == null || report.damageDealt <= 0f || !Object.op_Implicit((Object)(object)report.victim))
			{
				return;
			}
			bool minion;
			CharacterBody val = Owner(report.attackerBody, out minion);
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val == (Object)(object)report.victimBody || !Object.op_Implicit((Object)(object)val.master))
			{
				return;
			}
			NetworkInstanceId netId = ((NetworkBehaviour)val.master).netId;
			string source = Source(report, val, minion);
			float now = Now;
			if (!stage.TryGetValue(netId, out var value))
			{
				value = (stage[netId] = new Tally());
			}
			value.Add(source, report.damageDealt, now);
			CharacterBody victimBody = report.victimBody;
			if (Object.op_Implicit((Object)(object)victimBody) && (victimBody.isBoss || victimBody.isChampion))
			{
				if (!bosses.TryGetValue(report.victim, out var value2))
				{
					value2 = (bosses[report.victim] = new Dictionary<NetworkInstanceId, Tally>());
				}
				if (!value2.TryGetValue(netId, out var value3))
				{
					Dictionary<NetworkInstanceId, Tally> dictionary2 = value2;
					Tally obj = new Tally
					{
						victimName = Util.GetBestBodyName(((Component)victimBody).gameObject),
						victimLevel = Mathf.RoundToInt(victimBody.level),
						victimHealth = report.victim.fullCombinedHealth
					};
					value3 = obj;
					dictionary2[netId] = obj;
				}
				value3.Add(source, report.damageDealt, now);
			}
		}

		private static void OnCharacterDeath(DamageReport report)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || report == null || !Object.op_Implicit((Object)(object)report.victim) || !bosses.TryGetValue(report.victim, out var value))
			{
				return;
			}
			bosses.Remove(report.victim);
			foreach (KeyValuePair<NetworkInstanceId, Tally> item in value)
			{
				Write("boss " + item.Value.victimName + " (lv " + item.Value.victimLevel + ", " + Mathf.RoundToInt(item.Value.victimHealth) + " HP)", item.Key, item.Value);
			}
		}

		private static void OnStageComplete(Stage completed)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			string text = ((Object.op_Implicit((Object)(object)completed) && Object.op_Implicit((Object)(object)completed.sceneDef)) ? completed.sceneDef.baseSceneName : "?");
			foreach (KeyValuePair<NetworkInstanceId, Tally> item in stage)
			{
				Write("stage " + text, item.Key, item.Value);
			}
			if (stageNote != null)
			{
				Log.Info("[DamageMeter] " + label + " stage " + text + ":" + stageNote());
			}
			stage.Clear();
			bosses.Clear();
		}

		private static void Write(string what, NetworkInstanceId id, Tally tally)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = NetworkServer.FindLocalObject(id);
			CharacterMaster val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<CharacterMaster>() : null);
			CharacterBody val3 = (Object.op_Implicit((Object)(object)val2) ? val2.GetBody() : null);
			float num = Mathf.Max(0.1f, tally.lastTime - tally.startTime);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("[DamageMeter] ").Append(label).Append(" vs ")
				.Append(what)
				.Append(": ")
				.Append(Mathf.RoundToInt(tally.total))
				.Append(" dmg in ")
				.Append(num.ToString("0.0"))
				.Append(" s = ")
				.Append(Mathf.RoundToInt(tally.total / num))
				.Append("/s");
			if (Object.op_Implicit((Object)(object)val3))
			{
				stringBuilder.Append(" | his lv ").Append(Mathf.RoundToInt(val3.level)).Append(", damage ")
					.Append(val3.damage.ToString("0.0"))
					.Append(" (M1 100% = ")
					.Append(val3.damage.ToString("0"))
					.Append("), attack speed ")
					.Append(val3.attackSpeed.ToString("0.00"))
					.Append(", crit ")
					.Append(val3.crit.ToString("0"))
					.Append("%, items ")
					.Append(Object.op_Implicit((Object)(object)val2.inventory) ? val2.inventory.itemAcquisitionOrder.Count : 0);
				if (OgiController.DefinitionOf(val3) != null)
				{
					stringBuilder.Append(", ogi mastery ").Append(OgiMastery.Level(val3)).Append(", gauge ")
						.Append(OgiController.Gauge(val3));
				}
			}
			if (Object.op_Implicit((Object)(object)Run.instance))
			{
				DifficultyDef difficultyDef = DifficultyCatalog.GetDifficultyDef(Run.instance.selectedDifficulty);
				stringBuilder.Append(", ").Append((difficultyDef != null) ? Language.GetString(difficultyDef.nameToken) : "?").Append(", stage ")
					.Append(Run.instance.stageClearCount + 1)
					.Append(", run ")
					.Append((Run.instance.GetRunStopwatch() / 60f).ToString("0.0"))
					.Append(" min");
			}
			foreach (KeyValuePair<string, float> item in tally.bySource.OrderByDescending((KeyValuePair<string, float> pair) => pair.Value))
			{
				stringBuilder.Append("\n    ").Append(item.Key).Append(": ")
					.Append(Mathf.RoundToInt(item.Value))
					.Append(" (")
					.Append((100f * item.Value / Mathf.Max(1f, tally.total)).ToString("0"))
					.Append("%, ")
					.Append(Mathf.RoundToInt(item.Value / num))
					.Append("/s)");
			}
			Log.Info(stringBuilder.ToString());
		}
	}
	public static class HitStop
	{
		public const float duration = 0.06f;

		public const float heavyCoefficient = 4f;

		public const float minInterval = 0.2f;

		private static Func<CharacterBody, bool> isHim;

		public static void Init(Func<CharacterBody, bool> isSurvivor)
		{
			isHim = isSurvivor;
			GlobalEventManager.onClientDamageNotified += OnClientDamageNotified;
		}

		private static void OnClientDamageNotified(DamageDealtMessage message)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (message == null || !Object.op_Implicit((Object)(object)message.attacker) || (message.damageType.damageType & 0x4000000) != 0)
			{
				return;
			}
			CharacterBody component = message.attacker.GetComponent<CharacterBody>();
			if (!Object.op_Implicit((Object)(object)component) || component.damage <= 0f || !isHim(component) || message.damage / (message.crit ? 2f : 1f) < component.damage * 4f)
			{
				return;
			}
			Transform val = (Object.op_Implicit((Object)(object)component.modelLocator) ? component.modelLocator.modelTransform : null);
			Animator val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<Animator>() : null);
			if (Object.op_Implicit((Object)(object)val2))
			{
				HitStopFreeze hitStopFreeze = ((Component)val).GetComponent<HitStopFreeze>();
				if (!Object.op_Implicit((Object)(object)hitStopFreeze))
				{
					hitStopFreeze = ((Component)val).gameObject.AddComponent<HitStopFreeze>();
				}
				hitStopFreeze.Freeze(val2);
			}
		}
	}
	public class HitStopFreeze : MonoBehaviour
	{
		private Animator animator;

		private float savedSpeed = 1f;

		private float left;

		private float lastStart = -10f;

		public void Freeze(Animator target)
		{
			if (!(left > 0f) && !(Time.time - lastStart < 0.2f))
			{
				animator = target;
				savedSpeed = ((animator.speed > 0f) ? animator.speed : 1f);
				animator.speed = 0f;
				left = 0.06f;
				lastStart = Time.time;
			}
		}

		private void Update()
		{
			if (!(left <= 0f))
			{
				left -= Time.deltaTime;
				if (left <= 0f && Object.op_Implicit((Object)(object)animator))
				{
					animator.speed = savedSpeed;
				}
			}
		}

		private void OnDisable()
		{
			if (left > 0f && Object.op_Implicit((Object)(object)animator))
			{
				animator.speed = savedSpeed;
			}
			left = 0f;
		}
	}
	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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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)
		{
			KeyAssetRuleGroup[] keyAssetRuleGroups = ((Component)LegacyResourcesAPI.Load<GameObject>("Prefabs/CharacterBodies/" + bodyName).GetComponent<ModelLocator>().modelTransform).GetComponent<CharacterModel>().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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (keyAsset_ == (Object)null)
			{
				Log.Error("could not find keyasset");
			}
			return new KeyAssetRuleGroup
			{
				keyAsset = keyAsset_,
				displayRuleGroup = new DisplayRuleGroup
				{
					rules = rules
				}
			};
		}

		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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			return new ItemDisplayRule
			{
				ruleType = (ItemDisplayRuleType)0,
				childName = childName,
				followerPrefab = itemPrefab,
				limbMask = (LimbFlags)0,
				localPos = position,
				localAngles = rotation,
				localScale = scale
			};
		}

		public static ItemDisplayRule CreateLimbMaskDisplayRule(LimbFlags limb)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			return new ItemDisplayRule
			{
				ruleType = (ItemDisplayRuleType)1,
				limbMask = limb,
				childName = "",
				followerPrefab = null
			};
		}

		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)SasukeRinneganPlugin.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 Add(string token, string text, string language)
		{
			if (!usingLanguageFolder)
			{
				LanguageAPI.Add(token, text, language);
			}
		}

		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))
				{
					File.WriteAllText(Path.Combine(Directory.GetParent(((BaseUnityPlugin)SasukeRinneganPlugin.instance).Info.Location).FullName, "Language", "en", fileName), 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			Material val = cachedMaterials.Find((Material mat) => ((Object)mat).name.Replace(" (Instance)", "") == 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0006: 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_0012: 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;
		}
	}
	public class PipHud : MonoBehaviour
	{
		public class Source
		{
			public string bodyName;

			public int pips;

			public Func<CharacterBody, int> filled;

			public Func<CharacterBody, int> points;

			public Color color = Color.white;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_Awake <>9__17_0;

			internal void <Register>b__17_0(orig_Awake orig, HUD self)
			{
				orig.Invoke(self);
				((Component)self).gameObject.AddComponent<PipHud>().hud = self;
			}
		}

		private static readonly Dictionary<string, Source> sources = new Dictionary<string, Source>();

		private static readonly Color emptyColor = new Color(0.12f, 0.12f, 0.14f, 0.75f);

		private static Sprite circle;

		private static bool hooked;

		private const float pipSize = 0.17f;

		private const float pipGap = 0.05f;

		private const float rowHeight = 0.72f;

		private HUD hud;

		private GameObject lastTarget;

		private CharacterBody targetBody;

		private Source source;

		private RectTransform root;

		private Image[] pips;

		private TextMeshProUGUI label;

		private int shownFilled = -1;

		private int shownPoints = -1;

		public static void Register(Source source)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			sources[source.bodyName] = source;
			if (hooked)
			{
				return;
			}
			hooked = true;
			object obj = <>c.<>9__17_0;
			if (obj == null)
			{
				hook_Awake val = delegate(orig_Awake orig, HUD self)
				{
					orig.Invoke(self);
					((Component)self).gameObject.AddComponent<PipHud>().hud = self;
				};
				<>c.<>9__17_0 = val;
				obj = (object)val;
			}
			HUD.Awake += (hook_Awake)obj;
		}

		private void Update()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Invalid comparison between Unknown and I4
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (Object.op_Implicit((Object)(object)hud) ? hud.targetBodyObject : null);
			if ((Object)(object)val != (Object)(object)lastTarget)
			{
				lastTarget = val;
				targetBody = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<CharacterBody>() : null);
				source = null;
				if (Object.op_Implicit((Object)(object)targetBody) && (int)targetBody.bodyIndex != -1)
				{
					sources.TryGetValue(BodyCatalog.GetBodyName(targetBody.bodyIndex) ?? "", out source);
				}
				if (Object.op_Implicit((Object)(object)root))
				{
					Object.Destroy((Object)(object)((Component)root).gameObject);
					root = null;
				}
			}
			if (source == null || !Object.op_Implicit((Object)(object)targetBody) || (!Object.op_Implicit((Object)(object)root) && !Build()))
			{
				return;
			}
			int num = Mathf.Clamp(source.filled(targetBody), 0, pips.Length);
			if (num != shownFilled)
			{
				shownFilled = num;
				for (int i = 0; i < pips.Length; i++)
				{
					((Graphic)pips[i]).color = ((i < num) ? source.color : emptyColor);
				}
			}
			int num2 = source.points(targetBody);
			if (num2 != shownPoints)
			{
				shownPoints = num2;
				((TMP_Text)label).text = ((num2 > 0) ? ("×" + num2) : "");
			}
		}

		private bool Build()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Expected O, but got Unknown
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			SkillIcon[] array = (Object.op_Implicit((Object)(object)hud) ? hud.skillIcons : null);
			if (array == null || array.Length < 1 || !Object.op_Implicit((Object)(object)array[0]) || !Object.op_Implicit((Object)(object)array[0].iconImage))
			{
				return false;
			}
			RectTransform rectTransform = ((Graphic)array[0].iconImage).rectTransform;
			Rect rect = rectTransform.rect;
			float height = ((Rect)(ref rect)).height;
			if (height <= 0f)
			{
				return false;
			}
			GameObject val = new GameObject("PipHud", new Type[1] { typeof(RectTransform) });
			root = val.GetComponent<RectTransform>();
			((Transform)root).SetParent((Transform)(object)rectTransform, false);
			val.AddComponent<LayoutElement>().ignoreLayout = true;
			RectTransform obj = root;
			RectTransform obj2 = root;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			obj2.anchorMax = val2;
			obj.anchorMin = val2;
			root.pivot = new Vector2(0.5f, 0.5f);
			root.anchoredPosition = new Vector2(0f, height * 0.72f);
			root.sizeDelta = Vector2.zero;
			float num = height * 0.17f;
			float num2 = num + height * 0.05f;
			float num3 = num2 * (float)source.pips - height * 0.05f;
			pips = (Image[])(object)new Image[source.pips];
			for (int i = 0; i < pips.Length; i++)
			{
				GameObject val3 = new GameObject("Pip" + i, new Type[1] { typeof(RectTransform) });
				RectTransform component = val3.GetComponent<RectTransform>();
				((Transform)component).SetParent((Transform)(object)root, false);
				component.sizeDelta = new Vector2(num, num);
				component.anchoredPosition = new Vector2((0f - num3) * 0.5f + num * 0.5f + num2 * (float)i, 0f);
				Image val4 = val3.AddComponent<Image>();
				val4.sprite = Circle();
				((Graphic)val4).raycastTarget = false;
				((Graphic)val4).color = emptyColor;
				pips[i] = val4;
			}
			GameObject val5 = new GameObject("Points", new Type[1] { typeof(RectTransform) });
			RectTransform component2 = val5.GetComponent<RectTransform>();
			((Transform)component2).SetParent((Transform)(object)root, false);
			component2.sizeDelta = new Vector2(height * 2f, height * 0.5f);
			component2.anchoredPosition = new Vector2(0f, height * 0.3f);
			label = val5.AddComponent<TextMeshProUGUI>();
			TextMeshProUGUI val6 = (Object.op_Implicit((Object)(object)array[0].stockText) ? array[0].stockText : array[0].cooldownText);
			if (Object.op_Implicit((Object)(object)val6))
			{
				((TMP_Text)label).font = ((TMP_Text)val6).font;
			}
			((TMP_Text)label).fontSize = height * 0.34f;
			((TMP_Text)label).alignment = (TextAlignmentOptions)514;
			((Graphic)label).color = source.color;
			((Graphic)label).raycastTarget = false;
			((TMP_Text)label).enableWordWrapping = false;
			((TMP_Text)label).text = "";
			shownFilled = (shownPoints = -1);
			return true;
		}

		private static Sprite Circle()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)circle))
			{
				return circle;
			}
			Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[1024];
			for (int i = 0; i < 32; i++)
			{
				for (int j = 0; j < 32; j++)
				{
					float num = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), new Vector2(16f, 16f)) / 16f;
					array[i * 32 + j] = Color32.op_Implicit(new Color(1f, 1f, 1f, Mathf.Clamp01((1f - num) * 6f)));
				}
			}
			val.SetPixels32(array);
			val.Apply();
			circle = Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f));
			return circle;
		}
	}
	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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: 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)48;
			component.rootMotionInMainState = false;
			component.hullClassification = (HullClassification)0;
			component.isChampion = false;
		}

		private static Transform AddCharacterModelToSurvivorBody(GameObject bodyPrefab, Transform modelTransform, BodyInfo bodyInfo)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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;
			if ((Object)(object)bodyPrefab.transform.Find("CameraPivot") == (Object)null)
			{
				Transform transform = new GameObject("CameraPivot").transform;
				transform.parent = bodyPrefab.transform;
				transform.localPosition = bodyInfo.cameraPivotPosition;
				transform.localRotation = Quaternion.identity;
			}
			Transform val2 = bodyPrefab.transform.Find("AimOrigin");
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = new GameObject("AimOrigin").transform;
				val2.parent = bodyPrefab.transform;
				val2.localPosition = bodyInfo.aimOriginPosition;
				val2.localRotation = Quaternion.identity;
			}
			bodyPrefab.GetComponent<CharacterBody>().aimOriginTransform = val2;
			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 modelTransfo