Decompiled source of RouletteOfItems v1.0.1

BepInEx/plugins/PeakCaseRoulette/PeakCaseRoulette.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Roulette_of_items")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Roulette_of_items")]
[assembly: AssemblyTitle("Roulette_of_items")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace PeakCaseMod;

[HarmonyPatch]
public static class CampfirePatch
{
	private static readonly Dictionary<string, ushort> _nameToId = new Dictionary<string, ushort>(StringComparer.OrdinalIgnoreCase);

	private static readonly Dictionary<string, Texture2D> _nameToIcon = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase);

	private static bool _catalogBuilt = false;

	public static bool IsCatalogBuilt => _catalogBuilt;

	[HarmonyPatch(typeof(Campfire), "Interact_CastFinished")]
	[HarmonyPrefix]
	public static void OnCampfireInteract_Prefix(Campfire __instance, Character interactor)
	{
	}

	[HarmonyPatch(typeof(Campfire), "Update")]
	[HarmonyPostfix]
	public static void OnCampfireUpdate_Postfix(Campfire __instance)
	{
	}

	private static void BuildItemCatalog()
	{
		_nameToId.Clear();
		_nameToIcon.Clear();
		CasePlugin.Logger.LogInfo((object)"[PEAK Case] Scanning items...");
		Item[] array = Resources.FindObjectsOfTypeAll<Item>();
		CasePlugin.Logger.LogInfo((object)$"Found {array.Length} Item objects");
		HashSet<int> hashSet = new HashSet<int>();
		Item[] array2 = array;
		foreach (Item val in array2)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			int instanceID = ((Object)val).GetInstanceID();
			if (!hashSet.Add(instanceID))
			{
				continue;
			}
			List<string> list = new List<string>();
			Texture2D val2 = null;
			try
			{
				if (!string.IsNullOrEmpty(val.GetName()))
				{
					list.Add(val.GetName());
				}
			}
			catch
			{
			}
			try
			{
				if (val.UIData != null && !string.IsNullOrEmpty(val.UIData.itemName))
				{
					list.Add(val.UIData.itemName);
				}
			}
			catch
			{
			}
			try
			{
				if (!string.IsNullOrEmpty(((Object)((Component)val).gameObject).name))
				{
					list.Add(((Object)((Component)val).gameObject).name);
				}
			}
			catch
			{
			}
			try
			{
				if (val.UIData != null)
				{
					val2 = val.UIData.GetIcon();
				}
			}
			catch
			{
			}
			foreach (string item in list)
			{
				if (!_nameToId.ContainsKey(item))
				{
					_nameToId[item] = val.itemID;
					if ((Object)(object)val2 != (Object)null && !_nameToIcon.ContainsKey(item))
					{
						_nameToIcon[item] = val2;
					}
				}
			}
		}
		CasePlugin.Logger.LogInfo((object)$"Catalog: {_nameToId.Count} names, {_nameToIcon.Count} icons");
		LootTable.LoadAllItemsFromCatalog(_nameToId, _nameToIcon);
	}

	private static void GiveItemToPlayerWithSpawn(Player player, string itemName)
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Expected O, but got Unknown
		if (!_nameToId.TryGetValue(itemName, out var value))
		{
			CasePlugin.Logger.LogError((object)("Item '" + itemName + "' not found!"));
			return;
		}
		bool flag = false;
		for (int i = 1; i < player.itemSlots.Length; i++)
		{
			if (player.itemSlots[i].IsEmpty())
			{
				flag = true;
				break;
			}
		}
		if (flag)
		{
			ItemInstanceData val = new ItemInstanceData(Guid.NewGuid());
			ItemSlot val2 = default(ItemSlot);
			if (player.AddItem(value, val, ref val2) && val2 != null && val2.itemSlotID > 0)
			{
				CasePlugin.Logger.LogInfo((object)$"Gave to inventory: {itemName} (ID: {value}) in slot {val2.itemSlotID}");
				return;
			}
			CasePlugin.Logger.LogWarning((object)("Item added to hand slot or failed. Spawning '" + itemName + "' on ground..."));
			SpawnItemOnGround(value, itemName);
		}
		else
		{
			CasePlugin.Logger.LogWarning((object)("Inventory full (3/3)! Spawning '" + itemName + "' on ground..."));
			SpawnItemOnGround(value, itemName);
		}
	}

	private static void SpawnItemOnGround(ushort itemID, string itemName)
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: 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_00e0: 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_00f0: 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_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_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Item val = default(Item);
			if (!ItemDatabase.TryGetItem(itemID, ref val))
			{
				CasePlugin.Logger.LogError((object)$"Failed to find prefab for item '{itemName}' (ID: {itemID})");
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				CasePlugin.Logger.LogError((object)$"itemPrefab = null for '{itemName}' (ID: {itemID})");
				return;
			}
			Vector3 position;
			Vector3 forward;
			if ((Object)(object)Camera.main != (Object)null)
			{
				position = ((Component)Camera.main).transform.position;
				forward = ((Component)Camera.main).transform.forward;
				CasePlugin.Logger.LogInfo((object)$"Using camera position: {position}");
			}
			else
			{
				if (!((Object)(object)Character.localCharacter != (Object)null))
				{
					CasePlugin.Logger.LogError((object)"Both Camera.main and Character.localCharacter are null!");
					return;
				}
				position = ((Component)Character.localCharacter).transform.position;
				forward = ((Component)Character.localCharacter).transform.forward;
				CasePlugin.Logger.LogInfo((object)$"Using character position (fallback): {position}");
			}
			Vector3 val2 = position + forward * 1.5f;
			string text = "0_Items/" + ((Object)((Component)val).gameObject).name;
			GameObject val3 = PhotonNetwork.Instantiate(text, val2, Quaternion.identity, (byte)0, (object[])null);
			if ((Object)(object)val3 != (Object)null)
			{
				PhotonView component = val3.GetComponent<PhotonView>();
				Item component2 = val3.GetComponent<Item>();
				if (!((Object)(object)component != (Object)null) || !((Object)(object)component2 != (Object)null))
				{
					return;
				}
				if (!component.IsMine)
				{
					Renderer componentInChildren = val3.GetComponentInChildren<Renderer>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.enabled = false;
					}
					Collider component3 = val3.GetComponent<Collider>();
					if ((Object)(object)component3 != (Object)null)
					{
						component3.enabled = false;
					}
					CasePlugin.Logger.LogInfo((object)("Hidden item '" + itemName + "' for non-owner (client-side only)"));
				}
				else
				{
					component2.SetKinematicNetworked(false);
					MethodInfo method = typeof(Item).GetMethod("SetState", BindingFlags.Instance | BindingFlags.NonPublic);
					if (method != null)
					{
						method.Invoke(component2, new object[2]
						{
							(object)(ItemState)0,
							null
						});
						CasePlugin.Logger.LogInfo((object)("Spawned networked item '" + itemName + "' for owner"));
					}
				}
			}
			else
			{
				CasePlugin.Logger.LogError((object)("Failed to spawn item '" + itemName + "'"));
			}
		}
		catch (Exception ex)
		{
			CasePlugin.Logger.LogError((object)("Error spawning item '" + itemName + "': " + ex.Message + "\n" + ex.StackTrace));
		}
	}

	public static void BuildCatalogPublic()
	{
		BuildItemCatalog();
		_catalogBuilt = true;
	}

	public static void GiveItemToPlayerWithSpawnPublic(Player player, string itemName)
	{
		GiveItemToPlayerWithSpawn(player, itemName);
	}
}
[BepInPlugin("com.you.peakcase", "PEAK Case Roulette", "1.0.0")]
public class CasePlugin : BaseUnityPlugin
{
	public static CasePlugin Instance;

	internal static ManualLogSource Logger;

	private Harmony _harmony;

	private DebugInputHandler _debugHandler;

	private RouletteTimerHandler _timerHandler;

	private void Awake()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Expected O, but got Unknown
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Expected O, but got Unknown
		Instance = this;
		Logger = ((BaseUnityPlugin)this).Logger;
		Logger.LogInfo((object)"[PEAK Case] Mod loaded successfully (Mono)!");
		_harmony = new Harmony("com.you.peakcase");
		_harmony.PatchAll();
		LootTable.Initialize();
		GameObject val = new GameObject("PeakCaseDebugInput");
		Object.DontDestroyOnLoad((Object)(object)val);
		_debugHandler = val.AddComponent<DebugInputHandler>();
		GameObject val2 = new GameObject("PeakCaseRouletteTimer");
		Object.DontDestroyOnLoad((Object)(object)val2);
		_timerHandler = val2.AddComponent<RouletteTimerHandler>();
		Logger.LogInfo((object)"[PEAK Case] Debug key F11 activated");
		Logger.LogInfo((object)"[PEAK Case] Key F10 for roulette (60s cooldown)");
	}

	private void OnDestroy()
	{
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		Logger.LogInfo((object)"[PEAK Case] Mod unloaded");
	}
}
public class DebugInputHandler : MonoBehaviour
{
	private void Update()
	{
		if (Input.GetKeyDown((KeyCode)292))
		{
			CasePlugin.Logger.LogInfo((object)"[DEBUG] F11 pressed! Triggering roulette manually...");
			TriggerDebugRoulette();
		}
	}

