Decompiled source of UpgradableStats v1.0.0

BepInEx\plugins\UpgradableStats.dll

Decompiled 9 hours 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.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.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Upgradable Stats")]
[assembly: AssemblyTitle("UpgradableStats")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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(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 && 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(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);
				}
			}
		}

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

		public const string PluginName = "Upgradable Stats";

		public const string PluginVersion = "1.0.0";

		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<bool> StaminaBarVisual;

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

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

		private void Awake()
		{
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Maquina", "DesplazamientoX", -1.6f, "Posición respecto al terminal: a los lados (negativo = izquierda).");
			OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Maquina", "DesplazamientoY", 0f, "Posición respecto al terminal: altura.");
			OffsetZ = ((BaseUnityPlugin)this).Config.Bind<float>("Maquina", "DesplazamientoZ", 0f, "Posición respecto al terminal: adelante/atrás.");
			MachineRotationY = ((BaseUnityPlugin)this).Config.Bind<float>("Maquina", "RotacionY", 0f, "Giro de la máquina en grados.");
			FreeUpgrades = ((BaseUnityPlugin)this).Config.Bind<bool>("Fichas", "MejorasGratis", false, "true = las mejoras no consumen fichas (solo para probar).");
			TokenBuyPrice = ((BaseUnityPlugin)this).Config.Bind<int>("Fichas", "PrecioCompra", 450, "Créditos que cuesta comprar una ficha en la terminal (\"buy ficha\").");
			TokenSellValue = ((BaseUnityPlugin)this).Config.Bind<int>("Fichas", "ValorChatarra", 200, "Valor de chatarra de la ficha (en el suelo y al comprarla): lo que paga la Compañía.");
			TokenFallbackRarity = ((BaseUnityPlugin)this).Config.Bind<int>("Fichas", "RarezaRespaldo", 8, "Rareza usada solo si una luna no tiene Regalo del que copiar la suya.");
			StaminaBarVisual = ((BaseUnityPlugin)this).Config.Bind<bool>("Interfaz", "BarraEstaminaVisual", true, "Muestra la barra verde extra de estamina (25/50/75% según tus tokens).");
			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.0.0 cargado correctamente!");
			Log.LogInfo((object)"Fase 3: fichas (aparecen como el Regalo, \"buy ficha\" 450, venta 400) + efectos reales.");
		}
	}
	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 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()
		{
			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)
			{
				CreateStaminaExtraBar(local);
			}
			if (!((Object)(object)_staminaExtraBar == (Object)null))
			{
				float num = local.sprintMeter * staminaMultiplier;
				local.sprintMeterUI.fillAmount = Mathf.Min(num, 1f);
				_staminaExtraBar.fillAmount = Mathf.Clamp(num - 1f, 0f, staminaMultiplier - 1f);
				((Behaviour)_staminaExtraBar).enabled = true;
			}
		}

		private static void CreateStaminaExtraBar(PlayerControllerB p)
		{
			//IL_00a8: 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_00e0: 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)
			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;
			RectTransform component2 = val.GetComponent<RectTransform>();
			RectTransform rectTransform = ((Graphic)p.sprintMeterUI).rectTransform;
			component2.anchoredPosition = rectTransform.anchoredPosition;
			((Transform)component2).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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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)
			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;
			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 obj = Object.Instantiate<GameObject>(((Component)rectTransform).gameObject, ((Transform)rectTransform).parent);
				((Object)obj).name = $"Slot{i}[UpgradableStats]";
				obj.GetComponent<RectTransform>().anchoredPosition = rectTransform.anchoredPosition + val * (float)(i - num + 1);
				Image component = obj.GetComponent<Image>();
				Image val2 = null;
				Image[] componentsInChildren = obj.GetComponentsInChildren<Image>(true);
				foreach (Image val3 in componentsInChildren)
				{
					if ((Object)(object)val3 != (Object)(object)component)
					{
						val2 = val3;
						break;
					}
				}
				if ((Object)(object)val2 != (Object)null)
				{
					val2.sprite = null;
					((Behaviour)val2).enabled = false;
				}
				list.Add(component);
				list2.Add(((Object)(object)val2 != (Object)null) ? val2 : component);
			}
			instance.itemSlotIconFrames = list.ToArray();
			instance.itemSlotIcons = list2.ToArray();
		}
	}
	public class UpgradeRuntime : MonoBehaviour
	{
		private void LateUpdate()
		{
			StatsEffects.EnforceCarryWeight();
			StatsEffects.UpdateWeightLabel();
			StatsEffects.UpdateMeleeLabel();
			StatsEffects.UpdateStaminaBarVisual();
			StatsEffects.UpdateVignettes();
		}
	}
	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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: 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.martinchavez.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;
			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_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Expected O, but got Unknown
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Expected O, but got Unknown
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Expected O, but got Unknown
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: 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);
			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 enum UpgradeSkill
	{
		Health,
		Stamina,
		Strength,
		Inventory
	}
	public static class UpgradeInfo
	{
		public const int SkillCount = 4;

		public static int MaxLevel(UpgradeSkill skill)
		{
			if (skill != UpgradeSkill.Health)
			{
				return 3;
			}
			return 4;
		}

		public static string DisplayName(UpgradeSkill skill)
		{
			return skill switch
			{
				UpgradeSkill.Health => "HEALTH", 
				UpgradeSkill.Stamina => "STAMINA", 
				UpgradeSkill.Strength => "STRENGTH", 
				UpgradeSkill.Inventory => "INVENTORY", 
				_ => "???", 
			};
		}

		public static string NextEffect(UpgradeSkill skill, int currentLevel)
		{
			if (currentLevel >= MaxLevel(skill))
			{
				return "MAX LEVEL REACHED";
			}
			switch (skill)
			{
			case UpgradeSkill.Health:
				if (currentLevel >= 3)
				{
					return "SECOND WIND: survive a lethal hit with 1 HP";
				}
				return "+33% max health";
			case UpgradeSkill.Stamina:
				return "+25% stamina bar";
			case UpgradeSkill.Strength:
				return "-25% carry weight + 50% melee damage";
			case UpgradeSkill.Inventory:
				return "+1 inventory slot";
			default:
				return "";
			}
		}
	}
	public class PlayerUpgrades
	{
		private readonly int[] _levels = new int[4];

		public float HealthMultiplier => 1f + 0.33f * (float)Mathf.Min(GetLevel(UpgradeSkill.Health), 3);

		public bool HasSecondWind => GetLevel(UpgradeSkill.Health) >= 4;

		public float StaminaMultiplier => 1f + 0.25f * (float)GetLevel(UpgradeSkill.Stamina);

		public float MeleeMultiplier => 1f + 0.5f * (float)GetLevel(UpgradeSkill.Strength);

		public int ExtraSlots => GetLevel(UpgradeSkill.Inventory);

		public int GetLevel(UpgradeSkill skill)
		{
			return _levels[(int)skill];
		}

		public bool CanUpgrade(UpgradeSkill skill)
		{
			return GetLevel(skill) < UpgradeInfo.MaxLevel(skill);
		}

		public bool TryUpgrade(UpgradeSkill skill)
		{
			if (!CanUpgrade(skill))
			{
				return false;
			}
			_levels[(int)skill]++;
			return true;
		}

		public void ResetAll()
		{
			for (int i = 0; i < _levels.Length; i++)
			{
				_levels[i] = 0;
			}
		}

		public int[] ExportLevels()
		{
			return (int[])_levels.Clone();
		}

		public void ImportLevels(int[] levels)
		{
			if (levels != null)
			{
				for (int i = 0; i < _levels.Length && i < levels.Length; i++)
				{
					_levels[i] = Mathf.Clamp(levels[i], 0, UpgradeInfo.MaxLevel((UpgradeSkill)i));
				}
			}
		}
	}
	public class UpgradeMenuUI : MonoBehaviour
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__Close;
		}

		private GameObject _root;

		private PlayerControllerB _player;

		private readonly TextMeshProUGUI[] _effectLabels = (TextMeshProUGUI[])(object)new TextMeshProUGUI[4];

		private readonly TextMeshProUGUI[] _buttonLabels = (TextMeshProUGUI[])(object)new TextMeshProUGUI[4];

		private readonly Button[] _buttons = (Button[])(object)new Button[4];

		private readonly Image[][] _pips = new Image[4][];

		private TextMeshProUGUI _tokensLabel;

		private TextMeshProUGUI _statusLabel;

		private TextMeshProUGUI _subtitle;

		private static readonly Color BronzeGreen = new Color(0.24f, 0.4f, 0.31f, 1f);

		private static readonly Color Bronze = new Color(0.72f, 0.53f, 0.22f, 1f);

		private static readonly Color PanelBg = new Color(0.05f, 0.07f, 0.06f, 0.94f);

		private static readonly Color PipEmpty = new Color(0.16f, 0.18f, 0.16f, 1f);

		private static readonly Color TextDim = new Color(0.62f, 0.68f, 0.62f, 1f);

		private static readonly Color WarnRed = new Color(0.85f, 0.35f, 0.25f, 1f);

		private static readonly Color OkGreen = new Color(0.45f, 0.85f, 0.45f, 1f);

		private static TMP_FontAsset _cachedFont;

		public static UpgradeMenuUI Instance { get; private set; }

		public static bool IsOpen
		{
			get
			{
				if ((Object)(object)Instance != (Object)null && (Object)(object)Instance._root != (Object)null)
				{
					return Instance._root.activeSelf;
				}
				return false;
			}
		}

		public static void Open(PlayerControllerB player)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				GameObject val = new GameObject("UpgradableStats_MenuHost");
				Object.DontDestroyOnLoad((Object)val);
				Instance = val.AddComponent<UpgradeMenuUI>();
				Instance.Build();
			}
			Instance._player = player;
			Instance._root.SetActive(true);
			Instance.SetStatus("", Color.clear);
			Instance.Refresh();
			player.inSpecialMenu = true;
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			if ((Object)(object)player.cursorIcon != (Object)null)
			{
				((Behaviour)player.cursorIcon).enabled = false;
			}
			if ((Object)(object)player.cursorTip != (Object)null)
			{
				((TMP_Text)player.cursorTip).text = "";
			}
			player.hoveringOverTrigger = null;
		}

		public static void Close()
		{
			if (IsOpen)
			{
				Instance._root.SetActive(false);
				PlayerControllerB player = Instance._player;
				if ((Object)(object)player != (Object)null)
				{
					player.inSpecialMenu = false;
					Cursor.lockState = (CursorLockMode)1;
					Cursor.visible = false;
				}
				Instance._player = null;
			}
		}

		private void OnUpgradeClicked(UpgradeSkill skill)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			PlayerUpgrades localUpgrades = Plugin.LocalUpgrades;
			if (!localUpgrades.CanUpgrade(skill))
			{
				SetStatus(UpgradeInfo.DisplayName(skill) + " is already at max level.", TextDim);
				return;
			}
			if (!Plugin.FreeUpgrades.Value && !TokenItem.ConsumeOne(_player))
			{
				SetStatus("YOU NEED A FICHA — found on moons, or type \"buy ficha\" in the terminal.", WarnRed);
				return;
			}
			localUpgrades.TryUpgrade(skill);
			StatsEffects.OnUpgraded(skill);
			UpgradeSync.OnLocalLevelsChanged();
			int level = localUpgrades.GetLevel(skill);
			SetStatus($"{UpgradeInfo.DisplayName(skill)} upgraded to level {level}.", OkGreen);
			Plugin.Log.LogInfo((object)$"Mejora aplicada: {UpgradeInfo.DisplayName(skill)} -> nivel {level}");
			Refresh();
		}

		private void Refresh()
		{
			//IL_005d: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			PlayerUpgrades localUpgrades = Plugin.LocalUpgrades;
			bool value = Plugin.FreeUpgrades.Value;
			int num = TokenItem.CountInInventory(_player);
			((TMP_Text)_tokensLabel).text = (value ? "TEST MODE: FREE UPGRADES" : $"FICHAS IN YOUR INVENTORY: {num}");
			((Graphic)_tokensLabel).color = (value ? TextDim : ((num > 0) ? Bronze : TextDim));
			((TMP_Text)_subtitle).text = (value ? "UPGRADE MACHINE  //  CONFIG: MejorasGratis = true" : "UPGRADE MACHINE  //  1 FICHA PER UPGRADE");
			for (int i = 0; i < 4; i++)
			{
				UpgradeSkill skill = (UpgradeSkill)i;
				int level = localUpgrades.GetLevel(skill);
				bool flag = localUpgrades.CanUpgrade(skill);
				for (int j = 0; j < _pips[i].Length; j++)
				{
					((Graphic)_pips[i][j]).color = ((j < level) ? Bronze : PipEmpty);
				}
				((TMP_Text)_effectLabels[i]).text = UpgradeInfo.NextEffect(skill, level);
				((Selectable)_buttons[i]).interactable = flag;
				((TMP_Text)_buttonLabels[i]).text = ((!flag) ? "MAX" : (value ? "UPGRADE" : "UPGRADE · 1 FICHA"));
				Image component = ((Component)_buttons[i]).GetComponent<Image>();
				if ((Object)(object)component != (Object)null)
				{
					((Graphic)component).color = (Color)(flag ? BronzeGreen : new Color(0.12f, 0.13f, 0.12f));
				}
			}
		}

		private void SetStatus(string text, Color color)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)_statusLabel).text = text;
			((Graphic)_statusLabel).color = color;
		}

		private void Build()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_005f: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00e6: 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_010b: 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)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: 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_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Expected O, but got Unknown
			_root = new GameObject("UpgradeCanvas");
			_root.transform.SetParent(((Component)this).transform, false);
			Canvas obj = _root.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 1000;
			CanvasScaler obj2 = _root.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			_root.AddComponent<GraphicRaycaster>();
			if ((Object)(object)EventSystem.current == (Object)null)
			{
				Plugin.Log.LogWarning((object)"No hay EventSystem en la escena: los botones podrían no responder.");
			}
			RectTransform val = NewRect("Panel", _root.transform, new Vector2(940f, 640f), Vector2.zero);
			AddImage(val, PanelBg);
			AddImage(NewRect("BarraSup", (Transform)(object)val, new Vector2(940f, 6f), new Vector2(0f, 317f)), Bronze);
			AddImage(NewRect("BarraInf", (Transform)(object)val, new Vector2(940f, 6f), new Vector2(0f, -317f)), Bronze);
			AddText((Transform)(object)val, "Titulo", "UPGRADES", new Vector2(600f, 60f), new Vector2(0f, 265f), 40f, Bronze, (TextAlignmentOptions)514);
			_subtitle = AddText((Transform)(object)val, "Sub", "UPGRADE MACHINE", new Vector2(900f, 30f), new Vector2(0f, 225f), 18f, TextDim, (TextAlignmentOptions)514);
			_tokensLabel = AddText((Transform)(object)val, "Fichas", "", new Vector2(900f, 30f), new Vector2(0f, 193f), 20f, Bronze, (TextAlignmentOptions)514);
			for (int i = 0; i < 4; i++)
			{
				BuildSkillRow(val, (UpgradeSkill)i, 128f - (float)i * 92f);
			}
			_statusLabel = AddText((Transform)(object)val, "Estado", "", new Vector2(900f, 30f), new Vector2(0f, -245f), 17f, TextDim, (TextAlignmentOptions)514);
			ButtonClickedEvent onClick = AddButton((Transform)(object)val, "Cerrar", "CLOSE  [ESC]", new Vector2(260f, 46f), new Vector2(0f, -285f), 20f).onClick;
			object obj3 = <>O.<0>__Close;
			if (obj3 == null)
			{
				UnityAction val2 = Close;
				<>O.<0>__Close = val2;
				obj3 = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj3);
		}

		private void BuildSkillRow(RectTransform parent, UpgradeSkill skill, float y)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_009d: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			AddText((Transform)(object)parent, $"Nombre{(int)skill}", UpgradeInfo.DisplayName(skill), new Vector2(260f, 40f), new Vector2(-320f, y + 12f), 26f, Color.white, (TextAlignmentOptions)513);
			_effectLabels[(int)skill] = AddText((Transform)(object)parent, $"Efecto{(int)skill}", "", new Vector2(560f, 28f), new Vector2(-170f, y - 18f), 16f, TextDim, (TextAlignmentOptions)513);
			int num = UpgradeInfo.MaxLevel(skill);
			_pips[(int)skill] = (Image[])(object)new Image[num];
			for (int i = 0; i < num; i++)
			{
				RectTransform rt = NewRect($"Pip{(int)skill}_{i}", (Transform)(object)parent, new Vector2(26f, 26f), new Vector2(50f + (float)i * 34f, y + 12f));
				_pips[(int)skill][i] = AddImage(rt, PipEmpty);
			}
			Button val = AddButton((Transform)(object)parent, $"Btn{(int)skill}", "MEJORAR", new Vector2(230f, 52f), new Vector2(330f, y), 18f);
			_buttons[(int)skill] = val;
			_buttonLabels[(int)skill] = ((Component)val).GetComponentInChildren<TextMeshProUGUI>();
			UpgradeSkill captured = skill;
			((UnityEvent)val.onClick).AddListener((UnityAction)delegate
			{
				OnUpgradeClicked(captured);
			});
		}

		private static RectTransform NewRect(string name, Transform parent, Vector2 size, Vector2 anchoredPos)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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)
			RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
			((Transform)component).SetParent(parent, false);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			component.pivot = val;
			Vector2 anchorMin = (component.anchorMax = val);
			component.anchorMin = anchorMin;
			component.sizeDelta = size;
			component.anchoredPosition = anchoredPos;
			return component;
		}

		private static Image AddImage(RectTransform rt, Color color)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Image obj = ((Component)rt).gameObject.AddComponent<Image>();
			((Graphic)obj).color = color;
			return obj;
		}

		private static TextMeshProUGUI AddText(Transform parent, string name, string text, Vector2 size, Vector2 pos, float fontSize, Color color, TextAlignmentOptions align)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = ((Component)NewRect(name, parent, size, pos)).gameObject.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val).text = text;
			((TMP_Text)val).fontSize = fontSize;
			((Graphic)val).color = color;
			((TMP_Text)val).alignment = align;
			((TMP_Text)val).enableWordWrapping = false;
			((Graphic)val).raycastTarget = false;
			TMP_FontAsset font = GetFont();
			if ((Object)(object)font != (Object)null)
			{
				((TMP_Text)val).font = font;
			}
			return val;
		}

		private static Button AddButton(Transform parent, string name, string label, Vector2 size, Vector2 pos, float fontSize)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_004d: 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_0083: 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_009b: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = NewRect(name, parent, size, pos);
			Image targetGraphic = AddImage(val, BronzeGreen);
			Button obj = ((Component)val).gameObject.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)targetGraphic;
			ColorBlock colors = ((Selectable)obj).colors;
			((ColorBlock)(ref colors)).normalColor = Color.white;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1.4f, 1.4f, 1.4f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.7f, 0.7f, 0.7f);
			((ColorBlock)(ref colors)).disabledColor = new Color(0.6f, 0.6f, 0.6f);
			((Selectable)obj).colors = colors;
			AddText((Transform)(object)val, "Label", label, size, Vector2.zero, fontSize, Color.white, (TextAlignmentOptions)514);
			return obj;
		}

		private static TMP_FontAsset GetFont()
		{
			if ((Object)(object)_cachedFont != (Object)null)
			{
				return _cachedFont;
			}
			_cachedFont = Resources.FindObjectsOfTypeAll<TMP_FontAsset>().FirstOrDefault();
			if ((Object)(object)_cachedFont == (Object)null)
			{
				Plugin.Log.LogWarning((object)"No encontré ninguna fuente TMP; los textos podrían no verse.");
			}
			return _cachedFont;
		}
	}
	public class UpgradesMachine : MonoBehaviour
	{
		internal static GameObject MachinePrefab;

		internal static int UnlockableIndex = -1;

		private static GameObject _prefabContainer;

		private const float Scale = 1.18f;

		private InteractTrigger _trigger;

		public static UpgradesMachine Instance { get; private set; }

		public Transform SlotTransform { get; private set; }

		private void Awake()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			Instance = this;
			Transform val = ((Component)this).transform.Find("RanuraHueco");
			if ((Object)(object)val != (Object)null)
			{
				SlotTransform = val;
			}
			_trigger = ((Component)this).GetComponentInChildren<InteractTrigger>();
			if ((Object)(object)_trigger != (Object)null)
			{
				if (_trigger.onInteract == null)
				{
					_trigger.onInteract = new InteractEvent();
				}
				if (_trigger.onInteractEarly == null)
				{
					_trigger.onInteractEarly = new InteractEvent();
				}
				if (_trigger.onInteractEarlyOtherClients == null)
				{
					_trigger.onInteractEarlyOtherClients = new InteractEvent();
				}
				if (_trigger.onStopInteract == null)
				{
					_trigger.onStopInteract = new InteractEvent();
				}
				if (_trigger.onCancelAnimation == null)
				{
					_trigger.onCancelAnimation = new InteractEvent();
				}
				if (_trigger.holdingInteractEvent == null)
				{
					_trigger.holdingInteractEvent = new InteractEventFloat();
				}
				((UnityEvent<PlayerControllerB>)(object)_trigger.onInteract).AddListener((UnityAction<PlayerControllerB>)OnPlayerInteract);
				((MonoBehaviour)this).StartCoroutine(GrabHoverIconWhenReady());
			}
		}

		private IEnumerator GrabHoverIconWhenReady()
		{
			for (int i = 0; i < 40; i++)
			{
				if (!((Object)(object)_trigger.hoverIcon == (Object)null))
				{
					break;
				}
				Terminal val = Object.FindObjectOfType<Terminal>();
				if ((Object)(object)val != (Object)null)
				{
					InteractTrigger component = ((Component)val).GetComponent<InteractTrigger>();
					if ((Object)(object)component != (Object)null)
					{
						_trigger.hoverIcon = component.hoverIcon;
					}
					break;
				}
				yield return (object)new WaitForSeconds(0.5f);
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void OnPlayerInteract(PlayerControllerB player)
		{
			if (!((Object)(object)player == (Object)null) && !UpgradeMenuUI.IsOpen)
			{
				UpgradeMenuUI.Open(player);
			}
		}

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

		internal static void RegisterUnlockable()
		{
			//IL_0050: 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_0060: 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_006e: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			if (!((Object)(object)StartOfRound.Instance == (Object)null))
			{
				List<UnlockableItem> unlockables = StartOfRound.Instance.unlockablesList.unlockables;
				int num = unlockables.FindIndex((UnlockableItem u) => u != null && u.unlockableName == "Maquina de mejoras");
				if (num >= 0)
				{
					UnlockableIndex = num;
					return;
				}
				unlockables.Add(new UnlockableItem
				{
					unlockableName = "Maquina de mejoras",
					unlockableType = 1,
					IsPlaceable = false,
					alreadyUnlocked = true,
					spawnPrefab = false,
					canBeStored = false,
					maxNumber = 1
				});
				UnlockableIndex = unlockables.Count - 1;
				Plugin.Log.LogInfo((object)$"Unlockable de la máquina registrado (id {UnlockableIndex}).");
			}
		}

		internal static IEnumerator SpawnRoutine()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				yield break;
			}
			yield return (object)new WaitForSeconds(1.5f);
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer || (Object)(object)Instance != (Object)null)
			{
				yield break;
			}
			if ((Object)(object)MachinePrefab == (Object)null)
			{
				Plugin.Log.LogError((object)"MachinePrefab es null: no puedo spawnear la máquina.");
				yield break;
			}
			Terminal val = Object.FindObjectOfType<Terminal>();
			Transform val2 = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.elevatorTransform : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Sin terminal o nave; no coloco la máquina.");
				yield break;
			}
			Vector3 val3 = val2.InverseTransformPoint(((Component)val).transform.position) + Plugin.MachineOffset;
			Vector3 val4 = val2.TransformPoint(val3);
			Quaternion val5 = val2.rotation * Quaternion.Euler(0f, 180f + Plugin.MachineRotationY.Value, 0f);
			int collidersAndRoomMaskAndDefault = StartOfRound.Instance.collidersAndRoomMaskAndDefault;
			RaycastHit val6 = default(RaycastHit);
			if (Physics.Raycast(val4 + Vector3.up * 0.6f, Vector3.down, ref val6, 6f, collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
			{
				((Vector3)(ref val4))..ctor(val4.x, ((RaycastHit)(ref val6)).point.y + 0.005f, val4.z);
			}
			Vector3 val7 = val5 * Vector3.forward;
			RaycastHit val8 = default(RaycastHit);
			if (Physics.Raycast(val4 + Vector3.up * 1f, val7, ref val8, 3f, collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
			{
				val4 += val7 * (((RaycastHit)(ref val8)).distance - 0.4248f - 0.02f);
			}
			Object.Instantiate<GameObject>(MachinePrefab, val4, val5).GetComponent<NetworkObject>().Spawn(false);
			Plugin.Log.LogInfo((object)$"Máquina spawneada en red (pegada a piso y pared). localPos={val2.InverseTransformPoint(val4)}");
		}

		internal static void CreatePrefabEarly()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			if (!((Object)(object)MachinePrefab != (Object)null))
			{
				_prefabContainer = new GameObject("UpgradableStats_MachinePrefab");
				_prefabContainer.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_prefabContainer);
				((Object)_prefabContainer).hideFlags = (HideFlags)61;
				GameObject val = new GameObject("UpgradesMachine");
				val.transform.SetParent(_prefabContainer.transform, false);
				val.transform.localScale = Vector3.one * 1.18f;
				NetworkObject obj = val.AddComponent<NetworkObject>();
				byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("com.martinchavez.upgradablestatsUpgradesMachine"));
				obj.GlobalObjectIdHash = BitConverter.ToUInt32(value, 0);
				AutoParentToShip obj2 = val.AddComponent<AutoParentToShip>();
				obj2.overrideOffset = false;
				obj2.unlockableID = -1;
				BuildColliders(torre: BuildVisuals(val.transform), parent: val.transform);
				val.AddComponent<UpgradesMachine>();
				MachinePrefab = val;
				Plugin.Log.LogInfo((object)"Prefab de la máquina construido.");
			}
		}

		private static GameObject BuildVisuals(Transform parent)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_00b7: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: 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_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be du