Decompiled source of ChaosRoulette v1.2.0

Mods/ChaosRoulette.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BoneLib;
using ChaosRoulette;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSystem.Collections.Generic;
using LabFusion.Marrow.Pool;
using LabFusion.Menu.Data;
using LabFusion.Network;
using LabFusion.Player;
using LabFusion.SDK.Gamemodes;
using LabFusion.SDK.Metadata;
using LabFusion.UI.Popups;
using MelonLoader;
using MelonLoader.Preferences;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(ChaosRouletteMod), "Chaos Roulette", "1.2.0", "CosmicVR", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("ChaosRoulette")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ChaosRoulette")]
[assembly: AssemblyTitle("ChaosRoulette")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ChaosRoulette;

public class ChaosRouletteGamemode : Gamemode
{
	private enum Phase
	{
		Idle,
		Rolling,
		Running
	}

	public const string NotificationTag = "ChaosRoulette";

	public const string BarcodeId = "Cosmic.ChaosRoulette";

	private const string RoundKey = "cr_round";

	private const float RollSeconds = 3.4f;

	private const float RollTimeout = 15f;

	private Phase _phase;

	private float _phaseTime;

	private float _roundTime;

	private bool _teleported;

	private int _round;

	private readonly List<Perk> _localPerks = new List<Perk>();

	private int _minimumPlayers = 1;

	public int RoundMinutes = 5;

	public bool TeleportOnStart = true;

	public int MinimumPlayers
	{
		get
		{
			return _minimumPlayers;
		}
		set
		{
			_minimumPlayers = value;
			if (!((Gamemode)this).IsStarted && ((Gamemode)this).IsSelected)
			{
				try
				{
					GamemodeManager.ValidateReadyConditions();
				}
				catch
				{
				}
			}
		}
	}

	public override string Title => "Chaos Roulette";

	public override string Author => "CosmicVR";

	public override string Barcode => "Cosmic.ChaosRoulette";

	public override string Description => "Both players roll two random perks - and they are different for everyone. You might pull Super Speed and a Katana, or Blindfolded and Frozen Legs. Pulls range from absurdly lucky to hilariously unlucky. Good luck.";

	public static void Register()
	{
		GamemodeRegistration.RegisterGamemode<ChaosRouletteGamemode>();
	}

	public override void OnGamemodeRegistered()
	{
		try
		{
			_minimumPlayers = Math.Max(1, ChaosRouletteMod.PrefMinimumPlayers.Value);
			RoundMinutes = Math.Max(1, ChaosRouletteMod.PrefRoundMinutes.Value);
			TeleportOnStart = ChaosRouletteMod.PrefTeleport.Value;
		}
		catch
		{
		}
	}

	public override GroupElementData CreateSettingsGroup()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: 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_003c: 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)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Expected O, but got Unknown
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Expected O, but got Unknown
		GroupElementData obj = ((Gamemode)this).CreateSettingsGroup();
		GroupElementData val = new GroupElementData("Round Settings");
		obj.AddElement<GroupElementData>(val);
		val.AddElement<IntElementData>(new IntElementData
		{
			Title = "Minimum Players",
			Value = MinimumPlayers,
			Increment = 1,
			MinValue = 1,
			MaxValue = 8,
			OnValueChanged = delegate(int value)
			{
				MinimumPlayers = value;
				ChaosRouletteMod.PrefMinimumPlayers.Value = value;
				ChaosRouletteMod.SavePref<int>(ChaosRouletteMod.PrefMinimumPlayers);
			}
		});
		val.AddElement<IntElementData>(new IntElementData
		{
			Title = "Round Length (minutes)",
			Value = RoundMinutes,
			Increment = 1,
			MinValue = 1,
			MaxValue = 60,
			OnValueChanged = delegate(int value)
			{
				RoundMinutes = value;
				ChaosRouletteMod.PrefRoundMinutes.Value = value;
				ChaosRouletteMod.SavePref<int>(ChaosRouletteMod.PrefRoundMinutes);
			}
		});
		val.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Scatter Players",
			Value = TeleportOnStart,
			OnValueChanged = delegate(bool value)
			{
				TeleportOnStart = value;
				ChaosRouletteMod.PrefTeleport.Value = value;
				ChaosRouletteMod.SavePref<bool>(ChaosRouletteMod.PrefTeleport);
			}
		});
		return obj;
	}

	public override bool CheckReadyConditions()
	{
		try
		{
			return PlayerIDManager.PlayerCount >= MinimumPlayers;
		}
		catch
		{
			return false;
		}
	}

	public override bool CanAttack(PlayerID player)
	{
		return true;
	}

	public override void OnGamemodeStarted()
	{
		((Gamemode)this).OnGamemodeStarted();
		_round++;
		_roundTime = 0f;
		_teleported = false;
		StartLocalSequence();
		if (NetworkInfo.IsHost)
		{
			HostRoll();
		}
	}

	public override void OnGamemodeStopped()
	{
		((Gamemode)this).OnGamemodeStopped();
		_phase = Phase.Idle;
		_localPerks.Clear();
		PerkRuntime.Reset();
		if (NetworkInfo.IsHost)
		{
			ClearHostMetadata();
		}
		ModHelpers.Notify("CHAOS ROULETTE", "Round over!", 4f, "ChaosRoulette");
	}

	public override void OnLevelReady()
	{
		((Gamemode)this).OnLevelReady();
		if (((Gamemode)this).IsStarted && _phase == Phase.Idle)
		{
			StartLocalSequence();
		}
	}

	protected override void OnPlayerJoined(PlayerID playerId)
	{
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		((Gamemode)this).OnPlayerJoined(playerId);
		if (!NetworkInfo.IsHost || playerId == null)
		{
			return;
		}
		try
		{
			PerkPool.RollTwo(new Random(Environment.TickCount * 31 + playerId.SmallID), out var first, out var second);
			SetMeta(RollKey(playerId.SmallID), first.ToString(CultureInfo.InvariantCulture) + "|" + second.ToString(CultureInfo.InvariantCulture));
			List<Vector3> list = ModHelpers.PickSpawnPoints(1);
			if (list.Count > 0)
			{
				SetMeta(PosKey(playerId.SmallID), FormatVector(list[0]));
			}
		}
		catch (Exception ex)
		{
			ModHelpers.Warning("rolling for a late joiner failed: " + ex.Message);
		}
	}

	private void StartLocalSequence()
	{
		_localPerks.Clear();
		_phase = Phase.Rolling;
		_phaseTime = 0f;
		_teleported = false;
		ModHelpers.Notify("CHAOS ROULETTE", "Rolling...", 4f, "ChaosRoulette");
	}

	protected override void OnUpdate()
	{
		if (!((Gamemode)this).IsStarted)
		{
			return;
		}
		if (_phase == Phase.Rolling)
		{
			_phaseTime += Time.deltaTime;
			if (TeleportOnStart && !_teleported)
			{
				TryTeleport();
			}
			if (_phaseTime >= 3.4f)
			{
				if (TryReveal())
				{
					_phase = Phase.Running;
				}
				else if (_phaseTime >= 15f)
				{
					ModHelpers.Notify("CHAOS ROULETTE", "No roll came back from the host - free round!", 5f, "ChaosRoulette");
					_phase = Phase.Running;
				}
			}
		}
		else
		{
			if (_phase != Phase.Running)
			{
				return;
			}
			PerkRuntime.Tick(Time.deltaTime);
			_roundTime += Time.deltaTime;
			if (!NetworkInfo.IsHost)
			{
				return;
			}
			float num = (float)Mathf.Max(1, RoundMinutes) * 60f;
			if (_roundTime >= num)
			{
				try
				{
					GamemodeManager.StopGamemode();
				}
				catch
				{
				}
			}
		}
	}

	protected override void OnFixedUpdate()
	{
		if (((Gamemode)this).IsStarted && _phase == Phase.Running)
		{
			PerkRuntime.TickFixed();
		}
	}

	private void TryTeleport()
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!((Object)(object)Player.RigManager == (Object)null))
			{
				byte localSmallID = PlayerIDManager.LocalSmallID;
				string meta = GetMeta(PosKey(localSmallID));
				if (!string.IsNullOrEmpty(meta) && TryParseVector(meta, out var result))
				{
					LocalPlayer.TeleportToPosition(result);
					_teleported = true;
				}
			}
		}
		catch (Exception ex)
		{
			ModHelpers.Warning("teleport retry: " + ex.Message);
		}
	}

	private bool TryReveal()
	{
		try
		{
			byte localSmallID = PlayerIDManager.LocalSmallID;
			string meta = GetMeta(RollKey(localSmallID));
			if (string.IsNullOrEmpty(meta))
			{
				return false;
			}
			List<Perk> list = new List<Perk>();
			string[] array = meta.Split('|');
			for (int i = 0; i < array.Length; i++)
			{
				if (int.TryParse(array[i], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
				{
					Perk perk = PerkPool.Get(result);
					if (perk != null)
					{
						list.Add(perk);
					}
				}
			}
			if (list.Count == 0)
			{
				return false;
			}
			_localPerks.Clear();
			_localPerks.AddRange(list);
			ModHelpers.Log("rolled (server=" + NetworkInfo.HasServer + " host=" + NetworkInfo.IsHost + "): " + PerkPool.Describe(_localPerks).Replace("<color=#", "").Replace("</color>", ""));
			PerkRuntime.Apply(_localPerks);
			ModHelpers.Notify("You rolled...", PerkPool.Describe(_localPerks), 7f, "ChaosRoulette");
			return true;
		}
		catch (Exception ex)
		{
			ModHelpers.Warning("reveal failed: " + ex.Message);
			return false;
		}
	}

	private void HostRoll()
	{
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			List<PlayerID> list = (from p in PlayerIDManager.PlayerIDs
				where p != null
				orderby p.SmallID
				select p).ToList();
			if (list.Count == 0)
			{
				return;
			}
			ClearHostMetadata();
			if (TeleportOnStart)
			{
				List<Vector3> list2 = ModHelpers.PickSpawnPoints(list.Count);
				for (int num = 0; num < list.Count && num < list2.Count; num++)
				{
					SetMeta(PosKey(list[num].SmallID), FormatVector(list2[num]));
				}
			}
			Random rng = new Random(Environment.TickCount * 31 + list.Count * 7919);
			HashSet<int> hashSet = new HashSet<int>();
			for (int num2 = 0; num2 < list.Count; num2++)
			{
				int num3 = 0;
				int first;
				int second;
				int item;
				do
				{
					PerkPool.RollTwo(rng, out first, out second);
					item = PairKey(first, second);
				}
				while (hashSet.Contains(item) && num3++ < 16);
				hashSet.Add(item);
				SetMeta(RollKey(list[num2].SmallID), first.ToString(CultureInfo.InvariantCulture) + "|" + second.ToString(CultureInfo.InvariantCulture));
			}
			SetMeta("cr_round", _round.ToString(CultureInfo.InvariantCulture));
		}
		catch (Exception ex)
		{
			ModHelpers.Warning("host roll failed: " + ex.Message);
		}
	}

	private void ClearHostMetadata()
	{
		try
		{
			foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
			{
				if (playerID != null)
				{
					RemoveMeta(RollKey(playerID.SmallID));
					RemoveMeta(PosKey(playerID.SmallID));
				}
			}
			RemoveMeta("cr_round");
		}
		catch
		{
		}
	}

	private void RemoveMeta(string key)
	{
		try
		{
			Meta(key).Remove();
			if (NetworkInfo.IsHost)
			{
				((Gamemode)this).Metadata.ForceRemoveLocalMetadata(key);
			}
		}
		catch
		{
		}
	}

	private static string RollKey(byte id)
	{
		return "cr_roll_" + id.ToString(CultureInfo.InvariantCulture);
	}

	private static int PairKey(int first, int second)
	{
		int num = Math.Min(first, second);
		int num2 = Math.Max(first, second);
		return num * 1000 + num2;
	}

	private static string PosKey(byte id)
	{
		return "cr_pos_" + id.ToString(CultureInfo.InvariantCulture);
	}

	private MetadataVariable Meta(string key)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		return new MetadataVariable(key, ((Gamemode)this).Metadata);
	}

	private void SetMeta(string key, string value)
	{
		try
		{
			if (NetworkInfo.IsHost)
			{
				((Gamemode)this).Metadata.ForceSetLocalMetadata(key, value);
			}
			Meta(key).SetValue(value);
		}
		catch (Exception ex)
		{
			ModHelpers.Warning("setting metadata '" + key + "' failed: " + ex.Message);
		}
	}

	private string GetMeta(string key)
	{
		try
		{
			return Meta(key).GetValueOrEmpty();
		}
		catch
		{
			return string.Empty;
		}
	}

	private static string FormatVector(Vector3 value)
	{
		return value.x.ToString("F3", CultureInfo.InvariantCulture) + ";" + value.y.ToString("F3", CultureInfo.InvariantCulture) + ";" + value.z.ToString("F3", CultureInfo.InvariantCulture);
	}

	private static bool TryParseVector(string text, out Vector3 result)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		result = Vector3.zero;
		string[] array = text.Split(';');
		if (array.Length != 3)
		{
			return false;
		}
		if (!float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) || !float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3) || !float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result4))
		{
			return false;
		}
		result = new Vector3(result2, result3, result4);
		return true;
	}
}
public class ChaosRouletteMod : MelonMod
{
	public const string ModName = "Chaos Roulette";