	private void TriggerDebugRoulette()
	{
		if ((Object)(object)Character.localCharacter == (Object)null)
		{
			CasePlugin.Logger.LogWarning((object)"[DEBUG] Character.localCharacter = null (not in game?)");
			return;
		}
		Player player = Character.localCharacter.player;
		if ((Object)(object)player == (Object)null)
		{
			CasePlugin.Logger.LogWarning((object)"[DEBUG] player = null");
			return;
		}
		if (!CampfirePatch.IsCatalogBuilt)
		{
			CasePlugin.Logger.LogInfo((object)"[DEBUG] Building item catalog...");
			CampfirePatch.BuildCatalogPublic();
		}
		ManualLogSource logger = CasePlugin.Logger;
		PhotonView photonView = ((MonoBehaviourPun)Character.localCharacter).photonView;
		object obj;
		if (photonView == null)
		{
			obj = null;
		}
		else
		{
			Player owner = photonView.Owner;
			obj = ((owner != null) ? owner.NickName : null);
		}
		if (obj == null)
		{
			obj = "Unknown";
		}
		logger.LogInfo((object)("[DEBUG] Starting roulette for player: " + (string?)obj));
		RouletteUI.Instance.ShowRoulette(delegate(LootItem wonItem)
		{
			CasePlugin.Logger.LogInfo((object)("[DEBUG] Giving item: " + wonItem.ItemName));
			CampfirePatch.GiveItemToPlayerWithSpawnPublic(player, wonItem.ItemName);
		});
	}
}
public class RouletteTimerHandler : MonoBehaviour
{
	private float _lastRouletteTime = -999f;

	private const float COOLDOWN_DURATION = 60f;

	private const KeyCode ACTIVATION_KEY = (KeyCode)291;

	private Font _peakFont = null;

	private bool _fontLoaded = false;

	public static void ResetCooldown()
	{
		RouletteTimerHandler rouletteTimerHandler = Object.FindObjectOfType<RouletteTimerHandler>();
		if ((Object)(object)rouletteTimerHandler != (Object)null)
		{
			rouletteTimerHandler._lastRouletteTime = -999f;
			CasePlugin.Logger.LogInfo((object)"[Timer] Cooldown reset by slot machine");
		}
	}

	private void Update()
	{
		if (!((Object)(object)Character.localCharacter == (Object)null) && !RouletteUI.Instance.IsActive && Input.GetKeyDown((KeyCode)291))
		{
			TryActivateRoulette();
		}
	}

	private void LoadPeakFont()
	{
		if (_fontLoaded)
		{
			return;
		}
		_fontLoaded = true;
		Font[] array = Resources.FindObjectsOfTypeAll<Font>();
		CasePlugin.Logger.LogInfo((object)$"[Timer] Found {array.Length} fonts in game");
		Font[] array2 = array;
		foreach (Font val in array2)
		{
			if (!((Object)(object)val == (Object)null) && ((Object)val).name.Contains("Binggrae"))
			{
				_peakFont = val;
				CasePlugin.Logger.LogInfo((object)("[Timer] Using PEAK font: " + ((Object)val).name));
				break;
			}
		}
		if ((Object)(object)_peakFont == (Object)null)
		{
			Font[] array3 = array;
			foreach (Font val2 in array3)
			{
				if (!((Object)(object)val2 == (Object)null) && ((Object)val2).name.Contains("Pangolin"))
				{
					_peakFont = val2;
					CasePlugin.Logger.LogInfo((object)("[Timer] Using fallback font: " + ((Object)val2).name));
					break;
				}
			}
		}
		if ((Object)(object)_peakFont == (Object)null && array.Length != 0)
		{
			_peakFont = array[0];
			CasePlugin.Logger.LogInfo((object)("[Timer] Using first available font: " + ((Object)_peakFont).name));
		}
		if ((Object)(object)_peakFont == (Object)null)
		{
			_peakFont = Font.CreateDynamicFontFromOSFont("Arial", 24);
			CasePlugin.Logger.LogWarning((object)"[Timer] No fonts found, using Arial");
		}
	}

	private void TryActivateRoulette()
	{
		if (!_fontLoaded)
		{
			LoadPeakFont();
		}
		float num = Time.time - _lastRouletteTime;
		if (num >= 60f)
		{
			_lastRouletteTime = Time.time;
			CasePlugin.Logger.LogInfo((object)$"[Timer] Roulette activated! Next in {60f}s");
			TriggerRoulette();
		}
		else
		{
			float num2 = 60f - num;
			CasePlugin.Logger.LogInfo((object)$"[Timer] Cooldown! {Mathf.CeilToInt(num2)}s remaining");
		}
	}

	private void TriggerRoulette()
	{
		if ((Object)(object)Character.localCharacter == (Object)null)
		{
			CasePlugin.Logger.LogWarning((object)"[Timer] Character.localCharacter = null");
			return;
		}
		Player player = Character.localCharacter.player;
		if ((Object)(object)player == (Object)null)
		{
			CasePlugin.Logger.LogWarning((object)"[Timer] player = null");
			return;
		}
		if (!CampfirePatch.IsCatalogBuilt)
		{
			CampfirePatch.BuildCatalogPublic();
		}
		RouletteUI.Instance.ShowRoulette(delegate(LootItem wonItem)
		{
			CasePlugin.Logger.LogInfo((object)("[Timer] Gave item: " + wonItem.ItemName));
			CampfirePatch.GiveItemToPlayerWithSpawnPublic(player, wonItem.ItemName);
		});
	}

	private void OnGUI()
	{
		if (!((Object)(object)Character.localCharacter == (Object)null) && !RouletteUI.Instance.IsActive)
		{
			if (!_fontLoaded)
			{
				LoadPeakFont();
			}
			DrawTimer();
		}
	}

	private void DrawTimer()
	{
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: 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_00e9: Expected O, but got Unknown
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Expected O, but got Unknown
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		float num = Time.time - _lastRouletteTime;
		float num2 = 60f - num;
		Color textColor = default(Color);
		string text;
		if (num2 <= 0f)
		{
			((Color)(ref textColor))..ctor(0.2f, 1f, 0.2f, 1f);
			text = "READY (F10)";
		}
		else
		{
			((Color)(ref textColor))..ctor(1f, 0.3f, 0.3f, 1f);
			text = $"COOLDOWN: {Mathf.CeilToInt(num2)}s";
		}
		float num3 = 400f;
		float num4 = 40f;
		float num5 = ((float)Screen.width - num3) / 2f;
		float num6 = 20f;
		GUIStyle val = new GUIStyle(GUI.skin.label)
		{
			font = _peakFont,
			fontSize = 24,
			alignment = (TextAnchor)4,
			fontStyle = (FontStyle)1
		};
		val.normal.textColor = textColor;
		GUIStyle val2 = val;
		GUIStyle val3 = new GUIStyle(val2);
		val3.normal.textColor = new Color(0f, 0f, 0f, 0.7f);
		GUIStyle val4 = val3;
		GUI.Label(new Rect(num5 + 2f, num6 + 2f, num3, num4), text, val4);
		GUI.Label(new Rect(num5, num6, num3, num4), text, val2);
	}
}
public class LootItem
{
	public string ItemName;

	public float Weight;

	public Texture2D Icon;

	public LootItem(string name, float weight, Texture2D icon = null)
	{
		ItemName = name;
		Weight = weight;
		Icon = icon;
	}
}
public static class LootTable
{
	private static readonly List<LootItem> _allItems = new List<LootItem>();

	private static readonly Random _random = new Random();

	private static bool _initialized = false;

	public static readonly Color ArrowColor = new Color(1f, 0.84f, 0f);

	public static void Initialize()
	{
		if (!_initialized)
		{
			_initialized = true;
			CasePlugin.Logger.LogInfo((object)"[LootTable] Initialized (items will be loaded from catalog)");
		}
	}

