Decompiled source of PotatoFighter v1.1.0

plugins/PotatoFighter.dll

Decompiled 9 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace PotatoFighter;

internal static class Assets
{
	internal static string Dir;

	internal static Mesh LoadMesh(string name)
	{
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Expected O, but got Unknown
		string text = Path.Combine(Dir, name + ".mesh");
		if (!File.Exists(text))
		{
			Plugin.Log.LogError((object)("Missing " + text));
			return null;
		}
		using BinaryReader binaryReader = new BinaryReader(File.OpenRead(text));
		if (new string(binaryReader.ReadChars(4)) != "PTM1")
		{
			Plugin.Log.LogError((object)(text + " isn't a model file from the PotatoFighter tools."));
			return null;
		}
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		Vector3[] array = (Vector3[])(object)new Vector3[num];
		Vector3[] array2 = (Vector3[])(object)new Vector3[num];
		Vector2[] array3 = (Vector2[])(object)new Vector2[num];
		int[] array4 = new int[num2];
		for (int i = 0; i < num; i++)
		{
			array[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
		}
		for (int j = 0; j < num; j++)
		{
			array2[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
		}
		for (int k = 0; k < num; k++)
		{
			array3[k] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
		}
		for (int l = 0; l < num2; l++)
		{
			array4[l] = binaryReader.ReadInt32();
		}
		Mesh val = new Mesh
		{
			name = "potato_" + name
		};
		if (num > 65535)
		{
			val.indexFormat = (IndexFormat)1;
		}
		val.vertices = array;
		val.normals = array2;
		val.uv = array3;
		val.triangles = array4;
		val.RecalculateTangents();
		val.RecalculateBounds();
		return val;
	}

	internal static Texture2D LoadTexture(string file, bool linear)
	{
		//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_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Expected O, but got Unknown
		if (GUIManager.IsHeadless())
		{
			return null;
		}
		string text = Path.Combine(Dir, file);
		if (!File.Exists(text))
		{
			Plugin.Log.LogWarning((object)("Missing " + text));
			return null;
		}
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
		{
			name = Path.GetFileNameWithoutExtension(file),
			wrapMode = (TextureWrapMode)1
		};
		if (!ImageConversion.LoadImage(val, File.ReadAllBytes(text), true))
		{
			Plugin.Log.LogWarning((object)("Couldn't read " + text));
			return null;
		}
		((Texture)val).filterMode = (FilterMode)0;
		return val;
	}
}
internal static class AttackCancel
{
	[HarmonyPatch(typeof(Attack), "OnAttackTrigger")]
	internal static class SkipCancelled
	{
		[HarmonyPriority(800)]
		private static bool Prefix(Attack __instance)
		{
			QueuedBowRelease.BeforeTrigger(__instance);
			return !IsCancelled(__instance);
		}

		private static void Postfix(Attack __instance, bool __runOriginal)
		{
			if (__runOriginal && !Landed.TryGetValue(__instance, out var _))
			{
				Landed.Add(__instance, Marker);
			}
		}
	}

	[HarmonyPatch(typeof(Player), "Awake")]
	internal static class Register
	{
		private static void Postfix(Player __instance)
		{
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null)
			{
				component.Register<string>("PotatoFighter_AttackCancel", (Action<long, string>)delegate(long sender, string animation)
				{
					Interrupt(__instance, animation);
				});
			}
		}
	}

	[HarmonyPatch(typeof(Player), "SetControls")]
	internal static class Controls
	{
		private static void Prefix(Player __instance, out bool __state)
		{
			__state = Blocking.Invoke((Character)(object)__instance);
		}

		private static void Postfix(Player __instance, bool __state)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (Plugin.AttackCancelEnabled.Value && !__state && Blocking.Invoke((Character)(object)__instance) && CanCancel(__instance))
			{
				Cancel(__instance);
				holdIgnored = true;
			}
			if (holdIgnored)
			{
				if (!AttackHold.Invoke((Character)(object)__instance) && !SecondaryAttackHold.Invoke((Character)(object)__instance))
				{
					holdIgnored = false;
				}
				AttackHold.Invoke((Character)(object)__instance) = false;
				SecondaryAttackHold.Invoke((Character)(object)__instance) = false;
			}
		}
	}

	[HarmonyPatch(typeof(Humanoid), "StartAttack")]
	internal static class Waiting
	{
		private static bool Prefix(Humanoid __instance, ref bool __result)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || Time.time >= AttackAllowedAt)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}

	private const float BlendSeconds = 0.1f;

	private const float WindupWait = 0.2f;

	private const string Rpc = "PotatoFighter_AttackCancel";

	private static readonly int AttackTag = ZSyncAnimation.GetHash("attack");

	private static readonly int Movement = Animator.StringToHash("Base Layer.Movement");

	private static readonly int UpperBodyIdle = Animator.StringToHash("upperbody.None");

	private static readonly FieldRef<Character, Animator> CharacterAnimator = AccessTools.FieldRefAccess<Character, Animator>("m_animator");

	private static readonly FieldRef<Character, bool> Blocking = AccessTools.FieldRefAccess<Character, bool>("m_blocking");

	private static readonly FieldRef<Character, bool> AttackHold = AccessTools.FieldRefAccess<Character, bool>("m_attackHold");

	private static readonly FieldRef<Character, bool> SecondaryAttackHold = AccessTools.FieldRefAccess<Character, bool>("m_secondaryAttackHold");

	private static readonly FieldRef<Humanoid, Attack> CurrentAttack = AccessTools.FieldRefAccess<Humanoid, Attack>("m_currentAttack");

	private static readonly FieldRef<Humanoid, Attack> PreviousAttack = AccessTools.FieldRefAccess<Humanoid, Attack>("m_previousAttack");

	private static readonly FieldRef<Player, float> QueuedAttack = AccessTools.FieldRefAccess<Player, float>("m_queuedAttackTimer");

	private static readonly FieldRef<Player, float> QueuedSecondAttack = AccessTools.FieldRefAccess<Player, float>("m_queuedSecondAttackTimer");

	private static readonly FieldRef<Attack, float> AttackTime = AccessTools.FieldRefAccess<Attack, float>("m_time");

	private static readonly ConditionalWeakTable<Attack, object> Landed = new ConditionalWeakTable<Attack, object>();

	private static readonly ConditionalWeakTable<Attack, object> Cancelled = new ConditionalWeakTable<Attack, object>();

	private static readonly object Marker = new object();

	internal static float AttackAllowedAt;

	private static bool holdIgnored;

	internal static bool IsCancelled(Attack attack)
	{
		object value;
		if (attack != null)
		{
			return Cancelled.TryGetValue(attack, out value);
		}
		return false;
	}

	internal static void MarkCancelled(Attack attack)
	{
		if (attack != null && !Cancelled.TryGetValue(attack, out var _))
		{
			Cancelled.Add(attack, Marker);
		}
	}

	private static bool CanCancel(Player player)
	{
		if (CurrentAttack.Invoke((Humanoid)(object)player) != null && ((Character)player).InAttack() && !((Character)player).IsDead() && !((Character)player).InDodge() && !((Character)player).InPlaceMode() && !((Character)player).IsEncumbered() && !((Character)player).InMinorAction())
		{
			return !((Character)player).IsStaggering();
		}
		return false;
	}

	private static void Cancel(Player player)
	{
		Attack val = CurrentAttack.Invoke((Humanoid)(object)player);
		val.Stop();
		MarkCancelled(val);
		QueuedBowRelease.Forget(val);
		PreviousAttack.Invoke((Humanoid)(object)player) = null;
		CurrentAttack.Invoke((Humanoid)(object)player) = null;
		QueuedAttack.Invoke(player) = 0f;
		QueuedSecondAttack.Invoke(player) = 0f;
		AttackAllowedAt = Time.time + (Landed.TryGetValue(val, out var _) ? Remaining(CharacterAnimator.Invoke((Character)(object)player), AttackTime.Invoke(val)) : 0.2f);
		((Component)player).GetComponent<ZNetView>().InvokeRPC(ZNetView.Everybody, "PotatoFighter_AttackCancel", new object[1] { val.m_attackAnimation ?? "" });
	}

	private static float Remaining(Animator animator, float elapsed)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		float num = 0.2f;
		if (!Object.op_Implicit((Object)(object)animator))
		{
			return num;
		}
		for (int i = 0; i < animator.layerCount; i++)
		{
			AnimatorStateInfo val = State(animator, i);
			float num2 = Mathf.Clamp01(((AnimatorStateInfo)(ref val)).normalizedTime);
			if (((AnimatorStateInfo)(ref val)).tagHash == AttackTag && num2 > 0f)
			{
				num = Mathf.Max(num, (1f - num2) * elapsed / num2);
			}
		}
		return num;
	}

	private static AnimatorStateInfo State(Animator animator, int layer)
	{
		//IL_0013: 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)
		if (!animator.IsInTransition(layer))
		{
			return animator.GetCurrentAnimatorStateInfo(layer);
		}
		return animator.GetNextAnimatorStateInfo(layer);
	}

	private static void Interrupt(Player player, string animation)
	{
		Animator val = CharacterAnimator.Invoke((Character)(object)player);
		if (!Object.op_Implicit((Object)(object)val))
		{
			return;
		}
		if (!string.IsNullOrEmpty(animation))
		{
			foreach (AnimatorControllerParameter item in val.parameters.Where((AnimatorControllerParameter parameter) => (int)parameter.type == 9 && parameter.name.StartsWith(animation)))
			{
				val.ResetTrigger(item.nameHash);
			}
		}
		Blend(val, 0, Movement);
		int layerIndex = val.GetLayerIndex("upperbody");
		if (layerIndex > 0)
		{
			Blend(val, layerIndex, UpperBodyIdle);
		}
	}

	private static void Blend(Animator animator, int layer, int state)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		AnimatorStateInfo val = State(animator, layer);
		if (((AnimatorStateInfo)(ref val)).tagHash == AttackTag && animator.HasState(layer, state))
		{
			animator.CrossFadeInFixedTime(state, 0.1f, layer);
		}
	}
}
internal static class Bows
{
	internal static readonly FieldRef<Character, bool> AttackHold = AccessTools.FieldRefAccess<Character, bool>("m_attackHold");

	internal static readonly FieldRef<Character, bool> Blocking = AccessTools.FieldRefAccess<Character, bool>("m_blocking");

	internal static readonly FieldRef<Humanoid, Attack> CurrentAttack = AccessTools.FieldRefAccess<Humanoid, Attack>("m_currentAttack");
}
[HarmonyPatch(typeof(Player), "UpdateAttackBowDraw")]
internal static class BowRelease
{
	private struct DrawState
	{
		internal bool AttackHeld;

		internal bool QueuedRelease;

		internal Attack PreviousAttack;
	}

	private const float MaxWait = 1f;

	private static readonly FieldRef<Humanoid, float> DrawTime = AccessTools.FieldRefAccess<Humanoid, float>("m_attackDrawTime");

	private static float releaseBy = -1f;