	public const string ModVersion = "1.2.0";

	public static Instance Log;

	public static MelonPreferences_Entry<int> PrefMinimumPlayers;

	public static MelonPreferences_Entry<int> PrefRoundMinutes;

	public static MelonPreferences_Entry<bool> PrefTeleport;

	private static Harmony _harmony;

	private static bool _registered;

	private static int _ticks;

	private static int _warnings;

	public override void OnInitializeMelon()
	{
		Log = ((MelonBase)this).LoggerInstance;
		MelonPreferences_Category obj = MelonPreferences.CreateCategory("ChaosRoulette", "Chaos Roulette");
		PrefMinimumPlayers = obj.CreateEntry<int>("MinimumPlayers", 1, "Minimum Players", (string)null, false, false, (ValueValidator)null, (string)null);
		PrefRoundMinutes = obj.CreateEntry<int>("RoundMinutes", 5, "Round Length (minutes)", (string)null, false, false, (ValueValidator)null, (string)null);
		PrefTeleport = obj.CreateEntry<bool>("TeleportOnStart", true, "Scatter players at round start", (string)null, false, false, (ValueValidator)null, (string)null);
		ApplyPatches();
		MelonLogger.Msg("Chaos Roulette 1.2.0 loaded.");
	}

	private static void ApplyPatches()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Expected O, but got Unknown
		try
		{
			_harmony = new Harmony("ChaosRoulette.Core");
		}
		catch (Exception ex)
		{
			MelonLogger.Warning("Chaos Roulette: could not create the harmony instance: " + ex.Message);
			return;
		}
		PatchOne(typeof(OneShotDamagePatch), "one shot pistol (NPCs and props)");
		PatchOne(typeof(OneShotPlayerDamagePatch), "one shot pistol (other players)");
	}

	private static void PatchOne(Type patchType, string label)
	{
		try
		{
			_harmony.CreateClassProcessor(patchType).Patch();
			MelonLogger.Msg("Chaos Roulette: patch applied - " + label);
		}
		catch (Exception ex)
		{
			MelonLogger.Warning("Chaos Roulette: patch FAILED - " + label + ": " + ex.Message);
		}
	}

	public override void OnUpdate()
	{
		if (!_registered)
		{
			_ticks++;
			if (_ticks <= 5 || _ticks % 30 == 0)
			{
				TryRegister();
			}
		}
	}

	private static void TryRegister()
	{
		try
		{
			if (!IsFusionLoaded())
			{
				Warn("Fusion is not loaded yet, waiting...");
				return;
			}
			RegisterWithFusion();
			_registered = true;
			MelonLogger.Msg("Chaos Roulette: gamemode registered with Fusion.");
		}
		catch (Exception ex)
		{
			Warn("could not register the gamemode yet (" + ex.GetType().Name + ": " + ex.Message + ")");
		}
	}

	private static void RegisterWithFusion()
	{
		ChaosRouletteGamemode.Register();
	}

	private static bool IsFusionLoaded()
	{
		try
		{
			return AppDomain.CurrentDomain.GetAssemblies().Any((Assembly a) => a != null && a.GetName().Name == "LabFusion");
		}
		catch
		{
			return false;
		}
	}

	private static void Warn(string message)
	{
		if (_warnings < 3 || _ticks % 900 == 0)
		{
			_warnings++;
			MelonLogger.Warning("Chaos Roulette: " + message);
		}
	}

	public static void SavePref<T>(MelonPreferences_Entry<T> entry)
	{
		try
		{
			((MelonPreferences_Entry)entry).Category.SaveToFile(false);
		}
		catch
		{
		}
	}
}
internal static class ModHelpers
{
	public static void Notify(string title, string message, float length = 4f, string tag = null)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: 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_0038: 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_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		try
		{
			Notifier.Send(new Notification
			{
				Title = new NotificationText(title, new Color(0.35f, 0.85f, 1f), true),
				Message = new NotificationText(message, Color.white, true),
				Tag = tag,
				ShowPopup = true,
				SaveToMenu = false,
				PopupLength = length,
				Type = (NotificationType)0
			});
		}
		catch (Exception ex)
		{
			Warning("notification failed: " + ex.Message);
		}
	}

	public static void GiveWeapon(string barcode, string label)
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Expected O, but got Unknown
		//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_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: 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_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (string.IsNullOrWhiteSpace(barcode))
			{
				Warning("give weapon: empty barcode for " + label);
				return;
			}
			RigManager rigManager = Player.RigManager;
			if ((Object)(object)rigManager == (Object)null)
			{
				Warning("give weapon: no player rig for " + label);
				return;
			}
			if ((Object)(object)((CrateReferenceT<SpawnableCrate>)new SpawnableCrateReference(barcode)).Crate == (Object)null)
			{
				Warning("give weapon: '" + label + "' barcode " + barcode + " is not a loaded crate");
				return;
			}
			Transform chest = Player.Chest;
			Transform head = Player.Head;
			Vector3 val;
			Vector3 right;
			Vector3 forward;
			if ((Object)(object)chest != (Object)null)
			{
				val = chest.position;
				right = chest.right;
				forward = chest.forward;
			}
			else if ((Object)(object)head != (Object)null)
			{
				val = head.position;
				right = head.right;
				forward = head.forward;
			}
			else
			{
				Transform transform = ((Component)rigManager).transform;
				val = transform.position + Vector3.up * 1.2f;
				right = transform.right;
				forward = transform.forward;
			}
			Vector3 position = val + right * 0.6f + forward * 0.2f - Vector3.up * 0.25f;
			Vector3 forward2 = default(Vector3);
			((Vector3)(ref forward2))..ctor(forward.x, 0f, forward.z);
			if (((Vector3)(ref forward2)).sqrMagnitude < 0.0001f)
			{
				forward2 = Vector3.forward;
			}
			Quaternion rotation = Quaternion.LookRotation(((Vector3)(ref forward2)).normalized, Vector3.up);
			Log("spawning " + label + " beside the player at " + ((Vector3)(ref position)).ToString("F1"));
			Spawnable obj = LocalAssetSpawner.CreateSpawnable(barcode);
			LocalAssetSpawner.Register(obj);
			LocalAssetSpawner.Spawn(obj, position, rotation, (Action<Poolee>)delegate(Poolee poolee)
			{
				//IL_005e: 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)
				try
				{
					if ((Object)(object)poolee == (Object)null)
					{
						Warning("give weapon: '" + label + "' spawned nothing");
					}
					else
					{
						GameObject gameObject = ((Component)poolee).gameObject;
						if ((Object)(object)gameObject == (Object)null)
						{
							Warning("give weapon: '" + label + "' has no game object");
						}
						else
						{
							gameObject.transform.position = position;
							gameObject.transform.rotation = rotation;
							Log("spawned " + label);
							Hand rightHand = Player.RightHand;
							if (!((Object)(object)rightHand == (Object)null))
							{
								if (rightHand.HasAttachedObject())
								{
									Log(label + " left in front of the player (right hand is full)");
								}
								else
								{
									rightHand.AttachObject(gameObject);
									Log("put " + label + " in the right hand");
								}
							}
						}
					}
				}
				catch (Exception ex2)
				{
					Warning("give weapon post-spawn for " + label + " failed: " + ex2.Message);
				}
			});
		}
		catch (Exception ex)
		{
			Warning("give weapon (" + label + ") failed: " + ex.Message);
		}
	}

	public static List<Vector3> PickSpawnPoints(int count)
	{
		//IL_0101: 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_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> list = new List<Vector3>();
		try
		{
			Il2CppArrayBase<ZoneCheckpoint> val = Object.FindObjectsOfType<ZoneCheckpoint>();
			if (val != null)
			{
				for (int i = 0; i < val.Length; i++)
				{
					ZoneCheckpoint val2 = val[i];
					if (!((Object)(object)val2 == (Object)null))
					{
						Vector3 position = ((Component)val2).transform.position;
						if (!float.IsNaN(position.x) && !float.IsNaN(position.y) && !float.IsNaN(position.z))
						{
							list.Add(position + Vector3.up * 0.25f);
						}
					}
				}
			}
		}
		catch (Exception ex)
		{
			Warning("checkpoint scan failed: " + ex.Message);
		}
		Shuffle(list);
		int num = 0;
		while (list.Count < count && num++ < 40)
		{
			Vector3? val3 = FindGroundPoint();
			if (!val3.HasValue)
			{
				break;
			}
			list.Add(val3.Value);
		}
		RigManager rigManager = Player.RigManager;
		Vector3 val4 = (((Object)(object)rigManager != (Object)null) ? ((Component)rigManager).transform.position : Vector3.zero);
		int num2 = 0;
		while (list.Count < count && num2 < 32)
		{
			float num3 = (float)num2 * ((float)Math.PI / 4f);
			float num4 = 4f + (float)(num2 / 8) * 3f;
			list.Add(val4 + new Vector3(Mathf.Cos(num3), 0f, Mathf.Sin(num3)) * num4 + Vector3.up * 0.2f);
			num2++;
		}
		return list;
	}

	private static Vector3? FindGroundPoint()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: 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_006c: 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_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_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			RigManager rigManager = Player.RigManager;
			Vector3 val = (((Object)(object)rigManager != (Object)null) ? ((Component)rigManager).transform.position : Vector3.zero);
			RaycastHit val3 = default(RaycastHit);
			for (int i = 0; i < 14; i++)
			{
				float num = Random.Range(0f, (float)Math.PI * 2f);
				float num2 = Random.Range(12f, 34f);
				Vector3 val2 = new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * num2;
				if (Physics.Raycast(val + val2 + Vector3.up * 30f, Vector3.down, ref val3, 80f, -5, (QueryTriggerInteraction)1) && ((RaycastHit)(ref val3)).normal.y > 0.35f)
				{
					return ((RaycastHit)(ref val3)).point + Vector3.up * 0.4f;
				}
			}
		}
		catch (Exception ex)
		{
			Warning("ground sample failed: " + ex.Message);
		}
		return null;
	}

	private static void Shuffle(List<Vector3> list)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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)
		for (int num = list.Count - 1; num > 0; num--)
		{
			int index = Random.Range(0, num + 1);
			Vector3 value = list[num];
			list[num] = list[index];
			list[index] = value;
		}
	}

	public static void Log(string message)
	{
		try
		{
			MelonLogger.Msg("Chaos Roulette: " + message);
		}
		catch
		{
		}
	}

	public static void Warning(string message)
	{
		try
		{
			MelonLogger.Warning("Chaos Roulette: " + message);
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(Health), "TAKEDAMAGE")]
internal static class OneShotDamagePatch
{
	[HarmonyPrefix]
	private static void Prefix(Health __instance, ref float damage)
	{
		try
		{
			if (PerkRuntime.OneShot && !((Object)(object)__instance == (Object)null) && !IsLocalPlayerHealth(__instance))
			{
				damage = 100000f;
			}
		}
		catch
		{
		}
	}