	public static void LoadAllItemsFromCatalog(Dictionary<string, ushort> nameToId, Dictionary<string, Texture2D> nameToIcon)
	{
		_allItems.Clear();
		HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "King", "Queen", "Bishop", "Knight", "Rook", "Pawn" };
		HashSet<string> hashSet2 = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "ClimbingChalk", "Climbing Chalk", "SCOUTMASTERSOUL", "LOC:NAME_CLIMBINGCHALK", "LOC: NAME_CLIMBING CHALK", "Torn Page" };
		int num = 0;
		int num2 = 0;
		int num3 = 0;
		int num4 = 0;
		foreach (KeyValuePair<string, ushort> item in nameToId)
		{
			string key = item.Key;
			ushort value = item.Value;
			if (key.Contains("(Clone)") || key.StartsWith("Item_"))
			{
				num4++;
				continue;
			}
			if (ContainsCyrillic(key))
			{
				num2++;
				continue;
			}
			if (key.StartsWith("C_"))
			{
				num3++;
				continue;
			}
			if (hashSet.Contains(key))
			{
				num3++;
				continue;
			}
			if (key.Contains("GuidebookPage"))
			{
				num3++;
				continue;
			}
			if (hashSet2.Contains(key))
			{
				num3++;
				continue;
			}
			float weight = 1f;
			Texture2D value2 = null;
			nameToIcon.TryGetValue(key, out value2);
			AddItem(key, weight, value2);
			num++;
		}
		CasePlugin.Logger.LogInfo((object)$"[LootTable] Loaded {num} items (skipped: {num2} cyrillic, {num3} excluded, {num4} duplicates)");
	}

	private static bool ContainsCyrillic(string text)
	{
		foreach (char c in text)
		{
			if (c >= 'Ѐ' && c <= 'ӿ')
			{
				return true;
			}
		}
		return false;
	}

	private static void AddItem(string name, float weight, Texture2D icon = null)
	{
		_allItems.Add(new LootItem(name, weight, icon));
	}

	public static void UpdateIcons(Dictionary<string, Texture2D> iconCatalog)
	{
		int num = 0;
		foreach (LootItem allItem in _allItems)
		{
			if (iconCatalog.TryGetValue(allItem.ItemName, out var value))
			{
				allItem.Icon = value;
				num++;
			}
		}
		CasePlugin.Logger.LogInfo((object)$"[LootTable] Updated icons: {num}/{_allItems.Count}");
	}

	public static LootItem RollItem()
	{
		if (_allItems.Count == 0)
		{
			CasePlugin.Logger.LogError((object)"[LootTable] Item list is empty!");
			return null;
		}
		float num = 0f;
		foreach (LootItem allItem in _allItems)
		{
			num += allItem.Weight;
		}
		float num2 = (float)(_random.NextDouble() * (double)num);
		float num3 = 0f;
		foreach (LootItem allItem2 in _allItems)
		{
			num3 += allItem2.Weight;
			if (num2 <= num3)
			{
				return allItem2;
			}
		}
		return _allItems[0];
	}
}
public class RouletteUI : MonoBehaviour
{
	private static RouletteUI _instance;

	private bool _isActive = false;

	private Font _peakFont = null;

	private bool _fontLoaded = false;

	private readonly List<LootItem> _rouletteItems = new List<LootItem>();

	private LootItem _wonItem;

	private Action<LootItem> _onItemWon;

	private float _phaseStartTime = -1f;

	private float _showResultTime = -1f;

	private float _closeStartTime = -1f;

	private const float FADE_IN_DURATION = 0.4f;

	private const float WAIT_DURATION = 1f;

	private const float ROLL_DURATION = 3f;

	private const float RESULT_DURATION = 3f;

	private const float FADE_OUT_DURATION = 0.4f;

	private float _scrollOffset = 0f;

	private float _targetScrollOffset = 0f;

	private float _uiAlpha = 0f;

	private static readonly Color PEAK_BG_COLOR = new Color(0.05f, 0.08f, 0.12f, 0.95f);

	private static readonly Color PEAK_BORDER_COLOR = new Color(0.3f, 0.5f, 0.7f, 1f);

	private static readonly Color PEAK_ACCENT_COLOR = new Color(1f, 0.8f, 0.3f, 1f);

	private static readonly Dictionary<string, Texture2D> _fallbackIcons = new Dictionary<string, Texture2D>();

	private const float ITEM_WIDTH = 140f;

	private const float ITEM_HEIGHT = 200f;

	private const int VISIBLE_ITEMS = 5;

	public bool IsActive => _isActive;

