Decompiled source of Golden Items v1.1.0

GoldItems.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("WorthyOtter")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+bfcbc57763a69349f8e5deb743f5629c90667e11")]
[assembly: AssemblyProduct("GoldItems")]
[assembly: AssemblyTitle("GoldItems")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 GoldItems
{
	[BepInPlugin("WorthyOtter.GoldItems", "Golden Items", "1.0.0")]
	public class GoldItems : BaseUnityPlugin
	{
		public ConfigEntry<float> GoldShopChance;

		public static ConfigEntry<int> GoldShopPriceMultiplier;

		public static ConfigEntry<int> CooldownSeconds;

		public static ConfigEntry<int> RechargePercentPerSecond;

		public static ConfigEntry<bool> ShareGoldenUpgrade;

		public AssetBundle GoldShopBundle;

		public GameObject GoldShopInteriorPrefab;

		public Material GoldDoorMaterial;

		public Material GoldDoorMaterialGlow;

		public static GoldItems Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			GoldShopChance = ((BaseUnityPlugin)this).Config.Bind<float>("Gold Shop", "GoldShopChance", 0.25f, new ConfigDescription("Chance (0–1) that a shop dead end is turned into the Golden Shop.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			GoldShopPriceMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("Gold Shop", "GoldShopPriceMultiplier", 5, new ConfigDescription("The price multiplier of items that appear in the Gold Shop.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
			CooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("Golden Items", "CooldownSeconds", 60, new ConfigDescription("Seconds of inactivity before a golden item starts recharging.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
			RechargePercentPerSecond = ((BaseUnityPlugin)this).Config.Bind<int>("Golden Items", "RechargePercentPerSecond", 5, new ConfigDescription("Percent of max charge restored per second while recharging (0–1).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			ShareGoldenUpgrade = ((BaseUnityPlugin)this).Config.Bind<bool>("Golden Items", "ShareGoldenUpgrade", false, "Should Golden Upgrades apply to all players.");
			LoadGoldShopPrefab();
			Harmony val = new Harmony("WorthyOtter.GoldItems");
			val.PatchAll();
		}

		private void LoadGoldShopPrefab()
		{
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			string text = Path.Combine(directoryName, "goldenitemsassets");
			GoldShopBundle = AssetBundle.LoadFromFile(text);
			if ((Object)(object)GoldShopBundle == (Object)null)
			{
				Log.LogError((object)("[GoldenItems] Failed to load AssetBundle at '" + text + "'."));
				return;
			}
			GoldShopInteriorPrefab = GoldShopBundle.LoadAsset<GameObject>("assets/goldenitems/module - shop - de - golden shop.prefab");
			if ((Object)(object)GoldShopInteriorPrefab == (Object)null)
			{
				Log.LogError((object)"[GoldenItems] Failed to load prefab 'assets/goldenitems/module - shop - de - golden shop.prefab' from bundle.");
			}
			else
			{
				Log.LogInfo((object)("[GoldenItems] Loaded GoldenShop prefab '" + ((Object)GoldShopInteriorPrefab).name + "' from AssetBundle."));
			}
			GoldDoorMaterial = GoldShopBundle.LoadAsset<Material>("assets/goldenitems/gold.mat");
			GoldDoorMaterialGlow = GoldShopBundle.LoadAsset<Material>("assets/goldenitems/gold1.mat");
		}
	}
	public class GoldBattery : MonoBehaviour
	{
		private ItemBattery battery;

		private ItemAttributes attributes;

		private float lastBatteryLife;

		private float maxBatteryLife;

		private bool initialized;

		private float nextRechargeTime = -1f;

		private void Awake()
		{
			battery = ((Component)this).GetComponent<ItemBattery>();
			attributes = ((Component)this).GetComponent<ItemAttributes>();
			if ((Object)(object)battery == (Object)null)
			{
				Debug.LogWarning((object)"[GoldBattery] No ItemBattery found on this object.");
				((Behaviour)this).enabled = false;
			}
		}

		private void Update()
		{
			if ((Object)(object)battery == (Object)null)
			{
				return;
			}
			if (!initialized)
			{
				if (!((Object)(object)LevelGenerator.Instance == (Object)null) && LevelGenerator.Instance.Generated && !((Object)(object)attributes == (Object)null) && attributes.instanceName != null)
				{
					int num = Mathf.Max(1, battery.batteryBars);
					int num2 = 100 / num;
					maxBatteryLife = num * num2;
					battery.batteryLife = Mathf.Clamp(battery.batteryLife, 0f, maxBatteryLife);
					lastBatteryLife = battery.batteryLife;
					if (battery.batteryLife < maxBatteryLife - 0.01f)
					{
						float num3 = GoldItems.CooldownSeconds.Value;
						nextRechargeTime = Time.time + num3;
					}
					initialized = true;
				}
			}
			else
			{
				float batteryLife = battery.batteryLife;
				if (batteryLife < lastBatteryLife - 0.01f)
				{
					float num4 = GoldItems.CooldownSeconds.Value;
					nextRechargeTime = Time.time + num4;
				}
				lastBatteryLife = batteryLife;
				if (!(batteryLife >= maxBatteryLife - 0.01f) && !(nextRechargeTime < 0f) && !(Time.time < nextRechargeTime))
				{
					float num5 = GoldItems.RechargePercentPerSecond.Value;
					float batteryLife2 = Mathf.Min(batteryLife + num5 * Time.deltaTime, maxBatteryLife);
					battery.batteryLife = batteryLife2;
					battery.batteryLife = Mathf.Clamp(battery.batteryLife, 0f, maxBatteryLife);
				}
			}
		}
	}
	public class GoldHealthPack : MonoBehaviour
	{
		public int healAmount;

		private ItemToggle itemToggle;

		private ItemEquippable itemEquippable;

		private ItemAttributes itemAttributes;

		private PhotonView photonView;

		private PhysGrabObject physGrabObject;

		[Space]
		public ParticleSystem[] particles;

		public ParticleSystem[] rejectParticles;

		[Space]
		public PropLight propLight;

		public AnimationCurve lightIntensityCurve;

		private float lightIntensityLerp;

		public MeshRenderer mesh;

		private Material material;

		private Color materialEmissionOriginal;

		private readonly int materialPropertyEmission = Shader.PropertyToID("_EmissionColor");

		[Space]
		public Sound soundUse;

		public Sound soundReject;

		private bool used;

		private int lastUsedLevelStep = int.MinValue;

		private void Start()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			itemToggle = ((Component)this).GetComponent<ItemToggle>();
			itemEquippable = ((Component)this).GetComponent<ItemEquippable>();
			itemAttributes = ((Component)this).GetComponent<ItemAttributes>();
			photonView = ((Component)this).GetComponent<PhotonView>();
			physGrabObject = ((Component)this).GetComponent<PhysGrabObject>();
			material = (((Object)(object)mesh != (Object)null) ? ((Renderer)mesh).material : null);
			if ((Object)(object)material != (Object)null)
			{
				materialEmissionOriginal = material.GetColor(materialPropertyEmission);
			}
		}

		private void Update()
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.RunIsShop() || RunManager.instance.levelIsShop)
			{
				return;
			}
			int num = (((Object)(object)RunManager.instance != (Object)null) ? RunManager.instance.levelsCompleted : 0);
			if (used && num != lastUsedLevelStep)
			{
				used = false;
				lightIntensityLerp = 0f;
				if ((Object)(object)propLight != (Object)null && (Object)(object)propLight.lightComponent != (Object)null)
				{
					propLight.lightComponent.intensity = propLight.originalIntensity;
				}
				if ((Object)(object)material != (Object)null)
				{
					material.SetColor(materialPropertyEmission, materialEmissionOriginal);
				}
				if ((Object)(object)itemAttributes != (Object)null)
				{
					itemAttributes.DisableUI(false);
				}
			}
			LightLogic();
			if (!SemiFunc.IsMasterClientOrSingleplayer() || (Object)(object)itemToggle == (Object)null || !itemToggle.toggleState || used)
			{
				return;
			}
			PlayerAvatar val = SemiFunc.PlayerAvatarGetFromPhotonID(itemToggle.playerTogglePhotonID);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			if (val.playerHealth.health >= val.playerHealth.maxHealth)
			{
				if (SemiFunc.IsMultiplayer())
				{
					photonView.RPC("RejectRPC", (RpcTarget)0, Array.Empty<object>());
				}
				else
				{
					RejectRPC();
				}
				itemToggle.ToggleItem(false, -1);
				if ((Object)(object)physGrabObject != (Object)null && (Object)(object)physGrabObject.rb != (Object)null)
				{
					physGrabObject.rb.AddForce(Vector3.up * 2f, (ForceMode)1);
					physGrabObject.rb.AddTorque(-((Component)physGrabObject).transform.right * 0.05f, (ForceMode)1);
				}
			}
			else
			{
				val.playerHealth.HealOther(healAmount, true);
				if ((Object)(object)physGrabObject != (Object)null && (Object)(object)physGrabObject.impactDetector != (Object)null)
				{
					physGrabObject.impactDetector.indestructibleBreakEffects = true;
				}
				if (SemiFunc.IsMultiplayer())
				{
					photonView.RPC("UsedRPC", (RpcTarget)0, Array.Empty<object>());
				}
				else
				{
					UsedRPC();
				}
			}
		}

		private void LightLogic()
		{
			//IL_00ca: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			if (used && !(lightIntensityLerp >= 1f))
			{
				lightIntensityLerp += Time.deltaTime;
				float num = ((lightIntensityCurve != null) ? lightIntensityCurve.Evaluate(lightIntensityLerp) : 1f);
				if ((Object)(object)propLight != (Object)null && (Object)(object)propLight.lightComponent != (Object)null)
				{
					propLight.lightComponent.intensity = num;
					propLight.originalIntensity = propLight.lightComponent.intensity;
				}
				if ((Object)(object)material != (Object)null)
				{
					material.SetColor(materialPropertyEmission, Color.Lerp(Color.black, materialEmissionOriginal, num));
				}
			}
		}

		[PunRPC]
		private void UsedRPC(PhotonMessageInfo _info = default(PhotonMessageInfo))
		{
			//IL_0001: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.MasterOnlyRPC(_info))
			{
				return;
			}
			GameDirector.instance.CameraImpact.ShakeDistance(5f, 1f, 6f, ((Component)this).transform.position, 0.2f);
			if ((Object)(object)itemToggle != (Object)null)
			{
				itemToggle.ToggleItem(false, -1);
			}
			if ((Object)(object)itemAttributes != (Object)null)
			{
				itemAttributes.DisableUI(true);
			}
			if (particles != null)
			{
				ParticleSystem[] array = particles;
				foreach (ParticleSystem val in array)
				{
					if ((Object)(object)val != (Object)null)
					{
						val.Play();
					}
				}
			}
			if (soundUse != null)
			{
				soundUse.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
			}
			used = true;
			if ((Object)(object)RunManager.instance != (Object)null)
			{
				lastUsedLevelStep = RunManager.instance.levelsCompleted;
			}
		}

		[PunRPC]
		private void RejectRPC(PhotonMessageInfo _info = default(PhotonMessageInfo))
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.MasterOnlyRPC(_info))
			{
				return;
			}
			PlayerAvatar val = SemiFunc.PlayerAvatarGetFromPhotonID(itemToggle.playerTogglePhotonID);
			if ((Object)(object)val != (Object)null && val.isLocal)
			{
				val.physGrabber.ReleaseObjectRPC(false, 1f, photonView.ViewID);
			}
			if (rejectParticles != null)
			{
				ParticleSystem[] array = rejectParticles;
				foreach (ParticleSystem val2 in array)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						val2.Play();
					}
				}
			}
			GameDirector.instance.CameraImpact.ShakeDistance(5f, 1f, 6f, ((Component)this).transform.position, 0.2f);
			if (soundReject != null)
			{
				soundReject.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
			}
		}

		public void OnDestroy()
		{
			//IL_0046: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			if (particles != null)
			{
				ParticleSystem[] array = particles;
				foreach (ParticleSystem val in array)
				{
					if (Object.op_Implicit((Object)(object)val) && val.isPlaying)
					{
						((Component)val).transform.SetParent((Transform)null);
						MainModule main = val.main;
						((MainModule)(ref main)).stopAction = (ParticleSystemStopAction)2;
					}
				}
			}
			if (rejectParticles == null)
			{
				return;
			}
			ParticleSystem[] array2 = rejectParticles;
			foreach (ParticleSystem val2 in array2)
			{
				if (Object.op_Implicit((Object)(object)val2) && val2.isPlaying)
				{
					((Component)val2).transform.SetParent((Transform)null);
					MainModule main2 = val2.main;
					((MainModule)(ref main2)).stopAction = (ParticleSystemStopAction)2;
				}
			}
		}
	}
	public class GoldItemMarker : MonoBehaviour
	{
	}
	public class GoldShopVolume : MonoBehaviour
	{
	}
	public class GoldUpgrade : MonoBehaviour
	{
		private ItemToggle itemToggle;

		private void Start()
		{
			itemToggle = ((Component)this).GetComponent<ItemToggle>();
		}

		public void Upgrade()
		{
			if (!((Object)(object)itemToggle == (Object)null))
			{
				PlayerAvatar val = SemiFunc.PlayerAvatarGetFromPhotonID(itemToggle.playerTogglePhotonID);
				if (!((Object)(object)val == (Object)null))
				{
					string steamID = SemiFunc.PlayerGetSteamID(val);
					GoldUpgradeHelper.ApplyGoldenUpgrade(steamID);
				}
			}
		}
	}
	internal static class GoldUpgradeHelper
	{
		public static void ApplyGoldenUpgrade(string steamID)
		{
			GoldItems instance = GoldItems.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)PunManager.instance == (Object)null)
			{
				return;
			}
			if (GoldItems.ShareGoldenUpgrade == null || !GoldItems.ShareGoldenUpgrade.Value)
			{
				ApplyGoldenUpgradeToSingle(steamID);
			}
			else
			{
				if ((Object)(object)GameDirector.instance == (Object)null || GameDirector.instance.PlayerList == null)
				{
					return;
				}
				foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
				{
					if (Object.op_Implicit((Object)(object)player) && !player.isDisabled)
					{
						string text = SemiFunc.PlayerGetSteamID(player);
						if (!string.IsNullOrEmpty(text))
						{
							ApplyGoldenUpgradeToSingle(text);
						}
					}
				}
			}
		}

		private static void ApplyGoldenUpgradeToSingle(string steamID)
		{
			PunManager instance = PunManager.instance;
			if (!((Object)(object)instance == (Object)null) && !string.IsNullOrEmpty(steamID))
			{
				instance.UpgradePlayerHealth(steamID, 1);
				instance.UpgradeDeathHeadBattery(steamID, 1);
				instance.UpgradePlayerEnergy(steamID, 1);
				instance.UpgradePlayerCrouchRest(steamID, 1);
				instance.UpgradePlayerSprintSpeed(steamID, 1);
				instance.UpgradePlayerExtraJump(steamID, 1);
				instance.UpgradePlayerTumbleLaunch(steamID, 1);
				instance.UpgradePlayerTumbleClimb(steamID, 1);
				instance.UpgradePlayerTumbleWings(steamID, 1);
				instance.UpgradeMapPlayerCount(steamID, 1);
				instance.UpgradePlayerGrabStrength(steamID, 1);
				instance.UpgradePlayerGrabRange(steamID, 1);
			}
		}
	}
	[HarmonyPatch(typeof(ItemLight))]
	internal static class FresnelScalePatch
	{
		private static float SafeGetFloat(Material mat, string property)
		{
			if ((Object)(object)mat == (Object)null)
			{
				return 0f;
			}
			return mat.HasProperty(property) ? mat.GetFloat(property) : 0f;
		}

		private static void SafeSetFloat(Material mat, string property, float value)
		{
			if (!((Object)(object)mat == (Object)null) && mat.HasProperty(property))
			{
				mat.SetFloat(property, value);
			}
		}

		private static IEnumerable<CodeInstruction> ReplaceFresnelCalls(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.Method(typeof(Material), "GetFloat", new Type[1] { typeof(string) }, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(Material), "SetFloat", new Type[2]
			{
				typeof(string),
				typeof(float)
			}, (Type[])null);
			MethodInfo operand = AccessTools.Method(typeof(FresnelScalePatch), "SafeGetFloat", (Type[])null, (Type[])null);
			MethodInfo operand2 = AccessTools.Method(typeof(FresnelScalePatch), "SafeSetFloat", (Type[])null, (Type[])null);
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if (val.opcode == OpCodes.Callvirt && val.operand is MethodInfo methodInfo3 && methodInfo3 == methodInfo)
				{
					val.opcode = OpCodes.Call;
					val.operand = operand;
				}
				else if (val.opcode == OpCodes.Callvirt && val.operand is MethodInfo methodInfo4 && methodInfo4 == methodInfo2)
				{
					val.opcode = OpCodes.Call;
					val.operand = operand2;
				}
			}
			return list;
		}

		[HarmonyPatch("Start")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpile_Start(IEnumerable<CodeInstruction> instructions)
		{
			return ReplaceFresnelCalls(instructions);
		}

		[HarmonyPatch("Update")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpile_Update(IEnumerable<CodeInstruction> instructions)
		{
			return ReplaceFresnelCalls(instructions);
		}
	}
	[HarmonyPatch(typeof(ItemGrenade))]
	internal static class GoldGrenadePatch
	{
		[HarmonyPatch("TickEndRPC")]
		[HarmonyPrefix]
		private static bool Prefix_TickEndRPC(ItemGrenade __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)__instance).GetComponent<GoldItemMarker>() == (Object)null)
			{
				return true;
			}
			__instance.isSpawnedGrenade = true;
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemMine))]
	internal static class GoldMinesPatch
	{
		[HarmonyPatch("DestroyMine")]
		[HarmonyPrefix]
		private static bool Prefix_DestroyMine(ItemMine __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)__instance).GetComponent<GoldItemMarker>() == (Object)null)
			{
				return true;
			}
			if (!SemiFunc.RunIsShop() && !__instance.mineDestroyed)
			{
				__instance.mineDestroyed = true;
				PhysGrabObjectImpactDetector component = ((Component)__instance).GetComponent<PhysGrabObjectImpactDetector>();
				if ((Object)(object)component != (Object)null)
				{
					component.DestroyObject(true);
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemAttributes))]
	internal static class GoldPricePatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetValue")]
		private static void Post_GetValue(ItemAttributes __instance)
		{
			try
			{
				if (!SemiFunc.RunIsShop())
				{
					return;
				}
				GoldItems instance = GoldItems.Instance;
				if (!((Object)(object)instance == (Object)null) && GoldItems.GoldShopPriceMultiplier != null && (!GameManager.Multiplayer() || PhotonNetwork.IsMasterClient) && !((Object)(object)__instance == (Object)null) && __instance.value > 0 && (Object)(object)((Component)__instance).GetComponentInChildren<GoldItemMarker>(true) != (Object)null)
				{
					int num = GoldItems.GoldShopPriceMultiplier.Value;
					if (num < 1)
					{
						num = 1;
					}
					int value = __instance.value;
					int num2 = (__instance.value = Mathf.Max(1, value * num));
					ManualLogSource log = GoldItems.Log;
					if (log != null)
					{
						log.LogInfo((object)$"[GoldenItems] Master price adjusted for gold item '{((Object)__instance).name}' from {value} to {num2}.");
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = GoldItems.Log;
				if (log2 != null)
				{
					log2.LogError((object)("[GoldenItems] Exception in GoldPricePatch.Post_GetValue: " + ex));
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetValueRPC")]
		private static void Post_GetValueRPC(ItemAttributes __instance)
		{
			try
			{
				if (!SemiFunc.RunIsShop())
				{
					return;
				}
				GoldItems instance = GoldItems.Instance;
				if (!((Object)(object)instance == (Object)null) && GoldItems.GoldShopPriceMultiplier != null && GameManager.Multiplayer() && !PhotonNetwork.IsMasterClient && !((Object)(object)__instance == (Object)null) && __instance.value > 0 && (Object)(object)((Component)__instance).GetComponentInChildren<GoldItemMarker>(true) != (Object)null)
				{
					int num = GoldItems.GoldShopPriceMultiplier.Value;
					if (num < 1)
					{
						num = 1;
					}
					int value = __instance.value;
					int num2 = (__instance.value = Mathf.Max(1, value * num));
					ManualLogSource log = GoldItems.Log;
					if (log != null)
					{
						log.LogInfo((object)$"[GoldenItems] Client price adjusted for gold item '{((Object)__instance).name}' from {value} to {num2}.");
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = GoldItems.Log;
				if (log2 != null)
				{
					log2.LogError((object)("[GoldenItems] Exception in GoldPricePatch.Post_GetValueRPC: " + ex));
				}
			}
		}
	}
	[HarmonyPatch(typeof(PunManager))]
	internal static class GoldShopItemSpawnPatch
	{
		[HarmonyPatch("SpawnShopItem")]
		[HarmonyPrefix]
		private static bool SpawnShopItem_GoldFilter(ItemVolume itemVolume, List<Item> itemList, ref int spawnCount, bool isSecret, ref bool __result)
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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_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_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)itemVolume == (Object)null || itemList == null || (Object)(object)ShopManager.instance == (Object)null)
			{
				__result = false;
				return false;
			}
			bool flag = (Object)(object)((Component)itemVolume).GetComponent<GoldShopVolume>() != (Object)null;
			for (int num = itemList.Count - 1; num >= 0; num--)
			{
				Item val = itemList[num];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				bool flag2 = false;
				GameObject val2 = null;
				try
				{
					val2 = ((val.prefab != null) ? val.prefab.Prefab : null);
				}
				catch
				{
					val2 = null;
				}
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.GetComponentInChildren<GoldItemMarker>(true) != (Object)null)
				{
					flag2 = true;
				}
				if (flag)
				{
					if (!flag2)
					{
						continue;
					}
				}
				else if (flag2)
				{
					continue;
				}
				if (val.itemVolume != itemVolume.itemVolume)
				{
					continue;
				}
				ShopManager instance = ShopManager.instance;
				Transform itemRotateHelper = instance.itemRotateHelper;
				((Component)itemRotateHelper).transform.parent = ((Component)itemVolume).transform;
				((Component)itemRotateHelper).transform.localRotation = val.spawnRotationOffset;
				Quaternion rotation = ((Component)itemRotateHelper).transform.rotation;
				((Component)itemRotateHelper).transform.parent = ((Component)instance).transform;
				if (SemiFunc.IsMultiplayer())
				{
					PhotonNetwork.InstantiateRoomObject(val.prefab.ResourcePath, ((Component)itemVolume).transform.position, rotation, (byte)0, (object[])null);
				}
				else
				{
					Object.Instantiate<GameObject>(val.prefab.Prefab, ((Component)itemVolume).transform.position, rotation);
				}
				itemList.RemoveAt(num);
				if (!isSecret)
				{
					spawnCount++;
				}
				__result = true;
				return false;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(LevelGenerator))]
	public static class GoldShopPatch
	{
		private static bool _goldShopSpawnedThisLevel;

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void Post_Start(LevelGenerator __instance)
		{
			_goldShopSpawnedThisLevel = false;
		}

		[HarmonyPostfix]
		[HarmonyPatch("SpawnModule")]
		private static void Post_SpawnModule(LevelGenerator __instance, int x, int y, Vector3 position, Vector3 rotation, Type type)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Invalid comparison between Unknown and I4
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((int)type != 2 || !SemiFunc.IsCurrentLevel(__instance.Level, RunManager.instance.levelShop) || _goldShopSpawnedThisLevel)
				{
					return;
				}
				GoldItems instance = GoldItems.Instance;
				if ((Object)(object)instance == (Object)null || instance.GoldShopChance == null)
				{
					return;
				}
				float num = Mathf.Clamp01(instance.GoldShopChance.Value);
				float value = Random.value;
				if (value > num)
				{
					return;
				}
				_goldShopSpawnedThisLevel = true;
				ManualLogSource log = GoldItems.Log;
				if (log != null)
				{
					log.LogInfo((object)$"[GoldenItems] Converting dead-end at ({x},{y}) into Golden Shop (roll={value:0.00}, chance={num:0.00}).");
				}
				Module val = FindModuleAtPosition(__instance, position, 1f);
				if ((Object)(object)val == (Object)null)
				{
					ManualLogSource log2 = GoldItems.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"[GoldenItems] Could not find Module at expected position; aborting Golden Shop conversion.");
					}
					return;
				}
				ClearModuleInterior(val);
				if ((Object)(object)instance.GoldShopInteriorPrefab != (Object)null)
				{
					GameObject val2 = Object.Instantiate<GameObject>(instance.GoldShopInteriorPrefab, ((Component)val).transform);
					val2.transform.localPosition = Vector3.zero;
					val2.transform.localRotation = Quaternion.identity;
					val2.transform.localScale = Vector3.one;
					ManualLogSource log3 = GoldItems.Log;
					if (log3 != null)
					{
						log3.LogInfo((object)("[GoldenItems] Golden Shop interior spawned under module '" + ((Object)val).name + "'."));
					}
				}
				else
				{
					ManualLogSource log4 = GoldItems.Log;
					if (log4 != null)
					{
						log4.LogInfo((object)"[GoldenItems] No Golden Shop interior prefab set; using vanilla layout (only door tint).");
					}
				}
				ApplyGoldDoorMaterial(val);
			}
			catch (Exception ex)
			{
				ManualLogSource log5 = GoldItems.Log;
				if (log5 != null)
				{
					log5.LogError((object)("[GoldenItems] Exception in GoldShopPatch.Post_SpawnModule: " + ex));
				}
			}
		}

		private static Module FindModuleAtPosition(LevelGenerator generator, Vector3 position, float maxDistance)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)generator == (Object)null || (Object)(object)generator.LevelParent == (Object)null)
			{
				return null;
			}
			Transform transform = generator.LevelParent.transform;
			Module result = null;
			float num = maxDistance;
			Module[] componentsInChildren = ((Component)transform).GetComponentsInChildren<Module>(false);
			Module[] array = componentsInChildren;
			foreach (Module val in array)
			{
				float num2 = Vector3.Distance(((Component)val).transform.position, position);
				if (num2 < num)
				{
					num = num2;
					result = val;
				}
			}
			return result;
		}

		private static void ClearModuleInterior(Module module)
		{
			if ((Object)(object)module == (Object)null)
			{
				return;
			}
			for (int num = ((Component)module).transform.childCount - 1; num >= 0; num--)
			{
				Transform child = ((Component)module).transform.GetChild(num);
				switch (((Object)child).name)
				{
				case "---- Level ------------":
				{
					Transform child2 = ((Component)child).transform.GetChild(1);
					if (child2.childCount == 0)
					{
						Object.Destroy((Object)(object)((Component)child).gameObject);
						break;
					}
					for (int num2 = ((Component)child2).transform.childCount - 1; num2 >= 0; num2--)
					{
						Transform child3 = ((Component)child2).transform.GetChild(num2);
						string name = ((Object)child3).name;
						if (!(name == "Wall 01 - 1x1 - Door (3)"))
						{
							Object.Destroy((Object)(object)((Component)child3).gameObject);
						}
					}
					Object.Destroy((Object)(object)((Component)child).transform.GetChild(3));
					Object.Destroy((Object)(object)((Component)child).transform.GetChild(2));
					Object.Destroy((Object)(object)((Component)child).transform.GetChild(0));
					break;
				}
				default:
					Object.Destroy((Object)(object)((Component)child).gameObject);
					break;
				case "---- Dependencies ----":
				case "Shop Door":
				case "Wall 01 - 1x1 - Door (3)":
					break;
				}
			}
			ManualLogSource log = GoldItems.Log;
			if (log != null)
			{
				log.LogInfo((object)("[GoldenItems] Cleared all module children except '---- Dependencies ----', 'Shop Door', and 'Wall 01 - 1x1 - Door (3)' in module '" + ((Object)module).name + "'."));
			}
		}

		private static void ApplyGoldDoorMaterial(Module targetModule)
		{
			GoldItems instance = GoldItems.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.GoldDoorMaterial == (Object)null)
			{
				ManualLogSource log = GoldItems.Log;
				if (log != null)
				{
					log.LogWarning((object)"[GoldenItems] GoldDoorMaterial is null; cannot tint door.");
				}
				return;
			}
			Transform val = ((Component)targetModule).transform.Find("Shop Door");
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log2 = GoldItems.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[GoldenItems] Could not find 'Shop Door' under module '" + ((Object)targetModule).name + "'; door tint skipped."));
				}
				return;
			}
			Transform val2 = val.Find("Hinge");
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = val;
			}
			TintRendererByIndex(val2, 0, instance.GoldDoorMaterialGlow);
			TintRendererByIndex(val2, 4, instance.GoldDoorMaterial);
			TintRendererByIndex(val2, 5, instance.GoldDoorMaterial);
			ManualLogSource log3 = GoldItems.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)("[GoldenItems] Applied gold material to shop door under module '" + ((Object)targetModule).name + "'."));
			}
		}

		private static void TintRendererByIndex(Transform parent, int index, Material mat)
		{
			if ((Object)(object)parent == (Object)null || (Object)(object)mat == (Object)null)
			{
				return;
			}
			if (index < 0 || index >= parent.childCount)
			{
				ManualLogSource log = GoldItems.Log;
				if (log != null)
				{
					log.LogWarning((object)$"[GoldenItems] Tried to tint child index {index} but hinge has only {parent.childCount} children.");
				}
				return;
			}
			Transform child = parent.GetChild(index);
			Renderer component = ((Component)child).GetComponent<Renderer>();
			if ((Object)(object)component != (Object)null)
			{
				component.material = mat;
			}
		}
	}
}