Decompiled source of REPO lucky block v1.2.0

REPO_lucky_block.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using REPOLib.Modules;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("REPO_lucky_block")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+37173992a6f2015f5c3debdb5967fae80505af17")]
[assembly: AssemblyProduct("REPO_lucky_block")]
[assembly: AssemblyTitle("REPO_lucky_block")]
[assembly: AssemblyVersion("1.0.0.0")]
[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;
		}
	}
}
internal static class CategoryWeights
{
	internal static ConfigEntry<float> Lucky;

	internal static ConfigEntry<float> Unlucky;

	internal static ConfigEntry<float> Chaotic;

	internal static ConfigEntry<float> Wacky;

	internal static void BindConfig(ConfigFile config)
	{
		Lucky = Bind(config, "Lucky", "good outcomes: loot, items, upgrades, heals");
		Unlucky = Bind(config, "Unlucky", "bad outcomes: monsters, explosives, quota hikes");
		Chaotic = Bind(config, "Chaotic", "level scramblers: loot scatter, meteors, earthquakes");
		Wacky = Bind(config, "Wacky", "silly client-side effects (Private edition only)");
	}

	private static ConfigEntry<float> Bind(ConfigFile config, string key, string what)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		return config.Bind<float>("Category Weights", key, 1f, new ConfigDescription("How often " + what + " roll, relative to the other categories. 1 = normal, 0.5 = half as often, 0 = never, 2 = twice as often.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>()));
	}

	internal static float Get(LuckyEventCategory category)
	{
		ConfigEntry<float> val = EntryFor(category);
		if (val == null)
		{
			return 1f;
		}
		return Mathf.Max(0f, val.Value);
	}

	internal static ConfigEntry<float> EntryFor(LuckyEventCategory category)
	{
		return (ConfigEntry<float>)(category switch
		{
			LuckyEventCategory.Lucky => Lucky, 
			LuckyEventCategory.Unlucky => Unlucky, 
			LuckyEventCategory.Chaotic => Chaotic, 
			LuckyEventCategory.Wacky => Wacky, 
			_ => null, 
		});
	}
}
internal static class EventHelpers
{
	internal static ConfigEntry<float> ConfigTeleportValueLoss;

	private static FieldInfo _fValCurrent;

	private static FieldInfo _fValOriginal;

	private static FieldInfo _fValSet;

	private static FieldInfo _fExtCurrent;

	private static FieldInfo _fGrabbedObj;

	private static bool _reflected;

	private const float IMPACT_GRACE_SECONDS = 4f;

	private static Item _grenadeItem;

	internal static float TeleportValueLoss
	{
		get
		{
			if (ConfigTeleportValueLoss == null)
			{
				return 0.05f;
			}
			return Mathf.Clamp(ConfigTeleportValueLoss.Value, 0f, 0.5f);
		}
	}

	internal static void BindConfig(ConfigFile config)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		ConfigTeleportValueLoss = config.Bind<float>("General", "TeleportValueLoss", 0.05f, new ConfigDescription("How much value loot loses when an event moves it (Hoarder's Curse, Treasure Migration, Vacuum Pulse). 0.05 = 5%. The fall itself no longer breaks anything.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>()));
	}

	private static void EnsureReflection()
	{
		if (!_reflected)
		{
			_reflected = true;
			Type? typeFromHandle = typeof(ValuableObject);
			_fValCurrent = typeFromHandle.GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.NonPublic);
			_fValOriginal = typeFromHandle.GetField("dollarValueOriginal", BindingFlags.Instance | BindingFlags.NonPublic);
			_fValSet = typeFromHandle.GetField("dollarValueSet", BindingFlags.Instance | BindingFlags.NonPublic);
			_fExtCurrent = typeof(RoundDirector).GetField("extractionPointCurrent", BindingFlags.Instance | BindingFlags.NonPublic);
			_fGrabbedObj = typeof(PhysGrabber).GetField("grabbedPhysGrabObject", BindingFlags.Instance | BindingFlags.NonPublic);
		}
	}

	internal static void Announce(string label)
	{
		LuckyFx.Broadcast("announce", label);
	}

	internal static List<PlayerAvatar> GetAllPlayers()
	{
		List<PlayerAvatar> list = new List<PlayerAvatar>();
		foreach (PlayerAvatar item in SemiFunc.PlayerGetAll())
		{
			if ((Object)(object)item != (Object)null)
			{
				list.Add(item);
			}
		}
		return list;
	}

	internal static void TeleportPlayer(PlayerAvatar avatar, Vector3 pos)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: 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_008f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)avatar == (Object)null)
		{
			return;
		}
		avatar.Spawn(pos, ((Component)avatar).transform.rotation);
		if ((Object)(object)avatar == (Object)(object)PlayerAvatar.instance)
		{
			TeleportLocalController(pos);
		}
		else if (SemiFunc.IsMultiplayer() && ModeManager.IsPrivate)
		{
			PhotonView component = ((Component)avatar).GetComponent<PhotonView>();
			if ((Object)(object)component != (Object)null)
			{
				LuckyFx.Broadcast("teleport", string.Format(CultureInfo.InvariantCulture, "{0},{1:F2},{2:F2},{3:F2}", component.ViewID, pos.x, pos.y, pos.z));
			}
		}
	}

	internal static void TeleportLocalController(Vector3 pos)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		PlayerController instance = PlayerController.instance;
		if (!((Object)(object)instance == (Object)null))
		{
			if ((Object)(object)instance.rb != (Object)null)
			{
				instance.rb.velocity = Vector3.zero;
				instance.rb.position = pos;
			}
			((Component)instance).transform.position = pos;
		}
	}

	internal static void UpgradePlayer(PlayerAvatar avatar, string upgradeName, int amount = 1)
	{
		//IL_0070: 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)
		if ((Object)(object)avatar == (Object)null || (Object)(object)PunManager.instance == (Object)null)
		{
			return;
		}
		string text = SemiFunc.PlayerGetSteamID(avatar);
		if (string.IsNullOrEmpty(text))
		{
			return;
		}
		if (SemiFunc.IsMultiplayer())
		{
			PhotonView component = ((Component)PunManager.instance).GetComponent<PhotonView>();
			if ((Object)(object)component != (Object)null)
			{
				component.RPC("TesterUpgradeCommandRPC", (RpcTarget)0, new object[3] { text, upgradeName, amount });
			}
		}
		else
		{
			PunManager.instance.TesterUpgradeCommandRPC(text, upgradeName, amount, default(PhotonMessageInfo));
		}
	}

	internal static void HealPlayer(PlayerAvatar avatar, int amount)
	{
		if ((Object)(object)avatar != (Object)null && (Object)(object)avatar.playerHealth != (Object)null)
		{
			avatar.playerHealth.HealOther(amount, true);
		}
	}

	internal static List<Enemy> GetSpawnedEnemies()
	{
		List<Enemy> list = new List<Enemy>();
		if ((Object)(object)EnemyDirector.instance == (Object)null)
		{
			return list;
		}
		foreach (EnemyParent item in EnemyDirector.instance.enemiesSpawned)
		{
			if (!((Object)(object)item == (Object)null))
			{
				Enemy componentInChildren = ((Component)item).GetComponentInChildren<Enemy>(true);
				if ((Object)(object)componentInChildren != (Object)null && ((Component)componentInChildren).gameObject.activeInHierarchy)
				{
					list.Add(componentInChildren);
				}
			}
		}
		return list;
	}

	internal static void TeleportEnemy(Enemy enemy, Vector3 pos)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)enemy != (Object)null)
		{
			enemy.EnemyTeleported(pos);
		}
	}

	internal static List<ValuableObject> GetLooseValuables(bool includeInCart = true)
	{
		List<ValuableObject> list = new List<ValuableObject>();
		List<GameObject> list2 = (((Object)(object)RoundDirector.instance != (Object)null) ? RoundDirector.instance.dollarHaulList : null);
		ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>();
		foreach (ValuableObject val in array)
		{
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponent<LuckyBlock>() != (Object)null))
			{
				LuckyBlockItem component = ((Component)val).GetComponent<LuckyBlockItem>();
				if ((!((Object)(object)component != (Object)null) || !component.IsLucky) && (list2 == null || !list2.Contains(((Component)val).gameObject)) && (includeInCart || !IsInCart((Component)(object)val)))
				{
					list.Add(val);
				}
			}
		}
		return list;
	}

	internal static bool IsInCart(Component c)
	{
		if ((Object)(object)c == (Object)null)
		{
			return false;
		}
		PhysGrabObjectImpactDetector component = c.GetComponent<PhysGrabObjectImpactDetector>();
		if ((Object)(object)component != (Object)null)
		{
			if (!component.inCart)
			{
				return component.isCart;
			}
			return true;
		}
		return false;
	}

	internal static float GetValuableValue(ValuableObject v)
	{
		EnsureReflection();
		if ((Object)(object)v == (Object)null || _fValCurrent == null)
		{
			return 0f;
		}
		return (float)_fValCurrent.GetValue(v);
	}

	internal static void SetValuableValue(ValuableObject v, float value)
	{
		EnsureReflection();
		if ((Object)(object)v == (Object)null || _fValCurrent == null)
		{
			return;
		}
		value = Mathf.Max(0f, Mathf.Round(value));
		_fValCurrent.SetValue(v, value);
		_fValOriginal?.SetValue(v, value);
		_fValSet?.SetValue(v, true);
		if (SemiFunc.IsMultiplayer())
		{
			PhotonView component = ((Component)v).GetComponent<PhotonView>();
			if ((Object)(object)component != (Object)null && component.ViewID != 0)
			{
				component.RPC("DollarValueSetRPC", (RpcTarget)1, new object[1] { value });
			}
		}
	}

	internal static void TeleportPhysObject(PhysGrabObject o, Vector3 pos)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)o != (Object)null)
		{
			o.Teleport(pos, ((Component)o).transform.rotation);
		}
	}

	internal static void TeleportValuableSafe(ValuableObject v, Vector3 pos, bool snapToFloor = true)
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: 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_004f: 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_0077: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)v == (Object)null)
		{
			return;
		}
		PhysGrabObject component = ((Component)v).GetComponent<PhysGrabObject>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		PhysGrabObjectImpactDetector component2 = ((Component)v).GetComponent<PhysGrabObjectImpactDetector>();
		if ((Object)(object)component2 != (Object)null)
		{
			component2.ImpactDisable(4f);
		}
		Rigidbody rb = component.rb;
		if ((Object)(object)rb != (Object)null && !rb.isKinematic)
		{
			rb.velocity = Vector3.zero;
			rb.angularVelocity = Vector3.zero;
		}
		component.Teleport(snapToFloor ? FloorBelow(pos) : pos, ((Component)component).transform.rotation);
		float teleportValueLoss = TeleportValueLoss;
		if (teleportValueLoss > 0f)
		{
			float valuableValue = GetValuableValue(v);
			if (valuableValue > 0f)
			{
				SetValuableValue(v, valuableValue * (1f - teleportValueLoss));
			}
		}
	}

	private static Vector3 FloorBelow(Vector3 pos)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: 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_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		RaycastHit val = default(RaycastHit);
		if (!Physics.Raycast(pos + Vector3.up * 1.5f, Vector3.down, ref val, 6f, -1, (QueryTriggerInteraction)1))
		{
			return pos;
		}
		return ((RaycastHit)(ref val)).point + Vector3.up * 0.35f;
	}

	internal static void DestroyValuable(ValuableObject v)
	{
		if (!((Object)(object)v == (Object)null))
		{
			PhysGrabObjectImpactDetector component = ((Component)v).GetComponent<PhysGrabObjectImpactDetector>();
			if ((Object)(object)component != (Object)null)
			{
				component.DestroyObject(true);
			}
			else
			{
				Object.Destroy((Object)(object)((Component)v).gameObject);
			}
		}
	}

	internal static ExtractionPoint GetActiveExtraction()
	{
		EnsureReflection();
		if ((Object)(object)RoundDirector.instance == (Object)null || _fExtCurrent == null)
		{
			return null;
		}
		object? value = _fExtCurrent.GetValue(RoundDirector.instance);
		return (ExtractionPoint)((value is ExtractionPoint) ? value : null);
	}

	internal static void SetHaulGoal(ExtractionPoint ep, int value)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ep == (Object)null)
		{
			return;
		}
		value = Mathf.Max(1, value);
		if (SemiFunc.IsMultiplayer())
		{
			PhotonView component = ((Component)ep).GetComponent<PhotonView>();
			if ((Object)(object)component != (Object)null && component.ViewID != 0)
			{
				component.RPC("HaulGoalSetRPC", (RpcTarget)0, new object[1] { value });
			}
		}
		else
		{
			ep.HaulGoalSetRPC(value, default(PhotonMessageInfo));
		}
	}

	internal static List<Vector3> GetRandomLevelPoints(int count)
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: 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)
		List<LevelPoint> reachablePoints = LevelPointUtils.GetReachablePoints(LuckyBlockSpawner.MaxSpawnDistance);
		List<Vector3> list = new List<Vector3>(count);
		if (reachablePoints.Count == 0)
		{
			PlayerAvatar instance = PlayerAvatar.instance;
			return SpawnUtils.GetFloorRing(((Object)(object)instance != (Object)null) ? ((Component)instance).transform.position : Vector3.zero, count, 5f);
		}
		for (int i = 0; i < count; i++)
		{
			LevelPoint lp = reachablePoints[Random.Range(0, reachablePoints.Count)];
			list.Add(LevelPointUtils.ToSpawnPosition(lp));
		}
		return list;
	}

	private static Item FindGrenadeItem()
	{
		if ((Object)(object)_grenadeItem != (Object)null)
		{
			return _grenadeItem;
		}
		foreach (Item allItem in Items.AllItems)
		{
			string text = ((Object)allItem).name.ToLowerInvariant();
			if (text.Contains("grenade") && !text.Contains("mine") && !text.Contains("human"))
			{
				_grenadeItem = allItem;
				break;
			}
		}
		return _grenadeItem;
	}

	internal static void SpawnGrenadeAt(Vector3 pos, float fuse)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: 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)
		Item val = FindGrenadeItem();
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		GameObject val2 = (SemiFunc.IsMultiplayer() ? Items.SpawnItem(val, pos, Quaternion.identity) : Object.Instantiate<GameObject>(((PrefabRef<GameObject>)(object)val.prefab).Prefab, pos, Quaternion.identity));
		if (!((Object)(object)val2 == (Object)null))
		{
			ItemGrenade componentInChildren = val2.GetComponentInChildren<ItemGrenade>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.isSpawnedGrenade = true;
				componentInChildren.tickTime = fuse;
			}
			ItemToggle componentInChildren2 = val2.GetComponentInChildren<ItemToggle>();
			if ((Object)(object)componentInChildren2 != (Object)null)
			{
				componentInChildren2.toggleState = true;
			}
		}
	}

	internal static void ReleaseLocalGrab()
	{
		EnsureReflection();
		PhysGrabber instance = PhysGrabber.instance;
		if (!((Object)(object)instance == (Object)null) && instance.grabbed && !(_fGrabbedObj == null))
		{
			object? value = _fGrabbedObj.GetValue(instance);
			PhysGrabObject val = (PhysGrabObject)((value is PhysGrabObject) ? value : null);
			if (!((Object)(object)val == (Object)null))
			{
				PhotonView component = ((Component)val).GetComponent<PhotonView>();
				int num = (((Object)(object)component != (Object)null) ? component.ViewID : 0);
				instance.OverrideGrabRelease(num, 1f);
			}
		}
	}
}
public class EvTreasureMigration : LuckyEvent
{
	public override string Id => "TreasureMigration";