	public static RouletteUI Instance
	{
		get
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)_instance == (Object)null)
			{
				GameObject val = new GameObject("PeakCaseRouletteUI");
				_instance = val.AddComponent<RouletteUI>();
				Object.DontDestroyOnLoad((Object)(object)val);
			}
			return _instance;
		}
	}

	private void LoadPeakFont()
	{
		if (_fontLoaded)
		{
			return;
		}
		_fontLoaded = true;
		Font[] array = Resources.FindObjectsOfTypeAll<Font>();
		CasePlugin.Logger.LogInfo((object)$"[RouletteUI] Found {array.Length} fonts in game");
		Font[] array2 = array;
		foreach (Font val in array2)
		{
			if (!((Object)(object)val == (Object)null) && ((Object)val).name.Contains("Binggrae"))
			{
				_peakFont = val;
				CasePlugin.Logger.LogInfo((object)("[RouletteUI] Using PEAK font: " + ((Object)val).name));
				break;
			}
		}
		if ((Object)(object)_peakFont == (Object)null)
		{
			Font[] array3 = array;
			foreach (Font val2 in array3)
			{
				if (!((Object)(object)val2 == (Object)null) && ((Object)val2).name.Contains("Pangolin"))
				{
					_peakFont = val2;
					CasePlugin.Logger.LogInfo((object)("[RouletteUI] Using fallback font: " + ((Object)val2).name));
					break;
				}
			}
		}
		if ((Object)(object)_peakFont == (Object)null && array.Length != 0)
		{
			_peakFont = array[0];
			CasePlugin.Logger.LogInfo((object)("[RouletteUI] Using first available font: " + ((Object)_peakFont).name));
		}
		if ((Object)(object)_peakFont == (Object)null)
		{
			_peakFont = Font.CreateDynamicFontFromOSFont("Arial", 24);
			CasePlugin.Logger.LogWarning((object)"[RouletteUI] No fonts found, using Arial");
		}
	}

	public void ShowRoulette(Action<LootItem> onItemWon)
	{
		_onItemWon = onItemWon;
		_isActive = true;
		_wonItem = null;
		_phaseStartTime = Time.time;
		_showResultTime = -1f;
		_closeStartTime = -1f;
		_scrollOffset = 0f;
		_uiAlpha = 0f;
		_rouletteItems.Clear();
		for (int i = 0; i < 20; i++)
		{
			_rouletteItems.Add(LootTable.RollItem());
		}
		_wonItem = LootTable.RollItem();
		_rouletteItems.Add(_wonItem);
		for (int j = 0; j < 10; j++)
		{
			_rouletteItems.Add(LootTable.RollItem());
		}
		int num = 20;
		int num2 = num - 2;
		_targetScrollOffset = (float)num2 * 140f;
		CasePlugin.Logger.LogInfo((object)("[RouletteUI] Roulette started. Winner: " + _wonItem.ItemName));
	}

	private void OnGUI()
	{
		//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Expected O, but got Unknown
		//IL_02ef: 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_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_035c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0601: Unknown result type (might be due to invalid IL or missing references)
		//IL_0624: Unknown result type (might be due to invalid IL or missing references)
		//IL_064e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0674: Unknown result type (might be due to invalid IL or missing references)
		//IL_0699: Unknown result type (might be due to invalid IL or missing references)
		//IL_0443: Unknown result type (might be due to invalid IL or missing references)
		//IL_045c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0475: Unknown result type (might be due to invalid IL or missing references)
		//IL_04db: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0506: Unknown result type (might be due to invalid IL or missing references)
		//IL_050e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0514: Unknown result type (might be due to invalid IL or missing references)
		//IL_0521: Expected O, but got Unknown
		//IL_0538: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0739: Unknown result type (might be due to invalid IL or missing references)
		//IL_073e: Unknown result type (might be due to invalid IL or missing references)
		//IL_074b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0754: Unknown result type (might be due to invalid IL or missing references)
		//IL_075c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0764: Unknown result type (might be due to invalid IL or missing references)
		//IL_076c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0772: Unknown result type (might be due to invalid IL or missing references)
		//IL_077f: Expected O, but got Unknown
		//IL_0798: Unknown result type (might be due to invalid IL or missing references)
		//IL_0721: Unknown result type (might be due to invalid IL or missing references)
		//IL_07e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_07e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_07f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_07ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0807: Unknown result type (might be due to invalid IL or missing references)
		//IL_080d: Unknown result type (might be due to invalid IL or missing references)
		//IL_081a: Expected O, but got Unknown
		//IL_0829: Unknown result type (might be due to invalid IL or missing references)
		if (!_isActive)
		{
			return;
		}
		if (!_fontLoaded)
		{
			LoadPeakFont();
		}
		float num = Time.time - _phaseStartTime;
		if (num < 0.4f)
		{
			_uiAlpha = Mathf.Clamp01(num / 0.4f);
		}
		else if (num < 1.4f)
		{
			_uiAlpha = 1f;
		}
		else if (num < 4.4f)
		{
			_uiAlpha = 1f;
		}
		else if (_showResultTime < 0f)
		{
			_showResultTime = Time.time;
			_uiAlpha = 1f;
			CasePlugin.Logger.LogInfo((object)("[RouletteUI] Won item: " + _wonItem.ItemName));
		}
		else
		{
			float num2 = Time.time - _showResultTime;
			if (num2 < 3f)
			{
				_uiAlpha = 1f;
			}
			else if (_closeStartTime < 0f)
			{
				_closeStartTime = Time.time;
			}
			else
			{
				float num3 = Time.time - _closeStartTime;
				_uiAlpha = 1f - Mathf.Clamp01(num3 / 0.4f);
				if (_uiAlpha <= 0f)
				{
					CasePlugin.Logger.LogInfo((object)("[RouletteUI] Auto close. Giving: " + _wonItem.ItemName));
					_onItemWon?.Invoke(_wonItem);
					CloseRoulette();
					return;
				}
			}
		}
		GUI.color = new Color(1f, 1f, 1f, _uiAlpha);
		GUI.color = new Color(0f, 0f, 0f, 0.4f * _uiAlpha);
		GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = new Color(1f, 1f, 1f, _uiAlpha);
		float num4 = 800f;
		float num5 = 500f;
		float num6 = ((float)Screen.width - num4) / 2f;
		float num7 = ((float)Screen.height - num5) / 2f;
		DrawStyledBox(new Rect(num6, num7, num4, num5), PEAK_BG_COLOR, PEAK_BORDER_COLOR, 3f);
		GUIStyle val = new GUIStyle(GUI.skin.label)
		{
			font = _peakFont,
			fontSize = 42,
			alignment = (TextAnchor)4,
			fontStyle = (FontStyle)1
		};
		val.normal.textColor = PEAK_ACCENT_COLOR;
		GUIStyle val2 = val;
		GUI.Label(new Rect(num6, num7 + 15f, num4, 60f), "ITEM ROULETTE", val2);
		float num8 = num7 + 90f;
		float num9 = 700f;
		float num10 = num6 + (num4 - num9) / 2f;
		DrawStyledBox(new Rect(num10 - 10f, num8 - 10f, num9 + 20f, 220f), new Color(0.1f, 0.15f, 0.2f, 0.8f), PEAK_BORDER_COLOR, 2f);
		float num11 = _phaseStartTime + 0.4f + 1f;
		float num12 = Time.time - num11;
		bool flag = num12 > 0f && num12 < 3f;
		GUI.BeginGroup(new Rect(num10, num8, num9, 200f));
		float num13 = 0f - _scrollOffset % 140f;
		int num14 = Mathf.FloorToInt(_scrollOffset / 140f);
		for (int i = -1; i < 6; i++)
		{
			int num15 = num14 + i;
			if (num15 >= 0 && num15 < _rouletteItems.Count)
			{
				LootItem lootItem = _rouletteItems[num15];
				float num16 = num13 + (float)i * 140f;
				DrawStyledBox(new Rect(num16 + 5f, 5f, 130f, 190f), new Color(0.15f, 0.2f, 0.25f, 0.9f), new Color(0.5f, 0.5f, 0.5f, 0.8f), 2f);
				Texture2D itemIcon = GetItemIcon(lootItem);
				if ((Object)(object)itemIcon != (Object)null)
				{
					float num17 = 80f;
					float num18 = num16 + (140f - num17) / 2f;
					GUI.DrawTexture(new Rect(num18, 30f, num17, num17), (Texture)(object)itemIcon);
				}
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					font = _peakFont,
					fontSize = 11,
					alignment = (TextAnchor)4,
					wordWrap = true,
					fontStyle = (FontStyle)1
				};
				val3.normal.textColor = Color.white;
				GUIStyle val4 = val3;
				GUI.Label(new Rect(num16 + 5f, 130f, 130f, 60f), lootItem.ItemName, val4);
			}
		}
		if (flag)
		{
			float num19 = num12 / 3f;
			float num20 = (1f - Mathf.Cos(num19 * MathF.PI)) / 2f;
			_scrollOffset = Mathf.Lerp(_scrollOffset, _targetScrollOffset * num20, Time.deltaTime * 8f);
		}
		GUI.EndGroup();
		float num21 = num10 + num9 / 2f;
		float num22 = 4f;
		float num23 = 20f;
		Color color = default(Color);
		((Color)(ref color))..ctor(LootTable.ArrowColor.r, LootTable.ArrowColor.g, LootTable.ArrowColor.b, _uiAlpha);
		GUI.color = color;
		DrawTriangle(new Rect(num21 - 10f, num8 - num23 - 5f, 20f, num23), pointingDown: true);
		DrawTriangle(new Rect(num21 - 10f, num8 + 200f + 5f, 20f, num23), pointingDown: false);
		GUI.DrawTexture(new Rect(num21 - num22 / 2f, num8 - 5f, num22, 210f), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = new Color(1f, 1f, 1f, _uiAlpha);
		if (_wonItem != null && _showResultTime >= 0f)
		{
			float num24 = Time.time - _showResultTime;
			Texture2D itemIcon2 = GetItemIcon(_wonItem);
			if ((Object)(object)itemIcon2 != (Object)null)
			{
				float num25 = 100f;
				float num26 = num6 + (num4 - num25) / 2f;
				float num27 = num8 + 200f + 40f;
				GUI.DrawTexture(new Rect(num26, num27, num25, num25), (Texture)(object)itemIcon2);
			}
			GUIStyle val5 = new GUIStyle(GUI.skin.label)
			{
				font = _peakFont,
				fontSize = 28,
				alignment = (TextAnchor)4,
				fontStyle = (FontStyle)1,
				wordWrap = true
			};
			val5.normal.textColor = PEAK_ACCENT_COLOR;
			GUIStyle val6 = val5;
			float num28 = num8 + 200f + 150f;
			GUI.Label(new Rect(num6, num28, num4, 40f), _wonItem.ItemName, val6);
			float num29 = 3f - num24;
			if (num29 > 0f && _closeStartTime < 0f)
			{
				GUIStyle val7 = new GUIStyle(GUI.skin.label)
				{
					font = _peakFont,
					fontSize = 14,
					alignment = (TextAnchor)4
				};
				val7.normal.textColor = Color.white;
				GUIStyle val8 = val7;
				GUI.Label(new Rect(num6, num28 + 60f, num4, 25f), $"Closes in {Mathf.CeilToInt(num29)} sec...", val8);
			}
		}
	}

	private void DrawTriangle(Rect rect, bool pointingDown)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: 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)
		int num = (int)((Rect)(ref rect)).width;
		Texture2D val = new Texture2D(num, num);
		for (int i = 0; i < num; i++)
		{
			for (int j = 0; j < num; j++)
			{
				float num2 = (float)i / (float)num;
				float num3 = (float)j / (float)num;
				bool flag = false;
				flag = ((!pointingDown) ? (num2 <= num3 && num2 <= 1f - num3) : (num2 >= 1f - num3 && num2 >= num3));
				val.SetPixel(j, i, (Color)(flag ? Color.white : new Color(0f, 0f, 0f, 0f)));
			}
		}
		val.Apply();
		GUI.DrawTexture(rect, (Texture)(object)val);
	}

	private Texture2D GetItemIcon(LootItem item)
	{
		if ((Object)(object)item.Icon != (Object)null)
		{
			return item.Icon;
		}
		if (!_fallbackIcons.ContainsKey(item.ItemName))
		{
			_fallbackIcons[item.ItemName] = CreateFallbackIcon(item.ItemName);
		}
		return _fallbackIcons[item.ItemName];
	}

	private Texture2D CreateFallbackIcon(string itemName)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: 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_0070: Unknown result type (might be due to invalid IL or missing references)
		int num = 128;
		Texture2D val = new Texture2D(num, num);
		Color val2 = default(Color);
		((Color)(ref val2))..ctor(0.4f, 0.4f, 0.4f);
		for (int i = 0; i < num; i++)
		{
			for (int j = 0; j < num; j++)
			{
				float num2 = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)num / 2f, (float)num / 2f)) / ((float)num / 2f);
				val.SetPixel(j, i, Color.Lerp(val2, Color.black, num2 * 0.5f));
			}
		}
		val.Apply();
		return val;
	}

	private void CloseRoulette()
	{
		_isActive = false;
		_wonItem = null;
		_phaseStartTime = -1f;
		_showResultTime = -1f;
		_closeStartTime = -1f;
		_fallbackIcons.Clear();
	}

	private void DrawStyledBox(Rect rect, Color bgColor, Color borderColor, float borderWidth)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		GUI.color = new Color(bgColor.r, bgColor.g, bgColor.b, bgColor.a * _uiAlpha);
		GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture);
		GUI.color = new Color(1f, 1f, 1f, _uiAlpha);
		GUI.color = new Color(borderColor.r, borderColor.g, borderColor.b, borderColor.a * _uiAlpha);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, borderWidth), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + ((Rect)(ref rect)).height - borderWidth, ((Rect)(ref rect)).width, borderWidth), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, borderWidth, ((Rect)(ref rect)).height), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + ((Rect)(ref rect)).width - borderWidth, ((Rect)(ref rect)).y, borderWidth, ((Rect)(ref rect)).height), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = new Color(1f, 1f, 1f, _uiAlpha);
	}
}