	private static bool IsLocalPlayerHealth(Health health)
	{
		try
		{
			RigManager rigManager = Player.RigManager;
			return (Object)(object)health != (Object)null && (Object)(object)rigManager != (Object)null && (Object)(object)rigManager.health == (Object)(object)health;
		}
		catch
		{
			return false;
		}
	}
}
[HarmonyPatch(typeof(PlayerDamageReceiver), "ReceiveAttack")]
internal static class OneShotPlayerDamagePatch
{
	[HarmonyPrefix]
	private static void Prefix(PlayerDamageReceiver __instance, ref Attack attack)
	{
		try
		{
			if (!PerkRuntime.OneShot || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			Health health = __instance.health;
			if (!((Object)(object)health == (Object)null))
			{
				RigManager rigManager = health._rigManager;
				RigManager rigManager2 = Player.RigManager;
				if (!((Object)(object)rigManager == (Object)null) && !((Object)(object)rigManager2 == (Object)null) && !((Object)(object)rigManager == (Object)(object)rigManager2))
				{
					attack.damage = 100000f;
				}
			}
		}
		catch
		{
		}
	}
}
internal enum PerkId
{
	SuperSpeed,
	OneShotPistol,
	Crowbar,
	Katana,
	Sledgehammer,
	Shotgun,
	Juggernaut,
	BouncyBones,
	AntMan,
	Kaiju,
	InfiniteAmmo,
	SuperStrength,
	Invincible,
	NearlyInvisible,
	NimbusGun,
	GodManipulator,
	BoxTurret,
	Blackout,
	RagdollEveryFive,
	Blindfolded,
	FrozenLegs,
	EmptyPockets,
	GlassBones,
	Butterfingers,
	Molasses,
	BackwardsDay,
	NoHands,
	AbsolutelyNothing
}
internal sealed class Perk
{
	public readonly int Id;