	private static void Prefix(Player __instance, out DrawState __state)
	{
		__state = new DrawState
		{
			AttackHeld = Bows.AttackHold.Invoke((Character)(object)__instance)
		};
		if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
		{
			return;
		}
		if (!Plugin.KeepFastShots.Value)
		{
			releaseBy = -1f;
			return;
		}
		if (DrawTime.Invoke((Humanoid)(object)__instance) <= 0f)
		{
			releaseBy = -1f;
			return;
		}
		bool flag = releaseBy >= 0f;
		if (!flag && __state.AttackHeld)
		{
			return;
		}
		if ((((Character)__instance).InAttack() || Time.time < AttackCancel.AttackAllowedAt) && (!flag || Time.time < releaseBy))
		{
			if (!flag)
			{
				releaseBy = Time.time + 1f;
			}
			Bows.AttackHold.Invoke((Character)(object)__instance) = true;
		}
		else
		{
			releaseBy = -1f;
			Bows.AttackHold.Invoke((Character)(object)__instance) = false;
			__state.QueuedRelease = flag;
			__state.PreviousAttack = Bows.CurrentAttack.Invoke((Humanoid)(object)__instance);
		}
	}

	private static void Postfix(Player __instance, DrawState __state)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Invalid comparison between Unknown and I4
		Bows.AttackHold.Invoke((Character)(object)__instance) = __state.AttackHeld;
		if (!__state.QueuedRelease)
		{
			return;
		}
		Attack val = Bows.CurrentAttack.Invoke((Humanoid)(object)__instance);
		if (val != null && val != __state.PreviousAttack)
		{
			ItemData weapon = val.GetWeapon();
			if (weapon != null && (int)weapon.m_shared.m_skillType == 8)
			{
				QueuedBowRelease.Track(__instance, val);
			}
		}
	}
}
[HarmonyPatch]
internal static class QueuedBowRelease
{
	private static Player queuedPlayer;

	private static Attack queuedAttack;

	internal static void Track(Player player, Attack attack)
	{
		queuedPlayer = player;
		queuedAttack = attack;
	}

	internal static void Forget(Attack attack)
	{
		if (attack == queuedAttack)
		{
			Clear();
		}
	}

	private static void Clear()
	{
		queuedPlayer = null;
		queuedAttack = null;
	}

	private static void Check()
	{
		if (queuedAttack != null && (!Object.op_Implicit((Object)(object)queuedPlayer) || !((Object)(object)queuedPlayer == (Object)(object)Player.m_localPlayer) || ((Character)queuedPlayer).IsDead() || Bows.CurrentAttack.Invoke((Humanoid)(object)queuedPlayer) != queuedAttack || ((Humanoid)queuedPlayer).GetCurrentWeapon() != queuedAttack.GetWeapon() || Bows.Blocking.Invoke((Character)(object)queuedPlayer)))
		{
			CancelPending();
		}
	}

	private static void CancelPending()
	{
		if (queuedAttack != null)
		{
			AttackCancel.MarkCancelled(queuedAttack);
			queuedAttack.Abort();
			queuedAttack.Stop();
			Clear();
		}
	}

	internal static void BeforeTrigger(Attack attack)
	{
		Check();
		if (attack == queuedAttack)
		{
			Clear();
		}
	}

	[HarmonyPatch(typeof(ZNet), "Shutdown")]
	[HarmonyPrefix]
	private static void Leaving()
	{
		CancelPending();
	}

	[HarmonyPatch(typeof(Player), "SetControls")]
	[HarmonyPostfix]
	private static void ControlsUpdated(Player __instance)
	{
		if ((Object)(object)__instance == (Object)(object)queuedPlayer || (Object)(object)queuedPlayer != (Object)(object)Player.m_localPlayer)
		{
			Check();
		}
	}
}
[HarmonyPatch]
internal static class TripleShotCancel
{
	private static MethodBase target;

	private static bool Prepare()
	{
		Type type = AccessTools.TypeByName("EpicLoot.MagicItemEffects.MultiShot");
		target = ((type == null) ? null : AccessTools.Method(type, "Attack_OnAttackTrigger_Prefix", (Type[])null, (Type[])null));
		return target != null;
	}

	private static MethodBase TargetMethod()
	{
		return target;
	}

	[HarmonyPriority(800)]
	private static bool Prefix(Attack __0)
	{
		return !AttackCancel.IsCancelled(__0);
	}
}
internal static class CreatureHud
{
	[HarmonyPatch(typeof(EnemyHud), "UpdateHuds")]
	internal static class Stars
	{
		private static bool Prepare()
		{
			if (Level2 != null && Level3 != null)
			{
				return Name != null;
			}
			return false;
		}

		private static void Postfix(EnemyHud __instance)
		{
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			if (!Creatures.On)
			{
				return;
			}
			IDictionary dictionary = Huds.Invoke(__instance);
			if (dictionary == null)
			{
				return;
			}
			if (shown.Count > 4 * dictionary.Count + 64)
			{
				shown.Clear();
			}
			foreach (DictionaryEntry item in dictionary)
			{
				object key = item.Key;
				Character val = (Character)((key is Character) ? key : null);
				object value = item.Value;
				RectTransform val2 = (RectTransform)((value == null) ? null : /*isinst with value type is only supported in some contexts*/);
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
				{
					continue;
				}
				int num = val.GetLevel() - 1;
				Creatures.Modifier modifier = Creatures.Get(val);
				if (num >= 2)
				{
					object? value2 = Level2.GetValue(value);
					object? obj = ((value2 is RectTransform) ? value2 : null);
					if (obj != null)
					{
						((Component)obj).gameObject.SetActive(false);
					}
					((Component)val2).gameObject.SetActive(true);
				}
				if (!shown.TryGetValue(value, out var value3) || value3 != num)
				{
					shown[value] = num;
					ShowExtraStars(val2, Mathf.Max(num, 2));
				}
				if (modifier != Creatures.Modifier.None)
				{
					object? value4 = Name.GetValue(value);
					TMP_Text val3 = (TMP_Text)((value4 is TMP_Text) ? value4 : null);
					if (val3 != null && !val3.text.StartsWith("<color="))
					{
						val3.text = "<color=#" + ColorUtility.ToHtmlStringRGB(ModifierColors[(int)modifier]) + ">" + Creatures.Names[(int)modifier] + " " + val3.text + "</color>";
					}
				}
			}
		}
	}

	[HarmonyPatch(typeof(LevelEffects), "SetupLevelVisualization")]
	internal static class Look
	{
		private static void Prefix(LevelEffects __instance, ref int level, out int __state)
		{
			__state = level;
			if (Creatures.On && __instance.m_levelSetups != null)
			{
				int num = __instance.m_levelSetups.Count + 1;
				if (level > num)
				{
					level = num;
				}
			}
		}

		private static void Postfix(LevelEffects __instance, int level, int __state)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (Creatures.On && __state > level && level >= 2 && !(((Component)__instance).transform.position.y > 4500f))
			{
				Transform transform = ((Component)__instance).transform;
				transform.localScale *= 1f + 0.05f * (float)(__state - level);
			}
		}
	}

	private const float GrowthPerStar = 0.05f;

	private const float DungeonHeight = 4500f;

	private static readonly FieldRef<EnemyHud, IDictionary> Huds = AccessTools.FieldRefAccess<EnemyHud, IDictionary>("m_huds");

	private static readonly Type HudType = AccessTools.Inner(typeof(EnemyHud), "HudData");

	private static readonly FieldInfo Level2 = AccessTools.Field(HudType, "m_level2");

	private static readonly FieldInfo Level3 = AccessTools.Field(HudType, "m_level3");

	private static readonly FieldInfo Name = AccessTools.Field(HudType, "m_name");

	private static bool logged;

	private static readonly Dictionary<object, int> shown = new Dictionary<object, int>();

	private static readonly Color[] ModifierColors = (Color[])(object)new Color[6]
	{
		Color.white,
		new Color(0.35f, 0.6f, 1f),
		new Color(1f, 0.35f, 1f),
		new Color(1f, 0.3f, 0.25f),
		new Color(0.35f, 1f, 0.35f),
		new Color(0.4f, 0.95f, 1f)
	};

	private static void ShowExtraStars(RectTransform group, int stars)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: 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_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		int num = 0;
		RectTransform val = null;
		RectTransform val2 = null;
		foreach (RectTransform item in (Transform)group)
		{
			RectTransform val3 = item;
			if (!((Object)val3).name.StartsWith("PotatoStar"))
			{
				num++;
				val2 = val;
				val = val3;
			}
		}
		if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
		{
			return;
		}
		Vector2 val4 = val.anchoredPosition - val2.anchoredPosition;
		for (int i = num; i < Mathf.Max(stars, num) || Object.op_Implicit((Object)(object)((Transform)group).Find("PotatoStar" + i)); i++)
		{
			Transform obj = ((Transform)group).Find("PotatoStar" + i);
			RectTransform val5 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			if (!Object.op_Implicit((Object)(object)val5) && i < stars)
			{
				val5 = Object.Instantiate<RectTransform>(val, (Transform)(object)group);
				((Object)val5).name = "PotatoStar" + i;
				val5.anchoredPosition = val.anchoredPosition + val4 * (float)(i - num + 1);
			}
			if (Object.op_Implicit((Object)(object)val5))
			{
				((Component)val5).gameObject.SetActive(i < stars);
			}
		}
	}
}
internal static class Creatures
{
	internal enum Modifier
	{
		None,
		Armored,
		Quick,
		Fierce,
		Regenerating,
		Splitting
	}