Roulette_of_items.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Roulette_of_items")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Roulette_of_items")]
[assembly: AssemblyTitle("Roulette_of_items")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace PeakCaseMod;

[HarmonyPatch]
public static class CampfirePatch
{
	private static readonly Dictionary<string, ushort> _nameToId = new Dictionary<string, ushort>(StringComparer.OrdinalIgnoreCase);

	private static readonly Dictionary<string, Texture2D> _nameToIcon = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase);

	private static bool _catalogBuilt = false;

	public static bool IsCatalogBuilt => _catalogBuilt;

	[HarmonyPatch(typeof(Campfire), "Interact_CastFinished")]
	[HarmonyPrefix]
	public static void OnCampfireInteract_Prefix(Campfire __instance, Character interactor)
	{
	}

	[HarmonyPatch(typeof(Campfire), "Update")]
	[HarmonyPostfix]
	public static void OnCampfireUpdate_Postfix(Campfire __instance)
	{
	}

	private static void BuildItemCatalog()
	{
		_nameToId.Clear();
		_nameToIcon.Clear();
		CasePlugin.Logger.LogInfo((object)"[PEAK Case] Scanning items...");
		Item[] array = Resources.FindObjectsOfTypeAll<Item>();
		CasePlugin.Logger.LogInfo((object)$"Found {array.Length} Item objects");
		HashSet<int> hashSet = new HashSet<int>();
		Item[] array2 = array;
		foreach (Item val in array2)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			int instanceID = ((Object)val).GetInstanceID();
			if (!hashSet.Add(instanceID))
			{
				continue;
			}
			List<string> list = new List<string>();
			Texture2D val2 = null;
			try
			{
				if (!string.IsNullOrEmpty(val.GetName()))
				{
					list.Add(val.GetName());
				}
			}
			catch
			{
			}
			try
			{
				if (val.UIData != null && !string.IsNullOrEmpty(val.UIData.itemName))
				{
					list.Add(val.UIData.itemName);
				}
			}
			catch
			{
			}
			try
			{
				if (!string.IsNullOrEmpty(((Object)((Component)val).gameObject).name))
				{
					list.Add(((Object)((Component)val).gameObject).name);
				}
			}
			catch
			{
			}
			try
			{
				if (val.UIData != null)
				{
					val2 = val.UIData.GetIcon();
				}
			}
			catch
			{
			}
			foreach (string item in list)
			{
				if (!_nameToId.ContainsKey(item))
				{
					_nameToId[item] = val.itemID;
					if ((Object)(object)val2 != (Object)null && !_nameToIcon.ContainsKey(item))
					{
						_nameToIcon[item] = val2;
					}
				}
			}
		}
		CasePlugin.Logger.LogInfo((object)$"Catalog: {_nameToId.Count} names, {_nameToIcon.Count} icons");
		LootTable.LoadAllItemsFromCatalog(_nameToId, _nameToIcon);
	}

	private static void GiveItemToPlayerWithSpawn(Player player, string itemName)
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Expected O, but got Unknown
		if (!_nameToId.TryGetValue(itemName, out var value))
		{
			CasePlugin.Logger.LogError((object)("Item '" + itemName + "' not found!"));
			return;
		}
		bool flag = false;
		for (int i = 1; i < player.itemSlots.Length; i++)
		{
			if (player.itemSlots[i].IsEmpty())
			{
				flag = true;
				break;
			}
		}
		if (flag)
		{
			ItemInstanceData val = new ItemInstanceData(Guid.NewGuid());
			ItemSlot val2 = default(ItemSlot);
			if (player.AddItem(value, val, ref val2) && val2 != null && val2.itemSlotID > 0)
			{
				CasePlugin.Logger.LogInfo((object)$"Gave to inventory: {itemName} (ID: {value}) in slot {val2.itemSlotID}");
				return;
			}
			CasePlugin.Logger.LogWarning((object)("Item added to hand slot or failed. Spawning '" + itemName + "' on ground..."));
			SpawnItemOnGround(value, itemName);
		}
		else
		{
			CasePlugin.Logger.LogWarning((object)("Inventory full (3/3)! Spawning '" + itemName + "' on ground..."));
			SpawnItemOnGround(value, itemName);
		}
	}

	private static void SpawnItemOnGround(ushort itemID, string itemName)
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: 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_00e0: 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_00f0: 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_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_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Item val = default(Item);
			if (!ItemDatabase.TryGetItem(itemID, ref val))
			{
				CasePlugin.Logger.LogError((object)$"Failed to find prefab for item '{itemName}' (ID: {itemID})");
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				CasePlugin.Logger.LogError((object)$"itemPrefab = null for '{itemName}' (ID: {itemID})");
				return;
			}
			Vector3 position;
			Vector3 forward;
			if ((Object)(object)Camera.main != (Object)null)
			{
				position = ((Component)Camera.main).transform.position;
				forward = ((Component)Camera.main).transform.forward;
				CasePlugin.Logger.LogInfo((object)$"Using camera position: {position}");
			}
			else
			{
				if (!((Object)(object)Character.localCharacter != (Object)null))
				{
					CasePlugin.Logger.LogError((object)"Both Camera.main and Character.localCharacter are null!");
					return;
				}
				position = ((Component)Character.localCharacter).transform.position;
				forward = ((Component)Character.localCharacter).transform.forward;
				CasePlugin.Logger.LogInfo((object)$"Using character position (fallback): {position}");
			}
			Vector3 val2 = position + forward * 1.5f;
			string text = "0_Items/" + ((Object)((Component)val).gameObject).name;
			GameObject val3 = PhotonNetwork.Instantiate(text, val2, Quaternion.identity, (byte)0, (object[])null);
			if ((Object)(object)val3 != (Object)null)
			{
				PhotonView component = val3.GetComponent<PhotonView>();
				Item component2 = val3.GetComponent<Item>();
				if (!((Object)(object)component != (Object)null) || !((Object)(object)component2 != (Object)null))
				{
					return;
				}
				if (!component.IsMine)
				{
					Renderer componentInChildren = val3.GetComponentInChildren<Renderer>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.enabled = false;
					}
					Collider component3 = val3.GetComponent<Collider>();
					if ((Object)(object)component3 != (Object)null)
					{
						component3.enabled = false;
					}
					CasePlugin.Logger.LogInfo((object)("Hidden item '" + itemName + "' for non-owner (client-side only)"));
				}
				else
				{
					component2.SetKinematicNetworked(false);
					MethodInfo method = typeof(Item).GetMethod("SetState", BindingFlags.Instance | BindingFlags.NonPublic);
					if (method != null)
					{
						method.Invoke(component2, new object[2]
						{
							(object)(ItemState)0,
							null
						});
						CasePlugin.Logger.LogInfo((object)("Spawned networked item '" + itemName + "' for owner"));
					}
				}
			}
			else
			{
				CasePlugin.Logger.LogError((object)("Failed to spawn item '" + itemName + "'"));
			}
		}
		catch (Exception ex)
		{
			CasePlugin.Logger.LogError((object)("Error spawning item '" + itemName + "': " + ex.Message + "\n" + ex.StackTrace));
		}
	}

	public static void BuildCatalogPublic()
	{
		BuildItemCatalog();
		_catalogBuilt = true;
	}

	public static void GiveItemToPlayerWithSpawnPublic(Player player, string itemName)
	{
		GiveItemToPlayerWithSpawn(player, itemName);
	}
}
[BepInPlugin("com.you.peakcase", "PEAK Case Roulette", "1.0.0")]
public class CasePlugin : BaseUnityPlugin
{
	public static CasePlugin Instance;

	internal static ManualLogSource Logger;

	private Harmony _harmony;

	private DebugInputHandler _debugHandler;

	private RouletteTimerHandler _timerHandler;

	private void Awake()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Expected O, but got Unknown
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Expected O, but got Unknown
		Instance = this;
		Logger = ((BaseUnityPlugin)this).Logger;
		Logger.LogInfo((object)"[PEAK Case] Mod loaded successfully (Mono)!");
		_harmony = new Harmony("com.you.peakcase");
		_harmony.PatchAll();
		LootTable.Initialize();
		GameObject val = new GameObject("PeakCaseDebugInput");
		Object.DontDestroyOnLoad((Object)(object)val);
		_debugHandler = val.AddComponent<DebugInputHandler>();
		GameObject val2 = new GameObject("PeakCaseRouletteTimer");
		Object.DontDestroyOnLoad((Object)(object)val2);
		_timerHandler = val2.AddComponent<RouletteTimerHandler>();
		Logger.LogInfo((object)"[PEAK Case] Debug key F11 activated");
		Logger.LogInfo((object)"[PEAK Case] Key F10 for roulette (60s cooldown)");
	}

	private void OnDestroy()
	{
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		Logger.LogInfo((object)"[PEAK Case] Mod unloaded");
	}
}
public class DebugInputHandler : MonoBehaviour
{
	private void Update()
	{
		if (Input.GetKeyDown((KeyCode)292))
		{
			CasePlugin.Logger.LogInfo((object)"[DEBUG] F11 pressed! Triggering roulette manually...");
			TriggerDebugRoulette();
		}
	}