	public override string Label => "Treasure Migration — all loot scatters";

	public override LuckyEventCategory Category => LuckyEventCategory.Chaotic;

	public override float DefaultWeight => 2f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		return EventHelpers.GetLooseValuables(includeInCart: false).Count > 2;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		List<ValuableObject> looseValuables = EventHelpers.GetLooseValuables(includeInCart: false);
		List<Vector3> randomLevelPoints = EventHelpers.GetRandomLevelPoints(looseValuables.Count);
		for (int i = 0; i < looseValuables.Count && i < randomLevelPoints.Count; i++)
		{
			EventHelpers.TeleportValuableSafe(looseValuables[i], randomLevelPoints[i]);
		}
	}
}
public class EvPositionSwap : LuckyEvent
{
	public override string Id => "PositionSwap";

	public override string Label => "Musical Chairs — everyone swaps positions";

	public override LuckyEventCategory Category => LuckyEventCategory.Chaotic;

	public override float DefaultWeight => 3f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		return EventHelpers.GetAllPlayers().Count >= 2;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		List<PlayerAvatar> allPlayers = EventHelpers.GetAllPlayers();
		List<Vector3> list = new List<Vector3>(allPlayers.Count);
		foreach (PlayerAvatar item in allPlayers)
		{
			list.Add(((Component)item).transform.position);
		}
		for (int i = 0; i < allPlayers.Count; i++)
		{
			EventHelpers.TeleportPlayer(allPlayers[i], list[(i + 1) % list.Count]);
		}
	}
}
public class EvMeteorShower : LuckyEvent
{
	public override string Id => "MeteorShower";

	public override string Label => "Meteor Shower — grenades rain on everyone";

	public override LuckyEventCategory Category => LuckyEventCategory.Chaotic;

	public override float DefaultWeight => 2.5f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = default(Vector3);
		foreach (PlayerAvatar allPlayer in EventHelpers.GetAllPlayers())
		{
			if (!((Object)(object)allPlayer == (Object)null))
			{
				Vector3 position = ((Component)allPlayer).transform.position;
				for (int i = 0; i < 3; i++)
				{
					((Vector3)(ref val))..ctor(Random.Range(-2.5f, 2.5f), 0f, Random.Range(-2.5f, 2.5f));
					EventHelpers.SpawnGrenadeAt(position + val + Vector3.up * 6f, 1.6f);
				}
			}
		}
	}
}
public class EvEarthquake : LuckyEvent
{
	public override string Id => "Earthquake";

	public override string Label => "Earthquake — everything gets launched";

	public override LuckyEventCategory Category => LuckyEventCategory.Chaotic;

	public override float DefaultWeight => 3f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		PhysGrabObject[] array = Object.FindObjectsOfType<PhysGrabObject>();
		Vector3 val2 = default(Vector3);
		foreach (PhysGrabObject val in array)
		{
			if (!((Object)(object)val == (Object)null) && !EventHelpers.IsInCart((Component)(object)val))
			{
				Rigidbody component = ((Component)val).GetComponent<Rigidbody>();
				if (!((Object)(object)component == (Object)null) && !component.isKinematic)
				{
					((Vector3)(ref val2))..ctor(Random.Range(-1.5f, 1.5f), Random.Range(2f, 4f), Random.Range(-1.5f, 1.5f));
					component.AddForce(val2, (ForceMode)2);
				}
			}
		}
		LuckyFx.Broadcast("shake", "5,1.5");
	}
}
public class EvVacuumPulse : LuckyEvent
{
	public override string Id => "VacuumPulse";

	public override string Label => "Vacuum Pulse — loot flies to the block";

	public override LuckyEventCategory Category => LuckyEventCategory.Chaotic;

	public override float DefaultWeight => 2f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		return EventHelpers.GetLooseValuables(includeInCart: false).Count > 1;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		List<ValuableObject> looseValuables = EventHelpers.GetLooseValuables(includeInCart: false);
		List<Vector3> floorRing = SpawnUtils.GetFloorRing(ctx.BlockPos, Mathf.Max(3, looseValuables.Count), 2.2f);
		int num = 0;
		foreach (ValuableObject item in looseValuables)
		{
			EventHelpers.TeleportValuableSafe(item, floorRing[num++ % floorRing.Count]);
		}
	}
}
public class EvEnemyScatter : LuckyEvent
{
	public override string Id => "EnemyScatter";

	public override string Label => "The Rapture — every enemy teleports away";

	public override LuckyEventCategory Category => LuckyEventCategory.Chaotic;

	public override float DefaultWeight => 2f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		return EventHelpers.GetSpawnedEnemies().Count > 0;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		List<Enemy> spawnedEnemies = EventHelpers.GetSpawnedEnemies();
		List<Vector3> randomLevelPoints = EventHelpers.GetRandomLevelPoints(spawnedEnemies.Count);
		for (int i = 0; i < spawnedEnemies.Count && i < randomLevelPoints.Count; i++)
		{
			EventHelpers.TeleportEnemy(spawnedEnemies[i], randomLevelPoints[i]);
		}
	}
}
public class EvZeroGLoot : LuckyEvent
{
	public override string Id => "ZeroGLoot";

	public override string Label => "Zero-G Loot — valuables float for 15s";

	public override LuckyEventCategory Category => LuckyEventCategory.Chaotic;

	public override float DefaultWeight => 3f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		return EventHelpers.GetLooseValuables(includeInCart: false).Count > 0;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_0048: 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)
		foreach (ValuableObject looseValuable in EventHelpers.GetLooseValuables(includeInCart: false))
		{
			PhysGrabObject component = ((Component)looseValuable).GetComponent<PhysGrabObject>();
			if (!((Object)(object)component == (Object)null))
			{
				component.OverrideZeroGravity(15f);
				Rigidbody component2 = ((Component)component).GetComponent<Rigidbody>();
				if ((Object)(object)component2 != (Object)null && !component2.isKinematic)
				{
					component2.AddForce(Vector3.up * 1.2f, (ForceMode)2);
				}
			}
		}
	}
}
public class EvValuable : LuckyEvent
{
	public override string Id => "Valuable";

	public override string Label => "Random Valuable";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 14f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		SpawnUtils.SpawnRandomValuable(SpawnUtils.GetSpawnPositionInFront(ctx.Opener, 2.5f));
	}
}
public class EvJackpot : LuckyEvent
{
	public override string Id => "Jackpot";

	public override string Label => "Jackpot — 3 Valuables";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 4f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		foreach (Vector3 item in SpawnUtils.GetFloorRing(ctx.BlockPos, 3, 1.8f))
		{
			SpawnUtils.SpawnRandomValuable(item);
		}
	}
}
public class EvItem : LuckyEvent
{
	public override string Id => "Item";