	public readonly string Name;

	public readonly string Hex;

	public readonly bool Good;

	public Perk(PerkId id, string name, string hex, bool good)
	{
		Id = (int)id;
		Name = name;
		Hex = hex;
		Good = good;
	}
}
internal static class PerkPool
{
	public static readonly List<Perk> All = new List<Perk>
	{
		new Perk(PerkId.SuperSpeed, "Super Speed", "00E5FF", good: true),
		new Perk(PerkId.OneShotPistol, "One Shot Pistol", "FFD54A", good: true),
		new Perk(PerkId.Crowbar, "Crowbar", "C9E4A0", good: true),
		new Perk(PerkId.Katana, "Katana", "C9E4A0", good: true),
		new Perk(PerkId.Sledgehammer, "Sledgehammer", "C9E4A0", good: true),
		new Perk(PerkId.Shotgun, "Shotgun", "FFD54A", good: true),
		new Perk(PerkId.Juggernaut, "Juggernaut", "7CFC6A", good: true),
		new Perk(PerkId.BouncyBones, "Bouncy Bones", "7CFC6A", good: true),
		new Perk(PerkId.AntMan, "Ant-Man", "7CFC6A", good: true),
		new Perk(PerkId.Kaiju, "Kaiju", "7CFC6A", good: true),
		new Perk(PerkId.InfiniteAmmo, "Infinite Ammo", "C9E4A0", good: true),
		new Perk(PerkId.SuperStrength, "Super Strength", "FFD54A", good: true),
		new Perk(PerkId.Invincible, "Invincible", "FFB300", good: true),
		new Perk(PerkId.NearlyInvisible, "Nearly Invisible", "B388FF", good: true),
		new Perk(PerkId.NimbusGun, "Nimbus Gun", "FFB300", good: true),
		new Perk(PerkId.GodManipulator, "God Manipulator", "FFB300", good: true),
		new Perk(PerkId.BoxTurret, "Box Turret", "C9E4A0", good: true),
		new Perk(PerkId.Blackout, "Blackout", "FF5252", good: false),
		new Perk(PerkId.RagdollEveryFive, "Ragdoll Every 5 Seconds", "FF5252", good: false),
		new Perk(PerkId.Blindfolded, "Blindfolded", "FF5252", good: false),
		new Perk(PerkId.FrozenLegs, "Frozen Legs", "FF5252", good: false),
		new Perk(PerkId.EmptyPockets, "Empty Pockets", "FF8A65", good: false),
		new Perk(PerkId.GlassBones, "Glass Bones", "FF8A65", good: false),
		new Perk(PerkId.Butterfingers, "Butterfingers", "FF8A65", good: false),
		new Perk(PerkId.Molasses, "Molasses", "FF8A65", good: false),
		new Perk(PerkId.BackwardsDay, "Backwards Day", "FF5252", good: false),
		new Perk(PerkId.NoHands, "No Hands", "FF5252", good: false),
		new Perk(PerkId.AbsolutelyNothing, "Absolutely Nothing", "9E9E9E", good: false)
	};