	private void TriggerDebugRoulette()
	{
		if ((Object)(object)Character.localCharacter == (Object)null)
		{
			CasePlugin.Logger.LogWarning((object)"[DEBUG] Character.localCharacter = null (not in game?)");
			return;
		}
		Player player = Character.localCharacter.player;
		if ((Object)(object)player == (Object)null)
		{
			CasePlugin.Logger.LogWarning((object)"[DEBUG] player = null");
			return;
		}
		if (!CampfirePatch.IsCatalogBuilt)
		{
			CasePlugin.Logger.LogInfo((object)"[DEBUG] Building item catalog...");
			CampfirePatch.BuildCatalogPublic();
		}
		ManualLogSource logger = CasePlugin.Logger;
		PhotonView photonView = ((MonoBehaviourPun)Character.localCharacter).photonView;
		object obj;
		if (photonView == null)
		{
			obj = null;
		}
		else
		{
			Player owner = photonView.Owner;
			obj = ((owner != null) ? owner.NickName : null);
		}
		if (obj == null)
		{
			obj = "Unknown";
		}
		logger.LogInfo((object)("[DEBUG] Starting roulette for player: " + (string?)obj));
		RouletteUI.Instance.ShowRoulette(delegate(LootItem wonItem)
		{
			CasePlugin.Logger.LogInfo((object)("[DEBUG] Giving item: " + wonItem.ItemName));
			CampfirePatch.GiveItemToPlayerWithSpawnPublic(player, wonItem.ItemName);
		});
	}
}
public class RouletteTimerHandler : MonoBehaviour
{
	private float _lastRouletteTime = -999f;

	private const float COOLDOWN_DURATION = 60f;

	private const KeyCode ACTIVATION_KEY = (KeyCode)291;

	private Font _peakFont = null;

	private bool _fontLoaded = false;

	public static void ResetCooldown()
	{
		RouletteTimerHandler rouletteTimerHandler = Object.FindObjectOfType<RouletteTimerHandler>();
		if ((Object)(object)rouletteTimerHandler != (Object)null)
		{
			rouletteTimerHandler._lastRouletteTime = -999f;
			CasePlugin.Logger.LogInfo((object)"[Timer] Cooldown reset by slot machine");
		}
	}

	private void Update()
	{
		if (!((Object)(object)Character.localCharacter == (Object)null) && !RouletteUI.Instance.IsActive && Input.GetKeyDown((KeyCode)291))
		{
			TryActivateRoulette();
		}
	}

	private void LoadPeakFont()
	{
		if (_fontLoaded)
		{
			return;
		}
		_fontLoaded = true;
		Font[] array = Resources.FindObjectsOfTypeAll<Font>();
		CasePlugin.Logger.LogInfo((object)$"[Timer] Found {array.Length} fonts in game");
		Font[] array2 = array;
		foreach (Font val in array2)
		{
			if (!((Object)(object)val == (Object)null) && ((Object)val).name.Contains("Binggrae"))
			{
				_peakFont = val;
				CasePlugin.Logger.LogInfo((object)("[Timer] Using PEAK font: " + ((Object)val).name));
				break;
			}
		}
		if ((Object)(object)_peakFont == (Object)null)
		{
			Font[] array3 = array;
			foreach (Font val2 in array3)
			{
				if (!((Object)(object)val2 == (Object)null) && ((Object)val2).name.Contains("Pangolin"))
				{
					_peakFont = val2;
					CasePlugin.Logger.LogInfo((object)("[Timer] Using fallback font: " + ((Object)val2).name));
					break;
				}
			}
		}
		if ((Object)(object)_peakFont == (Object)null && array.Length != 0)
		{
			_peakFont = array[0];
			CasePlugin.Logger.LogInfo((object)("[Timer] Using first available font: " + ((Object)_peakFont).name));
		}
		if ((Object)(object)_peakFont == (Object)null)
		{
			_peakFont = Font.CreateDynamicFontFromOSFont("Arial", 24);
			CasePlugin.Logger.LogWarning((object)"[Timer] No fonts found, using Arial");
		}
	}

	private void TryActivateRoulette()
	{
		if (!_fontLoaded)
		{
			LoadPeakFont();
		}
		float num = Time.time - _lastRouletteTime;
		if (num >= 60f)
		{
			_lastRouletteTime = Time.time;
			CasePlugin.Logger.LogInfo((object)$"[Timer] Roulette activated! Next in {60f}s");
			TriggerRoulette();
		}
		else
		{
			float num2 = 60f - num;
			CasePlugin.Logger.LogInfo((object)$"[Timer] Cooldown! {Mathf.CeilToInt(num2)}s remaining");
		}
	}

	private void TriggerRoulette()
	{
		if ((Object)(object)Character.localCharacter == (Object)null)
		{
			CasePlugin.Logger.LogWarning((object)"[Timer] Character.localCharacter = null");
			return;
		}
		Player player = Character.localCharacter.player;
		if ((Object)(object)player == (Object)null)
		{
			CasePlugin.Logger.LogWarning((object)"[Timer] player = null");
			return;
		}
		if (!CampfirePatch.IsCatalogBuilt)
		{
			CampfirePatch.BuildCatalogPublic();
		}
		RouletteUI.Instance.ShowRoulette(delegate(LootItem wonItem)
		{
			CasePlugin.Logger.LogInfo((object)("[Timer] Gave item: " + wonItem.ItemName));
			CampfirePatch.GiveItemToPlayerWithSpawnPublic(player, wonItem.ItemName);
		});
	}

	private void OnGUI()
	{
		if (!((Object)(object)Character.localCharacter == (Object)null) && !RouletteUI.Instance.IsActive)
		{
			if (!_fontLoaded)
			{
				LoadPeakFont();
			}
			DrawTimer();
		}
	}

	private void DrawTimer()
	{
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: 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_00e9: Expected O, but got Unknown
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Expected O, but got Unknown
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		float num = Time.time - _lastRouletteTime;
		float num2 = 60f - num;
		Color textColor = default(Color);
		string text;
		if (num2 <= 0f)
		{
			((Color)(ref textColor))..ctor(0.2f, 1f, 0.2f, 1f);
			text = "READY (F10)";
		}
		else
		{
			((Color)(ref textColor))..ctor(1f, 0.3f, 0.3f, 1f);
			text = $"COOLDOWN: {Mathf.CeilToInt(num2)}s";
		}
		float num3 = 400f;
		float num4 = 40f;
		float num5 = ((float)Screen.width - num3) / 2f;
		float num6 = 20f;
		GUIStyle val = new GUIStyle(GUI.skin.label)
		{
			font = _peakFont,
			fontSize = 24,
			alignment = (TextAnchor)4,
			fontStyle = (FontStyle)1
		};
		val.normal.textColor = textColor;
		GUIStyle val2 = val;
		GUIStyle val3 = new GUIStyle(val2);
		val3.normal.textColor = new Color(0f, 0f, 0f, 0.7f);
		GUIStyle val4 = val3;
		GUI.Label(new Rect(num5 + 2f, num6 + 2f, num3, num4), text, val4);
		GUI.Label(new Rect(num5, num6, num3, num4), text, val2);
	}
}
public class LootItem
{
	public string ItemName;

	public float Weight;

	public Texture2D Icon;

	public LootItem(string name, float weight, Texture2D icon = null)
	{
		ItemName = name;
		Weight = weight;
		Icon = icon;
	}
}
public static class LootTable
{
	private static readonly List<LootItem> _allItems = new List<LootItem>();

	private static readonly Random _random = new Random();

	private static bool _initialized = false;

	public static readonly Color ArrowColor = new Color(1f, 0.84f, 0f);

	public static void Initialize()
	{
		if (!_initialized)
		{
			_initialized = true;
			CasePlugin.Logger.LogInfo((object)"[LootTable] Initialized (items will be loaded from catalog)");
		}
	}