	public override string Label => "Random Item";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 10f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		SpawnUtils.SpawnRandomItem(SpawnUtils.GetSpawnPositionInFront(ctx.Opener, 2.5f));
	}
}
public class EvToolChest : LuckyEvent
{
	public override string Id => "ToolChest";

	public override string Label => "Tool Chest — 2 Items";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 3f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		foreach (Vector3 item in SpawnUtils.GetFloorRing(ctx.BlockPos, 2, 1.5f))
		{
			SpawnUtils.SpawnRandomItem(item);
		}
	}
}
public class EvWeaponDrop : LuckyEvent
{
	public override string Id => "WeaponDrop";

	public override string Label => "Armory — Random Weapon";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 1f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		SpawnUtils.SpawnRandomWeapon(SpawnUtils.GetSpawnPositionInFront(ctx.Opener, 2.5f));
	}
}
public class EvPotion : LuckyEvent
{
	public override string Id => "Potion";

	public override string Label => "Potion (breaks on floor)";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 6f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		SpawnUtils.SpawnPotion(SpawnUtils.GetSpawnPositionInFront(ctx.Opener, 2.5f));
	}
}
public class EvLuckyCluster : LuckyEvent
{
	public override string Id => "LuckyCluster";

	public override string Label => "Lucky Cluster — 3 New Blocks";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 6f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		LuckyBlockManager.Instance?.SpawnBlocks(SpawnUtils.GetFloorRing(ctx.BlockPos, 3, 2f));
	}
}
public class EvHealingWave : LuckyEvent
{
	public override string Id => "HealingWave";

	public override string Label => "Healing Wave — +50 HP everyone";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 5f;

	public override void Execute(LuckyEventContext ctx)
	{
		foreach (PlayerAvatar allPlayer in EventHelpers.GetAllPlayers())
		{
			EventHelpers.HealPlayer(allPlayer, 50);
		}
	}
}
public abstract class EvUpgradeBase : LuckyEvent
{
	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	protected abstract string UpgradeName { get; }

	public override void Execute(LuckyEventContext ctx)
	{
		EventHelpers.UpgradePlayer(ctx.Opener, UpgradeName);
	}
}
public class EvUpgradeSpeed : EvUpgradeBase
{
	public override string Id => "UpgradeSpeed";

	public override string Label => "Adrenaline — Sprint Speed +1";

	public override float DefaultWeight => 2.5f;

	protected override string UpgradeName => "Speed";
}
public class EvUpgradeJump : EvUpgradeBase
{
	public override string Id => "UpgradeJump";

	public override string Label => "Moon Boots — Extra Jump +1";

	public override float DefaultWeight => 2.5f;

	protected override string UpgradeName => "ExtraJump";
}
public class EvUpgradeStamina : EvUpgradeBase
{
	public override string Id => "UpgradeStamina";

	public override string Label => "Iron Lungs — Stamina +1";

	public override float DefaultWeight => 2.5f;

	protected override string UpgradeName => "Stamina";
}
public class EvUpgradeHealth : EvUpgradeBase
{
	public override string Id => "UpgradeHealth";

	public override string Label => "Vitality — Max Health +1";

	public override float DefaultWeight => 2.5f;

	protected override string UpgradeName => "Health";
}
public class EvUpgradeStrength : EvUpgradeBase
{
	public override string Id => "UpgradeStrength";

	public override string Label => "Strong Arms — Grab Strength +1";

	public override float DefaultWeight => 2f;

	protected override string UpgradeName => "Strength";
}
public class EvUpgradeRange : EvUpgradeBase
{
	public override string Id => "UpgradeRange";

	public override string Label => "Long Reach — Grab Range +1";

	public override float DefaultWeight => 2f;

	protected override string UpgradeName => "Range";
}
public class EvEnemyFreeze : LuckyEvent
{
	public override string Id => "EnemyFreeze";

	public override string Label => "Deep Freeze — enemies frozen 10s";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 4f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		return EventHelpers.GetSpawnedEnemies().Count > 0;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		foreach (Enemy spawnedEnemy in EventHelpers.GetSpawnedEnemies())
		{
			spawnedEnemy.Freeze(10f);
		}
	}
}
public class EvGoldenTouch : LuckyEvent
{
	public override string Id => "GoldenTouch";

	public override string Label => "Golden Touch — all loot +25% value";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 3f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		return EventHelpers.GetLooseValuables().Count > 0;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		foreach (ValuableObject looseValuable in EventHelpers.GetLooseValuables())
		{
			float valuableValue = EventHelpers.GetValuableValue(looseValuable);
			if (valuableValue > 0f)
			{
				EventHelpers.SetValuableValue(looseValuable, valuableValue * 1.25f);
			}
		}
	}
}
public class EvScavengerHunt : LuckyEvent
{
	public override string Id => "ScavengerHunt";

	public override string Label => "Scavenger Hunt — one hidden valuable ×10";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 3f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		return EventHelpers.GetLooseValuables().Count > 0;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		List<ValuableObject> looseValuables = EventHelpers.GetLooseValuables(includeInCart: false);
		if (looseValuables.Count == 0)
		{
			looseValuables = EventHelpers.GetLooseValuables();
		}
		if (looseValuables.Count != 0)
		{
			ValuableObject v = looseValuables[Random.Range(0, looseValuables.Count)];
			float valuableValue = EventHelpers.GetValuableValue(v);
			if (valuableValue > 0f)
			{
				EventHelpers.SetValuableValue(v, valuableValue * 10f);
			}
		}
	}
}
public class EvLuckyDiscount : LuckyEvent
{
	public override string Id => "LuckyDiscount";

	public override string Label => "Lucky Discount — quota −15%";

	public override LuckyEventCategory Category => LuckyEventCategory.Lucky;

	public override float DefaultWeight => 2f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		ExtractionPoint activeExtraction = EventHelpers.GetActiveExtraction();
		if ((Object)(object)activeExtraction != (Object)null)
		{
			return activeExtraction.haulGoal > 0;
		}
		return false;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		ExtractionPoint activeExtraction = EventHelpers.GetActiveExtraction();
		if (!((Object)(object)activeExtraction == (Object)null))
		{
			EventHelpers.SetHaulGoal(activeExtraction, Mathf.RoundToInt((float)activeExtraction.haulGoal * 0.85f));
		}
	}
}
public class EvMonster : LuckyEvent
{
	public override string Id => "Monster";

	public override string Label => "Random Monster";

	public override LuckyEventCategory Category => LuckyEventCategory.Unlucky;

	public override float DefaultWeight => 8f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		SpawnUtils.SpawnRandomMonster(SpawnUtils.GetSpawnPositionInFront(ctx.Opener, 2.5f), (MonoBehaviour)(object)LuckyBlockPlugin.Instance);
	}
}
public class EvMonsterPack : LuckyEvent
{
	public override string Id => "MonsterPack";

	public override string Label => "Monster Pack — 2 Monsters";

	public override LuckyEventCategory Category => LuckyEventCategory.Unlucky;

	public override float DefaultWeight => 2.5f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		foreach (Vector3 item in SpawnUtils.GetFloorRing(ctx.BlockPos, 2, 3f))
		{
			SpawnUtils.SpawnRandomMonster(item, (MonoBehaviour)(object)LuckyBlockPlugin.Instance);
		}
	}
}
public class EvExplosiveFeet : LuckyEvent
{
	public override string Id => "ExplosiveFeet";

	public override string Label => "Explosive at Feet";

	public override LuckyEventCategory Category => LuckyEventCategory.Unlucky;

	public override float DefaultWeight => 7f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		SpawnUtils.SpawnRandomExplosive(SpawnUtils.GetSpawnPositionOnPlayer(ctx.Opener));
	}
}
public class EvClusterSmall : LuckyEvent
{
	public override string Id => "ClusterSmall";

	public override string Label => "Small Cluster — 3 bombs around player";

	public override LuckyEventCategory Category => LuckyEventCategory.Unlucky;

	public override float DefaultWeight => 5f;

	public override void Execute(LuckyEventContext ctx)
	{
		SpawnUtils.SpawnExplosiveCluster(ctx.Opener);
	}
}
public class EvClusterLarge : LuckyEvent
{
	public override string Id => "ClusterLarge";

	public override string Label => "Large Cluster — 5 bombs around block";

	public override LuckyEventCategory Category => LuckyEventCategory.Unlucky;

	public override float DefaultWeight => 3f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		SpawnUtils.SpawnLargeExplosiveCluster(ctx.BlockPos);
	}
}
public class EvTumble : LuckyEvent
{
	public override string Id => "Tumble";

	public override string Label => "Knockdown — tumble lock 3s";

	public override LuckyEventCategory Category => LuckyEventCategory.Unlucky;

	public override float DefaultWeight => 4f;

	public override void Execute(LuckyEventContext ctx)
	{
		RandomEventRoller.ForceTumbleLock(ctx.Opener);
	}
}
public class EvTeleportRoulette : LuckyEvent
{
	public override string Id => "TeleportRoulette";

	public override string Label => "Teleport Roulette — opener sent somewhere";

	public override LuckyEventCategory Category => LuckyEventCategory.Unlucky;

	public override float DefaultWeight => 3f;

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> randomLevelPoints = EventHelpers.GetRandomLevelPoints(1);
		if (randomLevelPoints.Count > 0)
		{
			EventHelpers.TeleportPlayer(ctx.Opener, randomLevelPoints[0]);
		}
	}
}
public class EvPiedPiper : LuckyEvent
{
	public override string Id => "PiedPiper";

	public override string Label => "Pied Piper — every enemy comes to YOU";

	public override LuckyEventCategory Category => LuckyEventCategory.Unlucky;

	public override float DefaultWeight => 2f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		return EventHelpers.GetSpawnedEnemies().Count > 0;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		//IL_001a: 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)
		if ((Object)(object)ctx.Opener == (Object)null)
		{
			return;
		}
		List<Vector3> floorRing = SpawnUtils.GetFloorRing(((Component)ctx.Opener).transform.position, Mathf.Max(1, EventHelpers.GetSpawnedEnemies().Count), 4f);
		int num = 0;
		foreach (Enemy spawnedEnemy in EventHelpers.GetSpawnedEnemies())
		{
			EventHelpers.TeleportEnemy(spawnedEnemy, floorRing[num++ % floorRing.Count]);
		}
	}
}
public class EvTaxman : LuckyEvent
{
	public override string Id => "Taxman";

	public override string Label => "The Taxman — cheapest valuable repossessed";

	public override LuckyEventCategory Category => LuckyEventCategory.Unlucky;

	public override float DefaultWeight => 3f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		return EventHelpers.GetLooseValuables(includeInCart: false).Count > 1;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		ValuableObject val = null;
		float num = float.MaxValue;
		foreach (ValuableObject looseValuable in EventHelpers.GetLooseValuables(includeInCart: false))
		{
			float valuableValue = EventHelpers.GetValuableValue(looseValuable);
			if (valuableValue > 0f && valuableValue < num)
			{
				num = valuableValue;
				val = looseValuable;
			}
		}
		if ((Object)(object)val != (Object)null)
		{
			EventHelpers.DestroyValuable(val);
		}
	}
}
public class EvReversePayday : LuckyEvent
{
	public override string Id => "ReversePayday";

