Decompiled source of LuckyLotteryTicket v1.0.0

BepInEx\plugins\LuckyLotteryTicket\LuckyLotteryTicket.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using LuckyLotteryTicket.Assets;
using LuckyLotteryTicket.Config;
using LuckyLotteryTicket.Items;
using LuckyLotteryTicket.NetcodePatcher;
using LuckyLotteryTicket.Registry;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LuckyLotteryTicket")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Lucky Lottery Ticket")]
[assembly: AssemblyTitle("LuckyLotteryTicket")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LuckyLotteryTicket
{
	[BepInPlugin("YourName.LuckyLotteryTicket", "Lucky Lottery Ticket", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("YourName.LuckyLotteryTicket");

		public static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"Lucky Lottery Ticket v1.0.0 is loading...");
			LotteryConfig.Init(((BaseUnityPlugin)this).Config);
			InitializeNetcode();
			Bundles.Load("lotteryticket");
			ItemRegistry.RegisterAll();
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			Log.LogInfo((object)"Lucky Lottery Ticket loaded successfully!");
		}

		private static void InitializeNetcode()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "YourName.LuckyLotteryTicket";

		public const string NAME = "Lucky Lottery Ticket";

		public const string VERSION = "1.0.0";

		public const string LethalLibGUID = "evaisa.lethallib";
	}
}
namespace LuckyLotteryTicket.Registry
{
	internal static class ItemRegistry
	{
		public static void RegisterAll()
		{
			RegisterLotteryTicket();
		}

		private static void RegisterLotteryTicket()
		{
			bool flag = (Object)(object)Bundles.Main != (Object)null;
			Item val = (flag ? Bundles.Main.LoadAsset<Item>("LotteryTicketItem") : CodeItemFactory.CreateLotteryTicket());
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)"Failed to obtain the Lucky Lottery Ticket Item (asset bundle present but missing 'LotteryTicketItem'?).");
				return;
			}
			if ((Object)(object)val.spawnPrefab == (Object)null)
			{
				Plugin.Log.LogError((object)"Lucky Lottery Ticket Item has no spawnPrefab.");
				return;
			}
			val.isScrap = true;
			val.requiresBattery = false;
			val.minValue = Mathf.Min(LotterySettings.UnscratchedMinValue, LotterySettings.UnscratchedMaxValue);
			val.maxValue = Mathf.Max(LotterySettings.UnscratchedMinValue, LotterySettings.UnscratchedMaxValue);
			if (val.toolTips == null || val.toolTips.Length == 0)
			{
				val.toolTips = new string[1] { "Scratch ticket : [LMB]" };
			}
			if (flag)
			{
				AudioClip val2 = Bundles.Main.LoadAsset<AudioClip>("ScratchSound");
				if ((Object)(object)val2 != (Object)null)
				{
					LotteryTicketItem.ScratchClip = val2;
				}
			}
			Utilities.FixMixerGroups(val.spawnPrefab);
			NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
			int value = LotteryConfig.SpawnWeight.Value;
			Items.RegisterScrap(val, value, (LevelTypes)(-1));
			Plugin.Log.LogInfo((object)("Registered '" + val.itemName + "' as scrap (" + (flag ? "asset-bundle" : "code-built") + " model, " + $"weight {value}, unscratched value {val.minValue}-{val.maxValue})."));
		}
	}
}
namespace LuckyLotteryTicket.Items
{
	internal static class CodeItemFactory
	{
		private static GameObject _holder;