	[HarmonyPatch(typeof(Character), "Awake")]
	internal static class Loaded
	{
		private static void Postfix(Character __instance)
		{
			if (!__instance.IsPlayer() && Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<BaseAI>()))
			{
				waiting.Add(new KeyValuePair<Character, float>(__instance, Time.time + 10f));
			}
		}
	}

	[HarmonyPatch(typeof(Character), "RPC_Damage")]
	internal static class Damage
	{
		private static void Prefix(Character __instance, HitData hit)
		{
			if (On && hit != null)
			{
				if (Get(__instance) == Modifier.Armored)
				{
					hit.ApplyModifier(0.5f);
				}
				Character attacker = hit.GetAttacker();
				if (Object.op_Implicit((Object)(object)attacker) && Get(attacker) == Modifier.Fierce)
				{
					hit.ApplyModifier(1.3f);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Character), "OnDeath")]
	internal static class Split
	{
		private static void Prefix(Character __instance)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00a9: 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_00b7: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			if (!On || Get(__instance) != Modifier.Splitting || __instance.GetLevel() < 2 || !View.Invoke(__instance).IsOwner())
			{
				return;
			}
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.GetPrefab(Utils.GetPrefabName(((Component)__instance).gameObject)) : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			int level = 1 + (__instance.GetLevel() - 1) / 2;
			bool flag = __instance.IsTamed();
			for (int i = 0; i < 2; i++)
			{
				Vector3 val2 = Quaternion.Euler(0f, (float)i * 180f + Random.Range(-40f, 40f), 0f) * Vector3.forward * 0.8f;
				Character component = Object.Instantiate<GameObject>(val, ((Component)__instance).transform.position + val2 + Vector3.up * 0.3f, ((Component)__instance).transform.rotation).GetComponent<Character>();
				if (Object.op_Implicit((Object)(object)component))
				{
					ZDO obj = Zdo(component);
					if (obj != null)
					{
						obj.Set(RolledKey, true);
					}
					if (flag)
					{
						component.SetTamed(true);
					}
					component.SetLevel(level);
					Assign(component, Modifier.Splitting);
				}
			}
		}
	}

	[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
	internal static class Loot
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Mathf), "Pow", (Type[])null, (Type[])null);
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = 0;
			foreach (CodeInstruction item in list)
			{
				if (CodeInstructionExtensions.Calls(item, methodInfo))
				{
					item.operand = AccessTools.Method(typeof(Loot), "Factor", (Type[])null, (Type[])null);
					num++;
				}
			}
			if (num != 1)
			{
				throw new InvalidOperationException($"expected one Mathf.Pow in CharacterDrop.GenerateDropList, found {num}");
			}
			return list;
		}

		private static float Factor(float two, float stars)
		{
			if (!On)
			{
				return Mathf.Pow(two, stars);
			}
			float num = 1f + 0.5f * stars;
			float num2 = Mathf.Floor(num);
			return num2 + ((Random.value < num - num2) ? 1f : 0f);
		}
	}

	[HarmonyPatch(typeof(Procreation), "Procreate")]
	internal static class Birth
	{
		private static readonly FieldRef<Procreation, Character> Parent = AccessTools.FieldRefAccess<Procreation, Character>("m_character");

		private static void Prefix(Procreation __instance)
		{
			carryFrom = Parent.Invoke(__instance);
			carryAlways = false;
		}

		private static void Finalizer()
		{
			carryFrom = null;
		}
	}

	[HarmonyPatch(typeof(Growup), "GrowUpdate")]
	internal static class GrowUp
	{
		private static void Prefix(Growup __instance)
		{
			carryFrom = ((Component)__instance).GetComponent<Character>();
			carryAlways = true;
		}

		private static void Finalizer()
		{
			carryFrom = null;
		}
	}

	[HarmonyPatch(typeof(Character), "SetLevel")]
	internal static class Carry
	{
		private static void Postfix(Character __instance)
		{
			if (!On || (Object)(object)Creatures.carryFrom == (Object)null || (Object)(object)__instance == (Object)(object)Creatures.carryFrom)
			{
				return;
			}
			Character carryFrom = Creatures.carryFrom;
			Creatures.carryFrom = null;
			ZDO obj = Zdo(__instance);
			if (obj != null)
			{
				obj.Set(RolledKey, true);
			}
			Modifier modifier = Get(carryFrom);
			switch (modifier)
			{
			case Modifier.Armored:
				if (__instance.m_health >= 800f)
				{
					break;
				}
				goto default;
			default:
				if (carryAlways || Random.value * 100f < (float)Plugin.OffspringModifierChance.Value)
				{
					Assign(__instance, modifier);
				}
				break;
			case Modifier.None:
				break;
			}
		}
	}

	internal class Ticker : MonoBehaviour
	{
		private float nextSecond;

		private void Update()
		{
			if (!On)
			{
				return;
			}
			if (waiting.Count > 0)
			{
				CheckWaiting();
			}
			if (Time.time < nextSecond)
			{
				return;
			}
			nextSecond = Time.time + 1f;
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (!Object.op_Implicit((Object)(object)allCharacter) || allCharacter.IsPlayer())
				{
					continue;
				}
				Modifier modifier = Get(allCharacter);
				if (modifier != Modifier.None)
				{
					Apply(allCharacter);
					if (modifier == Modifier.Regenerating && !allCharacter.IsDead() && View.Invoke(allCharacter).IsOwner() && allCharacter.GetHealth() < allCharacter.GetMaxHealth())
					{
						allCharacter.Heal(Mathf.Max(1f, allCharacter.GetMaxHealth() * 0.01f), false);
					}
				}
			}
		}
	}

	internal const string SlsId = "MidnightsFX.StarLevelSystem";

	internal const string CllcId = "org.bepinex.plugins.creaturelevelcontrol";

	internal const bool Diagnostics = false;

	internal static readonly int ModKey = StringExtensionMethods.GetStableHashCode("PotatoFighter_Modifier");

	private static readonly int RolledKey = StringExtensionMethods.GetStableHashCode("PotatoFighter_Rolled");

	private static readonly int BountyKey = StringExtensionMethods.GetStableHashCode("BountyID");

	private const float FreshSeconds = 15f;

	private const float OwnerWait = 10f;

	internal static readonly string[] Names = new string[6] { "", "Armored", "Quick", "Fierce", "Regenerating", "Splitting" };

	private const float ArmoredMaxBaseHealth = 800f;

	private static readonly FieldRef<Character, ZNetView> View = AccessTools.FieldRefAccess<Character, ZNetView>("m_nview");

	private static readonly List<KeyValuePair<Character, float>> waiting = new List<KeyValuePair<Character, float>>();

	private static readonly string[] BiomeBoss = new string[8] { "defeated_eikthyr", "defeated_gdking", "defeated_bonemass", "defeated_dragon", "defeated_goblinking", "defeated_queen", "defeated_fader", "" };

	private static readonly float[] FirstStar = new float[8] { 0.15f, 0.27f, 0.38f, 0.48f, 0.6f, 0.68f, 0.68f, 0.68f };

	private static readonly float[] NextStar = new float[8] { 0.3f, 0.38f, 0.45f, 0.53f, 0.6f, 0.68f, 0.68f, 0.68f };

	private static readonly int[] BiomeMaxStars = new int[8] { 2, 3, 4, 5, 5, 5, 5, 5 };

	private const float BossBump = 0.06f;

	private static readonly HashSet<string> NoStarsInVanilla = new HashSet<string> { "Lox", "Deathsquito", "Serpent", "Hatchling", "Wraith" };

	private static readonly HashSet<int> applied = new HashSet<int>();

	private static Character carryFrom;

	private static bool carryAlways;

	internal static bool StandAside
	{
		get
		{
			if (!Chainloader.PluginInfos.ContainsKey("MidnightsFX.StarLevelSystem"))
			{
				return Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.creaturelevelcontrol");
			}
			return true;
		}
	}

	internal static bool On
	{
		get
		{
			if (Plugin.CreatureLevels.Value)
			{
				return !StandAside;
			}
			return false;
		}
	}

	internal static int MaxLevel => 1 + Plugin.CreatureMaxStars.Value;

	internal static ZDO Zdo(Character c)
	{
		if (!Object.op_Implicit((Object)(object)c))
		{
			return null;
		}
		ZNetView obj = View.Invoke(c);
		if (obj == null)
		{
			return null;
		}
		return obj.GetZDO();
	}

	internal static Modifier Get(Character c)
	{
		ZDO obj = Zdo(c);
		if (obj == null)
		{
			return Modifier.None;
		}
		return (Modifier)obj.GetInt(ModKey, 0);
	}

	private static void CheckWaiting()
	{
		int num = waiting.Count - 1;
		int num2 = 0;
		while (num >= 0 && num2 < 20)
		{
			Character key = waiting[num].Key;
			ZNetView val = (Object.op_Implicit((Object)(object)key) ? View.Invoke(key) : null);
			if ((Object)(object)val == (Object)null || !val.IsValid() || !On)
			{
				waiting.RemoveAt(num);
			}
			else if (!val.IsOwner())
			{
				if (Time.time > waiting[num].Value)
				{
					waiting.RemoveAt(num);
				}
			}
			else
			{
				waiting.RemoveAt(num);
				num2++;
				Check(key, val.GetZDO());
			}
			num--;
		}
	}

	private static void Check(Character c, ZDO zdo)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		if (zdo.GetBool(RolledKey, false) || c.IsTamed() || c.IsBoss() || (int)c.m_faction == 0 || zdo.GetString(BountyKey, "").Length > 0)
		{
			return;
		}
		BaseAI component = ((Component)c).GetComponent<BaseAI>();
		int level = c.GetLevel();
		bool flag = Object.op_Implicit((Object)(object)component) && component.GetTimeSinceSpawned().TotalSeconds < 15.0;
		if (flag || level > MaxLevel)
		{
			int num = 1 + RollStars(c);
			int num2 = (flag ? Mathf.Min(Mathf.Max(level, num), MaxLevel) : num);
			if (num2 != level)
			{
				c.SetLevel(num2);
			}
			zdo.Set(RolledKey, true);
			if (flag && num2 > 1 && zdo.GetInt(ModKey, 0) == 0)
			{
				Assign(c, RollModifier(c, num2 - 1));
			}
		}
	}

	private static string Stars(int level)
	{
		if (level - 1 != 1)
		{
			return $"{level - 1} stars";
		}
		return "1 star";
	}

	private static int Tier(Biome biome)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Invalid comparison between Unknown and I4
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Invalid comparison between Unknown and I4
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Invalid comparison between Unknown and I4
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Invalid comparison between Unknown and I4
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Invalid comparison between Unknown and I4
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Invalid comparison between Unknown and I4
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Invalid comparison between Unknown and I4
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		if ((int)biome <= 8)
		{
			if ((int)biome == 1)
			{
				return 0;
			}
			if ((int)biome == 4)
			{
				return 3;
			}
			if ((int)biome == 8)
			{
				return 1;
			}
		}
		else if ((int)biome <= 32)
		{
			if ((int)biome == 16)
			{
				return 4;
			}
			if ((int)biome == 32)
			{
				return 6;
			}
		}
		else
		{
			if ((int)biome == 64)
			{
				return 7;
			}
			if ((int)biome == 512)
			{
				return 5;
			}
		}
		return 2;
	}

	private static bool Beaten(string key)
	{
		if (key.Length > 0)
		{
			if (!Object.op_Implicit((Object)(object)ZoneSystem.instance) || !ZoneSystem.instance.GetGlobalKey(key))
			{
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					return ((Humanoid)Player.m_localPlayer).HaveUniqueKey(key);
				}
				return false;
			}
			return true;
		}
		return false;
	}

	internal static void Chances(Character c, out float first, out float next, out int most)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		int num = Tier(Heightmap.FindBiome(((Component)c).transform.position));
		bool flag = Beaten(BiomeBoss[num]);
		if (!CanHaveStars(c))
		{
			num -= 2;
		}
		if (num < 0)
		{
			first = (next = 0f);
			most = 0;
		}
		else
		{
			next = NextStar[num];
			first = Mathf.Min(0.95f, (FirstStar[num] + (flag ? 0.06f : 0f)) * (float)Plugin.CreatureStarChance.Value / 100f);
			most = Mathf.Min(BiomeMaxStars[num], Plugin.CreatureMaxStars.Value);
		}
	}

	private static int RollStars(Character c)
	{
		Chances(c, out var first, out var next, out var most);
		int i;
		for (i = 0; i < most && Random.value < ((i == 0) ? first : next); i++)
		{
		}
		return i;
	}

	private static bool CanHaveStars(Character c)
	{
		return !NoStarsInVanilla.Contains(Utils.GetPrefabName(((Component)c).gameObject));
	}

	private static Modifier RollModifier(Character c, int stars)
	{
		if (Random.value >= Mathf.Min(0.95f, (0.35f + 0.1f * (float)(stars - 1)) * (float)Plugin.CreatureModifierChance.Value / 100f))
		{
			return Modifier.None;
		}
		List<Modifier> list = new List<Modifier>
		{
			Modifier.Quick,
			Modifier.Fierce,
			Modifier.Regenerating,
			Modifier.Splitting
		};
		if (c.m_health < 800f)
		{
			list.Add(Modifier.Armored);
		}
		return list[Random.Range(0, list.Count)];
	}

	internal static void Assign(Character c, Modifier modifier)
	{
		ZDO val = Zdo(c);
		if (val != null && modifier != Modifier.None)
		{
			val.Set(ModKey, (int)modifier, false);
			Apply(c);
		}
	}

	private static void Apply(Character c)
	{
		Modifier modifier = Get(c);
		if (modifier != Modifier.None && applied.Add(((Object)c).GetInstanceID()))
		{
			float num = modifier switch
			{
				Modifier.Armored => 0.75f, 
				Modifier.Quick => 1.35f, 
				_ => 1f, 
			};
			if (num != 1f)
			{
				c.m_speed *= num;
				c.m_walkSpeed *= num;
				c.m_runSpeed *= num;
				c.m_crouchSpeed *= num;
				c.m_swimSpeed *= num;
				c.m_flySlowSpeed *= num;
				c.m_flyFastSpeed *= num;
			}
		}
	}
}
internal static class CrossbowLoad
{
	[HarmonyPatch(typeof(Humanoid), "UnequipItem")]
	internal static class PutAway
	{
		private static void Prefix(Humanoid __instance, ItemData item)
		{
			try
			{
				if (Plugin.CrossbowsStayLoaded.Value)
				{
					Player val = (Player)(object)((__instance is Player) ? __instance : null);
					if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && Reloads(item) && item.m_customData != null && Loaded.Invoke(val) == item)
					{
						item.m_customData["PotatoFighter_Loaded"] = "1";
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Crossbows stay loaded: " + ex.Message));
			}
		}
	}