	public override string Label => "Reverse Payday — quota +15%";

	public override LuckyEventCategory Category => LuckyEventCategory.Unlucky;

	public override float DefaultWeight => 2f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		ExtractionPoint activeExtraction = EventHelpers.GetActiveExtraction();
		if ((Object)(object)activeExtraction != (Object)null)
		{
			return activeExtraction.haulGoal > 0;
		}
		return false;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		ExtractionPoint activeExtraction = EventHelpers.GetActiveExtraction();
		if (!((Object)(object)activeExtraction == (Object)null))
		{
			EventHelpers.SetHaulGoal(activeExtraction, Mathf.RoundToInt((float)activeExtraction.haulGoal * 1.15f));
		}
	}
}
public class EvHoardersCurse : LuckyEvent
{
	public override string Id => "HoardersCurse";

	public override string Label => "Hoarder's Curse — all loot piles up in one room";

	public override LuckyEventCategory Category => LuckyEventCategory.Unlucky;

	public override float DefaultWeight => 2f;

	public override bool CanRun(LuckyEventContext ctx)
	{
		return EventHelpers.GetLooseValuables(includeInCart: false).Count > 2;
	}

	public override void Execute(LuckyEventContext ctx)
	{
		//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_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> randomLevelPoints = EventHelpers.GetRandomLevelPoints(1);
		if (randomLevelPoints.Count == 0)
		{
			return;
		}
		Vector3 val = randomLevelPoints[0];
		float num = 1.3499999f;
		int num2 = 0;
		Vector3 val2 = default(Vector3);
		foreach (ValuableObject looseValuable in EventHelpers.GetLooseValuables(includeInCart: false))
		{
			int num3 = num2++;
			int num4 = num3 / 16;
			int num5 = num3 % 16;
			((Vector3)(ref val2))..ctor((float)(num5 % 4) * 0.9f - num, (float)num4 * 0.8f, (float)(num5 / 4) * 0.9f - num);
			EventHelpers.TeleportValuableSafe(looseValuable, val + val2, snapToFloor: false);
		}
	}
}
public class EvBlackout : LuckyEvent
{
	public override string Id => "Blackout";

	public override string Label => "Blackout — lights out for 30s";

	public override LuckyEventCategory Category => LuckyEventCategory.Wacky;

	public override float DefaultWeight => 3f;

	public override bool RequiresAllClients => true;

	public override void Execute(LuckyEventContext ctx)
	{
		LuckyFx.Broadcast("blackout", "30");
	}
}
public class EvLowGravity : LuckyEvent
{
	public override string Id => "LowGravity";

	public override string Label => "Low Gravity — 20s of moon physics";

	public override LuckyEventCategory Category => LuckyEventCategory.Wacky;

	public override float DefaultWeight => 3f;

	public override bool RequiresAllClients => true;

	public override void Execute(LuckyEventContext ctx)
	{
		LuckyFx.Broadcast("lowgrav", "20");
	}
}
public class EvRaveLights : LuckyEvent
{
	public override string Id => "RaveLights";

	public override string Label => "Rave — rainbow lighting for 20s";

	public override LuckyEventCategory Category => LuckyEventCategory.Wacky;

	public override float DefaultWeight => 2.5f;

	public override bool RequiresAllClients => true;

	public override void Execute(LuckyEventContext ctx)
	{
		LuckyFx.Broadcast("rave", "20");
	}
}
public class EvFalseAlarm : LuckyEvent
{
	public override string Id => "FalseAlarm";

	public override string Label => "False Alarm — something is coming...";

	public override LuckyEventCategory Category => LuckyEventCategory.Wacky;

	public override float DefaultWeight => 3f;

	public override bool RequiresAllClients => true;

	public override void Execute(LuckyEventContext ctx)
	{
		LuckyFx.Broadcast("falsealarm", "");
	}
}
public class EvButterFingers : LuckyEvent
{
	public override string Id => "ButterFingers";

	public override string Label => "Butter Fingers — everyone drops their grab";

	public override LuckyEventCategory Category => LuckyEventCategory.Wacky;

	public override float DefaultWeight => 3f;

	public override bool RequiresAllClients => true;

	public override void Execute(LuckyEventContext ctx)
	{
		LuckyFx.Broadcast("butterfingers", "");
	}
}
public class EvTinyPlayers : LuckyEvent
{
	public override string Id => "TinyPlayers";

	public override string Label => "Honey I Shrunk the Crew — tiny for 30s";

	public override LuckyEventCategory Category => LuckyEventCategory.Wacky;

	public override float DefaultWeight => 2f;

	public override bool RequiresAllClients => true;

	public override void Execute(LuckyEventContext ctx)
	{
		LuckyFx.Broadcast("avatarscale", "0.5,30");
	}
}
public class EvGiantPlayers : LuckyEvent
{
	public override string Id => "GiantPlayers";

	public override string Label => "Growth Spurt — giant avatars for 30s";

	public override LuckyEventCategory Category => LuckyEventCategory.Wacky;

	public override float DefaultWeight => 2f;

	public override bool RequiresAllClients => true;

	public override void Execute(LuckyEventContext ctx)
	{
		LuckyFx.Broadcast("avatarscale", "1.6,30");
	}
}
public class EvDanceParty : LuckyEvent
{
	public override string Id => "DanceParty";

	public override string Label => "Dance Party — everybody boogie 15s";

	public override LuckyEventCategory Category => LuckyEventCategory.Wacky;

	public override float DefaultWeight => 2.5f;

	public override bool RequiresAllClients => true;

	public override void Execute(LuckyEventContext ctx)
	{
		LuckyFx.Broadcast("danceparty", "15");
	}
}
public enum LuckyEventCategory
{
	Lucky,
	Unlucky,
	Chaotic,
	Wacky
}
public class LuckyEventContext
{
	public PlayerAvatar Opener;

	public Vector3 BlockPos;
}
public abstract class LuckyEvent
{
	internal ConfigEntry<float> ConfigWeight;

	public abstract string Id { get; }

	public abstract string Label { get; }

	public abstract LuckyEventCategory Category { get; }

	public abstract float DefaultWeight { get; }

	public virtual bool RequiresAllClients => false;

	public float BaseWeight
	{
		get
		{
			if (ConfigWeight == null)
			{
				return DefaultWeight;
			}
			return Mathf.Max(0f, ConfigWeight.Value);
		}
	}

	public float Weight => BaseWeight * CategoryWeights.Get(Category);

	public virtual bool CanRun(LuckyEventContext ctx)
	{
		return true;
	}

	public abstract void Execute(LuckyEventContext ctx);
}
public static class LuckyEventLog
{
	internal static ConfigEntry<bool> ConfigEnabled;

	internal static ConfigEntry<int> ConfigMaxEntries;

	internal static ConfigEntry<float> ConfigDuration;

	public static bool Enabled
	{
		get
		{
			if (ConfigEnabled != null)
			{
				return ConfigEnabled.Value;
			}
			return true;
		}
	}

	public static int MaxEntries
	{
		get
		{
			if (ConfigMaxEntries == null)
			{
				return 3;
			}
			return Mathf.Max(1, ConfigMaxEntries.Value);
		}
	}

	public static float Duration
	{
		get
		{
			if (ConfigDuration == null)
			{
				return 60f;
			}
			return Mathf.Max(1f, ConfigDuration.Value);
		}
	}