	public static Perk Get(int id)
	{
		if (id < 0 || id >= All.Count)
		{
			return null;
		}
		return All[id];
	}

	public static void RollTwo(Random rng, out int first, out int second)
	{
		first = rng.Next(All.Count);
		second = rng.Next(All.Count);
		if (All.Count > 1 && second == first)
		{
			second = (second + 1 + rng.Next(All.Count - 1)) % All.Count;
		}
	}

	public static string Describe(List<Perk> perks)
	{
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < perks.Count; i++)
		{
			if (i > 0)
			{
				stringBuilder.Append((i == perks.Count - 1) ? " and " : ", ");
			}
			stringBuilder.Append("<color=#").Append(perks[i].Hex).Append(">")
				.Append(perks[i].Name)
				.Append("</color>");
		}
		return stringBuilder.ToString();
	}
}
internal static class PerkRuntime
{
	public static bool SuperSpeed;

	public static bool Molasses;

	public static bool Backwards;

	public static bool Bouncy;

	public static bool OneShot;

	public static bool InfiniteAmmo;

	public static bool EmptyPockets;

	public static bool Blind;

	public static bool Frozen;

	public static bool NoHands;

	public static bool Butterfingers;

	public static bool Invisible;

	public static bool Invincible;

	public static bool Blackout;

	public static bool RagdollEveryFive;

	public static float HeightOverride = -1f;

	public static float Vitality = -1f;

	private static float _ammoTimer;

	private static float _butterTimer;

	private static float _bounceTimer;

	private static float _moveLogTimer;

	private static float _healthTimer;

	private static float _blackoutTimer;

	private static float _ragdollTimer;

	private static float _appliedHeight = -1f;

	private static float _appliedVitality = -1f;

	private static bool _appliedImmortal;

	private static bool _appliedLock;

	private static bool _appliedNoHands;

	private static bool _appliedBlind;

	private static float _blindTimer;

	private static bool _blindOn;

	private static readonly List<Rigidbody> _frozenRbs = new List<Rigidbody>();

	private static readonly List<Vector3> _frozenPositions = new List<Vector3>();

	private static readonly List<Quaternion> _frozenRotations = new List<Quaternion>();

	private static readonly List<Renderer> _tintedRenderers = new List<Renderer>();

	private static readonly List<Material> _originalMaterials = new List<Material>();

	private const float BaseWalkSpeed = 4.6f;

	private const float SuperSpeedMultiplier = 2.4f;

	private const float MolassesMultiplier = 0.28f;

	private const float JumpStrength = 7f;

	private const float RagdollEveryFiveInterval = 5f;

	private const float RagdollEveryFiveLength = 1.2f;

	private const float BlackoutInterval = 12f;

	private const float BlackoutLength = 2.6f;

	private const float BlindPeriod = 8f;

	private const float SightPeriod = 4f;

	public static void Apply(List<Perk> perks)
	{
		ClearFlags();
		List<string> list = new List<string>();
		if (perks != null)
		{
			foreach (Perk perk in perks)
			{
				try
				{
					ApplyOne(perk);
					list.Add(perk.Name);
				}
				catch (Exception ex)
				{
					ModHelpers.Warning("applying " + perk.Name + " failed: " + ex);
				}
			}
		}
		SyncOverrides();
		_blackoutTimer = 6f;
		_ragdollTimer = 5f;
		ModHelpers.Log((list.Count == 0) ? "no perks to apply" : ("applied: " + string.Join(", ", list)));
	}