	[HarmonyPatch(typeof(Humanoid), "EquipItem")]
	internal static class TakeOut
	{
		private static void Postfix(Humanoid __instance, ItemData item, bool __result)
		{
			try
			{
				if (__result)
				{
					Player val = (Player)(object)((__instance is Player) ? __instance : null);
					if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && item?.m_customData != null && item.m_customData.Remove("PotatoFighter_Loaded") && Plugin.CrossbowsStayLoaded.Value && Reloads(item) && !(SetLoaded == null))
					{
						SetLoaded.Invoke(val, new object[1] { item });
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Crossbows stay loaded: " + ex.Message));
			}
		}
	}

	private const string Key = "PotatoFighter_Loaded";

	internal const bool Diagnostics = false;

	private static readonly FieldRef<Player, ItemData> Loaded = AccessTools.FieldRefAccess<Player, ItemData>("m_weaponLoaded");

	private static readonly MethodInfo SetLoaded = AccessTools.Method(typeof(Player), "SetWeaponLoaded", (Type[])null, (Type[])null);

	private static bool Reloads(ItemData item)
	{
		if (item?.m_shared?.m_attack != null)
		{
			return item.m_shared.m_attack.m_requiresReload;
		}
		return false;
	}
}
internal static class EpicLootThrowable
{
	[HarmonyPatch]
	internal static class NoThrowableRoll
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(AccessTools.TypeByName("EpicLoot.MagicItemEffectDefinitions"), "Initialize", (Type[])null, (Type[])null);
		}

		private static bool Prepare()
		{
			if (EpicLoot)
			{
				return TargetMethod() != null;
			}
			return false;
		}

		private static void Postfix()
		{
			Exclude();
		}

		internal static void Exclude()
		{
			if (!EpicLoot || !(AccessTools.Field(AccessTools.TypeByName("EpicLoot.MagicItemEffectDefinitions"), "AllDefinitions")?.GetValue(null) is IDictionary dictionary) || !dictionary.Contains("Throwable"))
			{
				return;
			}
			object obj = dictionary["Throwable"];
			object obj2 = AccessTools.Field(obj.GetType(), "Requirements")?.GetValue(obj);
			if (obj2 == null)
			{
				return;
			}
			FieldInfo fieldInfo = AccessTools.Field(obj2.GetType(), "ExcludedItemNames");
			IList list = fieldInfo?.GetValue(obj2) as IList;
			if (list == null)
			{
				list = (IList)Activator.CreateInstance(fieldInfo?.FieldType ?? typeof(List<string>));
				fieldInfo?.SetValue(obj2, list);
			}
			int num = 0;
			foreach (string throwingWeapon in ThrowingWeapons)
			{
				if (!list.Contains(throwingWeapon))
				{
					list.Add(throwingWeapon);
					num++;
				}
			}
			if (num > 0)
			{
				Plugin.Log.LogInfo((object)$"{num} PotatoFighter throwing weapon(s) kept out of Epic Loot's Throwable enchantment.");
			}
		}
	}

	internal static readonly HashSet<string> ThrowingWeapons = new HashSet<string>();

	private static bool EpicLoot => Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot");
}
internal static class FastSwap
{
	[HarmonyPatch(typeof(Player), "InMinorActionSlowdown")]
	internal static class NoSlowdown
	{
		private static void Postfix(Player __instance, ref bool __result)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (swapActive)
			{
				if (__result)
				{
					sawSlowdown = true;
					slowFrames++;
					lastSlowdown = Time.time;
				}
				else if (sawSlowdown ? (Time.time - lastSlowdown > 0.25f) : (Time.time - swapStarted > 0.5f))
				{
					swapActive = false;
					swapEnded = Time.time;
				}
			}
			if (__result && On((Character)(object)__instance) && Swapping(__instance))
			{
				__result = false;
				liftedFrames++;
			}
			else
			{
				_ = __result;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "CheckRun")]
	internal static class KeepOnRun
	{
		private static readonly MethodInfo ClearMethod = AccessTools.Method(typeof(Humanoid), "ClearActionQueue", (Type[])null, (Type[])null);

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Humanoid), "ClearActionQueue", (Type[])null, (Type[])null);
			List<CodeInstruction> list = instructions.ToList();
			int num = 0;
			foreach (CodeInstruction item in list)
			{
				if (CodeInstructionExtensions.Calls(item, methodInfo))
				{
					item.opcode = OpCodes.Call;
					item.operand = AccessTools.Method(typeof(KeepOnRun), "ClearForRun", (Type[])null, (Type[])null);
					num++;
				}
			}
			if (num != 1)
			{
				throw new InvalidOperationException($"expected one action-queue clear in Player.CheckRun, found {num}");
			}
			return list;
		}

		private static void ClearForRun(Humanoid humanoid)
		{
			Player val = (Player)(object)((humanoid is Player) ? humanoid : null);
			if ((Object)(object)val == (Object)null || !On((Character)(object)val) || !Plugin.FastSwapSprint.Value)
			{
				Clear(humanoid);
				return;
			}
			List<MinorActionData> list = Queue.Invoke(val);
			if (list != null && !list.All(HandAction))
			{
				Clear(humanoid);
			}
		}

		private static void Clear(Humanoid humanoid)
		{
			ClearMethod.Invoke(humanoid, null);
		}
	}

	[HarmonyPatch]
	internal static class SprintCost
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(Player), "QueueEquipAction", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(Player), "QueueUnequipAction", (Type[])null, (Type[])null);
		}

		private static void Postfix(Player __instance, ItemData item)
		{
			if (!On((Character)(object)__instance) || !HandItem(item))
			{
				return;
			}
			StartSwap();
			if (!Plugin.FastSwapSprint.Value || !((Character)__instance).IsRunning())
			{
				return;
			}
			List<MinorActionData> list = Queue.Invoke(__instance);
			if (list != null && list.Count != 0)
			{
				MinorActionData val = list[list.Count - 1];
				if (val.m_item == item && !PaySprint(__instance))
				{
					list.Remove(val);
				}
			}
		}
	}

	[HarmonyPatch]
	internal static class Sheath
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(Humanoid), "HideHandItems", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(Humanoid), "ShowHandItems", (Type[])null, (Type[])null);
		}

		private static void Postfix(Humanoid __instance)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (On((Character)(object)val))
			{
				StartSwap();
				if (((Character)val).IsRunning() && Plugin.FastSwapSprint.Value)
				{
					PaySprint(val);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Humanoid), "StartAttack")]
	internal static class AttackInterrupts
	{
		private static void Prefix(Humanoid __instance)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null)
			{
				Interrupt(val);
			}
		}

		private static void Postfix(bool __result)
		{
			if (__result)
			{
				interruptUntil = -1f;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "UpdateAttackBowDraw")]
	internal static class BowInterrupts
	{
		private static void Prefix(Player __instance)
		{
			if (On((Character)(object)__instance) && Plugin.FastSwapAttack.Value && Bows.AttackHold.Invoke((Character)(object)__instance) && Swapping(__instance))
			{
				Interrupt(__instance);
			}
		}
	}

	[HarmonyPatch(typeof(Player), "InMinorAction")]
	internal static class NotInAction
	{
		private static bool Prefix(Player __instance, ref bool __result)
		{
			if (Time.time >= interruptUntil || !On((Character)(object)__instance))
			{
				return true;
			}
			__result = false;
			return false;
		}
	}

	internal const string OtherModId = "com.skarif.fastswap";

	private const float SwapCap = 2.5f;

	private const float InterruptSeconds = 1f;

	private static readonly FieldRef<Player, List<MinorActionData>> Queue = AccessTools.FieldRefAccess<Player, List<MinorActionData>>("m_actionQueue");

	private static readonly FieldRef<Player, string> ActionAnimation = AccessTools.FieldRefAccess<Player, string>("m_actionAnimation");

	private static readonly FieldRef<Character, ZSyncAnimation> Zanim = AccessTools.FieldRefAccess<Character, ZSyncAnimation>("m_zanim");

	private static bool swapActive;

	private static bool sawSlowdown;

	private static float swapStarted = -1f;

	private static float lastSlowdown = -1f;

	private static float interruptUntil = -1f;

	private const float SettledSeconds = 0.25f;

	internal const bool Diagnostics = false;

	private static int slowFrames;

	private static int liftedFrames;

	private static float swapEnded = -1f;

	private static float outsideStarted = -1f;

	private static int outsideFrames;

	private static string outsideClips;

	private static void OutsideSlowdown(Player player)
	{
		if (outsideFrames++ <= 0)
		{
			outsideStarted = Time.time;
			outsideClips = Clips(player);
		}
	}

	private static void EndOutsideSlowdown()
	{
		if (outsideFrames != 0)
		{
			string text = ((swapEnded < 0f) ? "no switch yet" : $"{outsideStarted - swapEnded:0.00} s after the last switch ended");
			Plugin.Log.LogInfo((object)$"[Swap] slowed outside a switch for {Time.time - outsideStarted:0.00} s ({outsideFrames} frames), {text}; layer 1: {outsideClips}");
			outsideFrames = 0;
		}
	}

	private static string Clips(Player player)
	{
		Animator componentInChildren = ((Component)player).GetComponentInChildren<Animator>();
		if (!Object.op_Implicit((Object)(object)componentInChildren))
		{
			return "no animator";
		}
		string text = Names(componentInChildren.GetCurrentAnimatorClipInfo(1));
		if (!componentInChildren.IsInTransition(1))
		{
			return text;
		}
		return text + " -> " + Names(componentInChildren.GetNextAnimatorClipInfo(1));
		static string Names(AnimatorClipInfo[] infos)
		{
			if (infos != null && infos.Length != 0)
			{
				return string.Join("+", Array.ConvertAll(infos, (AnimatorClipInfo i) => (!Object.op_Implicit((Object)(object)((AnimatorClipInfo)(ref i)).clip)) ? "?" : ((Object)((AnimatorClipInfo)(ref i)).clip).name));
			}
			return "-";
		}
	}

	private static void StartSwap()
	{
		slowFrames = (liftedFrames = 0);
		swapActive = true;
		sawSlowdown = false;
		swapStarted = Time.time;
	}

	private static bool On(Character character)
	{
		if (Plugin.FastSwapEnabled.Value && Object.op_Implicit((Object)(object)character) && (Object)(object)character == (Object)(object)Player.m_localPlayer)
		{
			return !Chainloader.PluginInfos.ContainsKey("com.skarif.fastswap");
		}
		return false;
	}

	internal static bool HandItem(ItemData item)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Invalid comparison between Unknown and I4
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Invalid comparison between Unknown and I4
		//IL_0021: 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_0025: Invalid comparison between Unknown and I4
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Invalid comparison between Unknown and I4
		//IL_0027: 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_002c: Invalid comparison between Unknown and I4
		if (item?.m_shared == null)
		{
			return false;
		}
		ItemType itemType = item.m_shared.m_itemType;
		if ((int)itemType <= 15)
		{
			if (itemType - 3 <= 2 || itemType - 14 <= 1)
			{
				goto IL_003a;
			}
		}
		else if ((int)itemType == 19 || (int)itemType == 22)
		{
			goto IL_003a;
		}
		return false;
		IL_003a:
		return true;
	}

	private static bool HandAction(MinorActionData action)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Invalid comparison between Unknown and I4
		if (action != null && (int)action.m_type != 2)
		{
			return HandItem(action.m_item);
		}
		return false;
	}

	private static bool Swapping(Player player)
	{
		List<MinorActionData> list = Queue.Invoke(player);
		if (list != null && list.Count > 0)
		{
			return HandAction(list[0]);
		}
		if (swapActive)
		{
			return Time.time - swapStarted < 2.5f;
		}
		return false;
	}

	private static bool PaySprint(Player player)
	{
		if (!((Character)player).IsRunning() || !((Character)player).IsOnGround())
		{
			return true;
		}
		float num = Plugin.FastSwapStamina.Value;
		if (num <= 0f)
		{
			return true;
		}
		if (!((Character)player).HaveStamina(num))
		{
			Hud instance = Hud.instance;
			if (instance != null)
			{
				instance.StaminaBarEmptyFlash();
			}
			return false;
		}
		((Character)player).UseStamina(num);
		return true;
	}

	internal static void Interrupt(Player player)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		if (!On((Character)(object)player) || !Plugin.FastSwapAttack.Value || !Swapping(player))
		{
			return;
		}
		List<MinorActionData> list = Queue.Invoke(player);
		if (list != null && list.Count > 0 && HandAction(list[0]))
		{
			MinorActionData val = list[0];
			list.RemoveAt(0);
			if ((int)val.m_type == 0)
			{
				((Humanoid)player).EquipItem(val.m_item, true);
			}
			else
			{
				((Humanoid)player).UnequipItem(val.m_item, true);
			}
		}
		string text = ActionAnimation.Invoke(player);
		if (text != null)
		{
			ZSyncAnimation obj = Zanim.Invoke((Character)(object)player);
			if (obj != null)
			{
				obj.SetBool(text, false);
			}
			ActionAnimation.Invoke(player) = null;
		}
		swapActive = false;
		interruptUntil = Time.time + 1f;
	}
}
internal static class Flight
{
	private sealed class Track
	{
		public Vector3 Start;