	public static void BindConfig(ConfigFile config)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Expected O, but got Unknown
		ConfigEnabled = config.Bind<bool>("Event Log", "Enabled", true, "Keep a log of the most recent lucky block outcomes.");
		ConfigMaxEntries = config.Bind<int>("Event Log", "MaxEntries", 3, new ConfigDescription("How many recent events to keep at most.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
		ConfigDuration = config.Bind<float>("Event Log", "DurationSeconds", 60f, new ConfigDescription("Events older than this drop off the log — except the newest one, which always stays.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 300f), Array.Empty<object>()));
	}

	public static List<RandomEventRoller.EventLogEntry> GetVisible()
	{
		List<RandomEventRoller.EventLogEntry> list = new List<RandomEventRoller.EventLogEntry>();
		List<RandomEventRoller.EventLogEntry> eventLog = RandomEventRoller.EventLog;
		if (eventLog.Count == 0)
		{
			return list;
		}
		float realtimeSinceStartup = Time.realtimeSinceStartup;
		foreach (RandomEventRoller.EventLogEntry item in eventLog)
		{
			if (list.Count >= MaxEntries)
			{
				break;
			}
			if (realtimeSinceStartup - item.TimeLogged <= Duration)
			{
				list.Add(item);
			}
		}
		if (list.Count == 0)
		{
			list.Add(eventLog[0]);
		}
		return list;
	}
}
public static class LuckyEventRegistry
{
	private static readonly List<LuckyEvent> _events = new List<LuckyEvent>();

	private static bool _built;

	public static IReadOnlyList<LuckyEvent> All => _events;

	public static void Build()
	{
		if (_built)
		{
			return;
		}
		_built = true;
		Type[] types = Assembly.GetExecutingAssembly().GetTypes();
		foreach (Type type in types)
		{
			if (!type.IsAbstract && typeof(LuckyEvent).IsAssignableFrom(type))
			{
				try
				{
					_events.Add((LuckyEvent)Activator.CreateInstance(type));
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[LuckyBlock] Failed to create event '" + type.Name + "': " + ex.Message));
				}
			}
		}
		_events.Sort(delegate(LuckyEvent a, LuckyEvent b)
		{
			int num = a.Category.CompareTo(b.Category);
			return (num == 0) ? string.CompareOrdinal(a.Id, b.Id) : num;
		});
		Debug.Log((object)$"[LuckyBlock] Event registry built: {_events.Count} events.");
	}

	public static void BindConfig(ConfigFile config)
	{
		BindCategory(config, LuckyEventCategory.Lucky);
		BindCategory(config, LuckyEventCategory.Unlucky);
		BindCategory(config, LuckyEventCategory.Chaotic);
		BindCategory(config, LuckyEventCategory.Wacky);
	}

	private static void BindCategory(ConfigFile config, LuckyEventCategory category)
	{
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Expected O, but got Unknown
		string text = $"Events - {category}";
		foreach (LuckyEvent @event in _events)
		{
			if (@event.Category == category)
			{
				string text2 = (@event.RequiresAllClients ? " Only rolls in Private edition or singleplayer." : "");
				@event.ConfigWeight = config.Bind<float>(text, @event.Id, @event.DefaultWeight, new ConfigDescription(@event.Label + " — how often it rolls. 0 = never." + text2, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			}
		}
	}

	public static void Roll(LuckyEventContext ctx)
	{
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		if (!SemiFunc.IsMasterClientOrSingleplayer())
		{
			return;
		}
		List<LuckyEvent> list = new List<LuckyEvent>();
		float num = 0f;
		foreach (LuckyEvent @event in _events)
		{
			if (IsEligible(@event, ctx))
			{
				list.Add(@event);
				num += @event.Weight;
			}
		}
		if (list.Count == 0 || num <= 0f)
		{
			Debug.LogWarning((object)"[LuckyBlock] Roll: no eligible events — falling back to a valuable.");
			SpawnUtils.SpawnRandomValuable(SpawnUtils.GetSpawnPositionInFront(ctx.Opener, 2.5f));
			return;
		}
		float num2 = Random.value * num;
		float num3 = 0f;
		LuckyEvent ev = list[list.Count - 1];
		foreach (LuckyEvent item in list)
		{
			num3 += item.Weight;
			if (num2 < num3)
			{
				ev = item;
				break;
			}
		}
		Fire(ev, ctx);
	}

	public static void Fire(LuckyEvent ev, LuckyEventContext ctx)
	{
		try
		{
			ev.Execute(ctx);
			EventHelpers.Announce($"[{ev.Category}] {ev.Label}");
		}
		catch (Exception arg)
		{
			Debug.LogError((object)$"[LuckyBlock] Event '{ev.Id}' failed: {arg}");
		}
	}

	private static bool IsEligible(LuckyEvent ev, LuckyEventContext ctx)
	{
		if (ev.Weight <= 0f)
		{
			return false;
		}
		if (ev.RequiresAllClients && SemiFunc.IsMultiplayer() && !ModeManager.IsPrivate)
		{
			return false;
		}
		try
		{
			return ev.CanRun(ctx);
		}
		catch
		{
			return false;
		}
	}
}
public static class LuckyFx
{
	public const string ANNOUNCE = "announce";

	public const string BLACKOUT = "blackout";

	public const string LOW_GRAVITY = "lowgrav";

	public const string SHAKE = "shake";

	public const string RAVE = "rave";

	public const string FALSE_ALARM = "falsealarm";

	public const string BUTTERFINGERS = "butterfingers";

	public const string AVATAR_SCALE = "avatarscale";

	public const string DANCE_PARTY = "danceparty";

	public const string TELEPORT = "teleport";

	private static bool _blackoutActive;

	private static bool _lowGravActive;

	private static bool _raveActive;

	private static bool _scaleActive;

	public static void Broadcast(string id, string args)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		string text = ((args != null && args.Length > 0) ? (id + "|" + args) : id);
		Run(text);
		if (SemiFunc.IsMultiplayer() && ModeManager.IsPrivate && LuckyBlockPlugin.FxEvent != null)
		{
			LuckyBlockPlugin.FxEvent.RaiseEvent((object)text, NetworkingEvents.RaiseOthers, SendOptions.SendReliable);
		}
	}

	public static void Run(string payload)
	{
		if (string.IsNullOrEmpty(payload))
		{
			return;
		}
		int num = payload.IndexOf('|');
		string text = ((num >= 0) ? payload.Substring(0, num) : payload);
		string text2 = ((num >= 0) ? payload.Substring(num + 1) : "");
		try
		{
			switch (text)
			{
			case "announce":
				RandomEventRoller.LogEvent(text2, "[LuckyBlock]");
				break;
			case "blackout":
				Start(Blackout(ParseF(text2, 0, 30f)));
				break;
			case "lowgrav":
				Start(LowGravity(ParseF(text2, 0, 20f)));
				break;
			case "shake":
				Start(Shake(ParseF(text2, 0, 6f), ParseF(text2, 1, 1.5f)));
				break;
			case "rave":
				Start(Rave(ParseF(text2, 0, 20f)));
				break;
			case "falsealarm":
				FalseAlarm();
				break;
			case "butterfingers":
				EventHelpers.ReleaseLocalGrab();
				break;
			case "avatarscale":
				Start(AvatarScale(ParseF(text2, 0, 0.5f), ParseF(text2, 1, 30f)));
				break;
			case "danceparty":
				DanceParty(ParseF(text2, 0, 15f));
				break;
			case "teleport":
				TeleportSelf(text2);
				break;
			default:
				Debug.LogWarning((object)("[LuckyBlock] Unknown FX id '" + text + "'."));
				break;
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[LuckyBlock] FX '" + text + "' failed: " + ex.Message));
		}
	}

	private static void Start(IEnumerator routine)
	{
		LuckyBlockPlugin.StartManagedCoroutine(routine);
	}

	private static float ParseF(string args, int index, float fallback)
	{
		if (string.IsNullOrEmpty(args))
		{
			return fallback;
		}
		string[] array = args.Split(',');
		if (index >= array.Length)
		{
			return fallback;
		}
		if (!float.TryParse(array[index], NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
		{
			return fallback;
		}
		return result;
	}

	private static IEnumerator Blackout(float duration)
	{
		if (_blackoutActive)
		{
			yield break;
		}
		_blackoutActive = true;
		List<KeyValuePair<Light, float>> dimmed = new List<KeyValuePair<Light, float>>();
		Light[] array = Object.FindObjectsOfType<Light>();
		foreach (Light val in array)
		{
			if (!((Object)(object)val == (Object)null) && !(val.intensity <= 0.01f))
			{
				dimmed.Add(new KeyValuePair<Light, float>(val, val.intensity));
				val.intensity = 0.02f;
			}
		}
		Color ambient = RenderSettings.ambientLight;
		RenderSettings.ambientLight = Color.black;
		yield return (object)new WaitForSeconds(duration);
		foreach (KeyValuePair<Light, float> item in dimmed)
		{
			if ((Object)(object)item.Key != (Object)null)
			{
				item.Key.intensity = item.Value;
			}
		}
		RenderSettings.ambientLight = ambient;
		_blackoutActive = false;
	}

	private static IEnumerator LowGravity(float duration)
	{
		if (!_lowGravActive)
		{
			_lowGravActive = true;
			Vector3 original = Physics.gravity;
			Physics.gravity = original * 0.25f;
			yield return (object)new WaitForSeconds(duration);
			Physics.gravity = original;
			_lowGravActive = false;
		}
	}

	private static IEnumerator Shake(float duration, float strength)
	{
		CameraShake shaker = Object.FindObjectOfType<CameraShake>();
		float elapsed = 0f;
		while (elapsed < duration)
		{
			if ((Object)(object)shaker != (Object)null)
			{
				shaker.Shake(strength, 0.3f);
			}
			elapsed += 0.25f;
			yield return (object)new WaitForSeconds(0.25f);
		}
	}

	private static IEnumerator Rave(float duration)
	{
		if (!_raveActive)
		{
			_raveActive = true;
			Color original = RenderSettings.ambientLight;
			float elapsed = 0f;
			while (elapsed < duration)
			{
				RenderSettings.ambientLight = Color.HSVToRGB(Mathf.Repeat(elapsed * 0.5f, 1f), 0.9f, 0.8f);
				elapsed += Time.deltaTime;
				yield return null;
			}
			RenderSettings.ambientLight = original;
			_raveActive = false;
		}
	}

	private static void FalseAlarm()
	{
		//IL_0033: 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)
		ChatManager instance = ChatManager.instance;
		if (!((Object)(object)instance == (Object)null))
		{
			instance.PossessChatScheduleStart(9);
			instance.PossessChat((PossessChatID)0, "something is coming . . .", 0.06f, new Color(0.9f, 0.1f, 0.1f), 0f, false, 0, (UnityEvent)null);
			instance.PossessChat((PossessChatID)0, "nevermind. probably nothing", 0.05f, new Color(0.6f, 0.6f, 0.6f), 3f, false, 0, (UnityEvent)null);
			instance.PossessChatScheduleEnd();
		}
	}

	private static IEnumerator AvatarScale(float scale, float duration)
	{
		if (_scaleActive)
		{
			yield break;
		}
		_scaleActive = true;
		List<KeyValuePair<Transform, Vector3>> scaled = new List<KeyValuePair<Transform, Vector3>>();
		foreach (PlayerAvatar allPlayer in EventHelpers.GetAllPlayers())
		{
			if (!((Object)(object)allPlayer == (Object)null) && !((Object)(object)allPlayer.playerAvatarVisuals == (Object)null))
			{
				Transform transform = ((Component)allPlayer.playerAvatarVisuals).transform;
				scaled.Add(new KeyValuePair<Transform, Vector3>(transform, transform.localScale));
				transform.localScale *= scale;
			}
		}
		yield return (object)new WaitForSeconds(duration);
		foreach (KeyValuePair<Transform, Vector3> item in scaled)
		{
			if ((Object)(object)item.Key != (Object)null)
			{
				item.Key.localScale = item.Value;
			}
		}
		_scaleActive = false;
	}

	private static void TeleportSelf(string args)
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		PlayerAvatar instance = PlayerAvatar.instance;
		if (!((Object)(object)instance == (Object)null))
		{
			PhotonView component = ((Component)instance).GetComponent<PhotonView>();
			if (!((Object)(object)component == (Object)null) && (int)ParseF(args, 0, -1f) == component.ViewID)
			{
				EventHelpers.TeleportLocalController(new Vector3(ParseF(args, 1, 0f), ParseF(args, 2, 0f), ParseF(args, 3, 0f)));
			}
		}
	}

	private static void DanceParty(float duration)
	{
		MonoBehaviour instance = (MonoBehaviour)(object)LuckyBlockPlugin.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		foreach (PlayerAvatar allPlayer in EventHelpers.GetAllPlayers())
		{
			RandomEventRoller.ForceBoomboxDance(allPlayer, duration, instance, "[LuckyBlock]");
		}
	}
}
internal static class LevelPointUtils
{
	private const float MIN_REACHABLE_SHARE = 0.25f;

	private static FieldInfo _fModuleConnected;

	private static bool _reflected;

	internal static bool IsGraphReady()
	{
		LevelGenerator instance = LevelGenerator.Instance;
		if ((Object)(object)instance == (Object)null || !instance.Generated)
		{
			return false;
		}
		EnsureReflection();
		if (_fModuleConnected == null)
		{
			return true;
		}
		foreach (LevelPoint levelPathPoint in instance.LevelPathPoints)
		{
			if (!((Object)(object)levelPathPoint == (Object)null) && levelPathPoint.ModuleConnect && ((Component)levelPathPoint).gameObject.activeInHierarchy && !(bool)_fModuleConnected.GetValue(levelPathPoint))
			{
				return false;
			}
		}
		return true;
	}

	internal static IEnumerator WaitForGraph(float timeout = 20f)
	{
		float waited = 0f;
		while (!IsGraphReady() && waited < timeout)
		{
			yield return (object)new WaitForSecondsRealtime(0.25f);
			waited += 0.25f;
		}
		yield return (object)new WaitForSecondsRealtime(0.25f);
	}

	internal static List<LevelPoint> GetReachablePoints(float maxDistanceFromTruck)
	{
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: 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)
		List<LevelPoint> list = new List<LevelPoint>();
		LevelGenerator instance = LevelGenerator.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return list;
		}
		List<LevelPoint> list2 = new List<LevelPoint>();
		foreach (LevelPoint levelPathPoint in instance.LevelPathPoints)
		{
			if (IsUsable(levelPathPoint))
			{
				list2.Add(levelPathPoint);
			}
		}
		LevelPoint levelPathTruck = instance.LevelPathTruck;
		if ((Object)(object)levelPathTruck == (Object)null)
		{
			Debug.LogWarning((object)"[LuckyBlock] No truck level point — using the distance-free fallback filter.");
			return list2;
		}
		Vector3 position = ((Component)levelPathTruck).transform.position;
		Dictionary<LevelPoint, bool> dictionary = new Dictionary<LevelPoint, bool> { { levelPathTruck, true } };
		Queue<LevelPoint> queue = new Queue<LevelPoint>();
		queue.Enqueue(levelPathTruck);
		while (queue.Count > 0)
		{
			LevelPoint val = queue.Dequeue();
			if ((Object)(object)val == (Object)null || val.ConnectedPoints == null)
			{
				continue;
			}
			foreach (LevelPoint connectedPoint in val.ConnectedPoints)
			{
				if (!((Object)(object)connectedPoint == (Object)null) && !dictionary.ContainsKey(connectedPoint))
				{
					dictionary[connectedPoint] = true;
					queue.Enqueue(connectedPoint);
					if (IsUsable(connectedPoint) && !(Vector3.Distance(((Component)connectedPoint).transform.position, position) > maxDistanceFromTruck))
					{
						list.Add(connectedPoint);
					}
				}
			}
		}
		if (list2.Count > 0 && (float)list.Count < (float)list2.Count * 0.25f)
		{
			List<LevelPoint> list3 = new List<LevelPoint>();
			foreach (LevelPoint item in list2)
			{
				if ((Object)(object)item.Room != (Object)null && Vector3.Distance(((Component)item).transform.position, position) <= maxDistanceFromTruck)
				{
					list3.Add(item);
				}
			}
			Debug.LogWarning((object)($"[LuckyBlock] Only {list.Count}/{list2.Count} points reachable from the truck — " + $"graph looks incomplete, using {list3.Count} distance-filtered point(s) instead."));
			if (list3.Count > 0)
			{
				return list3;
			}
		}
		Debug.Log((object)($"[LuckyBlock] Reachable level points: {list.Count}/{list2.Count} " + $"(within {maxDistanceFromTruck:F0}m of the truck)."));
		return list;
	}

	internal static int CountRooms()
	{
		LevelGenerator instance = LevelGenerator.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return 0;
		}
		Dictionary<RoomVolume, bool> dictionary = new Dictionary<RoomVolume, bool>();
		foreach (LevelPoint levelPathPoint in instance.LevelPathPoints)
		{
			if ((Object)(object)levelPathPoint != (Object)null && (Object)(object)levelPathPoint.Room != (Object)null)
			{
				dictionary[levelPathPoint.Room] = true;
			}
		}
		return dictionary.Count;
	}

	internal static Vector3 ToSpawnPosition(LevelPoint lp)
	{
		//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_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		RaycastHit val = default(RaycastHit);
		if (!Physics.Raycast(((Component)lp).transform.position + Vector3.up * 1.5f, Vector3.down, ref val, 6f, -1, (QueryTriggerInteraction)1))
		{
			return ((Component)lp).transform.position + Vector3.up * 0.5f;
		}
		return ((RaycastHit)(ref val)).point + Vector3.up * 0.4f;
	}

	private static bool IsUsable(LevelPoint lp)
	{
		if ((Object)(object)lp == (Object)null)
		{
			return false;
		}
		if (!((Component)lp).gameObject.activeInHierarchy)
		{
			return false;
		}
		if (lp.Truck)
		{
			return false;
		}
		if ((Object)(object)((Component)lp).GetComponentInParent<StartRoom>() != (Object)null)
		{
			return false;
		}
		return true;
	}

	private static void EnsureReflection()
	{
		if (!_reflected)
		{
			_reflected = true;
			_fModuleConnected = typeof(LevelPoint).GetField("ModuleConnected", BindingFlags.Instance | BindingFlags.NonPublic);
		}
	}
}
public class LuckyBlock : MonoBehaviour
{
	private PhysGrabObject _grab;

	private PhysGrabObjectImpactDetector _impact;

	private bool _triggered;

	private void Awake()
	{
		RandomEventRoller.Init();
		_grab = ((Component)this).GetComponent<PhysGrabObject>();
		_impact = ((Component)this).GetComponent<PhysGrabObjectImpactDetector>();
	}

	private void Update()
	{
		if (!_triggered && SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)_grab != (Object)null && _grab.grabbed)
		{
			Trigger(ResolveGrabber());
		}
	}

	private void Open()
	{
		Trigger(ResolveGrabber());
	}

	private void Trigger(PlayerAvatar grabber)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		if (!_triggered)
		{
			_triggered = true;
			if ((Object)(object)grabber == (Object)null)
			{
				grabber = PlayerAvatar.instance;
			}
			Vector3 position = ((Component)this).transform.position;
			LuckyBlockEvents.Roll(grabber, position);
			if ((Object)(object)_impact != (Object)null)
			{
				_impact.DestroyObject(true);
			}
			else
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}

	private PlayerAvatar ResolveGrabber()
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: 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)
		if ((Object)(object)_grab != (Object)null && _grab.playerGrabbing != null && _grab.playerGrabbing.Count > 0)
		{
			PhysGrabber val = _grab.playerGrabbing[0];
			if ((Object)(object)val != (Object)null && (Object)(object)val.playerAvatar != (Object)null)
			{
				return val.playerAvatar;
			}
		}
		List<PlayerAvatar> list = SemiFunc.PlayerGetAllPlayerAvatarWithinRange(8f, ((Component)this).transform.position, false, default(LayerMask));
		if (list != null && list.Count > 0 && (Object)(object)list[0] != (Object)null)
		{
			return list[0];
		}
		return PlayerAvatar.instance;
	}
}
public static class LuckyBlockEvents
{
	private static LuckyEventContext MakeContext(PlayerAvatar player, Vector3 blockPos)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: 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_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null)
		{
			player = PlayerAvatar.instance;
		}
		if (blockPos == Vector3.zero && (Object)(object)player != (Object)null)
		{
			blockPos = ((Component)player).transform.position;
		}
		return new LuckyEventContext
		{
			Opener = player,
			BlockPos = blockPos
		};
	}

	public static void Roll(PlayerAvatar opener, Vector3 blockPos)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		if (SemiFunc.IsMasterClientOrSingleplayer())
		{
			LuckyEventContext luckyEventContext = MakeContext(opener, blockPos);
			if (!((Object)(object)luckyEventContext.Opener == (Object)null))
			{
				LuckyEventRegistry.Roll(luckyEventContext);
			}
		}
	}

	public static void TriggerSpecific(int eventIdx, PlayerAvatar player, Vector3 blockPos)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		if (!SemiFunc.IsMasterClientOrSingleplayer())
		{
			return;
		}
		LuckyEventContext luckyEventContext = MakeContext(player, blockPos);
		if (!((Object)(object)luckyEventContext.Opener == (Object)null))
		{
			IReadOnlyList<LuckyEvent> all = LuckyEventRegistry.All;
			if (eventIdx >= 0 && eventIdx < all.Count)
			{
				LuckyEventRegistry.Fire(all[eventIdx], luckyEventContext);
			}
			else
			{
				LuckyEventRegistry.Roll(luckyEventContext);
			}
		}
	}
}
public class LuckyBlockItem : MonoBehaviour
{
	private bool _isLucky;