	private static void ApplyOne(Perk perk)
	{
		switch ((PerkId)perk.Id)
		{
		case PerkId.SuperSpeed:
			SuperSpeed = true;
			break;
		case PerkId.Molasses:
			Molasses = true;
			break;
		case PerkId.BackwardsDay:
			Backwards = true;
			break;
		case PerkId.BouncyBones:
			Bouncy = true;
			break;
		case PerkId.OneShotPistol:
			OneShot = true;
			InfiniteAmmo = true;
			ModHelpers.GiveWeapon("c1534c5a-fcfc-4f43-8fb0-d29531393131", "One Shot Pistol");
			break;
		case PerkId.Crowbar:
			ModHelpers.GiveWeapon("c1534c5a-0c8a-4b82-9f8b-7a9543726f77", "Crowbar");
			break;
		case PerkId.Katana:
			ModHelpers.GiveWeapon("c1534c5a-282b-4430-b009-58954b617461", "Katana");
			break;
		case PerkId.Sledgehammer:
			ModHelpers.GiveWeapon("c1534c5a-1f5a-4993-bbc1-03be4d656c65", "Sledgehammer");
			break;
		case PerkId.Shotgun:
			InfiniteAmmo = true;
			ModHelpers.GiveWeapon("c1534c5a-7f05-402f-9320-609647756e35", "Shotgun");
			break;
		case PerkId.SuperStrength:
			ModHelpers.GiveWeapon("c1534c5a-cebf-42cc-be3a-4595506f7765", "Super Strength");
			break;
		case PerkId.NimbusGun:
			ModHelpers.GiveWeapon("c1534c5a-6b38-438a-a324-d7e147616467", "Nimbus Gun");
			break;
		case PerkId.GodManipulator:
			ModHelpers.GiveWeapon("c1534c5a-c6a8-45d0-aaa2-2c954465764d", "God Manipulator");
			break;
		case PerkId.BoxTurret:
			ModHelpers.GiveWeapon("SLZ.BONELAB.Content.Spawnable.BoxTurret", "Box Turret");
			break;
		case PerkId.Juggernaut:
			Vitality = 8f;
			HeightOverride = 2.15f;
			break;
		case PerkId.Kaiju:
			Vitality = 3f;
			HeightOverride = 3f;
			break;
		case PerkId.AntMan:
			HeightOverride = 0.5f;
			break;
		case PerkId.GlassBones:
			Vitality = 0.3f;
			break;
		case PerkId.InfiniteAmmo:
			InfiniteAmmo = true;
			break;
		case PerkId.Invincible:
			Invincible = true;
			break;
		case PerkId.NearlyInvisible:
			Invisible = true;
			break;
		case PerkId.Blackout:
			Blackout = true;
			break;
		case PerkId.RagdollEveryFive:
			RagdollEveryFive = true;
			break;
		case PerkId.Blindfolded:
			Blind = true;
			break;
		case PerkId.FrozenLegs:
			Frozen = true;
			break;
		case PerkId.EmptyPockets:
			EmptyPockets = true;
			break;
		case PerkId.Butterfingers:
			Butterfingers = true;
			break;
		case PerkId.NoHands:
			NoHands = true;
			break;
		case PerkId.AbsolutelyNothing:
			break;
		}
	}

	private static void SyncOverrides()
	{
		//IL_0350: Unknown result type (might be due to invalid IL or missing references)
		if (HeightOverride > 0f)
		{
			if (Mathf.Abs(_appliedHeight - HeightOverride) > 0.001f)
			{
				try
				{
					LocalAvatar.HeightOverride = HeightOverride;
					_appliedHeight = HeightOverride;
					ModHelpers.Log("height override -> " + HeightOverride.ToString("0.00") + "m");
				}
				catch (Exception ex)
				{
					ModHelpers.Warning("height override failed: " + ex.Message);
				}
			}
		}
		else if (_appliedHeight > 0f)
		{
			try
			{
				LocalAvatar.HeightOverride = null;
				_appliedHeight = -1f;
				ModHelpers.Log("height override cleared");
			}
			catch (Exception ex2)
			{
				ModHelpers.Warning("clearing height failed: " + ex2.Message);
			}
		}
		if (Mathf.Abs(_appliedVitality - Vitality) > 0.001f || _appliedImmortal != Invincible)
		{
			try
			{
				LocalHealth.VitalityOverride = ((Vitality > 0f) ? new float?(Vitality) : ((float?)null));
				LocalHealth.MortalityOverride = (Invincible ? new bool?(false) : ((bool?)null));
				LocalHealth.RegenerationOverride = (Invincible ? new bool?(true) : ((Vitality > 0f) ? new bool?(false) : ((bool?)null)));
				_appliedVitality = Vitality;
				_appliedImmortal = Invincible;
				ModHelpers.Log("health override | vitality=" + ((Vitality > 0f) ? Vitality.ToString("0.00") : "normal") + " immortal=" + Invincible + " (server=" + NetworkInfo.HasServer + ")");
			}
			catch (Exception ex3)
			{
				ModHelpers.Warning("health override failed: " + ex3.Message);
			}
		}
		if (_appliedLock != Frozen)
		{
			try
			{
				LocalControls.LockedMovement = Frozen;
				_appliedLock = Frozen;
				ModHelpers.Log("movement lock = " + Frozen + " (server=" + NetworkInfo.HasServer + ")");
			}
			catch (Exception ex4)
			{
				ModHelpers.Warning("movement lock failed: " + ex4.Message);
			}
		}
		if (_appliedNoHands != NoHands)
		{
			try
			{
				LocalControls.DisableInteraction = NoHands;
				if (NoHands)
				{
					CaptureFrozenArms();
				}
				else
				{
					ReleaseFrozenArms();
				}
				_appliedNoHands = NoHands;
				ModHelpers.Log("no hands = " + NoHands + " | frozen arm bodies = " + _frozenRbs.Count + " (server=" + NetworkInfo.HasServer + ")");
			}
			catch (Exception ex5)
			{
				ModHelpers.Warning("interaction lock failed: " + ex5.Message);
			}
		}
		if (_appliedBlind != Blind)
		{
			try
			{
				if (Blind)
				{
					LocalVision.BlindColor = Color.black;
					_blindOn = true;
					_blindTimer = 8f;
				}
				else
				{
					_blindOn = false;
					_blindTimer = 0f;
				}
				LocalVision.Blind = Blind;
				_appliedBlind = Blind;
				ModHelpers.Log("blindfold = " + Blind + (Blind ? (" (closed for " + 8f + "s, open for " + 4f + "s, repeating)") : ""));
			}
			catch (Exception ex6)
			{
				ModHelpers.Warning("blind failed: " + ex6.Message);
			}
		}
		if (Invisible)
		{
			try
			{
				ModHelpers.Log("invisibility applied to " + MakeInvisible() + " renderers");
			}
			catch (Exception ex7)
			{
				ModHelpers.Warning("invisibility failed: " + ex7.Message);
			}
		}
		try
		{
			LocalHealth.SetFullHealth();
		}
		catch
		{
		}
	}

	private static void ClearFlags()
	{
		SuperSpeed = false;
		Molasses = false;
		Backwards = false;
		Bouncy = false;
		OneShot = false;
		InfiniteAmmo = false;
		EmptyPockets = false;
		Blind = false;
		Frozen = false;
		NoHands = false;
		Butterfingers = false;
		Invisible = false;
		Invincible = false;
		Blackout = false;
		RagdollEveryFive = false;
		HeightOverride = -1f;
		Vitality = -1f;
		_ammoTimer = 0f;
		_butterTimer = 0f;
		_bounceTimer = 0f;
		_moveLogTimer = 0f;
		_healthTimer = 0f;
		_blackoutTimer = 0f;
		_ragdollTimer = 0f;
		_blindTimer = 0f;
		_blindOn = false;
		ReleaseFrozenArms();
	}

