Decompiled source of MetalItemVariants v0.0.8

BepInEx/plugins/MetalItemVariants.dll

Decompiled 13 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
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 Dawn;
using Dusk;
using GameNetcodeStuff;
using MetalItemVariants.NetcodePatcher;
using MetalItemVariants.Utils;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MetalItemVariants")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.0.8.0")]
[assembly: AssemblyInformationalVersion("0.0.8")]
[assembly: AssemblyProduct("MetalItemVariants")]
[assembly: AssemblyTitle("MetalItemVariants")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.8.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 MetalItemVariants
{
	internal class ConfigManager
	{
		internal static ConfigEntry<bool>? DebugLogging { get; private set; }

		internal ConfigManager()
		{
			DebugLogging = DuskConfigParser.Bind("_Mod Internal Settings", "Debug Logs", defaultValue: false, "Enables debug logging");
		}
	}
	[BepInPlugin("MrHat.MetalItemVariants.Internals", "MetalItemVariants", "0.0.8")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		internal const string modGUID = "MrHat.MetalItemVariants.Internals";

		internal const string modName = "MetalItemVariants";

		internal const string modVersion = "0.0.8";

		internal static ManualLogSource mls;

		internal static Plugin instance;

		internal const string DawnNamespace = "metalitemvariants";

		internal static ConfigManager Configs { get; private set; }

		private void Awake()
		{
			instance = this;
			mls = Logger.CreateLogSource("MrHat.MetalItemVariants.Internals");
			Configs = new ConfigManager();
			((Registry<DawnItemInfo>)(object)LethalContent.Items).OnFreeze += Utility.CacheLoadedResources;
		}

		internal static void LogDebug(object message)
		{
			ConfigEntry<bool>? debugLogging = ConfigManager.DebugLogging;
			if (debugLogging != null && debugLogging.Value)
			{
				mls.LogDebug(message);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "MetalItemVariants";

		public const string PLUGIN_NAME = "MetalItemVariants";

		public const string PLUGIN_VERSION = "0.0.8";
	}
}
namespace MetalItemVariants.Utils
{
	internal static class DuskConfigParser
	{
		private const string dawnGUID = "MrHat.MetalItemVariants";

		internal static bool Get<T>(string key, out T value)
		{
			DuskMod val = ((IEnumerable<DuskMod>)DuskMod.AllMods).FirstOrDefault((Func<DuskMod, bool>)((DuskMod item) => item.Plugin.GUID == "MrHat.MetalItemVariants"));
			if (val != null)
			{
				ConfigEntryBase val2 = ((IEnumerable<ConfigEntryBase>)val.ConfigEntries).FirstOrDefault((Func<ConfigEntryBase, bool>)((ConfigEntryBase item) => item.Definition.Key == key));
				if (val2 is ConfigEntry<T> val3)
				{
					value = val3.Value;
					return true;
				}
			}
			value = default(T);
			return false;
		}

		internal static ConfigEntry<T>? Bind<T>(string section, string key, T defaultValue, string description)
		{
			DuskMod val = ((IEnumerable<DuskMod>)DuskMod.AllMods).FirstOrDefault((Func<DuskMod, bool>)((DuskMod item) => item.Plugin.GUID == "MrHat.MetalItemVariants"));
			if (val == null)
			{
				return null;
			}
			ConfigContext val2 = val.ConfigManager.CreateConfigSection(section);
			try
			{
				return val2.Bind<T>(key, description, defaultValue);
			}
			finally
			{
				((IDisposable)val2)?.Dispose();
			}
		}
	}
	internal static class Utility
	{
		internal static AudioClip? OpenGiftAudio { get; private set; }

		internal static void CacheLoadedResources()
		{
			NamespacedKey<DawnItemInfo> val = NamespacedKey<DawnItemInfo>.Vanilla("gift");
			NamespacedKey<DawnItemInfo> val2 = NamespacedKey<DawnItemInfo>.Vanilla("big_bolt");
			NamespacedKey<DawnItemInfo> val3 = NamespacedKey<DawnItemInfo>.Vanilla("cash_register");
			NamespacedKey<DawnItemInfo> val4 = NamespacedKey<DawnItemInfo>.Vanilla("cookie_pan");
			NamespacedKey<DawnItemInfo> val5 = NamespacedKey<DawnItemInfo>.Vanilla("egg_beater");
			NamespacedKey<DawnItemInfo> dropSourceKey = NamespacedKey<DawnItemInfo>.Vanilla("garbage_lid");
			NamespacedKey<DawnItemInfo> val6 = NamespacedKey<DawnItemInfo>.Vanilla("gold_bar");
			NamespacedKey<DawnItemInfo> dropSourceKey2 = NamespacedKey<DawnItemInfo>.Vanilla("golden_cup");
			NamespacedKey<DawnItemInfo> val7 = NamespacedKey<DawnItemInfo>.Vanilla("large_axle");
			NamespacedKey<DawnItemInfo> val8 = NamespacedKey<DawnItemInfo>.Vanilla("magnifying_glass");
			NamespacedKey<DawnItemInfo> dropSourceKey3 = NamespacedKey<DawnItemInfo>.Vanilla("metal_sheet");
			NamespacedKey<DawnItemInfo> val9 = NamespacedKey<DawnItemInfo>.Vanilla("proflashlight");
			NamespacedKey<DawnItemInfo> dropSourceKey4 = NamespacedKey<DawnItemInfo>.Vanilla("stop_sign");
			NamespacedKey<DawnItemInfo> val10 = NamespacedKey<DawnItemInfo>.Vanilla("vtype_engine");
			DawnItemInfo val11 = default(DawnItemInfo);
			if (((Registry<DawnItemInfo>)(object)LethalContent.Items).TryGetValue(val, ref val11))
			{
				GameObject spawnPrefab = val11.Item.spawnPrefab;
				GiftBoxItem val12 = ((spawnPrefab != null) ? spawnPrefab.GetComponent<GiftBoxItem>() : null);
				if ((Object)(object)val12?.openGiftAudio != (Object)null)
				{
					OpenGiftAudio = val12.openGiftAudio;
					Plugin.LogDebug("Found gift open audio " + ((Object)OpenGiftAudio).name);
				}
				else
				{
					Plugin.mls.LogError((object)"Gift open audio source field missing");
				}
			}
			else
			{
				Plugin.mls.LogError((object)"Gift open audio source item missing");
			}
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_bolt"), val2, val2, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_bolt"), val2, val2, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "gold_bolt"), val2, val2, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_cash_register"), val3, val3, null, val3);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_cash_register"), val3, val3, null, val3);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "gold_cash_register"), val3, val3, null, val3);
			AssignNoisemakerAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_cash_register"), val3);
			AssignNoisemakerAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_cash_register"), val3);
			AssignNoisemakerAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "gold_cash_register"), val3);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_cookie_mold"), val4, val4, null, val4);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_cookie_mold"), val4, val4, null, val4);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "gold_cookie_mold"), val4, val4, null, val4);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_egg_beater"), val5, val5, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_egg_beater"), val5, val5, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "gold_egg_beater"), val5, val5, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_cup"), null, dropSourceKey2, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_cup"), null, dropSourceKey2, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "true_gold_cup"), null, dropSourceKey2, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "lordly_garbage_lid"), null, dropSourceKey, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_gift"), val2, val2, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_gift"), val2, val2, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "gold_gift"), val2, val2, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_bar"), val6, val6, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_bar"), val6, val6, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "radiant_golden_jar_of_pickles"), val2, dropSourceKey4, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_large_axle"), val7, val7, null, val7);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_large_axle"), val7, val7, null, val7);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "gold_large_axle"), val7, val7, null, val7);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_magnifying_glass"), val8, val8, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_magnifying_glass"), val8, val8, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "gold_magnifying_glass"), val8, val8, null, null);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_metal_sheet"), null, dropSourceKey3, null, val3);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_metal_sheet"), null, dropSourceKey3, null, val3);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "gold_metal_sheet"), null, dropSourceKey3, null, val3);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "golden_flashlight"), val9, val2, val9, null);
			AssignFlashlightAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "golden_flashlight"), val9);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "bronze_vtype_engine"), val10, val10, null, val10);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "silver_vtype_engine"), val10, val10, null, val10);
			AssignItemAudio(NamespacedKey<DawnItemInfo>.From("metalitemvariants", "gold_vtype_engine"), val10, val10, null, val10);
		}

		private static void AssignItemAudio(NamespacedKey<DawnItemInfo> targetKey, NamespacedKey<DawnItemInfo>? grabSourceKey, NamespacedKey<DawnItemInfo>? dropSourceKey, NamespacedKey<DawnItemInfo>? pocketSourceKey, NamespacedKey<DawnItemInfo>? clinkSourceKey)
		{
			DawnItemInfo val = default(DawnItemInfo);
			if (!((Registry<DawnItemInfo>)(object)LethalContent.Items).TryGetValue(targetKey, ref val))
			{
				Plugin.mls.LogError((object)$"Audio target item missing: {targetKey}");
				return;
			}
			if (grabSourceKey != null)
			{
				DawnItemInfo val2 = default(DawnItemInfo);
				if (!((Registry<DawnItemInfo>)(object)LethalContent.Items).TryGetValue(grabSourceKey, ref val2))
				{
					Plugin.mls.LogError((object)$"Grab SFX source item missing for {targetKey}");
				}
				else if ((Object)(object)val2.Item.grabSFX == (Object)null)
				{
					Plugin.mls.LogError((object)$"Grab SFX source field missing for {targetKey}");
				}
				else
				{
					val.Item.grabSFX = val2.Item.grabSFX;
					Plugin.LogDebug($"Assigned grab SFX {((Object)val.Item.grabSFX).name} to {targetKey}");
				}
			}
			if (dropSourceKey != null)
			{
				DawnItemInfo val3 = default(DawnItemInfo);
				if (!((Registry<DawnItemInfo>)(object)LethalContent.Items).TryGetValue(dropSourceKey, ref val3))
				{
					Plugin.mls.LogError((object)$"Drop SFX source item missing for {targetKey}");
				}
				else if ((Object)(object)val3.Item.dropSFX == (Object)null)
				{
					Plugin.mls.LogError((object)$"Drop SFX source field missing for {targetKey}");
				}
				else
				{
					val.Item.dropSFX = val3.Item.dropSFX;
					Plugin.LogDebug($"Assigned drop SFX {((Object)val.Item.dropSFX).name} to {targetKey}");
				}
			}
			if (pocketSourceKey != null)
			{
				DawnItemInfo val4 = default(DawnItemInfo);
				if (!((Registry<DawnItemInfo>)(object)LethalContent.Items).TryGetValue(pocketSourceKey, ref val4))
				{
					Plugin.mls.LogError((object)$"Pocket SFX source item missing for {targetKey}");
				}
				else if ((Object)(object)val4.Item.pocketSFX == (Object)null)
				{
					Plugin.mls.LogError((object)$"Pocket SFX source field missing for {targetKey}");
				}
				else
				{
					val.Item.pocketSFX = val4.Item.pocketSFX;
					Plugin.LogDebug($"Assigned pocket SFX {((Object)val.Item.pocketSFX).name} to {targetKey}");
				}
			}
			if (clinkSourceKey == null)
			{
				return;
			}
			DawnItemInfo val5 = default(DawnItemInfo);
			if (!((Registry<DawnItemInfo>)(object)LethalContent.Items).TryGetValue(clinkSourceKey, ref val5))
			{
				Plugin.mls.LogError((object)$"Clink audios source item missing for {targetKey}");
				return;
			}
			AudioClip[] clinkAudios = val5.Item.clinkAudios;
			if (clinkAudios != null && clinkAudios.Length != 0)
			{
				val.Item.clinkAudios = clinkAudios;
				Plugin.LogDebug(string.Format("Assigned clink audios {0} to {1}", string.Join(", ", clinkAudios.Select((AudioClip clip) => ((Object)clip).name)), targetKey));
			}
			else
			{
				Plugin.mls.LogError((object)$"Clink audios source field missing for {targetKey}");
			}
		}

		private static void AssignNoisemakerAudio(NamespacedKey<DawnItemInfo> targetKey, NamespacedKey<DawnItemInfo> sourceKey)
		{
			DawnItemInfo val = default(DawnItemInfo);
			if (!((Registry<DawnItemInfo>)(object)LethalContent.Items).TryGetValue(targetKey, ref val))
			{
				Plugin.mls.LogError((object)$"NoisemakerProp audio target item missing: {targetKey}");
				return;
			}
			DawnItemInfo val2 = default(DawnItemInfo);
			if (!((Registry<DawnItemInfo>)(object)LethalContent.Items).TryGetValue(sourceKey, ref val2))
			{
				Plugin.mls.LogError((object)$"NoisemakerProp audio source item missing for {targetKey}");
				return;
			}
			GameObject spawnPrefab = val2.Item.spawnPrefab;
			NoisemakerProp val3 = ((spawnPrefab != null) ? spawnPrefab.GetComponent<NoisemakerProp>() : null);
			GameObject spawnPrefab2 = val.Item.spawnPrefab;
			NoisemakerProp val4 = ((spawnPrefab2 != null) ? spawnPrefab2.GetComponent<NoisemakerProp>() : null);
			if (val3?.noiseSFX == null)
			{
				Plugin.mls.LogError((object)$"NoisemakerProp audio source field missing for {targetKey}");
				return;
			}
			if ((Object)(object)val4 == (Object)null)
			{
				Plugin.mls.LogError((object)$"NoisemakerProp audio target field missing for {targetKey}");
				return;
			}
			val4.noiseSFX = val3.noiseSFX;
			Plugin.LogDebug(string.Format("Assigned NoisemakerProp noise SFX {0} to {1}", string.Join(", ", val4.noiseSFX.Select((AudioClip clip) => ((Object)clip).name)), targetKey));
		}

		private static void AssignFlashlightAudio(NamespacedKey<DawnItemInfo> targetKey, NamespacedKey<DawnItemInfo> sourceKey)
		{
			DawnItemInfo val = default(DawnItemInfo);
			if (!((Registry<DawnItemInfo>)(object)LethalContent.Items).TryGetValue(targetKey, ref val))
			{
				Plugin.mls.LogError((object)$"FlashlightItem audio target item missing: {targetKey}");
				return;
			}
			DawnItemInfo val2 = default(DawnItemInfo);
			if (!((Registry<DawnItemInfo>)(object)LethalContent.Items).TryGetValue(sourceKey, ref val2))
			{
				Plugin.mls.LogError((object)$"FlashlightItem audio source item missing for {targetKey}");
				return;
			}
			GameObject spawnPrefab = val2.Item.spawnPrefab;
			FlashlightItem val3 = ((spawnPrefab != null) ? spawnPrefab.GetComponent<FlashlightItem>() : null);
			GameObject spawnPrefab2 = val.Item.spawnPrefab;
			FlashlightItem val4 = ((spawnPrefab2 != null) ? spawnPrefab2.GetComponent<FlashlightItem>() : null);
			if (val3?.flashlightClips == null)
			{
				Plugin.mls.LogError((object)$"FlashlightItem clips source field missing for {targetKey}");
				return;
			}
			if ((Object)(object)val4 == (Object)null)
			{
				Plugin.mls.LogError((object)$"FlashlightItem audio target field missing for {targetKey}");
				return;
			}
			val4.flashlightClips = val3.flashlightClips;
			val4.outOfBatteriesClip = val3.outOfBatteriesClip;
			val4.flashlightFlicker = val3.flashlightFlicker;
			Plugin.LogDebug(string.Format("Assigned flashlight clips {0} to {1}", string.Join(", ", val4.flashlightClips.Select((AudioClip clip) => ((Object)clip).name)), targetKey));
			Plugin.LogDebug($"Assigned flashlight out of batteries clip {((Object)val4.outOfBatteriesClip).name} to {targetKey}");
			Plugin.LogDebug($"Assigned flashlight flicker clip {((Object)val4.flashlightFlicker).name} to {targetKey}");
		}
	}
}
namespace MetalItemVariants.MonoBehaviours
{
	public class MetalGiftBox : GrabbableObject
	{
		private static readonly WaitForSeconds _waitForSeconds0_03 = new WaitForSeconds(0.03f);