	internal bool _consumed;

	private bool _activatedLocal;

	private PhysGrabObject _grab;

	private PhotonView _view;

	internal bool IsLucky => _isLucky;

	private void Awake()
	{
		RandomEventRoller.Init();
		_grab = ((Component)this).GetComponent<PhysGrabObject>() ?? ((Component)this).GetComponentInParent<PhysGrabObject>();
		_view = ((Component)this).GetComponent<PhotonView>() ?? ((Component)this).GetComponentInParent<PhotonView>();
	}

	private void Update()
	{
		if (_isLucky && !_activatedLocal && !((Object)(object)_grab == (Object)null) && ModeManager.IsPrivate && _grab.grabbedLocal && SemiFunc.InputDown((InputKey)2))
		{
			Activate();
		}
	}

	internal void SetLucky()
	{
		MakeLucky();
		if (SemiFunc.IsMultiplayer() && (Object)(object)_view != (Object)null && _view.ViewID != 0)
		{
			_view.RPC("SetLuckyRPC", (RpcTarget)4, Array.Empty<object>());
		}
	}

	[PunRPC]
	private void SetLuckyRPC()
	{
		MakeLucky();
	}

	private void MakeLucky()
	{
		_isLucky = true;
		LuckyBlockSkin.Apply(((Component)this).gameObject, 1f / 6f);
	}

	private void Open()
	{
		Activate();
	}

	private void Activate()
	{
		if (!_activatedLocal)
		{
			_activatedLocal = true;
			int num = SemiFunc.PhotonViewIDPlayerAvatarLocal();
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				ActivateOnHost(((Component)this).gameObject, num);
			}
			else if ((Object)(object)_view != (Object)null && _view.ViewID != 0)
			{
				_view.RPC("ActivateRPC", (RpcTarget)2, new object[1] { num });
			}
		}
	}

	[PunRPC]
	private void ActivateRPC(int playerViewID)
	{
		ActivateOnHost(((Component)this).gameObject, playerViewID);
	}

	internal static void ActivateOnHost(GameObject item, int playerViewID)
	{
		//IL_003d: 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_0043: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)item == (Object)null || !SemiFunc.IsMasterClientOrSingleplayer())
		{
			return;
		}
		LuckyBlockItem component = item.GetComponent<LuckyBlockItem>();
		if ((Object)(object)component != (Object)null)
		{
			if (component._consumed)
			{
				return;
			}
			component._consumed = true;
		}
		PlayerAvatar opener = ResolvePlayer(playerViewID);
		Vector3 position = item.transform.position;
		LuckyBlockEvents.Roll(opener, position);
		if (SemiFunc.IsMultiplayer())
		{
			PhotonNetwork.Destroy(item);
		}
		else
		{
			Object.Destroy((Object)(object)item);
		}
	}

	private static PlayerAvatar ResolvePlayer(int viewID)
	{
		if (viewID > 0)
		{
			PhotonView val = PhotonView.Find(viewID);
			PlayerAvatar val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<PlayerAvatar>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
		}
		return PlayerAvatar.instance;
	}
}
[HarmonyPatch(typeof(ItemAttributes), "Awake")]
internal static class LuckyBlockItem_AttachPatch
{
	private static void Postfix(ItemAttributes __instance)
	{
		if (!((Object)(object)__instance == (Object)null))
		{
			string text = (((Object)(object)__instance.item != (Object)null) ? __instance.item.itemName : null);
			string value = "Drone Battery";
			if (((text != null && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) || ((Object)((Component)__instance).gameObject).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) && (Object)(object)((Component)__instance).GetComponent<LuckyBlockItem>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<LuckyBlockItem>();
			}
		}
	}
}
[HarmonyPatch(typeof(ItemAttributes), "GetItemNameLocalized")]
internal static class LuckyBlockItem_NamePatch
{
	private static void Postfix(ItemAttributes __instance, ref string __result)
	{
		LuckyBlockItem luckyBlockItem = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponent<LuckyBlockItem>() : null);
		if ((Object)(object)luckyBlockItem != (Object)null && luckyBlockItem.IsLucky)
		{
			__result = "Lucky Block";
		}
	}
}
public class LuckyBlockManager : MonoBehaviour
{
	public static LuckyBlockManager Instance { get; private set; }

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