	public static void Reset()
	{
		ClearFlags();
		try
		{
			LocalAvatar.HeightOverride = null;
		}
		catch
		{
		}
		try
		{
			LocalHealth.VitalityOverride = null;
		}
		catch
		{
		}
		try
		{
			LocalHealth.RegenerationOverride = null;
		}
		catch
		{
		}
		try
		{
			LocalHealth.MortalityOverride = null;
		}
		catch
		{
		}
		try
		{
			LocalControls.LockedMovement = false;
		}
		catch
		{
		}
		try
		{
			LocalControls.DisableInteraction = false;
		}
		catch
		{
		}
		try
		{
			LocalVision.Blind = false;
		}
		catch
		{
		}
		_appliedHeight = -1f;
		_appliedVitality = -1f;
		_appliedImmortal = false;
		_appliedLock = false;
		_appliedNoHands = false;
		_appliedBlind = false;
		RestoreMaterials();
	}

	public static void Tick(float dt)
	{
		try
		{
			TickAmmo(dt);
		}
		catch
		{
		}
		try
		{
			TickButterfingers(dt);
		}
		catch
		{
		}
		try
		{
			TickHealth(dt);
		}
		catch
		{
		}
		try
		{
			TickRagdolls(dt);
		}
		catch
		{
		}
		try
		{
			TickBlindfold(dt);
		}
		catch
		{
		}
	}

	public static void TickFixed()
	{
		try
		{
			TickMovement();
		}
		catch
		{
		}
		try
		{
			TickBounce();
		}
		catch
		{
		}
		try
		{
			TickFrozenArms();
		}
		catch
		{
		}
	}