		public ParticleSystem PoofParticle = null;

		public AudioSource presentAudio = null;

		public AudioClip openGiftAudio = null;

		[SerializeField]
		private string[] possibleItemKeys;

		[SerializeField]
		private string minimumValueBonusConfigKey;

		[SerializeField]
		private string maximumValueBonusConfigKey;

		private PlayerControllerB? previousHolder;

		private bool hasOpened;

		private bool hasLoadedSelectionFromSave;

		private int loadedSelectedIndex = -1;

		private int itemIndex = -1;

		private int selectedScrapValue;

		private int minimumValueBonus;

		private int maximumValueBonus;

		private bool hasNoItem;

		public override void Start()
		{
			((GrabbableObject)this).Start();
			DuskConfigParser.Get<int>(minimumValueBonusConfigKey, out minimumValueBonus);
			DuskConfigParser.Get<int>(maximumValueBonusConfigKey, out maximumValueBonus);
			openGiftAudio = Utility.OpenGiftAudio;
			if (((NetworkBehaviour)this).IsServer)
			{
				((MonoBehaviour)this).StartCoroutine(InitialiseSelectionNextFrame());
			}
		}

		public override void LoadItemSaveData(int saveData)
		{
			((GrabbableObject)this).LoadItemSaveData(saveData);
			if (possibleItemKeys != null && possibleItemKeys.Length != 0)
			{
				loadedSelectedIndex = Mathf.Clamp(saveData, 0, possibleItemKeys.Length - 1);
				hasLoadedSelectionFromSave = true;
			}
		}