	internal List<GameObject> SpawnBlocks(List<Vector3> positions)
	{
		List<GameObject> list = new List<GameObject>();
		if (positions == null || positions.Count == 0)
		{
			return list;
		}
		if (SemiFunc.IsMultiplayer() && !SemiFunc.IsMasterClientOrSingleplayer())
		{
			Debug.LogWarning((object)"[LuckyBlock] Only the host can spawn lucky blocks.");
			return list;
		}
		if (!ModeManager.IsPrivate)
		{
			return SpawnPublic(positions, list);
		}
		return SpawnPrivate(positions, list);
	}

	private List<GameObject> SpawnPrivate(List<Vector3> positions, List<GameObject> spawned)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: 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_0068: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)SpawnUtils.GetLuckyItem() == (Object)null)
		{
			Debug.LogError((object)"[LuckyBlock] PRIVATE mode: base item 'Drone Battery' not found. Switch back to Public mode (F6 menu).");
			return spawned;
		}
		foreach (Vector3 position in positions)
		{
			GameObject val = SpawnUtils.SpawnLuckyItem(position);
			if (!((Object)(object)val == (Object)null))
			{
				LuckyBlockItem componentInChildren = val.GetComponentInChildren<LuckyBlockItem>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.SetLucky();
				}
				else
				{
					Debug.LogError((object)"[LuckyBlock] spawned item has no LuckyBlockItem component.");
				}
				spawned.Add(val);
				Debug.Log((object)$"[LuckyBlock] Lucky ITEM spawned at {position:F1} (private edition).");
			}
		}
		return spawned;
	}

	private List<GameObject> SpawnPublic(List<Vector3> positions, List<GameObject> spawned)
	{
		//IL_000e: 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_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: 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_0099: Unknown result type (might be due to invalid IL or missing references)
		foreach (Vector3 position in positions)
		{
			GameObject val = SpawnUtils.SpawnLuckyValuable(position);
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)$"[LuckyBlock] Failed to spawn lucky valuable at {position:F1}.");
				continue;
			}
			if ((Object)(object)val.GetComponent<LuckyBlock>() == (Object)null)
			{
				val.AddComponent<LuckyBlock>();
			}
			LuckyBlockSkin.Apply(val);
			if (SemiFunc.IsMultiplayer())
			{
				PhotonView component = val.GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null && component.ViewID != 0 && LuckyBlockPlugin.SkinEvent != null)
				{
					LuckyBlockPlugin.SkinEvent.RaiseEvent((object)component.ViewID, NetworkingEvents.RaiseOthers, SendOptions.SendReliable);
				}
			}
			spawned.Add(val);
			Debug.Log((object)$"[LuckyBlock] Lucky six-pack spawned at {position:F1}.");
		}
		return spawned;
	}

	internal void ClearBlocks()
	{
	}
}
public enum LuckyBlockMode
{
	PublicServer,
	PrivateServer
}
public static class ModeManager
{
	internal static ConfigEntry<LuckyBlockMode> EditionConfig;

	public static LuckyBlockMode CurrentEdition
	{
		get
		{
			if (EditionConfig == null)
			{
				return LuckyBlockMode.PublicServer;
			}
			return EditionConfig.Value;
		}
	}

	public static bool IsPrivate => CurrentEdition == LuckyBlockMode.PrivateServer;

	public static void SetEdition(LuckyBlockMode mode)
	{
		if (EditionConfig != null)
		{
			EditionConfig.Value = mode;
		}
	}
}
[BepInPlugin("com.tonnom.luckyblock", "REPO_lucky_block", "1.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class LuckyBlockPlugin : BaseUnityPlugin
{
	private static MonoBehaviour _coroutineHost;

	private Harmony _harmony;

	public static LuckyBlockPlugin Instance { get; private set; }

	internal static NetworkedEvent SkinEvent { get; private set; }

	internal static NetworkedEvent FxEvent { get; private set; }

	private void Awake()
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected O, but got Unknown
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Expected O, but got Unknown
		Instance = this;
		_coroutineHost = (MonoBehaviour)(object)this;
		((Component)this).gameObject.AddComponent<LuckyBlockManager>();
		_harmony = new Harmony("com.tonnom.luckyblock");
		_harmony.PatchAll();
		SkinEvent = new NetworkedEvent("LuckyBlock Skin", (Action<EventData>)OnSkinEvent);
		FxEvent = new NetworkedEvent("LuckyBlock FX", (Action<EventData>)OnFxEvent);
		LuckyEventRegistry.Build();
		LuckyProfileStore.Discover();
		string text = ((BaseUnityPlugin)this).Info.Metadata.Version.ToString();
		((BaseUnityPlugin)this).Config.Bind<string>("Profiles", "ModVersion", text, new ConfigDescription("Currently installed REPO_lucky_block version.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[1] { text }), Array.Empty<object>()));
		LuckyProfileStore.BindConfig(((BaseUnityPlugin)this).Config);
		LuckySettingsMenu.BindConfig(((BaseUnityPlugin)this).Config);
		ModeManager.EditionConfig = ((BaseUnityPlugin)this).Config.Bind<LuckyBlockMode>("General", "Edition", LuckyBlockMode.PublicServer, "PublicServer = host-only, no client install needed (lucky block is a valuable, grab it). PrivateServer = everyone must install the mod (lucky block is a custom item, press E).");
		LuckyBlockSpawner.BindConfig(((BaseUnityPlugin)this).Config);
		EventHelpers.BindConfig(((BaseUnityPlugin)this).Config);
		CategoryWeights.BindConfig(((BaseUnityPlugin)this).Config);
		LuckyEventRegistry.BindConfig(((BaseUnityPlugin)this).Config);
		LuckyProfileStore.ApplyIfChanged();
		((Component)this).gameObject.AddComponent<LuckyConfigWatcher>();
		SceneManager.sceneLoaded += OnSceneLoaded;
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"[LuckyBlock] Plugin loaded — Manager alive: {(Object)(object)LuckyBlockManager.Instance != (Object)null}.");
	}

	private static void OnSkinEvent(EventData e)
	{
		if (((e != null) ? e.CustomData : null) is int viewID)
		{
			StartManagedCoroutine(SkinWhenReady(viewID));
		}
	}

	private static IEnumerator SkinWhenReady(int viewID)
	{
		for (int i = 0; i < 120; i++)
		{
			PhotonView val = PhotonView.Find(viewID);
			if ((Object)(object)val != (Object)null)
			{
				LuckyBlockSkin.Apply(((Component)val).gameObject);
				break;
			}
			yield return null;
		}
	}

	private static void OnFxEvent(EventData e)
	{
		if (((e != null) ? e.CustomData : null) is string payload)
		{
			LuckyFx.Run(payload);
		}
	}

	internal static void StartManagedCoroutine(IEnumerator routine)
	{
		if ((Object)(object)_coroutineHost != (Object)null)
		{
			_coroutineHost.StartCoroutine(routine);
		}
		else
		{
			Debug.LogWarning((object)"[LuckyBlock] CoroutineHost missing — coroutine dropped.");
		}
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		if ((int)mode == 0)
		{
			LuckyBlockManager.Instance?.ClearBlocks();
			if ((Object)(object)Object.FindObjectOfType<LuckySettingsMenu>() == (Object)null)
			{
				GameObject val = new GameObject("LuckyBlock_SettingsMenu");
				val.AddComponent<LuckySettingsMenu>();
				Object.DontDestroyOnLoad((Object)val);
			}
			LuckyProfileStore.ApplyIfChanged();
			LuckyBlockSpawner.ResetSpawnFlag();
			StartManagedCoroutine(BackupSpawnCoroutine());
		}
	}

	private static IEnumerator BackupSpawnCoroutine()
	{
		yield return (object)new WaitForSeconds(1f);
		if (!((Object)(object)RunManager.instance == (Object)null) && SemiFunc.RunIsLevel() && SemiFunc.IsMasterClientOrSingleplayer())
		{
			yield return LuckyBlockSpawner.SpawnWhenGraphReady("BackupCoroutine");
		}
	}
}
public class CoroutineHost : MonoBehaviour
{
}
internal static class LuckyBlockSkin
{
	private const string SKIN_NAME = "LuckyBlockSkin";

	private static Texture2D _tex;

	private static Material _mat;

	private static Mesh _cubeMesh;

	internal static void Apply(GameObject valuable, float scale = 1f)
	{
		//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_0053: 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_0071: 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_00b3: 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_00cb: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: 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_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)valuable == (Object)null || (Object)(object)valuable.transform.Find("LuckyBlockSkin") != (Object)null)
		{
			return;
		}
		Material material = GetMaterial();
		Mesh cubeMesh = GetCubeMesh();
		if (!((Object)(object)material == (Object)null) && !((Object)(object)cubeMesh == (Object)null))
		{
			Bounds val = ComputeBounds(valuable);
			float num = Mathf.Max(new float[3]
			{
				((Bounds)(ref val)).size.x,
				((Bounds)(ref val)).size.y,
				((Bounds)(ref val)).size.z
			}) * 1.05f;
			if (num <= 0.001f)
			{
				num = 0.5f;
			}
			num = Mathf.Clamp(num, 0.2f, 1f) * scale;
			GameObject val2 = new GameObject("LuckyBlockSkin");
			val2.transform.SetParent(valuable.transform, false);
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.position = ((Bounds)(ref val)).center;
			Vector3 lossyScale = valuable.transform.lossyScale;
			val2.transform.localScale = new Vector3(num / Mathf.Max(0.0001f, lossyScale.x), num / Mathf.Max(0.0001f, lossyScale.y), num / Mathf.Max(0.0001f, lossyScale.z));
			val2.AddComponent<MeshFilter>().sharedMesh = cubeMesh;
			((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = material;
		}
	}

	private static Bounds ComputeBounds(GameObject go)
	{
		//IL_0002: 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_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_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		Bounds result = default(Bounds);
		bool flag = false;
		Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>();
		foreach (Renderer val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null) && !(((Object)((Component)val).gameObject).name == "LuckyBlockSkin") && (val is MeshRenderer || val is SkinnedMeshRenderer))
			{
				if (!flag)
				{
					result = val.bounds;
					flag = true;
				}
				else
				{
					((Bounds)(ref result)).Encapsulate(val.bounds);
				}
			}
		}
		if (!flag)
		{
			((Bounds)(ref result))..ctor(go.transform.position, Vector3.one * 0.5f);
		}
		return result;
	}

	private static Mesh GetCubeMesh()
	{
		if ((Object)(object)_cubeMesh != (Object)null)
		{
			return _cubeMesh;
		}
		GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
		_cubeMesh = obj.GetComponent<MeshFilter>().sharedMesh;
		Object.Destroy((Object)(object)obj);
		return _cubeMesh;
	}

	private static Material GetMaterial()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Expected O, but got Unknown
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_mat != (Object)null)
		{
			return _mat;
		}
		Texture2D texture = GetTexture();
		Shader val = Shader.Find("Standard");
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		_mat = new Material(val)
		{
			name = "LuckyBlockMat",
			mainTexture = (Texture)(object)texture
		};
		_mat.SetFloat("_Glossiness", 0.1f);
		_mat.SetFloat("_Metallic", 0f);
		_mat.EnableKeyword("_EMISSION");
		_mat.SetColor("_EmissionColor", new Color(0.3f, 0.24f, 0f));
		if ((Object)(object)texture != (Object)null)
		{
			_mat.SetTexture("_EmissionMap", (Texture)(object)texture);
		}
		return _mat;
	}

	private static Texture2D GetTexture()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		if ((Object)(object)_tex != (Object)null)
		{
			return _tex;
		}
		_tex = new Texture2D(2, 2, (TextureFormat)4, false);
		string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)LuckyBlockPlugin.Instance).Info.Location), "lucky_block.png");
		if (File.Exists(text))
		{
			ImageConversion.LoadImage(_tex, File.ReadAllBytes(text));
			((Texture)_tex).filterMode = (FilterMode)0;
			((Texture)_tex).wrapMode = (TextureWrapMode)1;
			_tex.Apply();
		}
		else
		{
			Debug.LogError((object)("[LuckyBlock] Skin texture not found at '" + text + "'. Block will be untextured."));
		}
		return _tex;
	}
}
[HarmonyPatch(typeof(SemiFunc), "OnLevelGenDone")]
internal static class OnLevelGenDone_Patch
{
	private static void Postfix()
	{
		try
		{
			if (!((Object)(object)RunManager.instance == (Object)null) && SemiFunc.RunIsLevel() && SemiFunc.IsMasterClientOrSingleplayer())
			{
				LuckyBlockPlugin.StartManagedCoroutine(LuckyBlockSpawner.SpawnWhenGraphReady("OnLevelGenDone"));
			}
		}
		catch (Exception arg)
		{
			Debug.LogError((object)$"[LuckyBlock] Spawn postfix failed (ignored): {arg}");
		}
	}
}
internal static class LuckyBlockSpawner
{
	private const float MIN_BLOCK_SPACING = 4f;