	private static void TickMovement()
	{
		//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_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0224: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: 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_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: 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_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		if (!SuperSpeed && !Molasses && !Backwards)
		{
			return;
		}
		PhysicsRig physicsRig = Player.PhysicsRig;
		if ((Object)(object)physicsRig == (Object)null || (Object)(object)physicsRig.torso == (Object)null)
		{
			return;
		}
		Rigidbody rbPelvis = physicsRig.torso.rbPelvis;
		if ((Object)(object)rbPelvis == (Object)null)
		{
			return;
		}
		OpenControllerRig controllerRig = Player.ControllerRig;
		if ((Object)(object)controllerRig == (Object)null)
		{
			return;
		}
		Vector2 primaryAxis = ((ControllerRig)controllerRig).GetPrimaryAxis();
		if (((Vector2)(ref primaryAxis)).magnitude >= 0.25f)
		{
			Transform head = Player.Head;
			Vector3 val = (((Object)(object)head != (Object)null) ? head.forward : ((Component)rbPelvis).transform.forward);
			Vector3 val2 = (((Object)(object)head != (Object)null) ? head.right : ((Component)rbPelvis).transform.right);
			val.y = 0f;
			val2.y = 0f;
			val = ((Vector3)(ref val)).normalized;
			val2 = ((Vector3)(ref val2)).normalized;
			Vector3 val3 = val2 * primaryAxis.x + val * primaryAxis.y;
			if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f)
			{
				val3 = ((Vector3)(ref val3)).normalized;
				if (Backwards)
				{
					val3 = -val3;
				}
				float num = 4.6f;
				if (SuperSpeed)
				{
					num *= 2.4f;
				}
				if (Molasses)
				{
					num *= 0.28f;
				}
				Vector3 val4 = val3 * num;
				Enumerator<Rigidbody> enumerator = physicsRig.selfRbs.GetEnumerator();
				Vector3 val5 = default(Vector3);
				while (enumerator.MoveNext())
				{
					Rigidbody current = enumerator.Current;
					if (!((Object)(object)current == (Object)null) && !current.isKinematic)
					{
						Vector3 velocity = current.velocity;
						((Vector3)(ref val5))..ctor(velocity.x, 0f, velocity.z);
						Vector3 val6 = val4 - val5;
						val6 = Vector3.ClampMagnitude(val6, 8f);
						current.AddForce(new Vector3(val6.x, 0f, val6.z), (ForceMode)2);
					}
				}
			}
		}
		_moveLogTimer += Time.fixedDeltaTime;
		if (_moveLogTimer >= 2f)
		{
			_moveLogTimer = 0f;
			Vector3 velocity2 = rbPelvis.velocity;
			Vector3 val7 = new Vector3(velocity2.x, 0f, velocity2.z);
			float magnitude = ((Vector3)(ref val7)).magnitude;
			ModHelpers.Log("movement | stick=" + ((Vector2)(ref primaryAxis)).magnitude.ToString("0.00") + " bodySpeed=" + magnitude.ToString("0.00") + " super=" + SuperSpeed + " slow=" + Molasses + " back=" + Backwards);
		}
	}

	private static void TickBounce()
	{
		//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_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		if (!Bouncy)
		{
			return;
		}
		PhysicsRig physicsRig = Player.PhysicsRig;
		if ((Object)(object)physicsRig == (Object)null || (Object)(object)physicsRig.torso == (Object)null)
		{
			return;
		}
		Rigidbody rbPelvis = physicsRig.torso.rbPelvis;
		if ((Object)(object)rbPelvis == (Object)null)
		{
			return;
		}
		if (!Physics.Raycast(rbPelvis.position, Vector3.down, 1.6f, -5, (QueryTriggerInteraction)1))
		{
			_bounceTimer = 0f;
		}
		else
		{
			if (rbPelvis.velocity.y > 1.5f)
			{
				return;
			}
			_bounceTimer += Time.fixedDeltaTime;
			if (_bounceTimer < 0.3f)
			{
				return;
			}
			_bounceTimer = 0f;
			Enumerator<Rigidbody> enumerator = physicsRig.selfRbs.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Rigidbody current = enumerator.Current;
				if (!((Object)(object)current == (Object)null) && !current.isKinematic)
				{
					Vector3 velocity = current.velocity;
					current.AddForce(new Vector3(0f, 7f - velocity.y, 0f), (ForceMode)2);
				}
			}
		}
	}

	private static void TickAmmo(float dt)
	{
		if (!InfiniteAmmo && !EmptyPockets)
		{
			return;
		}
		_ammoTimer += dt;
		if (_ammoTimer < 1f)
		{
			return;
		}
		_ammoTimer = 0f;
		try
		{
			if (InfiniteAmmo)
			{
				LocalInventory.SetAmmo(9999);
			}
			else if (EmptyPockets)
			{
				LocalInventory.ClearAmmo();
			}
		}
		catch
		{
		}
	}

	private static void TickHealth(float dt)
	{
		if (!Invincible)
		{
			return;
		}
		_healthTimer += dt;
		if (_healthTimer < 2f)
		{
			return;
		}
		_healthTimer = 0f;
		try
		{
			LocalHealth.SetFullHealth();
		}
		catch
		{
		}
	}

	private static void TickRagdolls(float dt)
	{
		if (!Blackout && !RagdollEveryFive)
		{
			return;
		}
		if (RagdollEveryFive)
		{
			_ragdollTimer -= dt;
			if (_ragdollTimer <= 0f)
			{
				_ragdollTimer = 5f;
				try
				{
					LocalRagdoll.Knockout(1.2f, false);
					ModHelpers.Log("ragdolled (every " + 5f + "s)");
				}
				catch (Exception ex)
				{
					ModHelpers.Warning("ragdoll failed: " + ex.Message);
				}
			}
		}
		if (!Blackout)
		{
			return;
		}
		_blackoutTimer -= dt;
		if (_blackoutTimer <= 0f)
		{
			_blackoutTimer = 12f;
			try
			{
				LocalRagdoll.Knockout(2.6f, true);
				ModHelpers.Log("blacked out for " + 2.6f + "s");
			}
			catch (Exception ex2)
			{
				ModHelpers.Warning("blackout failed: " + ex2.Message);
			}
		}
	}

	private static void TickButterfingers(float dt)
	{
		if (!Butterfingers)
		{
			return;
		}
		_butterTimer += dt;
		if (_butterTimer < 0.5f)
		{
			return;
		}
		_butterTimer = 0f;
		Hand rightHand = Player.RightHand;
		Hand leftHand = Player.LeftHand;
		if (((!((Object)(object)rightHand != (Object)null) || !((Object)(object)rightHand.m_CurrentAttachedGO != (Object)null)) && (!((Object)(object)leftHand != (Object)null) || !((Object)(object)leftHand.m_CurrentAttachedGO != (Object)null))) || Random.value > 0.5f)
		{
			return;
		}
		try
		{
			LocalPlayer.ReleaseGrips();
			ModHelpers.Log("butterfingers: dropped what we were holding");
		}
		catch (Exception ex)
		{
			ModHelpers.Warning("butterfingers failed: " + ex.Message);
		}
	}

	private static void TickBlindfold(float dt)
	{
		if (!Blind)
		{
			return;
		}
		_blindTimer -= dt;
		if (_blindTimer > 0f)
		{
			return;
		}
		_blindOn = !_blindOn;
		_blindTimer = (_blindOn ? 8f : 4f);
		try
		{
			LocalVision.Blind = _blindOn;
			ModHelpers.Log(_blindOn ? ("blindfold closed for " + 8f + "s") : ("blindfold open for " + 4f + "s"));
		}
		catch (Exception ex)
		{
			ModHelpers.Warning("blindfold toggle failed: " + ex.Message);
		}
	}

	private static void CaptureFrozenArms()
	{
		ReleaseFrozenArms();
		AddFrozenArm(Player.LeftHand);
		AddFrozenArm(Player.RightHand);
	}

	private static void AddFrozenArm(Hand hand)
	{
		if (!((Object)(object)hand == (Object)null))
		{
			PhysHand physHand = hand.physHand;
			if (!((Object)(object)physHand == (Object)null))
			{
				AddFrozenRb(physHand.rbHand);
				AddFrozenRb(physHand.rbUpper);
				AddFrozenRb(physHand.rbLower);
			}
		}
	}

	private static void AddFrozenRb(Rigidbody rb)
	{
		//IL_0023: 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)
		if (!((Object)(object)rb == (Object)null) && !rb.isKinematic)
		{
			_frozenRbs.Add(rb);
			_frozenPositions.Add(rb.position);
			_frozenRotations.Add(rb.rotation);
		}
	}

	private static void TickFrozenArms()
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		if (!NoHands || _frozenRbs.Count == 0)
		{
			return;
		}
		for (int i = 0; i < _frozenRbs.Count; i++)
		{
			try
			{
				Rigidbody val = _frozenRbs[i];
				if (!((Object)(object)val == (Object)null))
				{
					val.velocity = Vector3.zero;
					val.angularVelocity = Vector3.zero;
					val.position = _frozenPositions[i];
					val.rotation = _frozenRotations[i];
				}
			}
			catch
			{
			}
		}
	}

	private static void ReleaseFrozenArms()
	{
		_frozenRbs.Clear();
		_frozenPositions.Clear();
		_frozenRotations.Clear();
	}

	private static int MakeInvisible()
	{
		RigManager rigManager = Player.RigManager;
		if ((Object)(object)rigManager == (Object)null)
		{
			return 0;
		}
		Il2CppArrayBase<Renderer> componentsInChildren = ((Component)rigManager).GetComponentsInChildren<Renderer>(true);
		if (componentsInChildren == null)
		{
			return 0;
		}
		int num = 0;
		foreach (Renderer item in componentsInChildren)
		{
			if ((Object)(object)item == (Object)null)
			{
				continue;
			}
			try
			{
				Material sharedMaterial = item.sharedMaterial;
				Material material = item.material;
				if (!((Object)(object)material == (Object)null))
				{
					SetAlpha(material, 0.2f);
					_tintedRenderers.Add(item);
					_originalMaterials.Add(sharedMaterial);
					num++;
				}
			}
			catch
			{
			}
		}
		return num;
	}

	private static void SetAlpha(Material material, float alpha)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (material.HasProperty("_Color"))
			{
				Color color = material.GetColor("_Color");
				color.a = alpha;
				material.SetColor("_Color", color);
			}
			if (material.HasProperty("_BaseColor"))
			{
				Color color2 = material.GetColor("_BaseColor");
				color2.a = alpha;
				material.SetColor("_BaseColor", color2);
			}
			if (material.HasProperty("_Mode"))
			{
				material.SetFloat("_Mode", 3f);
			}
			if (material.HasProperty("_SrcBlend"))
			{
				material.SetInt("_SrcBlend", 5);
			}
			if (material.HasProperty("_DstBlend"))
			{
				material.SetInt("_DstBlend", 10);
			}
			if (material.HasProperty("_ZWrite"))
			{
				material.SetInt("_ZWrite", 0);
			}
			material.DisableKeyword("_ALPHATEST_ON");
			material.EnableKeyword("_ALPHABLEND_ON");
			material.renderQueue = 3000;
		}
		catch
		{
		}
	}

	private static void RestoreMaterials()
	{
		for (int i = 0; i < _tintedRenderers.Count; i++)
		{
			try
			{
				Renderer val = _tintedRenderers[i];
				if ((Object)(object)val != (Object)null)
				{
					Material val2 = _originalMaterials[i];
					if ((Object)(object)val2 != (Object)null)
					{
						val.sharedMaterial = val2;
					}
				}
			}
			catch
			{
			}
		}
		_tintedRenderers.Clear();
		_originalMaterials.Clear();
	}
}