		public float Time;

		public string Name;

		public float Peak;
	}

	[HarmonyPatch(typeof(Projectile), "Setup")]
	private static class Launched
	{
		private static bool Prepare()
		{
			return false;
		}

		private static void Postfix(Projectile __instance, Character owner, ItemData item, Vector3 velocity)
		{
		}
	}

	[HarmonyPatch(typeof(Projectile), "FixedUpdate")]
	private static class Flying
	{
		private static bool Prepare()
		{
			return false;
		}

		private static void Postfix(Projectile __instance)
		{
		}
	}

	[HarmonyPatch(typeof(Projectile), "OnHit")]
	private static class Landed
	{
		private static bool Prepare()
		{
			return false;
		}

		private static void Prefix(Projectile __instance, Collider collider)
		{
		}
	}

	internal const bool Diagnostics = false;

	private static readonly Dictionary<Projectile, Track> tracks = new Dictionary<Projectile, Track>();

	private static readonly FieldRef<Humanoid, Attack> CurrentAttack = AccessTools.FieldRefAccess<Humanoid, Attack>("m_currentAttack");

	private static readonly FieldRef<Projectile, Vector3> Velocity = AccessTools.FieldRefAccess<Projectile, Vector3>("m_vel");

	private static string F(float v)
	{
		return v.ToString("0.###", CultureInfo.InvariantCulture);
	}
}
internal static class KrakenAxe
{
	[HarmonyPatch(typeof(Player), "Update")]
	private static class ThrowAnimation
	{
		private static readonly FieldRef<Character, ZSyncAnimation> Anim = AccessTools.FieldRefAccess<Character, ZSyncAnimation>("m_zanim");

		private static readonly FieldRef<Humanoid, Attack> Current = AccessTools.FieldRefAccess<Humanoid, Attack>("m_currentAttack");

		private static float current = 1f;