	private const int NO_LEVEL = -1;

	private static int _spawnedForLevel = -1;

	internal static ConfigEntry<bool> ConfigEnabled;

	internal static ConfigEntry<float> ConfigMaxSpawnDistance;

	internal static ConfigEntry<float> ConfigDensityPercent;

	public static bool Enabled
	{
		get
		{
			if (ConfigEnabled != null)
			{
				return ConfigEnabled.Value;
			}
			return true;
		}
	}

	public static float MaxSpawnDistance
	{
		get
		{
			if (ConfigMaxSpawnDistance == null)
			{
				return 100f;
			}
			return ConfigMaxSpawnDistance.Value;
		}
	}

	public static float DensityPercent
	{
		get
		{
			if (ConfigDensityPercent == null)
			{
				return 30f;
			}
			return Mathf.Clamp(ConfigDensityPercent.Value, 1f, 1000f);
		}
	}

	internal static void BindConfig(ConfigFile config)
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Expected O, but got Unknown
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Expected O, but got Unknown
		ConfigEnabled = config.Bind<bool>("General", "SpawningEnabled", true, "Master on/off switch. When false, no Lucky Blocks spawn — the mod stays installed but does nothing.");
		ConfigMaxSpawnDistance = config.Bind<float>("General", "MaxSpawnDistanceFromTruck", 100f, new ConfigDescription("Blocks never spawn further than this many metres from the truck. Stops one showing up somewhere nobody will ever walk to.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 400f), Array.Empty<object>()));
		ConfigDensityPercent = config.Bind<float>("General", "DensityPercent", 30f, new ConfigDescription("How many Lucky Blocks spawn per level, as a percentage of that level's room count (rounded, minimum 1 block). E.g. 10 rooms at 30% = 3 blocks; at 1000% = 100 blocks (10 per room) for maximum chaos. 1% is the floor on purpose — use SpawningEnabled to turn the mod off entirely instead of setting this to 0.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), Array.Empty<object>()));
	}

	internal static void ResetSpawnFlag()
	{
		_spawnedForLevel = -1;
	}

	internal static IEnumerator SpawnWhenGraphReady(string caller)
	{
		yield return LevelPointUtils.WaitForGraph();
		if ((Object)(object)RunManager.instance == (Object)null || !SemiFunc.RunIsLevel() || !SemiFunc.IsMasterClientOrSingleplayer())
		{
			yield break;
		}
		try
		{
			SpawnForCurrentLevel(caller);
		}
		catch (Exception arg)
		{
			Debug.LogError((object)$"[LuckyBlock] Spawn ({caller}) failed (ignored): {arg}");
		}
	}

	internal static void SpawnForCurrentLevel(string caller = "?")
	{
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: 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)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		if (!Enabled)
		{
			Debug.Log((object)("[LuckyBlock] SpawnForCurrentLevel(" + caller + "): spawning disabled in config — skip."));
			return;
		}
		int currentLevel = GetCurrentLevel();
		if (_spawnedForLevel == currentLevel)
		{
			Debug.Log((object)$"[LuckyBlock] SpawnForCurrentLevel({caller}): already spawned for level {currentLevel} — skip.");
			return;
		}
		if ((Object)(object)LuckyBlockManager.Instance == (Object)null)
		{
			Debug.LogError((object)"[LuckyBlock] LuckyBlockManager.Instance is null — cannot spawn.");
			return;
		}
		_spawnedForLevel = currentLevel;
		int blockCount = GetBlockCount();
		Debug.Log((object)$"[LuckyBlock] Spawning {blockCount} block(s) for level {currentLevel} (caller: {caller}).");
		List<LevelPoint> reachablePoints = LevelPointUtils.GetReachablePoints(MaxSpawnDistance);
		if (reachablePoints.Count == 0)
		{
			FallbackSpawn(blockCount);
			return;
		}
		for (int num = reachablePoints.Count - 1; num > 0; num--)
		{
			int index = Random.Range(0, num + 1);
			LevelPoint value = reachablePoints[num];
			reachablePoints[num] = reachablePoints[index];
			reachablePoints[index] = value;
		}
		List<Vector3> list = new List<Vector3>();
		List<Vector3> list2 = new List<Vector3>();
		foreach (LevelPoint item in reachablePoints)
		{
			if (list.Count >= blockCount)
			{
				break;
			}
			Vector3 val = LevelPointUtils.ToSpawnPosition(item);
			bool flag = false;
			foreach (Vector3 item2 in list2)
			{
				if (Vector3.Distance(val, item2) < 4f)
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				list.Add(val);
				list2.Add(val);
			}
		}
		if (list.Count < blockCount)
		{
			foreach (LevelPoint item3 in reachablePoints)
			{
				if (list.Count >= blockCount)
				{
					break;
				}
				Vector3 val2 = LevelPointUtils.ToSpawnPosition(item3);
				bool flag2 = false;
				foreach (Vector3 item4 in list2)
				{
					if (Vector3.Distance(val2, item4) < 0.5f)
					{
						flag2 = true;
						break;
					}
				}
				if (!flag2)
				{
					list.Add(val2);
					list2.Add(val2);
				}
			}
		}
		LuckyBlockManager.Instance.SpawnBlocks(list);
		Debug.Log((object)$"[LuckyBlock] Sent {list.Count}/{blockCount} block position(s) to manager.");
	}

	internal static GameObject SpawnOne(Vector3 pos)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)LuckyBlockManager.Instance == (Object)null)
		{
			Debug.LogError((object)"[LuckyBlock] SpawnOne: LuckyBlockManager.Instance is null.");
			return null;
		}
		List<GameObject> list = LuckyBlockManager.Instance.SpawnBlocks(new List<Vector3> { pos });
		if (list.Count <= 0)
		{
			return null;
		}
		return list[0];
	}

	internal static int GetCurrentLevel()
	{
		return Mathf.Clamp(SemiFunc.RunGetLevelsCompleted() + 1, 1, 20);
	}

	private static int GetBlockCount()
	{
		int num = LevelPointUtils.CountRooms();
		if (num > 0)
		{
			return Mathf.Max(1, Mathf.RoundToInt((float)num * (DensityPercent / 100f)));
		}
		Debug.LogWarning((object)"[LuckyBlock] GetBlockCount: could not read the room count — using the fallback formula.");
		return FallbackBlockCount(GetCurrentLevel());
	}

	private static int FallbackBlockCount(int level)
	{
		int[] array = new int[4] { 2, 5, 7, 9 };
		int num = ((level <= array.Length) ? array[level - 1] : (array[^1] + (level - array.Length) * 2));
		return Mathf.Max(1, num + Random.Range(-1, 2));
	}

	private static void FallbackSpawn(int count)
	{
		//IL_007b: 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_0082: 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_0091: 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_009b: 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_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_00b4: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		Debug.LogWarning((object)"[LuckyBlock] No interior LevelPathPoints — using fallback ring.");
		PlayerAvatar instance = PlayerAvatar.instance;
		if (!((Object)(object)instance == (Object)null) && !((Object)(object)LuckyBlockManager.Instance == (Object)null))
		{
			List<Vector3> list = new List<Vector3>(count);
			Vector3 val = default(Vector3);
			RaycastHit val2 = default(RaycastHit);
			for (int i = 0; i < count; i++)
			{
				float num = (float)i * (360f / (float)count) * ((float)Math.PI / 180f);
				float num2 = 6f + (float)i * 1.5f;
				((Vector3)(ref val))..ctor(Mathf.Cos(num) * num2, 0f, Mathf.Sin(num) * num2);
				Vector3 item = (Physics.Raycast(((Component)instance).transform.position + val + Vector3.up * 5f, Vector3.down, ref val2, 12f) ? (((RaycastHit)(ref val2)).point + Vector3.up * 0.4f) : (((Component)instance).transform.position + val + Vector3.up * 0.4f));
				list.Add(item);
			}
			LuckyBlockManager.Instance.SpawnBlocks(list);
		}
	}
}
public class LuckySettingsMenu : MonoBehaviour
{
	private enum Page
	{
		Main,
		EventsPick,
		EventsList
	}

	private enum RowKind
	{
		Slider,
		ForwardNav,
		Other
	}

	internal static ConfigEntry<bool> ConfigEnabled;

	internal static ConfigEntry<KeyCode> ConfigToggleKey;

	private bool _open;

	private int _selectedIndex;

	private Page _page;

	private LuckyEventCategory _eventsCategory;

	private Vector2 _scroll = Vector2.zero;

	private string _status = "";

	private float _statusUntil = -1f;

	private bool _profileDirty;

	private float _profileDirtyAt;

	private const float AUTOSAVE_DEBOUNCE = 0.5f;

	private const float WIN_W = 420f;

	private const float WIN_H = 560f;

	private const float ROW_H = 22f;

	private const float PAD = 8f;

	private const int FONT_SZ = 12;

	private const float HOLD_DELAY = 0.3f;

	private const float REPEAT_RATE = 0.05f;

	private float _upTimer;

	private float _downTimer;

	private float _enterTimer;

	private float _leftTimer;

	private float _rightTimer;

	private static readonly Color COL_SELECTED = new Color(1f, 0.85f, 0f);

	private sta