	public static void LoadAllItemsFromCatalog(Dictionary<string, ushort> nameToId, Dictionary<string, Texture2D> nameToIcon)
	{
		_allItems.Clear();
		HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "King", "Queen", "Bishop", "Knight", "Rook", "Pawn" };
		HashSet<string> hashSet2 = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "ClimbingChalk", "Climbing Chalk", "SCOUTMASTERSOUL", "LOC:NAME_CLIMBINGCHALK", "LOC: NAME_CLIMBING CHALK", "Torn Page" };
		int num = 0;
		int num2 = 0;
		int num3 = 0;
		int num4 = 0;
		foreach (KeyValuePair<string, ushort> item in nameToId)
		{
			string key = item.Key;
			ushort value = item.Value;
			if (key.Contains("(Clone)") || key.StartsWith("Item_"))
			{
				num4++;
				continue;
			}
			if (ContainsCyrillic(key))
			{
				num2++;
				continue;
			}
			if (key.StartsWith("C_"))
			{
				num3++;
				continue;
			}
			if (hashSet.Contains(key))
			{
				num3++;
				continue;
			}
			if (key.Contains("GuidebookPage"))
			{
				num3++;
				continue;
			}
			if (hashSet2.Contains(key))
			{
				num3++;
				continue;
			}
			float weight = 1f;
			Texture2D value2 = null;
			nameToIcon.TryGetValue(key, out value2);
			AddItem(key, weight, value2);
			num++;
		}
		CasePlugin.Logger.LogInfo((object)$"[LootTable] Loaded {num} items (skipped: {num2} cyrillic, {num3} excluded, {num4} duplicates)");
	}

	private static bool ContainsCyrillic(string text)
	{
		foreach (char c in text)
		{
			if (c >= 'Ѐ' && c <= 'ӿ')
			{
				return true;
			}
		}
		return false;
	}

	private static void AddItem(string name, float weight, Texture2D icon = null)
	{
		_allItems.Add(new LootItem(name, weight, icon));
	}

	public static void UpdateIcons(Dictionary<string, Texture2D> iconCatalog)
	{
		int num = 0;
		foreach (LootItem allItem in _allItems)
		{
			if (iconCatalog.TryGetValue(allItem.ItemName, out var value))
			{
				allItem.Icon = value;
				num++;
			}
		}
		CasePlugin.Logger.LogInfo((object)$"[LootTable] Updated icons: {num}/{_allItems.Count}");
	}

	public static LootItem RollItem()
	{
		if (_allItems.Count == 0)
		{
			CasePlugin.Logger.LogError((object)"[LootTable] Item list is empty!");
			return null;
		}
		float num = 0f;
		foreach (LootItem allItem in _allItems)
		{
			num += allItem.Weight;
		}
		float num2 = (float)(_random.NextDouble() * (double)num);
		float num3 = 0f;
		foreach (LootItem allItem2 in _allItems)
		{
			num3 += allItem2.Weight;
			if (num2 <= num3)
			{
				return allItem2;
			}
		}
		return _allItems[0];
	}
}
public class RouletteUI : MonoBehaviour
{
	private static RouletteUI _instance;

	private bool _isActive = false;

	private Font _peakFont = null;

	private bool _fontLoaded = false;

	private readonly List<LootItem> _rouletteItems = new List<LootItem>();

	private LootItem _wonItem;

	private Action<LootItem> _onItemWon;

	private float _phaseStartTime = -1f;

	private float _showResultTime = -1f;

	private float _closeStartTime = -1f;

	private const float FADE_IN_DURATION = 0.4f;

	private const float WAIT_DURATION = 1f;

	private const float ROLL_DURATION = 3f;

	private const float RESULT_DURATION = 3f;

	private const float FADE_OUT_DURATION = 0.4f;

	private float _scrollOffset = 0f;

	private float _targetScrollOffset = 0f;

	private float _uiAlpha = 0f;

	private static readonly Color PEAK_BG_COLOR = new Color(0.05f, 0.08f, 0.12f, 0.95f);

	private static readonly Color PEAK_BORDER_COLOR = new Color(0.3f, 0.5f, 0.7f, 1f);

	private static readonly Color PEAK_ACCENT_COLOR = new Color(1f, 0.8f, 0.3f, 1f);

	private static readonly Dictionary<string, Texture2D> _fallbackIcons = new Dictionary<string, Texture2D>();

	private const float ITEM_WIDTH = 140f;

	private const float ITEM_HEIGHT = 200f;

	private const int VISIBLE_ITEMS = 5;

	public bool IsActive => _isActive;