		public override int GetItemDataToSave()
		{
			((GrabbableObject)this).GetItemDataToSave();
			return (itemIndex >= 0) ? itemIndex : 0;
		}

		public override void EquipItem()
		{
			((GrabbableObject)this).EquipItem();
			previousHolder = base.playerHeldBy;
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (!hasNoItem && buttonDown && !((Object)(object)base.playerHeldBy == (Object)null) && !hasOpened)
			{
				hasOpened = true;
				base.playerHeldBy.activatingItem = true;
				OpenBoxRpc();
			}
		}

		public override void PocketItem()
		{
			((GrabbableObject)this).PocketItem();
			PlayerControllerB playerHeldBy = base.playerHeldBy;
			if (playerHeldBy != null)
			{
				playerHeldBy.activatingItem = false;
			}
		}

		[Rpc(/*Could not decode attribute arguments.*/)]
		private void OpenBoxRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: 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_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: 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)
			{
				RpcAttributeParams val = new RpcAttributeParams
				{
					RequireOwnership = false
				};
				RpcParams val3 = default(RpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendRpc(3293125562u, val3, val, (SendTo)2, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendRpc(ref val2, 3293125562u, val3, val, (SendTo)2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1)
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if (!GetItem(out Item item) || (Object)(object)item.spawnPrefab == (Object)null)
			{
				Plugin.mls.LogError((object)"MetalGiftBox could not find the selected item");
				EndOpenRpc();
				return;
			}
			Vector3 val4 = ((Component)this).transform.position + Vector3.up * 0.25f;
			GameObject spawnPrefab = item.spawnPrefab;
			Quaternion identity = Quaternion.identity;
			PlayerControllerB? obj = previousHolder;
			GameObject val5 = Object.Instantiate<GameObject>(spawnPrefab, val4, identity, ((obj != null && obj.isInElevator) || StartOfRound.Instance.inShipPhase) ? StartOfRound.Instance.elevatorTransform : null);
			GrabbableObject component = val5.GetComponent<GrabbableObject>();
			NetworkObject component2 = val5.GetComponent<NetworkObject>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
			{
				Plugin.mls.LogError((object)"MetalGiftBox (somehow) spawned an object without GrabbableObject or NetworkObject");
				Object.Destroy((Object)(object)val5);
				EndOpenRpc();
				return;
			}
			component.startFallingPosition = val4;
			component.targetFloorPosition = component.GetItemFloorPosition(((Component)this).transform.position);
			component.SetScrapValue(selectedScrapValue);
			((MonoBehaviour)this).StartCoroutine(ResetSpawnedItemFallState(component));
			ApplyShipDropState(component);
			component2.Spawn(false);
			SyncSpawnedItemRpc(NetworkObjectReference.op_Implicit(component2), selectedScrapValue, val4);
			EndOpenRpc();
		}

		private IEnumerator InitialiseSelectionNextFrame()
		{
			yield return null;
			if (possibleItemKeys == null || possibleItemKeys.Length == 0)
			{
				yield break;
			}
			if (hasLoadedSelectionFromSave)
			{
				itemIndex = loadedSelectedIndex;
				if (GetItem(out Item savedItem))
				{
					hasNoItem = false;
					Plugin.LogDebug("MetalGiftBox loaded item: " + savedItem.itemName + " (" + possibleItemKeys[itemIndex] + ")");
					selectedScrapValue = RollScrapValue(savedItem);
					yield break;
				}
				Plugin.mls.LogWarning((object)("MetalGiftBox could not find saved item key '" + possibleItemKeys[itemIndex] + "'. Is item disabled in config? Rerolling..."));
			}
			if (GetRandomItem(out Item selectedItem))
			{
				Plugin.LogDebug("MetalGiftBox rolled random item: " + selectedItem.itemName + " (" + possibleItemKeys[itemIndex] + ")");
				selectedScrapValue = RollScrapValue(selectedItem);
			}
		}

		private bool GetRandomItem([NotNullWhen(true)] out Item? item)
		{
			item = null;
			if (possibleItemKeys == null || possibleItemKeys.Length == 0)
			{
				return false;
			}
			int num = possibleItemKeys.Length;
			bool[] array = new bool[possibleItemKeys.Length];
			while (num > 0)
			{
				int num2 = Random.Range(0, possibleItemKeys.Length);
				while (array[num2])
				{
					num2 = Random.Range(0, possibleItemKeys.Length);
				}
				array[num2] = true;
				num--;
				itemIndex = num2;
				if (GetItem(out item))
				{
					hasNoItem = false;
					return true;
				}
				Plugin.mls.LogWarning((object)("MetalGiftBox could not find item key '" + possibleItemKeys[num2] + "', is item disabled in config? Rerolling..."));
			}
			Plugin.mls.LogError((object)"MetalGiftBox could not find any item keys, are all metal variant items disabled in config?");
			itemIndex = -1;
			hasNoItem = true;
			return false;
		}

		private IEnumerator ResetSpawnedItemFallState(GrabbableObject spawnedItem)
		{
			yield return (object)new WaitForEndOfFrame();
			spawnedItem.reachedFloorTarget = false;
			spawnedItem.hasHitGround = false;
			spawnedItem.fallTime = 0f;
		}

		[Rpc(/*Could not decode attribute arguments.*/)]
		private void EndOpenRpc()
		{
			//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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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)
			{
				RpcAttributeParams val = default(RpcAttributeParams);
				RpcParams val3 = default(RpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendRpc(3275437139u, val3, val, (SendTo)7, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendRpc(ref val2, 3275437139u, val3, val, (SendTo)7, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1)
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				ParticleSystem poofParticle = PoofParticle;
				if (poofParticle != null)
				{
					poofParticle.Play();
				}
				if ((Object)(object)presentAudio != (Object)null && (Object)(object)openGiftAudio != (Object)null)
				{
					presentAudio.PlayOneShot(openGiftAudio);
					WalkieTalkie.TransmitOneShotAudio(presentAudio, openGiftAudio, 1f);
					RoundManager.Instance.PlayAudibleNoise(((Component)presentAudio).transform.position, 8f, 0.5f, 0, base.isInShipRoom && StartOfRound.Instance.hangarDoorsClosed, 0);
				}
				if ((Object)(object)base.playerHeldBy != (Object)null)
				{
					base.playerHeldBy.activatingItem = false;
					((GrabbableObject)this).DestroyObjectInHand(base.playerHeldBy);
				}
				if (((NetworkBehaviour)this).IsServer)
				{
					AudioClip obj = openGiftAudio;
					((MonoBehaviour)this).StartCoroutine(DespawnGiftAfterOpenAudio((obj != null) ? obj.length : 0f));
				}
			}
		}

		private IEnumerator DespawnGiftAfterOpenAudio(float delay)
		{
			if (delay > 0f)
			{
				yield return (object)new WaitForSeconds(delay);
			}
			if (((NetworkBehaviour)this).NetworkObject.IsSpawned)
			{
				((NetworkBehaviour)this).NetworkObject.Despawn(true);
			}
		}

		[Rpc(/*Could not decode attribute arguments.*/)]
		private void SyncSpawnedItemRpc(NetworkObjectReference netObjectRef, int scrapValue, Vector3 spawnPosition)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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)
			{
				RpcAttributeParams val = default(RpcAttributeParams);
				RpcParams val3 = default(RpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendRpc(3654392344u, val3, val, (SendTo)7, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref netObjectRef, default(ForNetworkSerializable));
				BytePacker.WriteValueBitPacked(val2, scrapValue);
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref spawnPosition);
				((NetworkBehaviour)this).__endSendRpc(ref val2, 3654392344u, val3, val, (SendTo)7, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1)
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				if (!((NetworkBehaviour)this).IsServer)
				{
					((MonoBehaviour)this).StartCoroutine(FindSpawnedItemOnClient(netObjectRef, scrapValue, spawnPosition));
				}
			}
		}

		private IEnumerator FindSpawnedItemOnClient(NetworkObjectReference netObjectRef, int scrapValue, Vector3 spawnPosition)
		{
			//IL_000e: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			NetworkObject spawnedNetworkObject = null;
			float startTime = Time.realtimeSinceStartup;
			while (Time.realtimeSinceStartup - startTime < 8f && !((NetworkObjectReference)(ref netObjectRef)).TryGet(ref spawnedNetworkObject, (NetworkManager)null))
			{
				yield return _waitForSeconds0_03;
			}
			if ((Object)(object)spawnedNetworkObject == (Object)null)
			{
				yield break;
			}
			yield return (object)new WaitForEndOfFrame();
			GrabbableObject spawnedItem = default(GrabbableObject);
			if (((Component)spawnedNetworkObject).TryGetComponent<GrabbableObject>(ref spawnedItem))
			{
				RoundManager instance = RoundManager.Instance;
				instance.totalScrapValueInLevel -= (float)scrapValue;
				RoundManager instance2 = RoundManager.Instance;
				instance2.totalScrapValueInLevel += (float)spawnedItem.scrapValue;
				spawnedItem.SetScrapValue(scrapValue);
				((Component)spawnedItem).transform.SetParent(((previousHolder?.isInElevator ?? false) || StartOfRound.Instance.inShipPhase) ? StartOfRound.Instance.elevatorTransform : null, true);
				Vector3 floorPosition = spawnedItem.GetItemFloorPosition(spawnPosition);
				if ((Object)(object)((Component)spawnedItem).transform.parent != (Object)null)
				{
					spawnedItem.targetFloorPosition = ((Component)spawnedItem).transform.parent.InverseTransformPoint(floorPosition);
					spawnPosition = ((Component)spawnedItem).transform.parent.InverseTransformPoint(spawnPosition);
				}
				else
				{
					spawnedItem.targetFloorPosition = floorPosition;
				}
				spawnedItem.startFallingPosition = spawnPosition;
				spawnedItem.fallTime = 0f;
				spawnedItem.hasHitGround = false;
				spawnedItem.reachedFloorTarget = false;
				ApplyShipDropState(spawnedItem);
			}
		}

		private void ApplyShipDropState(GrabbableObject spawnedItem)
		{
			PlayerControllerB? obj = previousHolder;
			if (obj != null && obj.isInHangarShipRoom)
			{
				previousHolder.SetItemInElevator(true, true, spawnedItem);
			}
		}

		private bool GetItem([NotNullWhen(true)] out Item? item)
		{
			item = null;
			if (possibleItemKeys == null || itemIndex < 0 || itemIndex >= possibleItemKeys.Length || string.IsNullOrWhiteSpace(possibleItemKeys[itemIndex]))
			{
				return false;
			}
			NamespacedKey obj = NamespacedKey.From("metalitemvariants", possibleItemKeys[itemIndex]);
			foreach (KeyValuePair<NamespacedKey<DawnItemInfo>, DawnItemInfo> item2 in (Registry<DawnItemInfo>)(object)LethalContent.Items)
			{
				if (!((object)item2.Key).Equals((object?)obj))
				{
					continue;
				}
				item = item2.Value.Item;
				return (Object)(object)item != (Object)null;
			}
			return false;
		}

		private int RollScrapValue(Item item)
		{
			int num = item.minValue + minimumValueBonus;
			int num2 = item.maxValue + maximumValueBonus;
			if (num2 <= num)
			{
				num2 = num + 1;
			}
			return (int)((float)Random.Range(num, num2) * RoundManager.Instance.scrapValueMultiplier);
		}

		protected override void __initializeVariables()
		{
			((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
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(3293125562u, new RpcReceiveHandler(__rpc_handler_3293125562), "OpenBoxRpc");
			((NetworkBehaviour)this).__registerRpc(3275437139u, new RpcReceiveHandler(__rpc_handler_3275437139), "EndOpenRpc");
			((NetworkBehaviour)this).__registerRpc(3654392344u, new RpcReceiveHandler(__rpc_handler_3654392344), "SyncSpawnedItemRpc");
			((GrabbableObject)this).__initializeRpcs();
		}

		private static void __rpc_handler_3293125562(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MetalGiftBox)(object)target).OpenBoxRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3275437139(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MetalGiftBox)(object)target).EndOpenRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3654392344(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				NetworkObjectReference netObjectRef = default(NetworkObjectReference);
				((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref netObjectRef, default(ForNetworkSerializable));
				int scrapValue = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref scrapValue);
				Vector3 spawnPosition = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref spawnPosition);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MetalGiftBox)(object)target).SyncSpawnedItemRpc(netObjectRef, scrapValue, spawnPosition);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "MetalGiftBox";
		}
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
		}
	}
}
namespace MetalItemVariants.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}