		public static Item CreateLotteryTicket()
		{
			//IL_0048: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			EnsureHolder();
			Texture2D val = LoadIconTexture();
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)val2).name = "LotteryTicketItem";
			val2.transform.SetParent(_holder.transform, false);
			val2.transform.localScale = new Vector3(0.3f, 0.02f, 0.18f);
			SetLayer(val2, "Props");
			TrySetTag(val2, "PhysicsProp");
			MeshRenderer component = val2.GetComponent<MeshRenderer>();
			ApplyTicketMaterial(component, val);
			BoxCollider component2 = val2.GetComponent<BoxCollider>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Collider)component2).isTrigger = false;
			}
			AudioSource obj = val2.AddComponent<AudioSource>();
			obj.playOnAwake = false;
			obj.spatialBlend = 1f;
			obj.maxDistance = 25f;
			NetworkObject obj2 = val2.AddComponent<NetworkObject>();
			TrySetBool(obj2, "DontDestroyWithOwner", value: true);
			SetGlobalObjectIdHash(obj2, "YourName.LuckyLotteryTicket.LotteryTicketItem.v1");
			LotteryTicketItem lotteryTicketItem = val2.AddComponent<LotteryTicketItem>();
			((GrabbableObject)lotteryTicketItem).grabbable = true;
			((GrabbableObject)lotteryTicketItem).grabbableToEnemies = true;
			((GrabbableObject)lotteryTicketItem).isInFactory = true;
			((GrabbableObject)lotteryTicketItem).mainObjectRenderer = component;
			GameObject val3 = new GameObject("ScanNode");
			val3.transform.SetParent(val2.transform, false);
			SetLayer(val3, "ScanNode");
			val3.transform.localScale = new Vector3(1.3f, 20f, 2.2f);
			((Collider)val3.AddComponent<BoxCollider>()).isTrigger = false;
			ScanNodeProperties obj3 = val3.AddComponent<ScanNodeProperties>();
			obj3.maxRange = 13;
			obj3.minRange = 1;
			obj3.requiresLineOfSight = true;
			obj3.headerText = "Lucky Lottery Ticket";
			obj3.subText = "Value: ";
			obj3.scrapValue = 0;
			obj3.creatureScanID = -1;
			obj3.nodeType = 2;
			Item val4 = ScriptableObject.CreateInstance<Item>();
			((Object)val4).name = "LotteryTicketItem";
			val4.itemName = "Lucky Lottery Ticket";
			val4.spawnPrefab = val2;
			val4.isScrap = true;
			val4.requiresBattery = false;
			val4.twoHanded = false;
			val4.weight = 1f;
			val4.itemId = 76208001;
			val4.canBeGrabbedBeforeGameStart = false;
			val4.toolTips = new string[1] { "Scratch ticket : [LMB]" };
			if ((Object)(object)val != (Object)null)
			{
				val4.itemIcon = SpriteFromTexture(val);
			}
			((GrabbableObject)lotteryTicketItem).itemProperties = val4;
			if ((Object)(object)LotteryTicketItem.ScratchClip == (Object)null)
			{
				LotteryTicketItem.ScratchClip = MakeScratchClip(LotterySettings.ScratchDuration);
			}
			Plugin.Log.LogInfo((object)"Built Lucky Lottery Ticket prefab in code (no asset bundle present).");
			return val4;
		}

		private static void EnsureHolder()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)_holder != (Object)null))
			{
				_holder = new GameObject("LuckyLotteryTicket_Templates");
				_holder.SetActive(false);
				((Object)_holder).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)_holder);
			}
		}

		private static void SetLayer(GameObject go, string layerName)
		{
			int num = LayerMask.NameToLayer(layerName);
			if (num >= 0)
			{
				go.layer = num;
			}
			else
			{
				Plugin.Log.LogWarning((object)("Layer '" + layerName + "' not found; leaving default."));
			}
		}

		private static void TrySetTag(GameObject go, string tag)
		{
			try
			{
				go.tag = tag;
			}
			catch
			{
				Plugin.Log.LogWarning((object)("Tag '" + tag + "' is not defined; leaving default."));
			}
		}

		private static void TrySetBool(object obj, string field, bool value)
		{
			FieldInfo field2 = obj.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field2 != null && field2.FieldType == typeof(bool))
			{
				field2.SetValue(obj, value);
			}
		}

		private static void SetGlobalObjectIdHash(NetworkObject netObj, string key)
		{
			uint num = Fnv1a(key);
			FieldInfo field = typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				field.SetValue(netObj, num);
			}
			else
			{
				Plugin.Log.LogError((object)"Could not find NetworkObject.GlobalObjectIdHash to set.");
			}
		}

		private static uint Fnv1a(string s)
		{
			uint num = 2166136261u;
			foreach (char c in s)
			{
				num ^= (byte)c;
				num *= 16777619;
			}
			if (num != 0)
			{
				return num;
			}
			return 1u;
		}

		private static void ApplyTicketMaterial(MeshRenderer renderer, Texture2D icon)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)renderer == (Object)null))
			{
				Shader val = Shader.Find("HDRP/Lit");
				Material val2 = (Material)((!((Object)(object)val != (Object)null)) ? ((object)((Renderer)renderer).material) : ((object)new Material(val)));
				Color val3 = default(Color);
				((Color)(ref val3))..ctor(1f, 0.84f, 0.25f);
				val2.color = val3;
				val2.SetColor("_BaseColor", val3);
				if ((Object)(object)icon != (Object)null)
				{
					val2.mainTexture = (Texture)(object)icon;
					val2.SetTexture("_BaseColorMap", (Texture)(object)icon);
				}
				((Renderer)renderer).material = val2;
			}
		}

		private static Texture2D LoadIconTexture()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			try
			{
				string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "icon.png");
				if (!File.Exists(path))
				{
					return null;
				}
				byte[] array = File.ReadAllBytes(path);
				Texture2D val = new Texture2D(2, 2);
				return ImageConversion.LoadImage(val, array) ? val : null;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not load icon.png for the ticket texture: " + ex.Message));
				return null;
			}
		}

		private static Sprite SpriteFromTexture(Texture2D tex)
		{
			//IL_0019: 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)
			return Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f), 100f);
		}

		private static AudioClip MakeScratchClip(float seconds)
		{
			int num = Mathf.Clamp((int)(44100f * seconds), 11025, 176400);
			AudioClip val = AudioClip.Create("ScratchSound", num, 1, 44100, false);
			float[] array = new float[num];
			Random random = new Random(1337);
			float num2 = 0f;
			for (int i = 0; i < num; i++)
			{
				float num3 = (float)(random.NextDouble() * 2.0 - 1.0);
				num2 = num2 * 0.5f + num3 * 0.5f;
				float num4 = 0.3f * (0.55f + 0.45f * Mathf.Sin((float)i * 0.013f));
				array[i] = num2 * num4;
			}
			val.SetData(array, 0);
			return val;
		}
	}
	public static class LotterySettings
	{
		public static int UnscratchedMinValue = 12;

		public static int UnscratchedMaxValue = 18;

		public static float ScratchDuration = 2.5f;

		public static bool EnableSounds = true;

		public static bool EnableJackpotAnnouncement = true;

		public static bool AnnounceWinsToAll = false;

		public static int JackpotThreshold = 5000;

		public static int[] PrizeAmounts = new int[8] { 0, 25, 50, 100, 250, 500, 1000, 5000 };

		public static float[] PrizeChances = new float[8] { 50f, 20f, 10f, 7f, 5f, 4f, 3f, 1f };
	}
	public class LotteryTicketItem : GrabbableObject
	{
		public NetworkVariable<int> prizeValue = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public NetworkVariable<ulong> scratcherClientId = new NetworkVariable<ulong>(0uL, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public NetworkVariable<bool> isScratched = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		private bool _localScratchStarted;

		private bool _serverRolling;

		private bool _revealApplied;

		private AudioSource _audioSource;

		private ScanNodeProperties _scanNode;

		public static AudioClip ScratchClip;

		private static readonly Random Rng = new Random();

		public override void Start()
		{
			((GrabbableObject)this).Start();
			CacheComponents();
		}

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			CacheComponents();
			NetworkVariable<bool> obj = isScratched;
			obj.OnValueChanged = (OnValueChangedDelegate<bool>)(object)Delegate.Combine((Delegate?)(object)obj.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<bool>(OnScratchedChanged));
			if (isScratched.Value)
			{
				ApplyReveal(silent: true);
			}
		}

		public override void OnNetworkDespawn()
		{
			NetworkVariable<bool> obj = isScratched;
			obj.OnValueChanged = (OnValueChangedDelegate<bool>)(object)Delegate.Remove((Delegate?)(object)obj.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<bool>(OnScratchedChanged));
			((NetworkBehaviour)this).OnNetworkDespawn();
		}

		private void CacheComponents()
		{
			if ((Object)(object)_audioSource == (Object)null)
			{
				_audioSource = ((Component)this).GetComponent<AudioSource>();
				if ((Object)(object)_audioSource == (Object)null)
				{
					_audioSource = ((Component)this).GetComponentInChildren<AudioSource>();
				}
			}
			if ((Object)(object)_scanNode == (Object)null)
			{
				_scanNode = ((Component)this).GetComponentInChildren<ScanNodeProperties>();
			}
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (buttonDown && !isScratched.Value && !_localScratchStarted && !((Object)(object)base.playerHeldBy == (Object)null))
			{
				PlayerControllerB val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.localPlayerController : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)base.playerHeldBy != (Object)(object)val))
				{
					_localScratchStarted = true;
					BeginScratchServerRpc();
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void BeginScratchServerRpc(ServerRpcParams rpcParams = default(ServerRpcParams))
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(182269151u, rpcParams, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendServerRpc(ref val, 182269151u, rpcParams, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				if (!isScratched.Value && !_serverRolling)
				{
					_serverRolling = true;
					ulong senderClientId = rpcParams.Receive.SenderClientId;
					BeginScratchClientRpc(senderClientId);
					((MonoBehaviour)this).StartCoroutine(ServerScratchRoutine(senderClientId));
				}
			}
		}

		private IEnumerator ServerScratchRoutine(ulong scratcherId)
		{
			yield return (object)new WaitForSeconds(Mathf.Max(0f, LotterySettings.ScratchDuration));
			if (!((Object)(object)this == (Object)null) && ((NetworkBehaviour)this).IsSpawned && !isScratched.Value)
			{
				int value = RollPrize(Rng);
				prizeValue.Value = value;
				scratcherClientId.Value = scratcherId;
				isScratched.Value = true;
			}
		}

		[ClientRpc]
		public void BeginScratchClientRpc(ulong scratcherId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(292644908u, val2, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, scratcherId);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 292644908u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			_localScratchStarted = true;
			PlayScratchSound();
			PlayerControllerB val3 = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.localPlayerController : null);
			if ((Object)(object)val3 != (Object)null && val3.actualClientId == scratcherId)
			{
				HUDManager instance = HUDManager.Instance;
				if (instance != null)
				{
					instance.DisplayTip("Lucky Lottery Ticket", "Scratching...", false, false, "LC_Tip1");
				}
			}
		}

		private void OnScratchedChanged(bool previous, bool current)
		{
			if (current)
			{
				ApplyReveal(silent: false);
			}
		}

		private void ApplyReveal(bool silent)
		{
			if (!_revealApplied)
			{
				_revealApplied = true;
				_localScratchStarted = false;
				int value = prizeValue.Value;
				SetTicketValue(value);
				if (!silent)
				{
					ShowResult(value);
				}
			}
		}

		private void SetTicketValue(int value)
		{
			base.scrapValue = value;
			CacheComponents();
			if ((Object)(object)_scanNode != (Object)null)
			{
				_scanNode.scrapValue = value;
				_scanNode.subText = $"Value: ${value}";
			}
		}

		private void ShowResult(int value)
		{
			HUDManager instance = HUDManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if (value > 0 && value >= LotterySettings.JackpotThreshold && LotterySettings.EnableJackpotAnnouncement)
			{
				instance.DisplayTip("COMPANY LOTTERY SYSTEM", $"JACKPOT WINNER\nWinning ticket value: ${value}", false, false, "LC_Tip1");
				return;
			}
			PlayerControllerB val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.localPlayerController : null);
			if (((Object)(object)val != (Object)null && val.actualClientId == scratcherClientId.Value) || LotterySettings.AnnounceWinsToAll)
			{
				if (value > 0)
				{
					instance.DisplayTip("Lottery Ticket scratched", $"${value}", false, false, "LC_Tip1");
				}
				else
				{
					instance.DisplayTip("Lottery Ticket scratched", "No prize.", false, false, "LC_Tip1");
				}
			}
		}

		private void PlayScratchSound()
		{
			if (LotterySettings.EnableSounds)
			{
				CacheComponents();
				if ((Object)(object)_audioSource != (Object)null && (Object)(object)ScratchClip != (Object)null)
				{
					_audioSource.PlayOneShot(ScratchClip);
				}
			}
		}

		public static int RollPrize(Random rng)
		{
			int[] prizeAmounts = LotterySettings.PrizeAmounts;
			float[] prizeChances = LotterySettings.PrizeChances;
			if (prizeAmounts == null || prizeChances == null || prizeAmounts.Length == 0)
			{
				return 0;
			}
			int num = Math.Min(prizeAmounts.Length, prizeChances.Length);
			float num2 = 0f;
			for (int i = 0; i < num; i++)
			{
				num2 += Mathf.Max(0f, prizeChances[i]);
			}
			if (num2 <= 0f)
			{
				return 0;
			}
			double num3 = rng.NextDouble() * (double)num2;
			float num4 = 0f;
			for (int j = 0; j < num; j++)
			{
				num4 += Mathf.Max(0f, prizeChances[j]);
				if (num3 < (double)num4)
				{
					return Mathf.Max(0, prizeAmounts[j]);
				}
			}
			return Mathf.Max(0, prizeAmounts[num - 1]);
		}

		protected override void __initializeVariables()
		{
			if (prizeValue == null)
			{
				throw new Exception("LotteryTicketItem.prizeValue cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)prizeValue).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)prizeValue, "prizeValue");
			((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)prizeValue);
			if (scratcherClientId == null)
			{
				throw new Exception("LotteryTicketItem.scratcherClientId cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)scratcherClientId).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)scratcherClientId, "scratcherClientId");
			((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)scratcherClientId);
			if (isScratched == null)
			{
				throw new Exception("LotteryTicketItem.isScratched cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)isScratched).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)isScratched, "isScratched");
			((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)isScratched);
			((GrabbableObject)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(182269151u, new RpcReceiveHandler(__rpc_handler_182269151), "BeginScratchServerRpc");
			((NetworkBehaviour)this).__registerRpc(292644908u, new RpcReceiveHandler(__rpc_handler_292644908), "BeginScratchClientRpc");
			((GrabbableObject)this).__initializeRpcs();
		}

		private static void __rpc_handler_182269151(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0029: 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_003e: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ServerRpcParams server = rpcParams.Server;
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((LotteryTicketItem)(object)target).BeginScratchServerRpc(server);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_292644908(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong scratcherId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref scratcherId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((LotteryTicketItem)(object)target).BeginScratchClientRpc(scratcherId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "LotteryTicketItem";
		}
	}
}
namespace LuckyLotteryTicket.Config
{
	internal static class LotteryConfig
	{
		public static ConfigEntry<int> SpawnWeight;

		public static ConfigEntry<int> UnscratchedMinValue;

		public static ConfigEntry<int> UnscratchedMaxValue;

		public static ConfigEntry<float> ScratchDuration;

		public static ConfigEntry<bool> EnableSounds;

		public static ConfigEntry<bool> EnableJackpotAnnouncement;

		public static ConfigEntry<bool> AnnounceWinsToAll;

		public static ConfigEntry<int> JackpotThreshold;

		public static ConfigEntry<int>[] PrizeAmounts;

		public static ConfigEntry<float>[] PrizeChances;

		private static readonly int[] DefaultAmounts = new int[8] { 0, 25, 50, 100, 250, 500, 1000, 5000 };

		private static readonly float[] DefaultChances = new float[8] { 50f, 20f, 10f, 7f, 5f, 4f, 3f, 1f };

		public static void Init(ConfigFile cfg)
		{
			SpawnWeight = cfg.Bind<int>("01 - Spawning", "SpawnWeight", 15, "How likely the Lucky Lottery Ticket is to spawn as scrap on moons. This is a weight relative to all other scrap (vanilla scrap weights are roughly 1-100). Higher = more common.");
			UnscratchedMinValue = cfg.Bind<int>("02 - Unscratched Value", "MinValue", 12, "Minimum RAW scrap value of an UNSCRATCHED ticket. Like all scrap, the value shown in game is scaled by the moon's scrap multiplier, so the in-game amount is usually lower than this.");
			UnscratchedMaxValue = cfg.Bind<int>("02 - Unscratched Value", "MaxValue", 18, "Maximum RAW scrap value of an UNSCRATCHED ticket (see MinValue note about moon scaling).");
			ScratchDuration = cfg.Bind<float>("03 - Scratch", "ScratchDurationSeconds", 2.5f, "How long (seconds) the scratch takes before the prize is revealed.");
			EnableSounds = cfg.Bind<bool>("04 - Polish", "EnableSounds", true, "Play the scratching sound while a ticket is being scratched (if the asset bundle includes one). Local preference - only affects your own client.");
			EnableJackpotAnnouncement = cfg.Bind<bool>("04 - Polish", "EnableJackpotAnnouncement", true, "Show the big 'COMPANY LOTTERY SYSTEM / JACKPOT WINNER' banner to everyone when a jackpot is won.");
			AnnounceWinsToAll = cfg.Bind<bool>("04 - Polish", "AnnounceWinsToAll", false, "If true, normal (non-jackpot) results are announced to ALL players. If false, only the player who scratched the ticket sees the result. Local preference.");
			JackpotThreshold = cfg.Bind<int>("04 - Polish", "JackpotThreshold", 5000, "Any prize at or above this amount triggers the jackpot announcement.");
			PrizeAmounts = new ConfigEntry<int>[DefaultAmounts.Length];
			PrizeChances = new ConfigEntry<float>[DefaultChances.Length];
			for (int i = 0; i < DefaultAmounts.Length; i++)
			{
				int num = i + 1;
				PrizeAmounts[i] = cfg.Bind<int>("05 - Prize Table", $"Tier{num}.Amount", DefaultAmounts[i], $"Payout (credits) for prize tier {num}. Set to 0 for a losing tier.");
				PrizeChances[i] = cfg.Bind<float>("05 - Prize Table", $"Tier{num}.Chance", DefaultChances[i], $"Relative chance/weight for tier {num}. Defaults are percentages that sum to 100, " + "but any positive weights work (they don't have to sum to 100).");
			}
			ApplyToSettings();
		}

		public static void ApplyToSettings()
		{
			LotterySettings.UnscratchedMinValue = UnscratchedMinValue.Value;
			LotterySettings.UnscratchedMaxValue = UnscratchedMaxValue.Value;
			LotterySettings.ScratchDuration = ScratchDuration.Value;
			LotterySettings.EnableSounds = EnableSounds.Value;
			LotterySettings.EnableJackpotAnnouncement = EnableJackpotAnnouncement.Value;
			LotterySettings.AnnounceWinsToAll = AnnounceWinsToAll.Value;
			LotterySettings.JackpotThreshold = JackpotThreshold.Value;
			int[] array = new int[PrizeAmounts.Length];
			float[] array2 = new float[PrizeChances.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = PrizeAmounts[i].Value;
				array2[i] = PrizeChances[i].Value;
			}
			LotterySettings.PrizeAmounts = array;
			LotterySettings.PrizeChances = array2;
		}
	}
}
namespace LuckyLotteryTicket.Assets
{
	internal static class Bundles
	{
		public static AssetBundle Main { get; private set; }

		public static bool Load(string bundleFileName)
		{
			if ((Object)(object)Main != (Object)null)
			{
				return true;
			}
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), bundleFileName);
			if (!File.Exists(text))
			{
				Plugin.Log.LogWarning((object)("Asset bundle not found at: " + text));
				return false;
			}
			Main = AssetBundle.LoadFromFile(text);
			if ((Object)(object)Main == (Object)null)
			{
				Plugin.Log.LogError((object)("Failed to load asset bundle at: " + text));
				return false;
			}
			Plugin.Log.LogInfo((object)("Loaded asset bundle: " + bundleFileName));
			return true;
		}
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
			NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>();
			NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>();
		}
	}
}
namespace LuckyLotteryTicket.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}