	public static RouletteUI Instance
	{
		get
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)_instance == (Object)null)
			{
				GameObject val = new GameObject("PeakCaseRouletteUI");
				_instance = val.AddComponent<RouletteUI>();
				Object.DontDestroyOnLoad((Object)(object)val);
			}
			return _instance;
		}
	}

	private void LoadPeakFont()
	{
		if (_fontLoaded)
		{
			return;
		}
		_fontLoaded = true;
		Font[] array = Resources.FindObjectsOfTypeAll<Font>();
		CasePlugin.Logger.LogInfo((object)$"[RouletteUI] Found {array.Length} fonts in game");
		Font[] array2 = array;
		foreach (Font val in array2)
		{
			if (!((Object)(object)val == (Object)null) && ((Object)val).name.Contains("Binggrae"))
			{
				_peakFont = val;
				CasePlugin.Logger.LogInfo((object)("[RouletteUI] Using PEAK font: " + ((Object)val).name));
				break;
			}
		}
		if ((Object)(object)_peakFont == (Object)null)
		{
			Font[] array3 = array;
			foreach (Font val2 in array3)
			{
				if (!((Object)(object)val2 == (Object)null) && ((Object)val2).name.Contains("Pangolin"))
				{
					_peakFont = val2;
					CasePlugin.Logger.LogInfo((object)("[RouletteUI] Using fallback font: " + ((Object)val2).name));
					break;
				}
			}
		}
		if ((Object)(object)_peakFont == (Object)null && array.Length != 0)
		{
			_peakFont = array[0];
			CasePlugin.Logger.LogInfo((object)("[RouletteUI] Using first available font: " + ((Object)_peakFont).name));
		}
		if ((Object)(object)_peakFont == (Object)null)
		{
			_peakFont = Font.CreateDynamicFontFromOSFont("Arial", 24);
			CasePlugin.Logger.LogWarning((object)"[RouletteUI] No fonts found, using Arial");
		}
	}

	public void ShowRoulette(Action<LootItem> onItemWon)
	{
		_onItemWon = onItemWon;
		_isActive = true;
		_wonItem = null;
		_phaseStartTime = Time.time;
		_showResultTime = -1f;
		_closeStartTime = -1f;
		_scrollOffset = 0f;
		_uiAlpha = 0f;
		_rouletteItems.Clear();
		for (int i = 0; i < 20; i++)
		{
			_rouletteItems.Add(LootTable.RollItem());
		}
		_wonItem = LootTable.RollItem();
		_rouletteItems.Add(_wonItem);
		for (int j = 0; j < 10; j++)
		{
			_rouletteItems.Add(LootTable.RollItem());
		}
		int num = 20;
		int num2 = num - 2;
		_targetScrollOffset = (float)num2 * 140f;
		CasePlugin.Logger.LogInfo((object)("[RouletteUI] Roulette started. Winner: " + _wonItem.ItemName));
	}

	private void OnGUI()
	{
		//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Expected O, but got Unknown
		//IL_02ef: 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_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_035c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0601: Unknown result type (might be due to invalid IL or missing references)
		//IL_0624: Unknown result type (might be due to invalid IL or missing references)
		//IL_064e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0674: Unknown result type (might be due to invalid IL or missing references)
		//IL_0699: Unknown result type (might be due to invalid IL or missing references)
		//IL_0443: Unknown result type (might be due to invalid IL or missing references)
		//IL_045c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0475: Unknown result type (might be due to invalid IL or missing references)
		//IL_04db: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0506: Unknown result type (might be due to invalid IL or missing references)
		//IL_050e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0514: Unknown result type (might be due to invalid IL or missing references)
		//IL_0521: Expected O, but got Unknown
		//IL_0538: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0739: Unknown result type (might be due to invalid IL or missing references)
		//IL_073e: Unknown result type (might be due to invalid IL or missing references)
		//IL_074b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0754: Unknown result type (might be due to invalid IL or missing references)
		//IL_075c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0764: Unknown result type (might be due to invalid IL or missing references)
		//IL_076c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0772: Unknown result type (might be due to invalid IL or missing references)
		//IL_077f: Expected O, but got Unknown
		//IL_0798: Unknown result type (might be due to invalid IL or missing references)
		//IL_0721: Unknown result type (might be due to invalid IL or missing references)
		//IL_07e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_07e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_07f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_07ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0807: Unknown result type (might be due to invalid IL or missing references)
		//IL_080d: Unknown result type (might be due to invalid IL or missing references)
		//IL_081a: Expected O, but got Unknown
		//IL_0829: Unknown result type (might be due to invalid IL or missing references)
		if (!_isActive)
		{
			return;
		}
		if (!_fontLoaded)
		{
			LoadPeakFont();
		}
		float num = Time.time - _phaseStartTime;
		if (num < 0.4f)
		{
			_uiAlpha = Mathf.Clamp01(num / 0.4f);
		}
		else if (num < 1.4f)
		{
			_uiAlpha = 1f;
		}
		else if (num < 4.4f)
		{
			_uiAlpha = 1f;
		}
		else if (_showResultTime < 0f)
		{
			_showResultTime = Time.time;
			_uiAlpha = 1f;
			CasePlugin.Logger.LogInfo((object)("[RouletteUI] Won item: " + _wonItem.ItemName));
		}
		else
		{
			float num2 = Time.time - _showResultTime;
			if (num2 < 3f)
			{
				_uiAlpha = 1f;
			}
			else if (_closeStartTime < 0f)
			{
				_closeStartTime = Time.time;
			}
			else
			{
				float num3 = Time.time - _closeStartTime;
				_uiAlpha = 1f - Mathf.Clamp01(num3 / 0.4f);
				if (_uiAlpha <= 0f)
				{
					CasePlugin.Logger.LogInfo((object)("[RouletteUI] Auto close. Giving: " + _wonItem.ItemName));
					_onItemWon?.Invoke(_wonItem);
					CloseRoulette();
					return;
				}
			}
		}
		GUI.color = new Color(1f, 1f, 1f, _uiAlpha);
		GUI.color = new Color(0f, 0f, 0f, 0.4f * _uiAlpha);
		GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = new Color(1f, 1f, 1f, _uiAlpha);
		float num4 = 800f;
		float num5 = 500f;
		float num6 = ((float)Screen.width - num4) / 2f;
		float num7 = ((float)Screen.height - num5) / 2f;
		DrawStyledBox(new Rect(num6, num7, num4, num5), PEAK_BG_COLOR, PEAK_BORDER_COLOR, 3f);
		GUIStyle val = new GUIStyle(GUI.skin.label)
		{
			font = _peakFont,
			fontSize = 42,
			alignment = (TextAnchor)4,
			fontStyle = (FontStyle)1
		};
		val.normal.textColor = PEAK_ACCENT_COLOR;
		GUIStyle val2 = val;
		GUI.Label(new Rect(num6, num7 + 15f, num4, 60f), "ITEM ROULETTE", val2);
		float num8 = num7 + 90f;
		float num9 = 700f;
		float num10 = num6 + (num4 - num9) / 2f;
		DrawStyledBox(new Rect(num10 - 10f, num8 - 10f, num9 + 20f, 220f), new Color(0.1f, 0.15f, 0.2f, 0.8f), PEAK_BORDER_COLOR, 2f);
		float num11 = _phaseStartTime + 0.4f + 1f;
		float num12 = Time.time - num11;
		bool flag = num12 > 0f && num12 < 3f;
		GUI.BeginGroup(new Rect(num10, num8, num9, 200f));
		float num13 = 0f - _scrollOffset % 140f;
		int num14 = Mathf.FloorToInt(_scrollOffset / 140f);
		for (int i = -1; i < 6; i++)
		{
			int num15 = num14 + i;
			if (num15 >= 0 && num15 < _rouletteItems.Count)
			{
				LootItem lootItem = _rouletteItems[num15];
				float num16 = num13 + (float)i * 140f;
				DrawStyledBox(new Rect(num16 + 5f, 5f, 130f, 190f), new Color(0.15f, 0.2f, 0.25f, 0.9f), new Color(0.5f, 0.5f, 0.5f, 0.8f), 2f);
				Texture2D itemIcon = GetItemIcon(lootItem);
				if ((Object)(object)itemIcon != (Object)null)
				{
					float num17 = 80f;
					float num18 = num16 + (140f - num17) / 2f;
					GUI.DrawTexture(new Rect(num18, 30f, num17, num17), (Texture)(object)itemIcon);
				}
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					font = _peakFont,
					fontSize = 11,
					alignment = (TextAnchor)4,
					wordWrap = true,
					fontStyle = (FontStyle)1
				};
				val3.normal.textColor = Color.white;
				GUIStyle val4 = val3;
				GUI.Label(new Rect(num16 + 5f, 130f, 130f, 60f), lootItem.ItemName, val4);
			}
		}
		if (flag)
		{
			float num19 = num12 / 3f;
			float num20 = (1f - Mathf.Cos(num19 * MathF.PI)) / 2f;
			_scrollOffset = Mathf.Lerp(_scrollOffset, _targetScrollOffset * num20, Time.deltaTime * 8f);
		}
		GUI.EndGroup();
		float num21 = num10 + num9 / 2f;
		float num22 = 4f;
		float num23 = 20f;
		Color color = default(Color);
		((Color)(ref color))..ctor(LootTable.ArrowColor.r, LootTable.ArrowColor.g, LootTable.ArrowColor.b, _uiAlpha);
		GUI.color = color;
		DrawTriangle(new Rect(num21 - 10f, num8 - num23 - 5f, 20f, num23), pointingDown: true);
		DrawTriangle(new Rect(num21 - 10f, num8 + 200f + 5f, 20f, num23), pointingDown: false);
		GUI.DrawTexture(new Rect(num21 - num22 / 2f, num8 - 5f, num22, 210f), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = new Color(1f, 1f, 1f, _uiAlpha);
		if (_wonItem != null && _showResultTime >= 0f)
		{
			float num24 = Time.time - _showResultTime;
			Texture2D itemIcon2 = GetItemIcon(_wonItem);
			if ((Object)(object)itemIcon2 != (Object)null)
			{
				float num25 = 100f;
				float num26 = num6 + (num4 - num25) / 2f;
				float num27 = num8 + 200f + 40f;
				GUI.DrawTexture(new Rect(num26, num27, num25, num25), (Texture)(object)itemIcon2);
			}
			GUIStyle val5 = new GUIStyle(GUI.skin.label)
			{
				font = _peakFont,
				fontSize = 28,
				alignment = (TextAnchor)4,
				fontStyle = (FontStyle)1,
				wordWrap = true
			};
			val5.normal.textColor = PEAK_ACCENT_COLOR;
			GUIStyle val6 = val5;
			float num28 = num8 + 200f + 150f;
			GUI.Label(new Rect(num6, num28, num4, 40f), _wonItem.ItemName, val6);
			float num29 = 3f - num24;
			if (num29 > 0f && _closeStartTime < 0f)
			{
				GUIStyle val7 = new GUIStyle(GUI.skin.label)
				{
					font = _peakFont,
					fontSize = 14,
					alignment = (TextAnchor)4
				};
				val7.normal.textColor = Color.white;
				GUIStyle val8 = val7;
				GUI.Label(new Rect(num6, num28 + 60f, num4, 25f), $"Closes in {Mathf.CeilToInt(num29)} sec...", val8);
			}
		}
	}

	private void DrawTriangle(Rect rect, bool pointingDown)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: 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)
		int num = (int)((Rect)(ref rect)).width;
		Texture2D val = new Texture2D(num, num);
		for (int i = 0; i < num; i++)
		{
			for (int j = 0; j < num; j++)
			{
				float num2 = (float)i / (float)num;
				float num3 = (float)j / (float)num;
				bool flag = false;
				flag = ((!pointingDown) ? (num2 <= num3 && num2 <= 1f - num3) : (num2 >= 1f - num3 && num2 >= num3));
				val.SetPixel(j, i, (Color)(flag ? Color.white : new Color(0f, 0f, 0f, 0f)));
			}
		}
		val.Apply();
		GUI.DrawTexture(rect, (Texture)(object)val);
	}

	private Texture2D GetItemIcon(LootItem item)
	{
		if ((Object)(object)item.Icon != (Object)null)
		{
			return item.Icon;
		}
		if (!_fallbackIcons.ContainsKey(item.ItemName))
		{
			_fallbackIcons[item.ItemName] = CreateFallbackIcon(item.ItemName);
		}
		return _fallbackIcons[item.ItemName];
	}

	private Texture2D CreateFallbackIcon(string itemName)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: 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_0070: Unknown result type (might be due to invalid IL or missing references)
		int num = 128;
		Texture2D val = new Texture2D(num, num);
		Color val2 = default(Color);
		((Color)(ref val2))..ctor(0.4f, 0.4f, 0.4f);
		for (int i = 0; i < num; i++)
		{
			for (int j = 0; j < num; j++)
			{
				float num2 = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)num / 2f, (float)num / 2f)) / ((float)num / 2f);
				val.SetPixel(j, i, Color.Lerp(val2, Color.black, num2 * 0.5f));
			}
		}
		val.Apply();
		return val;
	}

	private void CloseRoulette()
	{
		_isActive = false;
		_wonItem = null;
		_phaseStartTime = -1f;
		_showResultTime = -1f;
		_closeStartTime = -1f;
		_fallbackIcons.Clear();
	}

	private void DrawStyledBox(Rect rect, Color bgColor, Color borderColor, float borderWidth)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		GUI.color = new Color(bgColor.r, bgColor.g, bgColor.b, bgColor.a * _uiAlpha);
		GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture);
		GUI.color = new Color(1f, 1f, 1f, _uiAlpha);
		GUI.color = new Color(borderColor.r, borderColor.g, borderColor.b, borderColor.a * _uiAlpha);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, borderWidth), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + ((Rect)(ref rect)).height - borderWidth, ((Rect)(ref rect)).width, borderWidth), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, borderWidth, ((Rect)(ref rect)).height), (Texture)(object)Texture2D.whiteTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + ((Rect)(ref rect)).width - borderWidth, ((Rect)(ref rect)).y, borderWidth, ((Rect)(ref rect)).height), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = new Color(1f, 1f, 1f, _uiAlpha);
	}
}