		private static void Postfix(Player __instance)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || throwAttack == null)
			{
				return;
			}
			Attack val = Current.Invoke((Humanoid)(object)__instance);
			float num = 1f;
			if (val != null && ((Character)__instance).InAttack() && Is(val.GetWeapon()))
			{
				if (val.m_attackAnimation == throwAttack.m_attackAnimation)
				{
					num = 1.49f;
				}
				else if (axeSpecial != null && val.m_attackAnimation == axeSpecial.m_attackAnimation)
				{
					num = 1.3f;
				}
			}
			if (!Mathf.Approximately(num, current))
			{
				current = num;
				ZSyncAnimation obj = Anim.Invoke((Character)(object)__instance);
				if (obj != null)
				{
					obj.SetSpeed(num);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Attack), "GetAttackStamina")]
	private static class ChopStamina
	{
		private static readonly FieldRef<Attack, Humanoid> Owner = AccessTools.FieldRefAccess<Attack, Humanoid>("m_character");

		private static void Postfix(Attack __instance, ref float __result)
		{
			if (axeSpecial != null && !(__instance.m_attackAnimation != axeSpecial.m_attackAnimation) && Is(__instance.GetWeapon()))
			{
				Humanoid val = Owner.Invoke(__instance);
				if (Object.op_Implicit((Object)(object)val))
				{
					float skillFactor = ((Character)val).GetSkillFactor((SkillType)7);
					__result *= (1f - 0.5f * skillFactor) / (1f - 0.33f * skillFactor);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Attack), "OnAttackTrigger")]
	private static class Chop
	{
		private static readonly FieldRef<Attack, Humanoid> Owner = AccessTools.FieldRefAccess<Attack, Humanoid>("m_character");

		private static Attack lastBurst;

		private static float lastBurstTime;

		private static void Postfix(Attack __instance)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)iceBurst) || axeSpecial == null || __instance.m_attackAnimation != axeSpecial.m_attackAnimation || AttackCancel.IsCancelled(__instance) || __instance == lastBurst || Time.time - lastBurstTime < 0.5f)
			{
				return;
			}
			Humanoid val = Owner.Invoke(__instance);
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			ItemData weapon = __instance.GetWeapon();
			if (Is(weapon))
			{
				lastBurst = __instance;
				lastBurstTime = Time.time;
				Transform transform = ((Component)val).transform;
				ApplyIceRadius();
				IProjectile component = Object.Instantiate<GameObject>(iceBurst, transform.position + transform.forward * 1.8f + Vector3.up * 0.2f, transform.rotation).GetComponent<IProjectile>();
				if (component != null)
				{
					component.Setup((Character)(object)val, Vector3.zero, -1f, (HitData)null, weapon, (ItemData)null);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Humanoid), "StartAttack")]
	private static class Attacks
	{
		private static void Prefix(Humanoid __instance, bool secondaryAttack)
		{
			if (secondaryAttack && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && throwAttack != null)
			{
				ItemData currentWeapon = __instance.GetCurrentWeapon();
				if (Is(currentWeapon))
				{
					bool flag = ZInput.GetButton("Run") || ZInput.GetButton("JoyRun");
					currentWeapon.m_shared.m_secondaryAttack = (flag ? axeSpecial : throwAttack);
				}
			}
		}
	}

	internal const string PrefabName = "potato_kraken_axe";

	internal const string ProjectileName = "potato_kraken_axe_projectile";

	internal const string IceBurstName = "potato_kraken_iceburst";

	private const string IceBurstEffect = "fx_DvergerMage_Ice_hit";

	private const float IceBurstFrost = 90f;

	private const float IceBurstFrostPerLevel = 10f;

	private const float IceBurstReach = 1.8f;

	private const float IceBurstRadius = 2.9f;

	private const float IceLookRadius = 2.5f;

	private const string Model = "kraken_axe";

	private const float BalanceZ = 0.45f;

	private const float SpinPerSecond = 792f;

	private static readonly Color FrostColor = new Color(0.35f, 0.75f, 1f);

	private const float GlowStrength = 1.4f;

	private const float LightIntensity = 0.6f;

	private const float LightRange = 3f;

	internal const float MaxFlightSeconds = 1.7f;

	internal const float ThrowSpeed = 32f;

	private const float ThrowAnimSpeed = 1.49f;

	private const float ChopAnimSpeed = 1.3f;

	private const float ChopSkillSaving = 0.5f;

	private static Mesh mesh;

	private static Material material;

	private static Attack throwAttack;

	private static Attack axeSpecial;

	private static GameObject iceBurst;

	private static GameObject iceEffect;

	private static Light[] iceLights;

	private static float[] iceLightRanges;

	internal static void Register()
	{
		CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
		string text = "English";
		localization.AddTranslation(ref text, new Dictionary<string, string>
		{
			{ "item_potato_kraken_axe", "Kraken Axe" },
			{ "item_potato_kraken_axe_description", "Cold as the deep and never far from its owner's hand. Throw it with the middle mouse button and call it back the same way once your hand is empty. Shift and middle mouse chops." }
		});
		PrefabManager.OnVanillaPrefabsAvailable += Create;
	}

	private static void Create()
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Expected O, but got Unknown
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected O, but got Unknown
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Expected O, but got Unknown
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Expected O, but got Unknown
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Expected O, but got Unknown
		PrefabManager.OnVanillaPrefabsAvailable -= Create;
		try
		{
			mesh = Assets.LoadMesh("kraken_axe");
			if (Object.op_Implicit((Object)(object)mesh))
			{
				ItemConfig val = new ItemConfig
				{
					Name = "$item_potato_kraken_axe",
					Description = "$item_potato_kraken_axe_description",
					CraftingStation = CraftingStations.BlackForge,
					MinStationLevel = 3
				};
				val.AddRequirement(new RequirementConfig("FlametalNew", 16, 6, true));
				val.AddRequirement(new RequirementConfig("Silver", 10, 4, true));
				val.AddRequirement(new RequirementConfig("FreezeGland", 6, 3, true));
				val.AddRequirement(new RequirementConfig("SerpentScale", 4, 0, true));
				CustomItem val2 = new CustomItem("potato_kraken_axe", "AxeIron", val);
				GameObject projectile = MakeProjectile();
				iceBurst = MakeIceBurst();
				Setup(val2.ItemPrefab, projectile);
				ItemManager.Instance.AddItem(val2);
				Plugin.OwnWeapons.Add("potato_kraken_axe");
				EpicLootThrowable.ThrowingWeapons.Add("$item_potato_kraken_axe");
				EpicLootThrowable.NoThrowableRoll.Exclude();
				Glow.Watch();
				ItemManager.OnItemsRegistered += AddUpgradeIdol;
			}
		}
		catch (Exception arg)
		{
			Plugin.Log.LogError((object)$"The Kraken Axe couldn't be made: {arg}");
		}
	}

	private static Material Material()
	{
		//IL_0050: 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_005a: Expected O, but got Unknown
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)material))
		{
			return material;
		}
		GameObject prefab = Cache.GetPrefab<GameObject>("AxeIron");
		object obj;
		if (prefab == null)
		{
			obj = null;
		}
		else
		{
			MeshRenderer componentInChildren = prefab.GetComponentInChildren<MeshRenderer>(true);
			obj = ((componentInChildren != null) ? ((Renderer)componentInChildren).sharedMaterial : null);
		}
		Material val = (Material)obj;
		material = (Object.op_Implicit((Object)(object)val) ? new Material(val) : new Material(Shader.Find("Standard")));
		((Object)material).name = "potato_kraken_axe";
		Set("_MainTex", Assets.LoadTexture("kraken_axe_d.png", linear: false));
		Set("_BumpMap", Assets.LoadTexture("kraken_axe_n.png", linear: true));
		Set("_MetallicGlossMap", Assets.LoadTexture("kraken_axe_m.png", linear: true));
		Set("_EmissionMap", Assets.LoadTexture("kraken_axe_e.png", linear: false));
		if (material.HasProperty("_Color"))
		{
			material.SetColor("_Color", Color.white);
		}
		Glow.Apply();
		return material;
	}

	private static void Set(string property, Texture2D texture)
	{
		if (Object.op_Implicit((Object)(object)texture) && material.HasProperty(property))
		{
			material.SetTexture(property, (Texture)(object)texture);
		}
	}

	internal static void ApplyGlow(float factor)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)material) && material.HasProperty("_EmissionColor"))
		{
			material.SetColor("_EmissionColor", FrostColor * 1.4f * factor);
		}
	}

	private static void Setup(GameObject prefab, GameObject projectile)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: 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_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: 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_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: 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)
		//IL_020a: Invalid comparison between Unknown and I4
		//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_02da: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0303: Unknown result type (might be due to invalid IL or missing references)
		//IL_0308: Unknown result type (might be due to invalid IL or missing references)
		//IL_030c: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Unknown result type (might be due to invalid IL or missing references)
		//IL_035e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0382: Unknown result type (might be due to invalid IL or missing references)
		SharedData shared = prefab.GetComponent<ItemDrop>().m_itemData.m_shared;
		shared.m_damages = new DamageTypes
		{
			m_slash = 100f,
			m_chop = 80f,
			m_frost = 40f,
			m_spirit = 20f
		};
		shared.m_damagesPerLevel = new DamageTypes
		{
			m_slash = 6f,
			m_chop = 4f,
			m_frost = 4f,
			m_spirit = 2f
		};
		shared.m_maxDurability = 300f;
		shared.m_durabilityPerLevel = 50f;
		shared.m_blockPower = 57f;
		shared.m_attackForce = 60f;
		shared.m_toolTier = 4;
		shared.m_maxQuality = 4;
		shared.m_attack.m_attackStamina = 16f;
		SetIcon(shared);
		axeSpecial = shared.m_secondaryAttack.Clone();
		axeSpecial.m_attackStamina = 32f;
		throwAttack = Cache.GetPrefab<GameObject>("SpearBronze").GetComponent<ItemDrop>().m_itemData.m_shared.m_secondaryAttack.Clone();
		throwAttack.m_attackProjectile = projectile;
		throwAttack.m_projectileVel = 32f;
		throwAttack.m_projectileVelMin = 32f;
		throwAttack.m_attackStamina = 18f;
		shared.m_secondaryAttack = throwAttack;
		Transform val = prefab.transform.Find("attach");
		Transform obj = val.Find("Viking_Axe");
		((Object)obj).name = "kraken_axe";
		obj.localPosition = Vector3.zero;
		obj.localRotation = Quaternion.identity;
		obj.localScale = Vector3.one;
		((Component)obj).GetComponent<MeshFilter>().sharedMesh = mesh;
		((Renderer)((Component)obj).GetComponent<MeshRenderer>()).sharedMaterial = Material();
		Transform val2 = val.Find("UpgraderGlow");
		if (Object.op_Implicit((Object)(object)val2))
		{
			ParticleSystem[] componentsInChildren = ((Component)val2).GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem obj2 in componentsInChildren)
			{
				ShapeModule shape = obj2.shape;
				if ((int)((ShapeModule)(ref shape)).shapeType == 6)
				{
					((ShapeModule)(ref shape)).mesh = mesh;
				}
				((Component)obj2).transform.localPosition = Vector3.zero;
				((Component)obj2).transform.localRotation = Quaternion.identity;
				((Component)obj2).transform.localScale = Vector3.one;
			}
			Light[] componentsInChildren2 = ((Component)val2).GetComponentsInChildren<Light>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				((Component)componentsInChildren2[i]).transform.localPosition = new Vector3(0f, 0f, 0.6f);
			}
		}
		Transform obj3 = val.Find("collider");
		BoxCollider val3 = ((obj3 != null) ? ((Component)obj3).GetComponent<BoxCollider>() : null);
		if (Object.op_Implicit((Object)(object)val3))
		{
			((Component)val3).transform.localPosition = Vector3.zero;
			((Component)val3).transform.localRotation = Quaternion.identity;
			((Component)val3).transform.localScale = Vector3.one;
			Bounds bounds = mesh.bounds;
			val3.center = ((Bounds)(ref bounds)).center;
			bounds = mesh.bounds;
			val3.size = ((Bounds)(ref bounds)).size;
		}
		Transform val4 = val.Find("equiped/trail");
		if (Object.op_Implicit((Object)(object)val4))
		{
			Transform val5 = val4.Find("base");
			Transform val6 = val4.Find("tip");
			if (Object.op_Implicit((Object)(object)val5))
			{
				val5.localPosition = new Vector3(0.21f, 0f, 0.45f);
			}
			if (Object.op_Implicit((Object)(object)val6))
			{
				val6.localPosition = new Vector3(0.24f, 0f, 0.72f);
			}
		}
		AddFrostLight(val);
	}

	private static void AddFrostLight(Transform parent)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: 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)
		GameObject val = new GameObject("frost light");
		val.transform.SetParent(parent, false);
		val.transform.localPosition = new Vector3(0f, 0f, 0.6f);
		Light obj = val.AddComponent<Light>();
		obj.type = (LightType)2;
		obj.color = new Color(0.48f, 0.8f, 1f);
		obj.range = 3f;
		obj.intensity = 0.6f;
		obj.shadows = (LightShadows)0;
		val.AddComponent<Glow.Lamp>().Base = 0.6f;
	}

	private static GameObject MakeProjectile()
	{
		GameObject val = PrefabManager.Instance.CreateClonedPrefab("potato_kraken_axe_projectile", "bronzespear_projectile");
		Projectile component = val.GetComponent<Projectile>();
		component.m_gravity = 1.5f;
		component.m_rotateVisual = 792f;
		component.m_rotateVisualY = 0f;
		component.m_rotateVisualZ = 0f;
		if (Object.op_Implicit((Object)(object)component.m_visual))
		{
			Object.DestroyImmediate((Object)(object)component.m_visual);
		}
		Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val2 in componentsInChildren)
		{
			if (!(val2 is ParticleSystemRenderer) && !(val2 is TrailRenderer))
			{
				val2.enabled = false;
			}
		}
		component.m_visual = SpinningModel(val.transform, "kraken_visual");
		AddFrostLight(component.m_visual.transform);
		PrefabManager.Instance.AddPrefab(val);
		return val;
	}

	private static void AddUpgradeIdol()
	{
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: 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_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Expected O, but got Unknown
		try
		{
			ObjectDB instance = ObjectDB.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return;
			}
			Recipe val = instance.m_recipes.Find((Recipe r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.m_item) && ((Object)r.m_item).name == "potato_kraken_axe");
			if (!Object.op_Implicit((Object)(object)val) || Array.Exists(val.m_resources, (Requirement r) => r.m_upgraderResource))
			{
				return;
			}
			GameObject itemPrefab = instance.GetItemPrefab("Upgrader6Weapon");
			ItemDrop val2 = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				Plugin.Log.LogInfo((object)"No upgrade idols in this game: the Kraken Axe upgrades at the forge only.");
				return;
			}
			Recipe val3 = instance.m_recipes.Find((Recipe r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.m_item) && ((Object)r.m_item).name == "AxeBerzerkr");
			Requirement val4 = (Object.op_Implicit((Object)(object)val3) ? Array.Find(val3.m_resources, (Requirement r) => r.m_upgraderResource) : null);
			List<Requirement> list = new List<Requirement>(val.m_resources)
			{
				new Requirement
				{
					m_resItem = val2,
					m_amount = (val4?.m_amount ?? 1),
					m_amountPerLevel = (val4?.m_amountPerLevel ?? 0),
					m_recover = (val4?.m_recover ?? false),
					m_upgraderResource = true
				}
			};
			val.m_resources = list.ToArray();
			GameObject itemPrefab2 = instance.GetItemPrefab("potato_kraken_axe");
			ItemDrop val5 = ((itemPrefab2 != null) ? itemPrefab2.GetComponent<ItemDrop>() : null);
			int num = (Object.op_Implicit((Object)(object)val3) ? val3.m_item.m_itemData.m_shared.m_maxQuality : 0);
			if (Object.op_Implicit((Object)(object)val5) && num > val5.m_itemData.m_shared.m_maxQuality)
			{
				val5.m_itemData.m_shared.m_maxQuality = num;
			}
			Plugin.Log.LogInfo((object)string.Format("Kraken Axe: upgrade idol Upgrader6Weapon x{0} (+{1} a level, {2}), upgrade cap {3}.", val4?.m_amount ?? 1, val4?.m_amountPerLevel ?? 0, (val4 != null) ? "as the Berserkir Axes" : "no Berserkir Axes recipe to copy", val5?.m_itemData.m_shared.m_maxQuality));
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("The Kraken Axe's upgrade idol couldn't be added: " + ex.Message));
		}
	}

	private static GameObject MakeIceBurst()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: 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_00d4: 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_00fa: Expected O, but got Unknown
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Expected O, but got Unknown
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Expected O, but got Unknown
		GameObject val = PrefabManager.Instance.CreateEmptyPrefab("potato_kraken_iceburst", true);
		Aoe val2 = val.AddComponent<Aoe>();
		val2.m_name = "$item_potato_kraken_axe";
		val2.m_useAttackSettings = false;
		val2.m_damage = new DamageTypes
		{
			m_frost = 90f
		};
		val2.m_damagePerLevel = new DamageTypes
		{
			m_frost = 10f
		};
		val2.m_hitEnemy = true;
		val2.m_hitFriendly = false;
		val2.m_hitOwner = false;
		val2.m_hitSame = false;
		val2.m_hitParent = false;
		val2.m_hitCharacters = true;
		val2.m_hitProps = false;
		val2.m_hitTerrain = false;
		val2.m_hitInterval = 0f;
		val2.m_ttl = 0.5f;
		val2.m_activationDelay = 0f;
		val2.m_multiSpawnMin = 0;
		val2.m_multiSpawnMax = 0;
		val2.m_chainStartChance = 0f;
		val2.m_skill = (SkillType)7;
		val2.m_attackForce = 10f;
		GameObject prefab = Cache.GetPrefab<GameObject>("fx_DvergerMage_Ice_hit");
		val2.m_initiateEffect = new EffectList();
		val2.m_hitEffects = new EffectList();
		if (Object.op_Implicit((Object)(object)prefab))
		{
			iceEffect = PrefabManager.Instance.CreateClonedPrefab("potato_kraken_iceburst_fx", prefab);
			ParticleSystem[] componentsInChildren = iceEffect.GetComponentsInChildren<ParticleSystem>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				MainModule main = componentsInChildren[i].main;
				((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0;
			}
			iceLights = iceEffect.GetComponentsInChildren<Light>(true);
			iceLightRanges = Array.ConvertAll(iceLights, (Light l) => l.range);
			val2.m_initiateEffect.m_effectPrefabs = (EffectData[])(object)new EffectData[1]
			{
				new EffectData
				{
					m_prefab = iceEffect,
					m_enabled = true,
					m_variant = -1
				}
			};
		}
		else
		{
			Plugin.Log.LogWarning((object)"The ice effect fx_DvergerMage_Ice_hit wasn't found; the burst still hits.");
		}
		Collider[] componentsInChildren2 = val.GetComponentsInChildren<Collider>(true);
		for (int i = 0; i < componentsInChildren2.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
		}
		MeshRenderer[] componentsInChildren3 = val.GetComponentsInChildren<MeshRenderer>(true);
		for (int i = 0; i < componentsInChildren3.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
		}
		MeshFilter[] componentsInChildren4 = val.GetComponentsInChildren<MeshFilter>(true);
		for (int i = 0; i < componentsInChildren4.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)componentsInChildren4[i]);
		}
		PrefabManager.Instance.AddPrefab(val);
		iceBurst = val;
		ApplyIceRadius();
		Plugin.ExplosionSize.SettingChanged += delegate
		{
			ApplyIceRadius();
		};
		return val;
	}

	private static void ApplyIceRadius()
	{
		//IL_005e: 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)
		if (!Object.op_Implicit((Object)(object)iceBurst))
		{
			return;
		}
		float num = 2.9f * (float)Plugin.ExplosionSize.Value / 100f;
		Aoe component = iceBurst.GetComponent<Aoe>();
		if (Object.op_Implicit((Object)(object)component))
		{
			component.m_radius = num;
		}
		if (!Object.op_Implicit((Object)(object)iceEffect))
		{
			return;
		}
		float num2 = num / 2.5f;
		iceEffect.transform.localScale = Vector3.one * num2;
		for (int i = 0; i < iceLights.Length; i++)
		{
			if (Object.op_Implicit((Object)(object)iceLights[i]))
			{
				iceLights[i].range = iceLightRanges[i] * num2;
			}
		}
	}

	internal static GameObject SpinningModel(Transform parent, string name)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.transform.SetParent(parent, false);
		GameObject val2 = new GameObject("kraken_axe");
		val2.transform.SetParent(val.transform, false);
		val2.transform.localRotation = Quaternion.Euler(0f, 0f, 90f);
		val2.transform.localPosition = new Vector3(0f, 0f, -0.45f);
		val2.AddComponent<MeshFilter>().sharedMesh = mesh;
		((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = Material();
		val.transform.localRotation = Quaternion.Euler(-90f, 0f, 0f);
		return val;
	}

	internal static bool Is(ItemData item)
	{
		if (Object.op_Implicit((Object)(object)item?.m_dropPrefab))
		{
			return ((Object)item.m_dropPrefab).name == "potato_kraken_axe";
		}
		return false;
	}

	private static void SetIcon(SharedData shared)
	{
		//IL_003e: 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)
		Texture2D val = Assets.LoadTexture("kraken_axe_icon.png", linear: false);
		if (Object.op_Implicit((Object)(object)val))
		{
			((Texture)val).filterMode = (FilterMode)1;
			shared.m_icons = (Sprite[])(object)new Sprite[1] { Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)) };
		}
	}
}
internal static class Glow
{
	internal sealed class Lamp : MonoBehaviour
	{
		public float Base = 0.6f;

