Decompiled source of UpgradableStats v1.1.4

BepInEx\plugins\UpgradableStats.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: AssemblyCompany("UpgradableStats")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.4.0")]
[assembly: AssemblyInformationalVersion("1.1.4")]
[assembly: AssemblyProduct("Upgradable Stats")]
[assembly: AssemblyTitle("UpgradableStats")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.4.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace UpgradableStats
{
	internal static class HudFigure
	{
		internal static RectTransform Anchor()
		{
			HUDManager instance = HUDManager.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.selfRedCanvasGroup == (Object)null)
			{
				return null;
			}
			return ((Component)instance.selfRedCanvasGroup).GetComponent<RectTransform>();
		}

		internal static RectTransform NewSibling(string name, Vector2 sizeFactor, Vector2 offsetFactor, Vector2 extraOffset)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = Anchor();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
			((Transform)component).SetParent(((Transform)val).parent, false);
			((Transform)component).SetSiblingIndex(((Transform)val).GetSiblingIndex() + 1);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			component.anchorMax = val2;
			component.anchorMin = val2;
			component.pivot = new Vector2(0.5f, 0.5f);
			Rect rect = val.rect;
			float width = ((Rect)(ref rect)).width;
			rect = val.rect;
			float height = ((Rect)(ref rect)).height;
			component.sizeDelta = new Vector2(width * sizeFactor.x, height * sizeFactor.y);
			((Transform)component).localPosition = ((Transform)val).localPosition + new Vector3(width * offsetFactor.x + extraOffset.x, height * offsetFactor.y + extraOffset.y, 0f);
			((Transform)component).localRotation = Quaternion.identity;
			((Transform)component).localScale = Vector3.one;
			return component;
		}

		internal static Sprite SpriteFromRows(string[] rows, Color mainColor, Color darkColor, Color gemColor)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_00e0: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			int num = rows.Length;
			int num2 = rows.Max((string r) => r.Length);
			Color val = default(Color);
			((Color)(ref val))..ctor(0f, 0f, 0f, 0f);
			Texture2D val2 = new Texture2D(num2, num, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)1
			};
			for (int num3 = 0; num3 < num; num3++)
			{
				string text = rows[num - 1 - num3];
				for (int num4 = 0; num4 < num2; num4++)
				{
					val2.SetPixel(num4, num3, (Color)(((num4 < text.Length) ? text[num4] : '.') switch
					{
						'X' => gemColor, 
						'd' => darkColor, 
						'g' => mainColor, 
						_ => val, 
					}));
				}
			}
			val2.Apply();
			return Sprite.Create(val2, new Rect(0f, 0f, (float)num2, (float)num), new Vector2(0.5f, 0.5f), 100f);
		}
	}
	internal static class CrownIndicator
	{
		private static Image _crown;

		private static AudioClip _glassClip;

		private static bool _searchedClip;

		internal static void Tick()
		{
			bool flag = StatsEffects.HasSecondWind && !StatsEffects.SecondWindActive && (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && !GameNetworkManager.Instance.localPlayerController.isPlayerDead;
			if ((Object)(object)_crown == (Object)null)
			{
				if (!flag)
				{
					return;
				}
				Build();
				if ((Object)(object)_crown == (Object)null)
				{
					return;
				}
			}
			if (((Behaviour)_crown).enabled != flag)
			{
				((Behaviour)_crown).enabled = flag;
			}
		}

		private static void Build()
		{
			//IL_000f: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = HudFigure.NewSibling("SecondWindCrown[UpgradableStats]", new Vector2(0.42f, 0.16f), new Vector2(0f, 0.62f), new Vector2(0f, 4f));
			if (!((Object)(object)val == (Object)null))
			{
				_crown = ((Component)val).gameObject.AddComponent<Image>();
				_crown.sprite = BuildCrownSprite();
				_crown.preserveAspect = true;
				((Graphic)_crown).raycastTarget = false;
				((Behaviour)_crown).enabled = false;
				Plugin.Log.LogInfo((object)"Corona del segundo aliento creada (anclada a la figura).");
			}
		}

		private static Sprite BuildCrownSprite()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			Color white = Color.white;
			return HudFigure.SpriteFromRows(new string[11]
			{
				".g.....g.....g...", ".gg...g.g...gg...", ".g.g..g.g..g.g...", ".g..g.g.g.g..g...", ".g...gg.gg...g...", ".g...........g...", ".ggggggggggggg...", ".g.....g.....g...", ".g....g.g....g...", ".g.....g.....g...",
				".ggggggggggggg..."
			}, white, white, white);
		}

		internal static void PlayBreakSound()
		{
			AudioClip val = FindGlassClip();
			if (!((Object)(object)val == (Object)null) && !((Object)(object)HUDManager.Instance == (Object)null) && !((Object)(object)HUDManager.Instance.UIAudio == (Object)null))
			{
				HUDManager.Instance.UIAudio.PlayOneShot(val, 0.4f);
			}
		}

		private static AudioClip FindGlassClip()
		{
			if ((Object)(object)_glassClip != (Object)null || _searchedClip)
			{
				return _glassClip;
			}
			_searchedClip = true;
			string[] obj = new string[5] { "glassbreak", "glassshatter", "shatter", "glass", "windowbreak" };
			AudioClip[] source = Resources.FindObjectsOfTypeAll<AudioClip>();
			string[] array = obj;
			foreach (string key in array)
			{
				_glassClip = ((IEnumerable<AudioClip>)source).FirstOrDefault((Func<AudioClip, bool>)((AudioClip c) => (Object)(object)c != (Object)null && ((Object)c).name.ToLowerInvariant().Contains(key)));
				if ((Object)(object)_glassClip != (Object)null)
				{
					Plugin.Log.LogInfo((object)("Sonido de vidrio: usando el clip del juego \"" + ((Object)_glassClip).name + "\"."));
					return _glassClip;
				}
			}
			_glassClip = SynthesizeGlass();
			Plugin.Log.LogInfo((object)"Sonido de vidrio: no encontré clip del juego, usando uno sintetizado.");
			return _glassClip;
		}

		private static AudioClip SynthesizeGlass()
		{
			int num = 15435;
			float[] array = new float[num];
			Random random = new Random(1234);
			for (int i = 0; i < num; i++)
			{
				float num2 = (float)i / (float)num;
				float num3 = Mathf.Pow(1f - num2, 2.6f);
				float num4 = (float)(random.NextDouble() * 2.0 - 1.0) * 0.55f;
				float num5 = Mathf.Sin(MathF.PI * 7600f * (float)i / 44100f) * 0.25f;
				float num6 = Mathf.Sin(MathF.PI * 11200f * (float)i / 44100f) * 0.18f;
				array[i] = (num4 + num5 + num6) * num3 * 0.5f;
			}
			AudioClip obj = AudioClip.Create("GlassBreakSynth", num, 1, 44100, false);
			obj.SetData(array, 0);
			return obj;
		}
	}
	internal static class StrengthArms
	{
		private static Image _left;

		private static Image _right;

		private static int _builtLevel = -1;

		private static Sprite[] _sprites;

		internal static void Tick()
		{
			int level = Plugin.LocalUpgrades.GetLevel(UpgradeSkill.Strength);
			if (level <= 0)
			{
				if ((Object)(object)_left != (Object)null)
				{
					((Behaviour)_left).enabled = false;
					((Behaviour)_right).enabled = false;
				}
				_builtLevel = 0;
				return;
			}
			if ((Object)(object)_left == (Object)null)
			{
				Build();
				if ((Object)(object)_left == (Object)null)
				{
					return;
				}
			}
			if (_builtLevel != level)
			{
				Sprite sprite = GetSprite(level);
				_left.sprite = sprite;
				_right.sprite = sprite;
				_builtLevel = level;
			}
			if (!((Behaviour)_left).enabled)
			{
				((Behaviour)_left).enabled = true;
				((Behaviour)_right).enabled = true;
			}
		}

		private static void Build()
		{
			//IL_000f: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = HudFigure.NewSibling("StrengthArmL[UpgradableStats]", new Vector2(0.38f, 0.34f), new Vector2(-0.34f, 0.12f), Vector2.zero);
			if (!((Object)(object)val == (Object)null))
			{
				RectTransform obj = HudFigure.NewSibling("StrengthArmR[UpgradableStats]", new Vector2(0.38f, 0.34f), new Vector2(0.34f, 0.12f), Vector2.zero);
				((Transform)obj).localScale = new Vector3(-1f, 1f, 1f);
				_left = ((Component)val).gameObject.AddComponent<Image>();
				_right = ((Component)obj).gameObject.AddComponent<Image>();
				Image[] array = (Image[])(object)new Image[2] { _left, _right };
				foreach (Image obj2 in array)
				{
					obj2.preserveAspect = true;
					((Graphic)obj2).raycastTarget = false;
					((Graphic)obj2).color = new Color(1f, 1f, 1f, 0.95f);
					((Behaviour)obj2).enabled = false;
				}
				Plugin.Log.LogInfo((object)"Brazos de fuerza creados en la figura del HUD.");
			}
		}

		private static Sprite GetSprite(int level)
		{
			if (_sprites == null)
			{
				_sprites = (Sprite[])(object)new Sprite[3];
			}
			int num = Mathf.Clamp(level, 1, 3) - 1;
			if ((Object)(object)_sprites[num] == (Object)null)
			{
				_sprites[num] = BuildArmSprite(level);
			}
			return _sprites[num];
		}

		private static Sprite BuildArmSprite(int level)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			Color white = Color.white;
			return HudFigure.SpriteFromRows(level switch
			{
				1 => new string[12]
				{
					"....................", "....................", "..............ggg...", "...........gggggg...", "........ggggggg.....", ".....ggggggg........", "...ggggggg..........", "..gggggg............", "..ggggg.............", "..gggg..............",
					"...gg...............", "...................."
				}, 
				2 => new string[12]
				{
					"....................", "..............gggg..", "..........gggggggg..", ".......ggggggggg....", ".....gggggggggg.....", "....ggggggggg.......", "...gggggggg.........", "..ggggggg...........", "..gggggg............", "..ggggg.............",
					"...ggg..............", "...................."
				}, 
				_ => new string[12]
				{
					"...gggg.............", "..gggggg............", "..gggggg............", "..ggggggg...........", "...gggggg...........", "...ggggggg......ggg.", "....gggggggg..ggggg.", ".....ggggggggggggg..", "......ggggggggggg...", ".......ggggggggg....",
					"....................", "...................."
				}, 
			}, white, white, white);
		}
	}
	public class MachineScreenFx : MonoBehaviour
	{
		private static readonly Color Celeste = new Color(0.45f, 0.85f, 1f, 0.95f);

		private RectTransform _figure;

		private readonly RectTransform[] _particles = (RectTransform[])(object)new RectTransform[3];

		private readonly Quaternion[] _orbitTilts = (Quaternion[])(object)new Quaternion[3]
		{
			Quaternion.Euler(72f, 0f, 0f),
			Quaternion.Euler(72f, 0f, 60f),
			Quaternion.Euler(72f, 0f, -60f)
		};

		private readonly float[] _speeds = new float[3] { 2f, 2.6f, 3.3f };

		private readonly float[] _phases = new float[3] { 0f, 2.1f, 4.2f };

		private const float OrbitRadius = 16f;

		private float _t;

		private void Start()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Empleado", new Type[1] { typeof(RectTransform) });
			_figure = val.GetComponent<RectTransform>();
			((Transform)_figure).SetParent(((Component)this).transform, false);
			_figure.sizeDelta = new Vector2(20f, 30f);
			Image obj = val.AddComponent<Image>();
			obj.sprite = FindEmployeeSprite();
			((Graphic)obj).color = Celeste;
			obj.preserveAspect = true;
			((Graphic)obj).raycastTarget = false;
			Sprite sprite = BuildDotSprite();
			for (int i = 0; i < _particles.Length; i++)
			{
				GameObject val2 = new GameObject($"Particula{i}", new Type[1] { typeof(RectTransform) });
				_particles[i] = val2.GetComponent<RectTransform>();
				((Transform)_particles[i]).SetParent(((Component)this).transform, false);
				_particles[i].sizeDelta = new Vector2(3.2f, 3.2f);
				Image obj2 = val2.AddComponent<Image>();
				obj2.sprite = sprite;
				((Graphic)obj2).color = Celeste;
				((Graphic)obj2).raycastTarget = false;
			}
		}

		private void Update()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			_t += Time.deltaTime;
			if ((Object)(object)_figure != (Object)null)
			{
				((Transform)_figure).localRotation = Quaternion.Euler(0f, _t * 85f, 0f);
			}
			for (int i = 0; i < _particles.Length; i++)
			{
				if (!((Object)(object)_particles[i] == (Object)null))
				{
					float num = _t * _speeds[i] + _phases[i];
					Vector3 val = _orbitTilts[i] * new Vector3(Mathf.Cos(num) * 16f, 0f, Mathf.Sin(num) * 16f);
					((Transform)_particles[i]).localPosition = val;
					float num2 = Mathf.InverseLerp(16f, -16f, val.z);
					((Transform)_particles[i]).localScale = Vector3.one * Mathf.Lerp(0.7f, 1.25f, num2);
				}
			}
		}

		private static Sprite FindEmployeeSprite()
		{
			HUDManager instance = HUDManager.Instance;
			if ((Object)(object)instance != (Object)null && (Object)(object)instance.selfRedCanvasGroup != (Object)null)
			{
				Image componentInChildren = ((Component)instance.selfRedCanvasGroup).GetComponentInChildren<Image>(true);
				if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.sprite != (Object)null)
				{
					return componentInChildren.sprite;
				}
				Transform parent = ((Component)instance.selfRedCanvasGroup).transform.parent;
				if ((Object)(object)parent != (Object)null)
				{
					Image[] componentsInChildren = ((Component)parent).GetComponentsInChildren<Image>(true);
					foreach (Image val in componentsInChildren)
					{
						if ((Object)(object)val.sprite != (Object)null)
						{
							return val.sprite;
						}
					}
				}
			}
			Plugin.Log.LogWarning((object)"No encontré el sprite del empleado; uso el de respaldo.");
			return BuildFallbackFigure();
		}

		private static Sprite BuildFallbackFigure()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			return HudFigure.SpriteFromRows(new string[15]
			{
				"....gggg....", "...g....g...", "...g....g...", "....gggg....", ".....gg.....", "..gggggggg..", ".g...gg...g.", "g....gg....g", "g....gg....g", ".....gg.....",
				"....g..g....", "....g..g....", "...g....g...", "...g....g...", "..g......g.."
			}, Color.white, Color.white, Color.white);
		}

		private static Sprite BuildDotSprite()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(12, 12, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1
			};
			float num = 5.5f;
			for (int i = 0; i < 12; i++)
			{
				for (int j = 0; j < 12; j++)
				{
					float num2 = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(num, num)) / num;
					float num3 = Mathf.Clamp01(1f - num2);
					val.SetPixel(j, i, new Color(1f, 1f, 1f, num3 * num3));
				}
			}
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 12f, 12f), new Vector2(0.5f, 0.5f), 100f);
		}
	}
	internal static class Patches
	{
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		internal static class GameNetworkManager_Start
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				TokenItem.RegisterNetworkPrefab();
				UpgradesMachine.RegisterNetworkPrefab();
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		internal static class StartOfRound_Awake
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				TokenItem.SetupEarlyInGame();
				UpgradesMachine.RegisterUnlockable();
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		internal static class StartOfRound_Start
		{
			[HarmonyPostfix]
			private static void Postfix(StartOfRound __instance)
			{
				TokenItem.SetupInGame();
				((MonoBehaviour)__instance).StartCoroutine(UpgradesMachine.SpawnRoutine());
				((MonoBehaviour)__instance).StartCoroutine(UpgradeSync.SessionStartRoutine());
				((MonoBehaviour)__instance).StartCoroutine(FixRemoteSlotsWhenReady());
			}

			private static IEnumerator FixRemoteSlotsWhenReady()
			{
				yield return (object)new WaitForSeconds(2f);
				UpgradeSync.EnsureRemotePlayersSlots();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Jump_performed")]
		internal static class PlayerControllerB_Jump
		{
			[HarmonyPrefix]
			private static void Prefix(PlayerControllerB __instance, ref float __state)
			{
				__state = -1f;
				if (StatsEffects.IsLocal(__instance) && Plugin.LocalUpgrades.HasGoodLegs)
				{
					__state = __instance.sprintMeter;
				}
			}

			[HarmonyPostfix]
			private static void Postfix(PlayerControllerB __instance, float __state)
			{
				if (__state >= 0f && __instance.sprintMeter < __state)
				{
					__instance.sprintMeter = __state;
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "AutoSaveShipData")]
		internal static class StartOfRound_AutoSaveShipData
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				UpgradeSync.SaveNow();
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
		internal static class StartOfRound_ResetShip
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				StatsEffects.ResetEverything();
				UpgradeSync.ClearAllSavedLevels();
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "ReviveDeadPlayers")]
		internal static class StartOfRound_ReviveDeadPlayers
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				StatsEffects.ReapplyAll(((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
			}
		}

		internal struct DamageState
		{
			internal int Prev;

			internal int Expected;

			internal bool SecondWind;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
		internal static class PlayerControllerB_DamagePlayer
		{
			[HarmonyPrefix]
			private static void Prefix(PlayerControllerB __instance, ref int damageNumber, ref DamageState __state)
			{
				__state = new DamageState
				{
					Prev = -1,
					Expected = -1
				};
				if (!StatsEffects.IsLocal(__instance) || !((NetworkBehaviour)__instance).IsOwner || __instance.isPlayerDead)
				{
					return;
				}
				int health = __instance.health;
				bool secondWind = false;
				int expected;
				if (health - damageNumber <= 0)
				{
					if (!__instance.criticallyInjured && damageNumber < 50)
					{
						expected = 5;
					}
					else if (StatsEffects.HasSecondWind && !StatsEffects.SecondWindActive && health > 1)
					{
						expected = 1;
						secondWind = true;
						damageNumber = health - 1;
						Plugin.Log.LogInfo((object)"¡Segundo aliento! Sobrevives con 1 HP.");
					}
					else
					{
						expected = 0;
					}
				}
				else
				{
					expected = Mathf.Clamp(health - damageNumber, 0, StatsEffects.MaxHealth);
				}
				__state = new DamageState
				{
					Prev = health,
					Expected = expected,
					SecondWind = secondWind
				};
			}

			[HarmonyPostfix]
			private static void Postfix(PlayerControllerB __instance, DamageState __state)
			{
				if (__state.SecondWind && !__instance.isPlayerDead)
				{
					StatsEffects.NotifySecondWind();
				}
				if (__state.Prev >= 0 && __state.Expected > 0 && !__instance.isPlayerDead && __instance.health != __state.Prev && __instance.health != __state.Expected)
				{
					__instance.health = __state.Expected;
					if ((Object)(object)HUDManager.Instance != (Object)null)
					{
						HUDManager.Instance.UpdateHealthUI(__instance.health, false);
					}
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
		internal static class PlayerControllerB_KillPlayer
		{
			[HarmonyPrefix]
			private static bool Prefix(PlayerControllerB __instance, CauseOfDeath causeOfDeath, int deathAnimation)
			{
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				if (!StatsEffects.IsLocal(__instance))
				{
					return true;
				}
				if (!((NetworkBehaviour)__instance).IsOwner || __instance.isPlayerDead)
				{
					return true;
				}
				if (!StatsEffects.HasSecondWind || StatsEffects.SecondWindActive)
				{
					return true;
				}
				if (__instance.health <= 1)
				{
					return true;
				}
				if (!IsSurvivable(__instance, causeOfDeath, deathAnimation))
				{
					return true;
				}
				__instance.health = 1;
				if ((Object)(object)HUDManager.Instance != (Object)null)
				{
					HUDManager.Instance.UpdateHealthUI(1, true);
				}
				StatsEffects.NotifySecondWind();
				EnemyAI inAnimationWithEnemy = __instance.inAnimationWithEnemy;
				__instance.inAnimationWithEnemy = null;
				__instance.inSpecialInteractAnimation = false;
				__instance.snapToServerPosition = false;
				__instance.disableMoveInput = false;
				__instance.disableLookInput = false;
				if ((Object)(object)inAnimationWithEnemy != (Object)null)
				{
					try
					{
						inAnimationWithEnemy.SetEnemyStunned(true, 5f, __instance);
					}
					catch
					{
					}
				}
				Plugin.Log.LogInfo((object)$"¡Segundo aliento! Sobreviviste a una muerte instantánea ({causeOfDeath}).");
				return false;
			}

			private static bool IsSurvivable(PlayerControllerB p, CauseOfDeath cause, int deathAnimation)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0004: Invalid comparison between Unknown and I4
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				if (cause - 3 <= 1 || (int)cause == 8)
				{
					return true;
				}
				if ((int)cause == 0 && deathAnimation == 1)
				{
					DressGirlAI[] array = Object.FindObjectsOfType<DressGirlAI>();
					foreach (DressGirlAI val in array)
					{
						if ((Object)(object)val != (Object)null && (Object)(object)val.hauntingPlayer == (Object)(object)p)
						{
							return true;
						}
					}
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Shovel), "HitShovel")]
		internal static class Shovel_HitShovel
		{
			[HarmonyPrefix]
			private static void Prefix(Shovel __instance, ref int __state)
			{
				__state = -1;
				if (StatsEffects.IsLocal(__instance.previousPlayerHeldBy))
				{
					float meleeMultiplier = StatsEffects.MeleeMultiplier;
					if (!(meleeMultiplier <= 1f))
					{
						__state = __instance.shovelHitForce;
						__instance.shovelHitForce = Mathf.Max(1, Mathf.RoundToInt((float)__state * meleeMultiplier));
					}
				}
			}

			[HarmonyPostfix]
			private static void Postfix(Shovel __instance, int __state)
			{
				if (__state >= 0)
				{
					__instance.shovelHitForce = __state;
				}
			}
		}

		[HarmonyPatch(typeof(KnifeItem), "HitKnife")]
		internal static class KnifeItem_HitKnife
		{
			[HarmonyPrefix]
			private static void Prefix(KnifeItem __instance, ref int __state)
			{
				__state = -1;
				if (StatsEffects.IsLocal(__instance.previousPlayerHeldBy))
				{
					float meleeMultiplier = StatsEffects.MeleeMultiplier;
					if (!(meleeMultiplier <= 1f))
					{
						__state = __instance.knifeHitForce;
						__instance.knifeHitForce = Mathf.Max(1, Mathf.RoundToInt((float)__state * meleeMultiplier));
					}
				}
			}

			[HarmonyPostfix]
			private static void Postfix(KnifeItem __instance, int __state)
			{
				if (__state >= 0)
				{
					__instance.knifeHitForce = __state;
				}
			}
		}

		[HarmonyPatch(typeof(TetraChemicalItem), "Update")]
		internal static class TetraChemicalItem_Update
		{
			private static float _healAccumulator;

			[HarmonyPostfix]
			private static void Postfix(TetraChemicalItem __instance)
			{
				if (!__instance.emittingGas || __instance.fuel <= 0f)
				{
					return;
				}
				PlayerControllerB playerHeldBy = ((GrabbableObject)__instance).playerHeldBy;
				if (!StatsEffects.IsLocal(playerHeldBy) || playerHeldBy.isPlayerDead || playerHeldBy.health >= StatsEffects.MaxHealth)
				{
					return;
				}
				_healAccumulator += Time.deltaTime / 38f * 198f;
				int num = (int)_healAccumulator;
				if (num <= 0)
				{
					StatsEffects.LastTzpHealTime = Time.time;
					return;
				}
				_healAccumulator -= num;
				playerHeldBy.health = Mathf.Min(playerHeldBy.health + num, StatsEffects.MaxHealth);
				StatsEffects.LastTzpHealTime = Time.time;
				if (playerHeldBy.health >= 20 && playerHeldBy.criticallyInjured)
				{
					playerHeldBy.MakeCriticallyInjured(false);
				}
				if ((Object)(object)HUDManager.Instance != (Object)null)
				{
					HUDManager.Instance.UpdateHealthUI(playerHeldBy.health, false);
				}
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		internal static class GrabbableObject_Start
		{
			[HarmonyPostfix]
			private static void Postfix(GrabbableObject __instance)
			{
				if (TokenItem.IsToken(__instance))
				{
					__instance.SetScrapValue(Plugin.TokenSellValue.Value);
					if (Plugin.TokenGlowEnabled.Value && (Object)(object)((Component)__instance).GetComponent<TokenGlow>() == (Object)null)
					{
						((Component)__instance).gameObject.AddComponent<TokenGlow>();
					}
				}
			}
		}

		[HarmonyPatch(typeof(Terminal), "LoadNewNodeIfAffordable")]
		internal static class Terminal_LoadNewNodeIfAffordable
		{
			[HarmonyPrefix]
			private static void Prefix(Terminal __instance, TerminalNode node)
			{
				SecretCode.RememberAttempt(__instance, node);
				SecretCode.BeforePurchase(__instance);
			}

			[HarmonyPostfix]
			private static void Postfix(Terminal __instance, TerminalNode node)
			{
				SecretCode.AfterPurchase(__instance);
				SecretCode.AttemptFinished(__instance, node);
			}
		}

		[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
		internal static class Terminal_ParsePlayerSentence
		{
			[HarmonyPrefix]
			private static bool Prefix(Terminal __instance, ref TerminalNode __result)
			{
				if ((Object)(object)__instance.screenText == (Object)null)
				{
					return true;
				}
				string text = __instance.screenText.text;
				if (string.IsNullOrEmpty(text) || __instance.textAdded <= 0)
				{
					return true;
				}
				if (__instance.textAdded > text.Length)
				{
					return true;
				}
				if (!SecretCode.IsCode(text.Substring(text.Length - __instance.textAdded)))
				{
					return true;
				}
				TerminalNode val = SecretCode.OnCodeTyped(__instance);
				if ((Object)(object)val == (Object)null)
				{
					return true;
				}
				__result = val;
				return false;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SetInSpecialMenu")]
		internal static class PlayerControllerB_SetInSpecialMenu
		{
			[HarmonyPostfix]
			private static void Postfix(bool setInMenu)
			{
				if (!setInMenu && UpgradeMenuUI.IsOpen)
				{
					UpgradeMenuUI.Close();
				}
			}
		}
	}
	[BepInPlugin("com.CommanderMechavala.upgradablestats", "Upgradable Stats", "1.1.4")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.CommanderMechavala.upgradablestats";

		public const string PluginName = "Upgradable Stats";

		public const string PluginVersion = "1.1.4";

		internal static ManualLogSource Log;

		internal static readonly PlayerUpgrades LocalUpgrades = new PlayerUpgrades();

		internal static ConfigEntry<float> OffsetX;

		internal static ConfigEntry<float> OffsetY;

		internal static ConfigEntry<float> OffsetZ;

		internal static ConfigEntry<float> MachineRotationY;

		internal static ConfigEntry<bool> FreeUpgrades;

		internal static ConfigEntry<int> TokenBuyPrice;

		internal static ConfigEntry<int> TokenSellValue;

		internal static ConfigEntry<int> TokenFallbackRarity;

		internal static ConfigEntry<int> RefundCredits;

		internal static ConfigEntry<bool> TokenGlowEnabled;

		internal static ConfigEntry<bool> StaminaBarVisual;

		internal static ConfigEntry<bool> PocketFlashlightEnabled;

		private readonly Harmony _harmony = new Harmony("com.CommanderMechavala.upgradablestats");

		internal static Vector3 MachineOffset => new Vector3(OffsetX.Value, OffsetY.Value, OffsetZ.Value);

		private void Awake()
		{
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Expected O, but got Unknown
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Machine", "OffsetX", -1.6f, "Position relative to the terminal: sideways (negative = left).");
			OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Machine", "OffsetY", 0f, "Position relative to the terminal: height.");
			OffsetZ = ((BaseUnityPlugin)this).Config.Bind<float>("Machine", "OffsetZ", 0f, "Position relative to the terminal: forward/back.");
			MachineRotationY = ((BaseUnityPlugin)this).Config.Bind<float>("Machine", "RotationY", 0f, "Extra rotation of the machine, in degrees.");
			FreeUpgrades = ((BaseUnityPlugin)this).Config.Bind<bool>("Fichas", "FreeUpgrades", false, "true = upgrades don't consume Fichas (for testing).");
			TokenBuyPrice = ((BaseUnityPlugin)this).Config.Bind<int>("Fichas", "BuyPrice", 450, "Credits a Ficha costs at the terminal (\"buy ficha\").");
			TokenSellValue = ((BaseUnityPlugin)this).Config.Bind<int>("Fichas", "ScrapValue", 200, "Scrap value of a Ficha — what the Company pays for it.");
			TokenGlowEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Fichas", "FloorGlow", true, "Golden legendary-style aura on Fichas lying on the floor.");
			RefundCredits = ((BaseUnityPlugin)this).Config.Bind<int>("Fichas", "RefundCredits", 200, "Credits refunded to the terminal when removing an upgrade with [-].");
			TokenFallbackRarity = ((BaseUnityPlugin)this).Config.Bind<int>("Fichas", "FallbackRarity", 8, "Spawn rarity used only on moons that have no Gift to copy it from.");
			StaminaBarVisual = ((BaseUnityPlugin)this).Config.Bind<bool>("Interface", "StaminaBar", true, "Show the extra stamina bar granted by your upgrades.");
			PocketFlashlightEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Extras", "FlashlightKeyF", true, "Toggle the flashlight with [F] even while it's stowed in your inventory.");
			TokenItem.CreateEarly();
			UpgradesMachine.CreatePrefabEarly();
			GameObject val = new GameObject("UpgradableStats_Runtime");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<UpgradeRuntime>();
			_harmony.PatchAll(typeof(Patches).Assembly);
			Log.LogInfo((object)"¡Upgradable Stats v1.1.4 cargado correctamente!");
			Log.LogInfo((object)"Fase 3: fichas (aparecen como el Regalo, \"buy ficha\" 450, venta 400) + efectos reales.");
		}
	}
	internal static class PocketFlashlight
	{
		internal static void Tick()
		{
			if (!Plugin.PocketFlashlightEnabled.Value || Keyboard.current == null || !((ButtonControl)Keyboard.current.fKey).wasPressedThisFrame)
			{
				return;
			}
			PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
			if ((Object)(object)val == (Object)null || !((NetworkBehaviour)val).IsOwner || val.isPlayerDead || val.ItemSlots == null || val.isTypingChat || val.inTerminalMenu || val.inSpecialMenu || ((Object)(object)val.quickMenuManager != (Object)null && val.quickMenuManager.isMenuOpen))
			{
				return;
			}
			FlashlightItem val2 = FindBestFlashlight(val);
			if (!((Object)(object)val2 == (Object)null))
			{
				if ((Object)(object)val.currentlyHeldObjectServer == (Object)(object)val2)
				{
					((GrabbableObject)val2).UseItemOnClient(true);
				}
				else
				{
					TogglePocketed(val, val2);
				}
			}
		}

		private static FlashlightItem FindBestFlashlight(PlayerControllerB p)
		{
			FlashlightItem val = null;
			for (int i = 0; i < p.ItemSlots.Length; i++)
			{
				GrabbableObject obj = p.ItemSlots[i];
				FlashlightItem val2 = (FlashlightItem)(object)((obj is FlashlightItem) ? obj : null);
				if (!((Object)(object)val2 == (Object)null))
				{
					if (((GrabbableObject)val2).isBeingUsed)
					{
						return val2;
					}
					bool flag = ((GrabbableObject)val2).insertedBattery != null && !((GrabbableObject)val2).insertedBattery.empty;
					if ((Object)(object)val == (Object)null && flag)
					{
						val = val2;
					}
				}
			}
			return val;
		}

		private static void TogglePocketed(PlayerControllerB p, FlashlightItem flashlight)
		{
			bool flag = !((GrabbableObject)flashlight).isBeingUsed;
			if (flag && (((GrabbableObject)flashlight).insertedBattery == null || ((GrabbableObject)flashlight).insertedBattery.empty))
			{
				return;
			}
			flashlight.SwitchFlashlight(false);
			((GrabbableObject)flashlight).isBeingUsed = flag;
			flashlight.usingPlayerHelmetLight = flag;
			if ((Object)(object)p.helmetLight != (Object)null)
			{
				((Behaviour)p.helmetLight).enabled = flag;
			}
			p.pocketedFlashlight = (GrabbableObject)(object)(flag ? flashlight : null);
			if ((Object)(object)flashlight.flashlightAudio != (Object)null && flashlight.flashlightClips != null && flashlight.flashlightClips.Length != 0)
			{
				flashlight.flashlightAudio.PlayOneShot(flashlight.flashlightClips[Random.Range(0, flashlight.flashlightClips.Length)]);
			}
			try
			{
				flashlight.PocketFlashlightServerRpc(flag);
			}
			catch
			{
			}
		}
	}
	internal static class SecretCode
	{
		private const string Code = "MECHAVALA24";

		private const string Reply = "Alr, Welcome Commander Mech\n\n";

		private const int LoanedCredits = 1000000;

		private static TerminalNode _pendingBuyNode;

		private static int _pendingAmount = 1;

		private static bool _freeMode;

		private static int _realCredits;

		private static bool _lending;

		private static bool _autoConfirming;

		private static TerminalNode _replyNode;

		private static bool IsPurchase(TerminalNode node)
		{
			if ((Object)(object)node == (Object)null)
			{
				return false;
			}
			if (node.buyItemIndex == -1 && node.shipUnlockableID == -1 && node.buyVehicleIndex == -1)
			{
				if (node.buyRerouteToMoon != -1)
				{
					return node.buyRerouteToMoon != -2;
				}
				return false;
			}
			return true;
		}

		internal static void RememberAttempt(Terminal terminal, TerminalNode node)
		{
			if (!((Object)(object)terminal == (Object)null) && IsPurchase(node))
			{
				_pendingBuyNode = node;
				_pendingAmount = Mathf.Max(1, terminal.playerDefinedAmount);
			}
		}

		internal static void AttemptFinished(Terminal terminal, TerminalNode node)
		{
			if (!((Object)(object)terminal == (Object)null) && !((Object)(object)node == (Object)null) && !((Object)(object)_pendingBuyNode != (Object)(object)node) && (Object)(object)terminal.currentNode == (Object)(object)node)
			{
				_pendingBuyNode = null;
			}
		}

		internal static bool IsCode(string typed)
		{
			if (string.IsNullOrEmpty(typed))
			{
				return false;
			}
			StringBuilder stringBuilder = new StringBuilder(typed.Length);
			foreach (char c in typed)
			{
				if (char.IsLetterOrDigit(c))
				{
					stringBuilder.Append(char.ToUpperInvariant(c));
				}
			}
			return stringBuilder.ToString() == "MECHAVALA24";
		}

		internal static TerminalNode OnCodeTyped(Terminal terminal)
		{
			if ((Object)(object)terminal == (Object)null)
			{
				return null;
			}
			_freeMode = true;
			TerminalNode val = ResolvePurchase(terminal);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogInfo((object)"[código] Modo gratis armado: la próxima compra será gratuita.");
				return BuildReply();
			}
			terminal.playerDefinedAmount = Mathf.Max(1, _pendingAmount);
			Plugin.Log.LogInfo((object)("[código] Reintentando gratis '" + ((Object)val).name + "' " + $"(item={val.buyItemIndex} unlockable={val.shipUnlockableID} " + $"vehiculo={val.buyVehicleIndex} luna={val.buyRerouteToMoon} " + $"cantidad={terminal.playerDefinedAmount})"));
			return val;
		}

		private static TerminalNode ResolvePurchase(Terminal terminal)
		{
			TerminalNode currentNode = terminal.currentNode;
			if (IsPurchase(currentNode))
			{
				return currentNode;
			}
			if ((Object)(object)currentNode != (Object)null && currentNode.terminalOptions != null)
			{
				CompatibleNoun[] terminalOptions = currentNode.terminalOptions;
				foreach (CompatibleNoun val in terminalOptions)
				{
					if (val != null && !((Object)(object)val.noun == (Object)null) && !(val.noun.word != "confirm") && IsPurchase(val.result))
					{
						return val.result;
					}
				}
			}
			return _pendingBuyNode;
		}

		internal static void BeforePurchase(Terminal terminal)
		{
			if (_freeMode && !_lending && !((Object)(object)terminal == (Object)null))
			{
				_lending = true;
				_realCredits = terminal.groupCredits;
				terminal.groupCredits = 1000000;
			}
		}

		internal static void AfterPurchase(Terminal terminal)
		{
			if (!_lending || (Object)(object)terminal == (Object)null)
			{
				return;
			}
			_lending = false;
			bool flag = terminal.groupCredits < 1000000;
			string arg = (((Object)(object)terminal.currentNode != (Object)null) ? ((Object)terminal.currentNode).name : "(null)");
			Plugin.Log.LogInfo((object)$"[código] Nodo final '{arg}' · ¿compró?: {flag}");
			terminal.groupCredits = _realCredits;
			if (((NetworkBehaviour)terminal).IsServer)
			{
				terminal.SyncGroupCreditsClientRpc(_realCredits, terminal.numberOfItemsInDropship);
			}
			else
			{
				terminal.SyncGroupCreditsServerRpc(_realCredits, terminal.numberOfItemsInDropship);
			}
			if (flag)
			{
				_freeMode = false;
				_pendingBuyNode = null;
				_pendingAmount = 1;
				terminal.LoadNewNode(BuildReply());
			}
			else
			{
				if (_autoConfirming)
				{
					return;
				}
				TerminalNode val = FindConfirmTarget(terminal.currentNode);
				if (!((Object)(object)val == (Object)null))
				{
					Plugin.Log.LogInfo((object)("[código] Confirmando automáticamente '" + ((Object)val).name + "'."));
					_autoConfirming = true;
					try
					{
						terminal.LoadNewNodeIfAffordable(val);
					}
					finally
					{
						_autoConfirming = false;
					}
				}
			}
		}

		private static TerminalNode FindConfirmTarget(TerminalNode node)
		{
			if ((Object)(object)node == (Object)null || node.terminalOptions == null)
			{
				return null;
			}
			CompatibleNoun[] terminalOptions = node.terminalOptions;
			foreach (CompatibleNoun val in terminalOptions)
			{
				if (val != null && !((Object)(object)val.noun == (Object)null) && !(val.noun.word != "confirm") && IsPurchase(val.result))
				{
					return val.result;
				}
			}
			return null;
		}

		private static TerminalNode BuildReply()
		{
			if ((Object)(object)_replyNode == (Object)null)
			{
				_replyNode = ScriptableObject.CreateInstance<TerminalNode>();
				((Object)_replyNode).name = "MechCodeNode";
				_replyNode.clearPreviousText = true;
				_replyNode.maxCharactersToType = 25;
				_replyNode.playSyncedClip = 0;
			}
			_replyNode.displayText = "Alr, Welcome Commander Mech\n\n";
			return _replyNode;
		}
	}
	internal static class StatsEffects
	{
		private const int BaseHealth = 100;

		private const float BaseSprintTime = 5f;

		private const int BaseSlots = 4;

		internal static bool SecondWindActive;

		internal static float LastTzpHealTime = -10f;

		private static float _lastRawExcess;

		private static readonly Color HudGreen = new Color(0.31f, 0.88f, 0.42f, 1f);

		private static GameObject _meleeRoot;

		private static TextMeshProUGUI _meleeText;

		private static Image _meleeSword;

		private static int _meleeShownLevel = -1;

		private static Image _staminaExtraBar;

		private static readonly List<GameObject> _hudSlotClones = new List<GameObject>();

		private static int _baseHudSlots = -1;

		private static PlayerControllerB Local
		{
			get
			{
				if (!((Object)(object)GameNetworkManager.Instance != (Object)null))
				{
					return null;
				}
				return GameNetworkManager.Instance.localPlayerController;
			}
		}

		internal static int MaxHealth => 100 + 33 * Mathf.Min(Plugin.LocalUpgrades.GetLevel(UpgradeSkill.Health), 3);

		internal static bool HasSecondWind => Plugin.LocalUpgrades.HasSecondWind;

		internal static float MeleeMultiplier => Plugin.LocalUpgrades.MeleeMultiplier;

		internal static float WeightFactor => 1f - 0.25f * (float)Plugin.LocalUpgrades.GetLevel(UpgradeSkill.Strength);

		internal static int TargetSlots => 4 + Plugin.LocalUpgrades.ExtraSlots;

		internal static bool IsLocal(PlayerControllerB p)
		{
			if ((Object)(object)p != (Object)null)
			{
				return (Object)(object)p == (Object)(object)Local;
			}
			return false;
		}

		internal static void OnUpgraded(UpgradeSkill skill)
		{
			PlayerControllerB local = Local;
			if ((Object)(object)local == (Object)null)
			{
				return;
			}
			switch (skill)
			{
			case UpgradeSkill.Health:
				if (Plugin.LocalUpgrades.GetLevel(UpgradeSkill.Health) <= 3)
				{
					local.health = Mathf.Min(local.health + 33, MaxHealth);
					HUDManager.Instance.UpdateHealthUI(local.health, false);
				}
				break;
			case UpgradeSkill.Stamina:
				ApplyStamina(local);
				break;
			case UpgradeSkill.Inventory:
				EnsureInventorySize(local);
				break;
			case UpgradeSkill.Strength:
				break;
			}
		}

		internal static void NotifySecondWind()
		{
			if (!SecondWindActive)
			{
				SecondWindActive = true;
				CrownIndicator.PlayBreakSound();
			}
		}

		internal static void UpdateVignettes()
		{
			PlayerControllerB local = Local;
			if (SecondWindActive && ((Object)(object)local == (Object)null || local.isPlayerDead || local.health >= 20))
			{
				SecondWindActive = false;
			}
			bool num = SecondWindActive && (Object)(object)local != (Object)null && !local.isPlayerDead;
			VignetteOverlay.SetTargets(pink: (Time.time - LastTzpHealTime < 0.35f) ? 0.35f : 0f, green: num ? 0.55f : 0f);
			VignetteOverlay.Tick(Time.deltaTime);
			CrownIndicator.Tick();
			StrengthArms.Tick();
		}

		internal static void ReapplyAll(PlayerControllerB p)
		{
			SecondWindActive = false;
			if (!((Object)(object)p == (Object)null) && IsLocal(p))
			{
				p.health = MaxHealth;
				if ((Object)(object)HUDManager.Instance != (Object)null)
				{
					HUDManager.Instance.UpdateHealthUI(p.health, false);
				}
				ApplyStamina(p);
				EnsureInventorySize(p);
			}
		}

		private static void ApplyStamina(PlayerControllerB p)
		{
			p.sprintTime = 5f * Plugin.LocalUpgrades.StaminaMultiplier;
		}

		internal static void EnforceCarryWeight()
		{
			PlayerControllerB local = Local;
			if ((Object)(object)local == (Object)null || local.isPlayerDead || local.ItemSlots == null)
			{
				return;
			}
			float num = 0f;
			for (int i = 0; i < local.ItemSlots.Length; i++)
			{
				GrabbableObject val = local.ItemSlots[i];
				if ((Object)(object)val != (Object)null && (Object)(object)val.itemProperties != (Object)null)
				{
					num += Mathf.Max(val.itemProperties.weight - 1f, 0f);
				}
			}
			_lastRawExcess = num;
			local.carryWeight = 1f + num * WeightFactor;
		}

		internal static void UpdateWeightLabel()
		{
			PlayerControllerB local = Local;
			HUDManager instance = HUDManager.Instance;
			if (!((Object)(object)local == (Object)null) && !((Object)(object)instance == (Object)null) && !((Object)(object)instance.weightCounter == (Object)null) && Plugin.LocalUpgrades.GetLevel(UpgradeSkill.Strength) > 0)
			{
				int num = Mathf.RoundToInt(_lastRawExcess * (1f - WeightFactor) * 105f);
				if (num > 0)
				{
					float num2 = Mathf.RoundToInt(Mathf.Clamp(local.carryWeight - 1f, 0f, 100f) * 105f);
					((TMP_Text)instance.weightCounter).text = $"{num2} lb <color=#4EE06A>(-{num} lb)</color>";
				}
			}
		}

		internal static void UpdateMeleeLabel()
		{
			HUDManager instance = HUDManager.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.weightCounter == (Object)null)
			{
				return;
			}
			int level = Plugin.LocalUpgrades.GetLevel(UpgradeSkill.Strength);
			if (level <= 0)
			{
				if ((Object)(object)_meleeRoot != (Object)null)
				{
					_meleeRoot.SetActive(false);
				}
				_meleeShownLevel = 0;
				return;
			}
			if ((Object)(object)_meleeRoot == (Object)null)
			{
				BuildMeleeLabel(instance);
			}
			if (!((Object)(object)_meleeRoot == (Object)null))
			{
				if (!_meleeRoot.activeSelf)
				{
					_meleeRoot.SetActive(true);
				}
				if (_meleeShownLevel != level)
				{
					((TMP_Text)_meleeText).text = $"(+{level * 50}%";
					_meleeShownLevel = level;
				}
			}
		}

		private static void BuildMeleeLabel(HUDManager hud)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Invalid comparison between Unknown and I4
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Invalid comparison between Unknown and I4
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI weightCounter = hud.weightCounter;
			RectTransform rectTransform = ((TMP_Text)weightCounter).rectTransform;
			_meleeRoot = new GameObject("MeleeBonus[UpgradableStats]", new Type[1] { typeof(RectTransform) });
			RectTransform component = _meleeRoot.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)rectTransform, false);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 1f);
			component.anchorMax = val;
			component.anchorMin = val;
			component.pivot = new Vector2(0.5f, 0f);
			Rect rect = rectTransform.rect;
			component.sizeDelta = new Vector2(Mathf.Max(((Rect)(ref rect)).width, 120f), ((TMP_Text)weightCounter).fontSize * 1.3f);
			component.anchoredPosition = new Vector2(0f, ((TMP_Text)weightCounter).fontSize * 0.35f);
			((Transform)component).localRotation = Quaternion.identity;
			((Transform)component).localScale = Vector3.one;
			HorizontalLayoutGroup obj = _meleeRoot.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = ((TMP_Text)weightCounter).fontSize * 0.12f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			((LayoutGroup)obj).childAlignment = (TextAnchor)(((int)((TMP_Text)weightCounter).alignment == 513) ? 3 : (((int)((TMP_Text)weightCounter).alignment == 516) ? 5 : 4));
			_meleeText = MakeMeleeTmp("Texto", component, weightCounter);
			((TMP_Text)_meleeText).text = "(+50%";
			GameObject val2 = new GameObject("Espada", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent((Transform)(object)component, false);
			_meleeSword = val2.AddComponent<Image>();
			_meleeSword.sprite = BuildSwordSprite();
			((Graphic)_meleeSword).color = HudGreen;
			_meleeSword.preserveAspect = true;
			((Graphic)_meleeSword).raycastTarget = false;
			LayoutElement obj2 = val2.AddComponent<LayoutElement>();
			obj2.preferredHeight = ((TMP_Text)weightCounter).fontSize * 1.1f;
			obj2.preferredWidth = ((TMP_Text)weightCounter).fontSize * 0.85f;
			((TMP_Text)MakeMeleeTmp("Cierre", component, weightCounter)).text = ")";
			Plugin.Log.LogInfo((object)"Indicador de daño melee creado sobre el contador de peso.");
		}

		private static TextMeshProUGUI MakeMeleeTmp(string name, RectTransform parent, TextMeshProUGUI copyFrom)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)parent, false);
			TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj).font = ((TMP_Text)copyFrom).font;
			((TMP_Text)obj).fontSize = ((TMP_Text)copyFrom).fontSize;
			((TMP_Text)obj).fontStyle = ((TMP_Text)copyFrom).fontStyle;
			((Graphic)obj).color = HudGreen;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)4098;
			((TMP_Text)obj).enableWordWrapping = false;
			((Graphic)obj).raycastTarget = false;
			ContentSizeFitter obj2 = val.AddComponent<ContentSizeFitter>();
			obj2.horizontalFit = (FitMode)2;
			obj2.verticalFit = (FitMode)2;
			return obj;
		}

		private static Sprite BuildSwordSprite()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			return HudFigure.SpriteFromRows(new string[16]
			{
				".....g.....", "....g.g....", "....g.g....", "....g.g....", "....g.g....", "....g.g....", "....g.g....", "....g.g....", "....g.g....", "..ggggggg..",
				"..g.....g..", "..ggggggg..", "....g.g....", "....g.g....", "....ggg....", "..........."
			}, Color.white, Color.white, Color.white);
		}

		internal static void UpdateStaminaBarVisual()
		{
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB local = Local;
			if ((Object)(object)local == (Object)null || (Object)(object)local.sprintMeterUI == (Object)null)
			{
				return;
			}
			float staminaMultiplier = Plugin.LocalUpgrades.StaminaMultiplier;
			if (staminaMultiplier <= 1f || !Plugin.StaminaBarVisual.Value)
			{
				if ((Object)(object)_staminaExtraBar != (Object)null)
				{
					((Behaviour)_staminaExtraBar).enabled = false;
				}
				return;
			}
			if ((Object)(object)_staminaExtraBar != (Object)null && (Object)(object)((Component)_staminaExtraBar).transform.parent != (Object)(object)((Component)local.sprintMeterUI).transform.parent)
			{
				Object.Destroy((Object)(object)((Component)_staminaExtraBar).gameObject);
				_staminaExtraBar = null;
			}
			if ((Object)(object)_staminaExtraBar == (Object)null)
			{
				CreateStaminaExtraBar(local);
			}
			if ((Object)(object)_staminaExtraBar == (Object)null)
			{
				return;
			}
			float alpha = ((Graphic)local.sprintMeterUI).canvasRenderer.GetAlpha();
			if (!((Behaviour)local.sprintMeterUI).enabled || !((Component)local.sprintMeterUI).gameObject.activeInHierarchy || !(alpha > 0.02f))
			{
				((Behaviour)_staminaExtraBar).enabled = false;
				return;
			}
			((Graphic)_staminaExtraBar).canvasRenderer.SetAlpha(alpha);
			Color val = (Plugin.LocalUpgrades.HasGoodLegs ? new Color(1f, 0.84f, 0.2f, 0.95f) : new Color(0.25f, 1f, 0.3f, 0.95f));
			if (((Graphic)_staminaExtraBar).color != val)
			{
				((Graphic)_staminaExtraBar).color = val;
			}
			float num = staminaMultiplier - 1f;
			float num2 = Mathf.Clamp01(local.sprintMeter) * staminaMultiplier;
			local.sprintMeterUI.fillAmount = Mathf.Min(num2, 1f);
			_staminaExtraBar.fillAmount = Mathf.Clamp(num2 - 1f, 0f, num);
			((Behaviour)_staminaExtraBar).enabled = true;
		}

		private static void CreateStaminaExtraBar(PlayerControllerB p)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)p.sprintMeterUI).gameObject, ((Component)p.sprintMeterUI).transform.parent);
			((Object)val).name = "SprintMeterExtra[UpgradableStats]";
			for (int num = val.transform.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)val.transform.GetChild(num)).gameObject);
			}
			Animator component = val.GetComponent<Animator>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			_staminaExtraBar = val.GetComponent<Image>();
			if ((Object)(object)_staminaExtraBar == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			((Graphic)_staminaExtraBar).color = new Color(0.25f, 1f, 0.3f, 0.95f);
			_staminaExtraBar.fillAmount = 0f;
			_staminaExtraBar.fillClockwise = !p.sprintMeterUI.fillClockwise;
			CanvasGroup component2 = val.GetComponent<CanvasGroup>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.ignoreParentGroups = false;
				component2.interactable = false;
				component2.blocksRaycasts = false;
			}
			RectTransform component3 = val.GetComponent<RectTransform>();
			RectTransform rectTransform = ((Graphic)p.sprintMeterUI).rectTransform;
			component3.anchoredPosition = rectTransform.anchoredPosition;
			((Transform)component3).localScale = ((Transform)rectTransform).localScale * 1.13f;
			val.transform.SetSiblingIndex(((Component)p.sprintMeterUI).transform.GetSiblingIndex());
			Plugin.Log.LogInfo((object)"Barra de estamina extra creada.");
		}

		internal static void EnsureInventorySize(PlayerControllerB p)
		{
			if (!((Object)(object)p == (Object)null) && IsLocal(p) && p.ItemSlots != null)
			{
				int targetSlots = TargetSlots;
				if (p.ItemSlots.Length < targetSlots)
				{
					GrabbableObject[] array = p.ItemSlots;
					Array.Resize(ref array, targetSlots);
					p.ItemSlots = array;
					GrowHud(targetSlots);
					Plugin.Log.LogInfo((object)$"Inventario ampliado a {targetSlots} espacios.");
				}
			}
		}

		private static void GrowHud(int target)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			HUDManager instance = HUDManager.Instance;
			if ((Object)(object)instance == (Object)null || instance.itemSlotIconFrames == null || instance.itemSlotIconFrames.Length == 0 || instance.itemSlotIconFrames.Length >= target)
			{
				return;
			}
			int num = instance.itemSlotIconFrames.Length;
			if (_baseHudSlots < 0)
			{
				_baseHudSlots = num;
			}
			RectTransform rectTransform = ((Graphic)instance.itemSlotIconFrames[num - 1]).rectTransform;
			Vector2 val = (Vector2)((num >= 2) ? (rectTransform.anchoredPosition - ((Graphic)instance.itemSlotIconFrames[num - 2]).rectTransform.anchoredPosition) : new Vector2(rectTransform.sizeDelta.x + 10f, 0f));
			List<Image> list = new List<Image>(instance.itemSlotIconFrames);
			List<Image> list2 = new List<Image>(instance.itemSlotIcons);
			for (int i = num; i < target; i++)
			{
				GameObject val2 = Object.Instantiate<GameObject>(((Component)rectTransform).gameObject, ((Transform)rectTransform).parent);
				((Object)val2).name = $"Slot{i}[UpgradableStats]";
				val2.GetComponent<RectTransform>().anchoredPosition = rectTransform.anchoredPosition + val * (float)(i - num + 1);
				Image component = val2.GetComponent<Image>();
				Image val3 = null;
				Image[] componentsInChildren = val2.GetComponentsInChildren<Image>(true);
				foreach (Image val4 in componentsInChildren)
				{
					if ((Object)(object)val4 != (Object)(object)component)
					{
						val3 = val4;
						break;
					}
				}
				if ((Object)(object)val3 != (Object)null)
				{
					val3.sprite = null;
					((Behaviour)val3).enabled = false;
				}
				list.Add(component);
				list2.Add(((Object)(object)val3 != (Object)null) ? val3 : component);
				_hudSlotClones.Add(val2);
			}
			instance.itemSlotIconFrames = list.ToArray();
			instance.itemSlotIcons = list2.ToArray();
		}

		internal static void ApplyInventorySize()
		{
			//IL_004d: 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)
			PlayerControllerB local = Local;
			int targetSlots = TargetSlots;
			if ((Object)(object)local != (Object)null && local.ItemSlots != null && local.ItemSlots.Length > targetSlots)
			{
				for (int i = targetSlots; i < local.ItemSlots.Length; i++)
				{
					if ((Object)(object)local.ItemSlots[i] != (Object)null)
					{
						if (local.currentItemSlot == i)
						{
							local.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true);
						}
						else
						{
							local.ItemSlots[i] = null;
						}
					}
				}
				GrabbableObject[] array = local.ItemSlots;
				Array.Resize(ref array, targetSlots);
				local.ItemSlots = array;
				if (local.currentItemSlot >= targetSlots)
				{
					local.currentItemSlot = 0;
				}
			}
			else if ((Object)(object)local != (Object)null)
			{
				EnsureInventorySize(local);
			}
			ShrinkHud(targetSlots);
		}

		private static void ShrinkHud(int target)
		{
			HUDManager instance = HUDManager.Instance;
			if ((Object)(object)instance == (Object)null || _baseHudSlots < 0 || instance.itemSlotIconFrames == null)
			{
				return;
			}
			int num = Mathf.Max(target, _baseHudSlots);
			if (instance.itemSlotIconFrames.Length <= num)
			{
				return;
			}
			List<Image> list = new List<Image>(instance.itemSlotIconFrames);
			List<Image> list2 = new List<Image>(instance.itemSlotIcons);
			for (int num2 = list.Count - 1; num2 >= num; num2--)
			{
				Image val = list[num2];
				list.RemoveAt(num2);
				if (num2 < list2.Count)
				{
					list2.RemoveAt(num2);
				}
				if ((Object)(object)val != (Object)null)
				{
					_hudSlotClones.Remove(((Component)val).gameObject);
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
			instance.itemSlotIconFrames = list.ToArray();
			instance.itemSlotIcons = list2.ToArray();
		}

		internal static void OnLevelsEdited()
		{
			PlayerControllerB local = Local;
			if (!((Object)(object)local == (Object)null))
			{
				local.sprintTime = 5f * Plugin.LocalUpgrades.StaminaMultiplier;
				local.health = Mathf.Min(local.health, MaxHealth);
				if ((Object)(object)HUDManager.Instance != (Object)null)
				{
					HUDManager.Instance.UpdateHealthUI(local.health, false);
				}
				ApplyInventorySize();
			}
		}

		internal static void ResetEverything()
		{
			Plugin.LocalUpgrades.ResetAll();
			SecondWindActive = false;
			ApplyInventorySize();
			PlayerControllerB local = Local;
			if ((Object)(object)local != (Object)null)
			{
				local.sprintTime = 5f;
				local.health = Mathf.Min(local.health, 100);
				if ((Object)(object)HUDManager.Instance != (Object)null)
				{
					HUDManager.Instance.UpdateHealthUI(local.health, false);
				}
			}
			Plugin.Log.LogInfo((object)"Partida perdida: mejoras y estadísticas reiniciadas.");
		}
	}
	public class UpgradeRuntime : MonoBehaviour
	{
		private void Update()
		{
			PocketFlashlight.Tick();
		}

		private void LateUpdate()
		{
			StatsEffects.EnforceCarryWeight();
			StatsEffects.UpdateWeightLabel();
			StatsEffects.UpdateMeleeLabel();
			StatsEffects.UpdateStaminaBarVisual();
			StatsEffects.UpdateVignettes();
		}
	}
	public class TokenGlow : MonoBehaviour
	{
		private const float FloorIntensity = 320f;

		private const float HeldIntensity = 45f;

		private const float LightRange = 5.5f;

		private static readonly Color Gold = new Color(1f, 0.82f, 0.25f);

		private GrabbableObject _item;

		private Light _light;

		private Transform _beam;

		private Transform _halo;

		private Transform _base;

		private Renderer[] _auraParts;

		private static Material _auraMat;

		private void Start()
		{
			_item = ((Component)this).GetComponent<GrabbableObject>();
			Build();
		}

		private void Build()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0032: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("TokenLight");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = new Vector3(0f, 0.25f, 0f);
			_light = val.AddComponent<Light>();
			_light.type = (LightType)2;
			_light.color = Gold;
			_light.range = 5.5f;
			_light.intensity = 320f;
			_light.shadows = (LightShadows)0;
			SetHdrpIntensity(val, 320f);
			Material auraMaterial = GetAuraMaterial();
			_beam = MakeMeshPart("Beam", BuildTaperedBeamMesh(), auraMaterial, new Vector3(0f, 0f, 0f), Vector3.one);
			_base = MakePart("BaseGlow", (PrimitiveType)2, auraMaterial, new Vector3(0f, 0.012f, 0f), new Vector3(0.55f, 0.01f, 0.55f));
			_halo = MakePart("Halo", (PrimitiveType)2, auraMaterial, new Vector3(0f, 0.22f, 0f), new Vector3(0.38f, 0.005f, 0.38f));
			_auraParts = (Renderer[])(object)new Renderer[3]
			{
				((Component)_beam).GetComponent<Renderer>(),
				((Component)_base).GetComponent<Renderer>(),
				((Component)_halo).GetComponent<Renderer>()
			};
		}

		private static Mesh BuildTaperedBeamMesh()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			Vector3[] array = (Vector3[])(object)new Vector3[16]
			{
				Vector3.zero,
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3),
				new Vector3(0f, 3.1f, 0f)
			};
			for (int i = 0; i < 14; i++)
			{
				float num = (float)i / 14f * MathF.PI * 2f;
				array[i + 1] = new Vector3(Mathf.Cos(num) * 0.17f, 0f, Mathf.Sin(num) * 0.17f);
			}
			List<int> list = new List<int>(84);
			for (int j = 0; j < 14; j++)
			{
				int item = j + 1;
				int item2 = (j + 1) % 14 + 1;
				list.Add(0);
				list.Add(item2);
				list.Add(item);
				list.Add(item);
				list.Add(item2);
				list.Add(15);
			}
			Mesh val = new Mesh
			{
				name = "TokenBeam"
			};
			val.SetVertices(new List<Vector3>(array));
			val.SetTriangles(list, 0);
			val.RecalculateNormals();
			val.RecalculateBounds();
			return val;
		}

		private Transform MakeMeshPart(string name, Mesh mesh, Material mat, Vector3 pos, Vector3 scale)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = pos;
			val.transform.localScale = scale;
			val.AddComponent<MeshFilter>().sharedMesh = mesh;
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterial = mat;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)obj).receiveShadows = false;
			return val.transform;
		}

		private Transform MakePart(string name, PrimitiveType type, Material mat, Vector3 pos, Vector3 scale)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive(type);
			((Object)obj).name = name;
			obj.transform.SetParent(((Component)this).transform, false);
			obj.transform.localPosition = pos;
			obj.transform.localScale = scale;
			Collider component = obj.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			Renderer component2 = obj.GetComponent<Renderer>();
			component2.sharedMaterial = mat;
			component2.shadowCastingMode = (ShadowCastingMode)0;
			component2.receiveShadows = false;
			return obj.transform;
		}

		private void LateUpdate()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_item == (Object)null)
			{
				return;
			}
			bool flag = !_item.isHeld && !_item.isPocketed;
			if (flag && Plugin.TokenGlowEnabled.Value)
			{
				Camera main = Camera.main;
				if ((Object)(object)main != (Object)null)
				{
					Vector3 val = ((Component)main).transform.position - ((Component)this).transform.position;
					if (((Vector3)(ref val)).sqrMagnitude > 2025f)
					{
						flag = false;
					}
				}
			}
			else if (!Plugin.TokenGlowEnabled.Value)
			{
				flag = false;
			}
			if (_auraParts != null)
			{
				Renderer[] auraParts = _auraParts;
				foreach (Renderer val2 in auraParts)
				{
					if ((Object)(object)val2 != (Object)null && val2.enabled != flag)
					{
						val2.enabled = flag;
					}
				}
			}
			if ((Object)(object)_light != (Object)null)
			{
				float num = (flag ? 320f : 45f);
				if (!Mathf.Approximately(_light.intensity, num))
				{
					_light.intensity = num;
					SetHdrpIntensity(((Component)_light).gameObject, num);
				}
			}
			if (flag)
			{
				float time = Time.time;
				float num2 = 1f + Mathf.Sin(time * 2.2f) * 0.06f;
				if ((Object)(object)_beam != (Object)null)
				{
					_beam.localScale = new Vector3(num2, 1f, num2);
					_beam.Rotate(Vector3.up, 25f * Time.deltaTime, (Space)1);
				}
				if ((Object)(object)_halo != (Object)null)
				{
					float num3 = Mathf.PingPong(time * 0.35f, 0.55f);
					_halo.localPosition = new Vector3(0f, 0.18f + num3, 0f);
					float num4 = Mathf.Lerp(0.42f, 0.18f, num3 / 0.55f);
					_halo.localScale = new Vector3(num4, 0.005f, num4);
					_halo.Rotate(Vector3.up, -40f * Time.deltaTime, (Space)1);
				}
				if ((Object)(object)_base != (Object)null)
				{
					_base.localScale = new Vector3(0.55f * num2, 0.01f, 0.55f * num2);
				}
			}
		}

		private static Material GetAuraMaterial()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0088: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_auraMat != (Object)null)
			{
				return _auraMat;
			}
			_auraMat = new Material(Shader.Find("HDRP/Unlit") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default"));
			Color val = default(Color);
			((Color)(ref val))..ctor(Gold.r, Gold.g, Gold.b, 0.12f);
			if (_auraMat.HasProperty("_UnlitColor"))
			{
				_auraMat.SetColor("_UnlitColor", val);
			}
			if (_auraMat.HasProperty("_BaseColor"))
			{
				_auraMat.SetColor("_BaseColor", val);
			}
			if (_auraMat.HasProperty("_Color"))
			{
				_auraMat.SetColor("_Color", val);
			}
			if (_auraMat.HasProperty("_EmissiveColor"))
			{
				if (_auraMat.HasProperty("_UseEmissiveIntensity"))
				{
					_auraMat.SetFloat("_UseEmissiveIntensity", 0f);
				}
				_auraMat.SetColor("_EmissiveColor", Gold * 3.2f);
			}
			if (_auraMat.HasProperty("_SurfaceType"))
			{
				_auraMat.SetFloat("_SurfaceType", 1f);
			}
			if (_auraMat.HasProperty("_BlendMode"))
			{
				_auraMat.SetFloat("_BlendMode", 1f);
			}
			if (_auraMat.HasProperty("_ZWrite"))
			{
				_auraMat.SetFloat("_ZWrite", 0f);
			}
			if (_auraMat.HasProperty("_CullMode"))
			{
				_auraMat.SetFloat("_CullMode", 0f);
			}
			if (_auraMat.HasProperty("_SrcBlend"))
			{
				_auraMat.SetFloat("_SrcBlend", 5f);
			}
			if (_auraMat.HasProperty("_DstBlend"))
			{
				_auraMat.SetFloat("_DstBlend", 1f);
			}
			_auraMat.renderQueue = 3000;
			_auraMat.EnableKeyword("_EMISSION");
			_auraMat.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
			_auraMat.EnableKeyword("_BLENDMODE_ADD");
			return _auraMat;
		}

		private static void SetHdrpIntensity(GameObject lightGo, float lumens)
		{
			Component[] components = lightGo.GetComponents<Component>();
			foreach (Component val in components)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Type type = ((object)val).GetType();
				if (!(type.Name != "HDAdditionalLightData"))
				{
					PropertyInfo property = type.GetProperty("intensity");
					if (property != null && property.CanWrite)
					{
						property.SetValue(val, lumens);
					}
					break;
				}
			}
		}
	}
	internal static class TokenItem
	{
		internal static Item Token;

		internal static GameObject TokenPrefab;

		private static GameObject _prefabContainer;

		private static Sprite _icon;

		private static bool _enriched;

		private static TerminalNode _buyNode1;

		private static TerminalNode _buyNode2;

		internal static bool IsToken(GrabbableObject obj)
		{
			if ((Object)(object)obj != (Object)null && (Object)(object)Token != (Object)null)
			{
				return (Object)(object)obj.itemProperties == (Object)(object)Token;
			}
			return false;
		}

		internal static int CountInInventory(PlayerControllerB player)
		{
			if ((Object)(object)player == (Object)null || player.ItemSlots == null)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < player.ItemSlots.Length; i++)
			{
				if (IsToken(player.ItemSlots[i]))
				{
					num++;
				}
			}
			return num;
		}

		internal static bool ConsumeOne(PlayerControllerB player)
		{
			if ((Object)(object)player == (Object)null || player.ItemSlots == null)
			{
				return false;
			}
			int num = -1;
			if (player.currentItemSlot >= 0 && player.currentItemSlot < player.ItemSlots.Length && IsToken(player.ItemSlots[player.currentItemSlot]))
			{
				num = player.currentItemSlot;
			}
			else
			{
				for (int i = 0; i < player.ItemSlots.Length; i++)
				{
					if (IsToken(player.ItemSlots[i]))
					{
						num = i;
						break;
					}
				}
			}
			if (num < 0)
			{
				return false;
			}
			player.DestroyItemInSlotAndSync(num);
			return true;
		}

		internal static void CreateEarly()
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Token != (Object)null))
			{
				Token = ScriptableObject.CreateInstance<Item>();
				((Object)Token).name = "UpgradeTokenItem";
				Token.itemName = "Ficha";
				Token.itemId = 613001;
				Token.isScrap = true;
				Token.twoHanded = false;
				Token.twoHandedAnimation = false;
				Token.weight = 1f;
				Token.creditsWorth = Plugin.TokenBuyPrice.Value;
				Token.minValue = Plugin.TokenSellValue.Value;
				Token.maxValue = Plugin.TokenSellValue.Value;
				Token.requiresBattery = false;
				Token.saveItemVariable = false;
				Token.isConductiveMetal = true;
				Token.itemSpawnsOnGround = true;
				Token.canBeGrabbedBeforeGameStart = true;
				Token.highestSalePercentage = 100;
				Token.itemIcon = GetIcon();
				Token.spawnPositionTypes = new List<ItemGroup>();
				Token.toolTips = new string[0];
				Token.restingRotation = new Vector3(0f, 0f, 0f);
				TokenPrefab = BuildPrefab();
				Token.spawnPrefab = TokenPrefab;
				Plugin.Log.LogInfo((object)"Ficha de mejora creada.");
			}
		}

		private static GameObject BuildPrefab()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			_prefabContainer = new GameObject("UpgradableStats_Prefabs");
			_prefabContainer.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)_prefabContainer);
			((Object)_prefabContainer).hideFlags = (HideFlags)61;
			GameObject val = new GameObject("UpgradeTokenProp");
			val.transform.SetParent(_prefabContainer.transform, false);
			val.tag = "PhysicsProp";
			val.layer = 6;
			NetworkObject obj = val.AddComponent<NetworkObject>();
			byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("com.CommanderMechavala.upgradablestatsUpgradeTokenProp"));
			obj.GlobalObjectIdHash = BitConverter.ToUInt32(value, 0);
			GameObject val2 = new GameObject("Gema");
			val2.transform.SetParent(val.transform, false);
			val2.layer = 6;
			val2.transform.localScale = new Vector3(1f, 0.45f, 1f);
			val2.AddComponent<MeshFilter>().sharedMesh = BuildIcosahedronMesh(0.09f);
			((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = UpgradesMachine.MakeMaterial(new Color(0.83f, 0.62f, 0.14f), 1f, 0.62f);
			val.AddComponent<BoxCollider>().size = new Vector3(0.16f, 0.09f, 0.16f);
			AudioSource obj2 = val.AddComponent<AudioSource>();
			obj2.playOnAwake = false;
			obj2.spatialBlend = 1f;
			PhysicsProp obj3 = val.AddComponent<PhysicsProp>();
			((GrabbableObject)obj3).grabbable = true;
			((GrabbableObject)obj3).grabbableToEnemies = true;
			((GrabbableObject)obj3).itemProperties = Token;
			val.AddComponent<TokenShipAnchor>();
			GameObject val3 = new GameObject("ScanNode");
			val3.transform.SetParent(val.transform, false);
			int num = LayerMask.NameToLayer("ScanNode");
			val3.layer = ((num >= 0) ? num : 22);
			val3.AddComponent<BoxCollider>().size = Vector3.one * 0.6f;
			ScanNodeProperties obj4 = val3.AddComponent<ScanNodeProperties>();
			obj4.headerText = "Ficha de mejora";
			obj4.subText = "";
			obj4.nodeType = 2;
			obj4.minRange = 1;
			obj4.maxRange = 13;
			obj4.requiresLineOfSight = true;
			return val;
		}

		private static Mesh BuildIcosahedronMesh(float radius)
		{
			//IL_002b: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00d0: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Expected O, but got Unknown
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			float num = (1f + Mathf.Sqrt(5f)) / 2f;
			Vector3[] array = (Vector3[])(object)new Vector3[12]
			{
				new Vector3(-1f, num, 0f),
				new Vector3(1f, num, 0f),
				new Vector3(-1f, 0f - num, 0f),
				new Vector3(1f, 0f - num, 0f),
				new Vector3(0f, -1f, num),
				new Vector3(0f, 1f, num),
				new Vector3(0f, -1f, 0f - num),
				new Vector3(0f, 1f, 0f - num),
				new Vector3(num, 0f, -1f),
				new Vector3(num, 0f, 1f),
				new Vector3(0f - num, 0f, -1f),
				new Vector3(0f - num, 0f, 1f)
			};
			int[][] obj = new int[20][]
			{
				new int[3] { 0, 11, 5 },
				new int[3] { 0, 5, 1 },
				new int[3] { 0, 1, 7 },
				new int[3] { 0, 7, 10 },
				new int[3] { 0, 10, 11 },
				new int[3] { 1, 5, 9 },
				new int[3] { 5, 11, 4 },
				new int[3] { 11, 10, 2 },
				new int[3] { 10, 7, 6 },
				new int[3] { 7, 1, 8 },
				new int[3] { 3, 9, 4 },
				new int[3] { 3, 4, 2 },
				new int[3] { 3, 2, 6 },
				new int[3] { 3, 6, 8 },
				new int[3] { 3, 8, 9 },
				new int[3] { 4, 9, 5 },
				new int[3] { 2, 4, 11 },
				new int[3] { 6, 2, 10 },
				new int[3] { 8, 6, 7 },
				new int[3] { 9, 8, 1 }
			};
			List<Vector3> list = new List<Vector3>(60);
			List<int> list2 = new List<int>(60);
			int[][] array2 = obj;
			foreach (int[] array3 in array2)
			{
				foreach (int num2 in array3)
				{
					list2.Add(list.Count);
					list.Add(((Vector3)(ref array[num2])).normalized * radius);
				}
			}
			Mesh val = new Mesh
			{
				name = "FichaIcosaedro"
			};
			val.SetVertices(list);
			val.SetTriangles(list2, 0);
			val.RecalculateNormals();
			val.RecalculateBounds();
			return val;
		}

		private static Sprite GetIcon()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_00e1: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_icon != (Object)null)
			{
				return _icon;
			}
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.9f, 0.72f, 0.2f, 1f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.55f, 0.4f, 0.08f, 1f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0f, 0f, 0f, 0f);
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = Mathf.Abs(j - 32) + Mathf.Abs(i - 32);
					val.SetPixel(j, i, (num <= 26) ? ((num > 22) ? val3 : val2) : val4);
				}
			}
			val.Apply();
			_icon = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f);
			return _icon;
		}

		internal static void RegisterNetworkPrefab()
		{
			if (!((Object)(object)TokenPrefab == (Object)null) && !((Object)(object)NetworkManager.Singleton == (Object)null) && !NetworkManager.Singleton.NetworkConfig.Prefabs.Contains(TokenPrefab))
			{
				NetworkManager.Singleton.AddNetworkPrefab(TokenPrefab);
				Plugin.Log.LogInfo((object)"Prefab de la Ficha registrado en red.");
			}
		}

		internal static void SetupEarlyInGame()
		{
			if (!((Object)(object)Token == (Object)null) && !((Object)(object)StartOfRound.Instance == (Object)null))
			{
				EnrichFromGift();
				RegisterInAllItemsList();
			}
		}

		internal static void SetupInGame()
		{
			if (!((Object)(object)Token == (Object)null) && !((Object)(object)StartOfRound.Instance == (Object)null))
			{
				SetupEarlyInGame();
				AddToLevels();
				Terminal val = Object.FindObjectOfType<Terminal>();
				if ((Object)(object)val != (Object)null)
				{
					RegisterInShop(val);
				}
				else
				{
					Plugin.Log.LogWarning((object)"No encontré la Terminal para registrar la compra de fichas.");
				}
			}
		}

		private static void EnrichFromGift()
		{
			if (!_enriched)
			{
				List<Item> itemsList = StartOfRound.Instance.allItemsList.itemsList;
				Item val = ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item x) => (Object)(object)x != (Object)null && (Object)(object)x.spawnPrefab != (Object)null && (Object)(object)x.spawnPrefab.GetComponent<GiftBoxItem>() != (Object)null)) ?? ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item x) => (Object)(object)x != (Object)null && x.itemName == "Gift"));
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogWarning((object)"No encontré el ítem 'Gift'; la Ficha usará valores por defecto.");
					return;
				}
				Token.spawnPositionTypes = new List<ItemGroup>(val.spawnPositionTypes);
				Token.grabSFX = val.grabSFX;
				Token.dropSFX = val.dropSFX;
				Token.pocketSFX = val.pocketSFX;
				Token.throwSFX = val.throwSFX;
				Token.grabAnim = val.grabAnim;
				Token.pocketAnim = val.pocketAnim;
				Token.grabAnimationTime = val.grabAnimationTime;
				Token.floorYOffset = val.floorYOffset;
				_enriched = true;
			}
		}

		private static void RegisterInAllItemsList()
		{
			List<Item> itemsList = StartOfRound.Instance.allItemsList.itemsList;
			if (!itemsList.Contains(Token))
			{
				itemsList.Add(Token);
			}
		}

		private static void AddToLevels()
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				if (!((Object)(object)val == (Object)null) && val.spawnableScrap != null && !val.spawnableScrap.Any((SpawnableItemWithRarity s) => s != null && (Object)(object)s.spawnableItem == (Object)(object)Token))
				{
					int num = ((IEnumerable<SpawnableItemWithRarity>)val.spawnableScrap).FirstOrDefault((Func<SpawnableItemWithRarity, bool>)((SpawnableItemWithRarity s) => s != null && (Object)(object)s.spawnableItem != (Object)null && (s.spawnableItem.itemName == "Gift" || ((Object)(object)s.spawnableItem.spawnPrefab != (Object)null && (Object)(object)s.spawnableItem.spawnPrefab.GetComponent<GiftBoxItem>() != (Object)null))))?.rarity ?? Plugin.TokenFallbackRarity.Value;
					if (num > 0)
					{
						val.spawnableScrap.Add(new SpawnableItemWithRarity(Token, num));
					}
				}
			}
			Plugin.Log.LogInfo((object)"Ficha añadida a las lunas con la rareza del Regalo.");
		}

		private static void RegisterInShop(Terminal terminal)
		{
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Expected O, but got Unknown
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Expected O, but got Unknown
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Expected O, but got Unknown
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Expected O, but got Unknown
			List<Item> list = terminal.buyableItemsList.ToList();
			if (!list.Contains(Token))
			{
				list.Add(Token);
			}
			terminal.buyableItemsList = list.ToArray();
			int buyItemIndex = list.IndexOf(Token);
			int num = terminal.buyableItemsList.Length + terminal.buyableVehicles.Length;
			if (terminal.itemSalesPercentages == null || terminal.itemSalesPercentages.Length < num)
			{
				int num2 = ((terminal.itemSalesPercentages != null) ? terminal.itemSalesPercentages.Length : 0);
				int[] array = terminal.itemSalesPercentages ?? new int[0];
				Array.Resize(ref array, num);
				for (int i = num2; i < num; i++)
				{
					array[i] = 100;
				}
				terminal.itemSalesPercentages = array;
				Plugin.Log.LogInfo((object)$"Array de ofertas del terminal ampliado a {num}.");
			}
			if ((Object)(object)_buyNode1 != (Object)null && (Object)(object)_buyNode2 != (Object)null)
			{
				_buyNode1.buyItemIndex = buyItemIndex;
				_buyNode2.buyItemIndex = buyItemIndex;
			}
			else if (!terminal.terminalNodes.allKeywords.Any((TerminalKeyword k) => (Object)(object)k != (Object)null && k.word == "ficha"))
			{
				TerminalKeyword val = terminal.terminalNodes.allKeywords.First((TerminalKeyword k) => k.word == "buy");
				TerminalKeyword val2 = terminal.terminalNodes.allKeywords.First((TerminalKeyword k) => k.word == "confirm");
				TerminalKeyword val3 = terminal.terminalNodes.allKeywords.First((TerminalKeyword k) => k.word == "deny");
				TerminalKeyword val4 = terminal.terminalNodes.allKeywords.First((TerminalKeyword k) => k.word == "info");
				TerminalNode result = val.compatibleNouns[0].result.terminalOptions[1].result;
				int value = Plugin.TokenBuyPrice.Value;
				_buyNode2 = ScriptableObject.CreateInstance<TerminalNode>();
				((Object)_buyNode2).name = "FichaBuyNode2";
				_buyNode2.displayText = "Ordered [variableAmount] Fichas. Your new balance is [playerCredits].\n\nLa maquina de mejoras espera tu proxima visita.\r\n\r\n";
				_buyNode2.clearPreviousText = true;
				_buyNode2.maxCharactersToType = 15;
				_buyNode2.buyItemIndex = buyItemIndex;
				_buyNode2.isConfirmationNode = false;
				_buyNode2.itemCost = value;
				_buyNode2.playSyncedClip = 0;
				_buyNode1 = ScriptableObject.CreateInstance<TerminalNode>();
				((Object)_buyNode1).name = "FichaBuyNode1";
				_buyNode1.displayText = "You have requested to order Fichas. Amount: [variableAmount].\nTotal cost of items: [totalCost].\n\nPlease CONFIRM or DENY.\r\n\r\n";
				_buyNode1.clearPreviousText = true;
				_buyNode1.maxCharactersToType = 35;
				_buyNode1.buyItemIndex = buyItemIndex;
				_buyNode1.isConfirmationNode = true;
				_buyNode1.overrideOptions = true;
				_buyNode1.itemCost = value;
				_buyNode1.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2]
				{
					new CompatibleNoun(val2, _buyNode2),
					new CompatibleNoun(val3, result)
				};
				TerminalKeyword val5 = ScriptableObject.CreateInstance<TerminalKeyword>();
				((Object)val5).name = "FichaKeyword";
				val5.word = "ficha";
				val5.isVerb = false;
				val5.defaultVerb = val;
				List<TerminalKeyword> list2 = terminal.terminalNodes.allKeywords.ToList();
				list2.Add(val5);
				terminal.terminalNodes.allKeywords = list2.ToArray();
				List<CompatibleNoun> list3 = val.compatibleNouns.ToList();
				list3.Add(new CompatibleNoun(val5, _buyNode1));
				val.compatibleNouns = list3.ToArray();
				TerminalNode val6 = ScriptableObject.CreateInstance<TerminalNode>();
				((Object)val6).name = "FichaInfoNode";
				val6.displayText = "FICHA\nMoneda romboidal de oro.\nInsertala en la maquina de mejoras de la nave para potenciar tus habilidades... o vendela a la Compania.\n\n";
				val6.clearPreviousText = true;
				val6.maxCharactersToType = 25;
				List<CompatibleNoun> list4 = val4.compatibleNouns.ToList();
				list4.Add(new CompatibleNoun(val5, val6));
				val4.compatibleNouns = list4.ToArray();
				Plugin.Log.LogInfo((object)$"Ficha en la terminal: \"buy ficha\" por {value} créditos.");
			}
		}
	}
	public class TokenShipAnchor : MonoBehaviour
	{
		private GrabbableObject _item;

		private float _timer;

		private void Start()
		{
			_item = ((Component)this).GetComponent<GrabbableObject>();
		}

		private void LateUpdate()
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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)
			if ((Object)(object)_item == (Object)null || _item.isHeld || _item.isPocketed || _item.isHeldByEnemy)
			{
				return;
			}
			_timer += Time.deltaTime;
			if (_timer < 0.25f)
			{
				return;
			}
			_timer = 0f;
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Transform val = (_item.isInElevator ? instance.elevatorTransform : inst