		private Light light;

		private void Awake()
		{
			light = ((Component)this).GetComponent<Light>();
			lamps.Add(this);
			Set(Factor);
		}

		private void OnDestroy()
		{
			lamps.Remove(this);
		}

		internal void Set(float factor)
		{
			if (Object.op_Implicit((Object)(object)light))
			{
				light.intensity = Base * factor;
				((Behaviour)light).enabled = factor > 0.001f;
			}
		}
	}

	private const string TweaksId = "potato.tweaks";

	private static readonly string[] Sections = new string[2] { "2 - Visual effects", "7 - Visual effects" };

	private static ConfigEntry<bool> enabled;

	private static ConfigEntry<float> strength;

	private static readonly HashSet<Lamp> lamps = new HashSet<Lamp>();

	internal static float Factor
	{
		get
		{
			if (enabled == null || strength == null || !enabled.Value)
			{
				return 1f;
			}
			return Mathf.Max(0f, strength.Value);
		}
	}

	internal static void Watch()
	{
		if (Chainloader.PluginInfos.TryGetValue("potato.tweaks", out var value) && Object.op_Implicit((Object)(object)value.Instance))
		{
			ConfigFile config = value.Instance.Config;
			string[] sections = Sections;
			foreach (string text in sections)
			{
				if (enabled == null && config.TryGetEntry<bool>(text, "Upgrade glow", ref enabled))
				{
					config.TryGetEntry<float>(text, "Upgrade glow strength", ref strength);
				}
			}
			if (enabled != null)
			{
				enabled.SettingChanged += delegate
				{
					Apply();
				};
			}
			if (strength != null)
			{
				strength.SettingChanged += delegate
				{
					Apply();
				};
			}
		}
		Apply();
	}

	internal static void Apply()
	{
		float factor = Factor;
		KrakenAxe.ApplyGlow(factor);
		foreach (Lamp lamp in lamps)
		{
			if (Object.op_Implicit((Object)(object)lamp))
			{
				lamp.Set(factor);
			}
		}
	}
}
[BepInPlugin("potato.fighter", "PotatoFighter", "1.1.0")]
[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.*/)]
public class Plugin : BaseUnityPlugin
{
	public const string Id = "potato.fighter";

	public const string Version = "1.1.0";

	internal const bool TestBuild = false;

	internal static readonly HashSet<string> OwnWeapons = new HashSet<string>();

	private const string WeaponSection = "1 - Weapons";

	private const string CombatSection = "2 - Combat";

	private const string CreatureSection = "3 - Creatures";

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> RecallEnabled;

	internal static ConfigEntry<bool> RecallPin;

	internal static ConfigEntry<bool> Beam;

	internal static ConfigEntry<bool> AttackCancelEnabled;

	internal static ConfigEntry<bool> KeepFastShots;

	internal static ConfigEntry<bool> FastSwapEnabled;

	internal static ConfigEntry<bool> FastSwapSprint;

	internal static ConfigEntry<bool> FastSwapAttack;

	internal static ConfigEntry<bool> CrossbowsStayLoaded;

	internal static ConfigEntry<int> FastSwapStamina;

	internal static ConfigEntry<Color> BeamColor;

	internal static ConfigEntry<int> ExplosionSize;

	internal static ConfigEntry<bool> RecallStamina;

	internal static ConfigEntry<bool> CreatureLevels;

	internal static ConfigEntry<int> CreatureMaxStars;

	internal static ConfigEntry<int> CreatureStarChance;

	internal static ConfigEntry<int> CreatureModifierChance;

	internal static ConfigEntry<int> OffspringModifierChance;

	internal const float RecallStaminaCost = 15f;

	private Harmony harmony;

	private void Awake()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Expected O, but got Unknown
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Expected O, but got Unknown
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Expected O, but got Unknown
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Expected O, but got Unknown
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Expected O, but got Unknown
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Expected O, but got Unknown
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Expected O, but got Unknown
		//IL_0295: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Expected O, but got Unknown
		//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Expected O, but got Unknown
		//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0306: Expected O, but got Unknown
		//IL_0337: Unknown result type (might be due to invalid IL or missing references)
		//IL_0341: Expected O, but got Unknown
		//IL_0372: Unknown result type (might be due to invalid IL or missing references)
		//IL_037c: Expected O, but got Unknown
		//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Expected O, but got Unknown
		//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d2: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		RecallEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Weapons", "Weapon recall", true, new ConfigDescription("After a throw, the throw button (middle mouse, or the gamepad's) calls a thrown weapon back to the hotbar slot it came from, while the hand it was thrown from is empty. Set by the server.", (AcceptableValueBase)null, new object[1] { val }));
		RecallStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Weapons", "Recall uses stamina", true, new ConfigDescription("Calling a weapon back costs stamina: 15 at skill 0 in the weapon's own skill (Axes for an axe), less as the skill grows, nothing at 100. Off: free. Set by the server.", (AcceptableValueBase)null, new object[1] { val }));
		RecallPin = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Weapons", "Recall map pin", true, "Mark a thrown weapon on the map until it's back in your hands.");
		Beam = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Weapons", "Light beam", true, "Show a beam of light over a thrown weapon lying on the ground.");
		BeamColor = ((BaseUnityPlugin)this).Config.Bind<Color>("1 - Weapons", "Light beam color", new Color(1f, 0.85f, 0.45f, 0.85f), "The beam's colour. Its alpha is how strong the beam is at the bottom; it fades out towards the top.");
		bool flag = File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath) && File.ReadAllText(((BaseUnityPlugin)this).Config.ConfigFilePath).Contains("[2 - Combat]");
		AttackCancelEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Combat", "Attack cancel", true, new ConfigDescription("Pressing block during an attack's windup or recovery abandons the attack and raises the guard at once, so you can parry mid-swing. A hit the swing hasn't reached never lands; stamina already paid and a hit already dealt stay. Cancelling never lets you attack faster. Set by the server.", (AcceptableValueBase)null, new object[1] { val }));
		KeepFastShots = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Combat", "Keep fast bow shots", true, "With a fast draw (high Bows skill, Quick Draw), letting go of a fully drawn arrow before the last shot's animation ends no longer loses the shot: the arrow stays drawn and flies as soon as the bow can fire. Blocking, switching weapons or dying before then cancels it without using an arrow.");
		FastSwapEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Combat", "Fast swap", true, new ConfigDescription("Switching weapons, shields, torches and tools, and sheathing or drawing with R, no longer slows you from a run to a walk. Armor keeps its normal equip time. Off by itself when Skarif's FastSwap is installed. Set by the server.", (AcceptableValueBase)null, new object[1] { val }));
		FastSwapSprint = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Combat", "Fast swap while sprinting", false, new ConfigDescription("A weapon switch made while sprinting goes ahead instead of being cancelled by the sprint, for the stamina in Fast swap stamina while sprinting. Needs Fast swap. Set by the server.", (AcceptableValueBase)null, new object[1] { val }));
		FastSwapStamina = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Combat", "Fast swap stamina while sprinting", 10, new ConfigDescription("Stamina a weapon switch or sheathing costs while sprinting on the ground, with Fast swap while sprinting on. Without that much stamina, the switch doesn't happen. 0: free. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), new object[1] { val }));
		FastSwapAttack = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Combat", "Attack cuts a swap short", false, new ConfigDescription("Attacking (or drawing a bow) during a weapon switch finishes the switch at once and goes ahead with the new weapon, instead of waiting for it. Needs Fast swap. Set by the server.", (AcceptableValueBase)null, new object[1] { val }));
		CrossbowsStayLoaded = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Combat", "Crossbows stay loaded", true, new ConfigDescription("A loaded crossbow stays loaded when you switch to something else and back (each crossbow keeps its own load). The bolt is still used only when it fires. Set by the server.", (AcceptableValueBase)null, new object[1] { val }));
		ExplosionSize = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Weapons", "Explosion size", 100, new ConfigDescription("The size of every PotatoFighter weapon's explosions, in percent of its own size (the Kraken Axe's ice explosion: 2.9 m at 100). Both the reach of the damage and the effect grow and shrink with it. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 200), new object[1] { val }));
		CreatureLevels = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Creatures", "Creature levels", true, new ConfigDescription("Creatures spawn with extra stars, more in later biomes (up to 2 in the Meadows, 3 in the Black Forest, 4 in the Swamp, 5 from the Mountain on) and a little more once a biome's boss is beaten, and some with a modifier (Armored, Quick, Fierce, Regenerating, Splitting) that their young can inherit. Creatures loaded from the world keep their level, except wild ones above Creature max stars, which get one new roll. Off by itself when StarLevelSystem or Creature Level and Loot Control is installed. Set by the server.", (AcceptableValueBase)null, new object[1] { val }));
		CreatureMaxStars = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Creatures", "Creature max stars", 5, new ConfigDescription("Most stars a creature can spawn with. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 10), new object[1] { val }));
		CreatureStarChance = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Creatures", "Creature star chance", 100, new ConfigDescription("How likely a creature is to get its first extra star, in percent of the normal chance (0: only the game's own stars). Each further star keeps its biome's own chance. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), new object[1] { val }));
		CreatureModifierChance = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Creatures", "Creature modifier chance", 100, new ConfigDescription("How likely a creature with stars spawns with a modifier, in percent of the normal chance (35% at 1 star, 10% more each star, 75% at 5). 0: no modifiers. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), new object[1] { val }));
		OffspringModifierChance = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Creatures", "Offspring modifier chance", 50, new ConfigDescription("Chance in percent that a newborn keeps its parent's modifier. A youngster always keeps its own when it grows up. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { val }));
		if (!flag)
		{
			CarryOverFromTweaks();
		}
		harmony = new Harmony("potato.fighter");
		IEnumerable<Type> enumerable = typeof(Recall).GetNestedTypes(AccessTools.all).Concat(typeof(Flight).GetNestedTypes(AccessTools.all)).Concat(typeof(AttackCancel).GetNestedTypes(AccessTools.all))
			.Concat(typeof(FastSwap).GetNestedTypes(AccessTools.all))
			.Concat(typeof(EpicLootThrowable).GetNestedTypes(AccessTools.all))
			.Concat(typeof(KrakenAxe).GetNestedTypes(AccessTools.all))
			.Concat(typeof(CrossbowLoad).GetNestedTypes(AccessTools.all));
		if (Creatures.StandAside)
		{
			Log.LogWarning((object)"StarLevelSystem or Creature Level and Loot Control is installed, so PotatoFighter's creature levels stay off. Remove it to use them.");
		}
		else
		{
			enumerable = enumerable.Concat(typeof(Creatures).GetNestedTypes(AccessTools.all)).Concat(typeof(CreatureHud).GetNestedTypes(AccessTools.all));
		}
		foreach (Type item in enumerable)
		{
			Patch(item);
		}
		Type[] array = new Type[4]
		{
			typeof(Probe),
			typeof(BowRelease),
			typeof(QueuedBowRelease),
			typeof(TripleShotCancel)
		};
		foreach (Type type in array)
		{
			Patch(type);
		}
		try
		{
			EpicLootThrowable.NoThrowableRoll.Exclude();
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("Couldn't keep Throwable off the Kraken Axe: " + ex.Message));
		}
		((Component)this).gameObject.AddComponent<Recall>();
		if (!Creatures.StandAside)
		{
			((Component)this).gameObject.AddComponent<Creatures.Ticker>();
		}
		Assets.Dir = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "assets");
		KrakenAxe.Register();
	}

	private void Patch(Type type)
	{
		if (!type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Any())
		{
			return;
		}
		try
		{
			harmony.CreateClassProcessor(type).Patch();
		}
		catch (Exception ex)
		{
			Log.LogError((object)(type.Name + " is disabled: " + ex.GetBaseException().Message));
		}
	}

	private void CarryOverFromTweaks()
	{
		Dictionary<string, string> dictionary = Read(Path.Combine(Paths.ConfigPath, "potato.tweaks.cfg"));
		bool flag = false;
		if (dictionary.TryGetValue("8 - Attack cancel|Enabled", out var value) && bool.TryParse(value, out var result))
		{
			AttackCancelEnabled.Value = result;
			flag = true;
		}
		if ((dictionary.TryGetValue("10 - Bug fixes|Game bug fixes", out var value2) || dictionary.TryGetValue("1 - General|Game bug fixes", out value2)) && bool.TryParse(value2, out var result2))
		{
			KeepFastShots.Value = result2;
			flag = true;
		}
		if (flag)
		{
			((BaseUnityPlugin)this).Config.Save();
			Log.LogInfo((object)$"Attack cancel ({AttackCancelEnabled.Value}) and keeping fast bow shots ({KeepFastShots.Value}) carried over from Potato Tweaks' settings.");
		}
	}

	private static Dictionary<string, string> Read(string path)
	{
		Dictionary<string, string> dictionary = new Dictionary<string, string>();
		try
		{
			if (!File.Exists(path))
			{
				return dictionary;
			}
			string text = "";
			string[] array = File.ReadAllLines(path);
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.Length == 0 || text2.StartsWith("#"))
				{
					continue;
				}
				if (text2.StartsWith("[") && text2.EndsWith("]"))
				{
					text = text2.Substring(1, text2.Length - 2);
					continue;
				}
				int num = text2.IndexOf('=');
				if (num > 0)
				{
					dictionary[text + "|" + text2.Substring(0, num).Trim()] = text2.Substring(num + 1).Trim();
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("Couldn't read " + Path.GetFileName(path) + ": " + ex.Message));
		}
		return dictionary;
	}
}
[HarmonyPatch(typeof(Player), "OnSpawned")]
internal static class Probe
{
	private static bool done;

	private static readonly string[] Items = new string[17]
	{
		"AxeStone", "AxeFlint", "AxeBronze", "AxeIron", "Battleaxe", "SpearFlint", "SpearBronze", "SpearElderbark", "SpearWolfFang", "MaceSilver",
		"KnifeSilver", "MaceIron", "AxeBlackMetal", "AxeJotunBane", "SpearCarapace", "SwordMistwalker", "KnifeSkollAndHati"
	};

	private static readonly HashSet<string> SeenMaterials = new HashSet<string>();

	private static bool Prepare()
	{
		return false;
	}

	private static string F(float v)
	{
		return v.ToString("0.###", CultureInfo.InvariantCulture);
	}

	private static string V(Vector3 v)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		return "(" + F(v.x) + "," + F(v.y) + "," + F(v.z) + ")";
	}

	private static string C(Color c)
	{
		//IL_0011: 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_003d: 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)
		return "(" + F(c.r) + "," + F(c.g) + "," + F(c.b) + "," + F(c.a) + ")";
	}

	private static void Postfix(Player __instance)
	{
		ObjectDB instance = ObjectDB.instance;
		if (done || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.GetItemPrefab("AxeStone")))
		{
			return;
		}
		done = true;
		ObjectDB val = instance;
		StringBuilder stringBuilder = new StringBuilder();
		try
		{
			string[] items = Items;
			foreach (string text in items)
			{
				GameObject itemPrefab = val.GetItemPrefab(text);
				if (!Object.op_Implicit((Object)(object)itemPrefab))
				{
					stringBuilder.AppendLine("## " + text + ": not found");
				}
				else
				{
					DumpItem(stringBuilder, itemPrefab);
				}
			}
			List<string> list = (from val2 in val.m_items
				where Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.GetComponentInChildren<ParticleIntensityScaler>(true))
				select ((Object)val2).name).ToList();
			stringBuilder.AppendLine(string.Format("## Items with ParticleIntensityScaler: {0}: {1}", list.Count, string.Join(", ", list)));
		}
		catch (Exception ex)
		{
			stringBuilder.AppendLine("PROBE ERROR " + ex);
		}
		File.WriteAllText(Path.Combine(Paths.BepInExRootPath, "PotatoFighter-probe.log"), stringBuilder.ToString());
		try
		{
			File.WriteAllText(Path.Combine(Paths.BepInExRootPath, "PotatoFighter-probe-aoe.log"), AoeReport(val));
		}
		catch (Exception ex2)
		{
			Plugin.Log.LogWarning((object)("AoE probe: " + ex2));
		}
		Plugin.Log.LogInfo((object)"Probe written to PotatoFighter-probe.log");
	}

	private static void DumpItem(StringBuilder sb, GameObject go)
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: 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_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		SharedData shared = go.GetComponent<ItemDrop>().m_itemData.m_shared;
		sb.AppendLine($"## {((Object)go).name}: {Localization.instance.Localize(shared.m_name)} type {shared.m_itemType} anim {shared.m_animationState} skill {shared.m_skillType} attachOverride {shared.m_attachOverride} " + $"maxQuality {shared.m_maxQuality} weight {F(shared.m_weight)} equipDuration {F(shared.m_equipDuration)} durability {F(shared.m_maxDurability)}+{F(shared.m_durabilityPerLevel)} " + $"blockPower {F(shared.m_blockPower)} parry {F(shared.m_timedBlockBonus)} attackForce {F(shared.m_attackForc