Decompiled source of InitialValuables v1.0.0

InitialValuables.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using REPOLib.Modules;
using RepoDice;
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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.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 Durability
{
	[BepInPlugin("ZeroTails.InitialValuables", "Initial Valuables", "1.0.0")]
	public class InitialValuables : BaseUnityPlugin
	{
		private class ValuableDefinition
		{
			public string Name { get; }

			public int SpawnCount { get; }

			public float SpawnChance { get; }

			public ValuableDefinition(string name, int spawnCount, float spawnChance)
			{
				Name = name;
				SpawnCount = spawnCount;
				SpawnChance = spawnChance;
			}
		}

		[CompilerGenerated]
		private sealed class <SpawnValuables>d__17 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private GameObject <targetItem>5__1;

			private Vector3 <itemPosition>5__2;

			private float <currentYOffset>5__3;

			private float <currentXOffset>5__4;

			private List<ValuableDefinition>.Enumerator <>s__5;

			private ValuableDefinition <valuable>5__6;

			private int <i>5__7;

			private float <randomValue>5__8;

			private Vector3 <spawnPos>5__9;

			private GameObject <spawnedValuable>5__10;

			private List<ValuableDefinition>.Enumerator <>s__11;

			private ValuableDefinition <valuable>5__12;

			private int <i>5__13;

			private float <randomValue>5__14;

			private Vector3 <spawnPos>5__15;

			private GameObject <spawnedValuable>5__16;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SpawnValuables>d__17(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<targetItem>5__1 = null;
				<>s__5 = default(List<ValuableDefinition>.Enumerator);
				<valuable>5__6 = null;
				<spawnedValuable>5__10 = null;
				<>s__11 = default(List<ValuableDefinition>.Enumerator);
				<valuable>5__12 = null;
				<spawnedValuable>5__16 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//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)
				//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01df: Expected O, but got Unknown
				//IL_0110: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: 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_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					_isCoroutineRunning = true;
					<targetItem>5__1 = FindTargetItem();
					if ((Object)(object)<targetItem>5__1 != (Object)null)
					{
						<itemPosition>5__2 = <targetItem>5__1.transform.position;
						<currentYOffset>5__3 = DefaultValuableYOffset;
						<>s__5 = DefaultValuables.GetEnumerator();
						try
						{
							while (<>s__5.MoveNext())
							{
								<valuable>5__6 = <>s__5.Current;
								<i>5__7 = 0;
								while (<i>5__7 < <valuable>5__6.SpawnCount)
								{
									<randomValue>5__8 = Random.Range(0f, 1f);
									if (<randomValue>5__8 > <valuable>5__6.SpawnChance)
									{
										ManualLogSource? logger2 = _logger;
										if (logger2 != null)
										{
											logger2.LogInfo((object)$"Skipping spawn of '{<valuable>5__6.Name}' due to spawn chance ({<randomValue>5__8} > {<valuable>5__6.SpawnChance}).");
										}
									}
									else
									{
										<spawnPos>5__9 = <itemPosition>5__2 + new Vector3(0f, <currentYOffset>5__3, 0f);
										<spawnedValuable>5__10 = SpawnValuable(<valuable>5__6.Name, <spawnPos>5__9);
										<currentYOffset>5__3 += DefaultValuableYOffset;
										<spawnedValuable>5__10 = null;
									}
									<i>5__7++;
								}
								<valuable>5__6 = null;
							}
						}
						finally
						{
							((IDisposable)<>s__5).Dispose();
						}
						<>s__5 = default(List<ValuableDefinition>.Enumerator);
						<>2__current = (object)new WaitForSeconds(1f);
						<>1__state = 1;
						return true;
					}
					ManualLogSource? logger3 = _logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)"No target item found in the scene. Valuables will not spawn.");
					}
					break;
				}
				case 1:
					<>1__state = -1;
					<currentXOffset>5__4 = 0f;
					<>s__11 = AdditionalValuables.GetEnumerator();
					try
					{
						while (<>s__11.MoveNext())
						{
							<valuable>5__12 = <>s__11.Current;
							<i>5__13 = 0;
							while (<i>5__13 < <valuable>5__12.SpawnCount)
							{
								<randomValue>5__14 = Random.Range(0f, 1f);
								if (<randomValue>5__14 > <valuable>5__12.SpawnChance)
								{
									ManualLogSource? logger = _logger;
									if (logger != null)
									{
										logger.LogInfo((object)$"Skipping spawn of '{<valuable>5__12.Name}' due to spawn chance ({<randomValue>5__14} > {<valuable>5__12.SpawnChance}).");
									}
								}
								else
								{
									<spawnPos>5__15 = <itemPosition>5__2 + new Vector3(<currentXOffset>5__4, AdditionalValuableYOffset, 0f);
									<spawnedValuable>5__16 = SpawnValuable(<valuable>5__12.Name, <spawnPos>5__15);
									<currentXOffset>5__4 += 0.5f;
									<spawnedValuable>5__16 = null;
								}
								<i>5__13++;
							}
							<valuable>5__12 = null;
						}
					}
					finally
					{
						((IDisposable)<>s__11).Dispose();
					}
					<>s__11 = default(List<ValuableDefinition>.Enumerator);
					break;
				}
				_isCoroutineRunning = false;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static InitialValuables? _instance;

		private static ManualLogSource? _logger;

		private static bool _isCoroutineRunning = false;

		private static bool _isPatched = false;

		private static readonly float DefaultValuableYOffset = 0.5f;

		private static readonly float AdditionalValuableYOffset = 1f;

		private static readonly List<ValuableDefinition> DefaultValuables = new List<ValuableDefinition>();

		private static readonly List<ValuableDefinition> AdditionalValuables = new List<ValuableDefinition>();

		private ConfigEntry<string>? _userDefinedValuables;

		private ConfigEntry<float>? _invincibilityDuration;

		private readonly Dictionary<string, ConfigEntry<float>> _scaleModifiers = new Dictionary<string, ConfigEntry<float>>();

		private readonly Dictionary<string, ConfigEntry<int>> _randomScaleOptions = new Dictionary<string, ConfigEntry<int>>();

		private void Awake()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			if ((Object)(object)_instance != (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			_instance = this;
			_logger = ((BaseUnityPlugin)this).Logger;
			_invincibilityDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "InvincibilityDuration", 5f, "Duration (in seconds) for which spawned valuables are invincible.");
			InitializeValuables();
			if (!_isPatched)
			{
				Harmony val = new Harmony("ZeroTails.InitialValuables");
				val.Patch((MethodBase)AccessTools.Method(typeof(LoadingUI), "LevelAnimationStart", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(InitialValuables), "OnLevelStart", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_isPatched = true;
			}
		}

		private void InitializeValuables()
		{
			List<ValuableDefinition> list = new List<ValuableDefinition>
			{
				new ValuableDefinition("Gambler", 1, 1f),
				new ValuableDefinition("Valuable Present Big (Chance)", 1, 1f),
				new ValuableDefinition("Valuable Dummy Item Smith Note", 1, 0.1f)
			};
			foreach (ValuableDefinition item in list)
			{
				ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("Default Valuables", item.Name + " Active", true, "Enable or disable spawning of " + item.Name + ".");
				ConfigEntry<int> val2 = ((BaseUnityPlugin)this).Config.Bind<int>("Default Valuables", item.Name + " Spawn Count", item.SpawnCount, "How many " + item.Name + " valuables to spawn per level.");
				ConfigEntry<float> val3 = ((BaseUnityPlugin)this).Config.Bind<float>("Default Valuables", item.Name + " Spawn Chance", item.SpawnChance, "Chance for " + item.Name + " to spawn (1.0 = 100%, 0.5 = 50%, etc.).");
				ConfigEntry<float> value = ((BaseUnityPlugin)this).Config.Bind<float>("Default Valuables", item.Name + " Scale Modifier", 1f, "Scale modifier for " + item.Name + " (1.0 = default size).");
				ConfigEntry<int> value2 = ((BaseUnityPlugin)this).Config.Bind<int>("Default Valuables", item.Name + " Random Scale", 0, "Enable random scale for " + item.Name + " (0 = disabled, 1 = enabled).");
				if (val.Value)
				{
					DefaultValuables.Add(new ValuableDefinition(item.Name, val2.Value, val3.Value));
					_scaleModifiers[item.Name] = value;
					_randomScaleOptions[item.Name] = value2;
				}
			}
			_userDefinedValuables = ((BaseUnityPlugin)this).Config.Bind<string>("Valuables", "UserDefinedValuables", "", "Define your own valuables in the format: ValuableName:SpawnCount:SpawnChance:ScaleModifier:RandomScale, e.g., Valuable1:2:0.5:1.5:1,Valuable2:1:0.2:0.8:0");
			if (!string.IsNullOrEmpty(_userDefinedValuables.Value))
			{
				ParseUserDefinedValuables(_userDefinedValuables.Value);
			}
		}

		private void ParseUserDefinedValuables(string userDefinedValuables)
		{
			string[] array = userDefinedValuables.Split(',');
			string[] array2 = array;
			foreach (string text in array2)
			{
				string[] array3 = text.Split(':');
				if (array3.Length != 5)
				{
					ManualLogSource? logger = _logger;
					if (logger != null)
					{
						logger.LogWarning((object)("Invalid valuable definition: " + text + ". Expected format: ValuableName:SpawnCount:SpawnChance:ScaleModifier:RandomScale"));
					}
					continue;
				}
				string text2 = array3[0].Trim();
				float result2;
				float result3;
				int result4;
				if (!int.TryParse(array3[1], out var result) || result < 1)
				{
					ManualLogSource? logger2 = _logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)("Invalid spawn count for valuable '" + text2 + "': " + array3[1] + ". Must be a positive integer."));
					}
				}
				else if (!float.TryParse(array3[2], out result2) || result2 < 0f || result2 > 1f)
				{
					ManualLogSource? logger3 = _logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)("Invalid spawn chance for valuable '" + text2 + "': " + array3[2] + ". Must be a float between 0.0 and 1.0."));
					}
				}
				else if (!float.TryParse(array3[3], out result3) || result3 <= 0f)
				{
					ManualLogSource? logger4 = _logger;
					if (logger4 != null)
					{
						logger4.LogWarning((object)("Invalid scale modifier for valuable '" + text2 + "': " + array3[3] + ". Must be a positive float."));
					}
				}
				else if (!int.TryParse(array3[4], out result4) || (result4 != 0 && result4 != 1))
				{
					ManualLogSource? logger5 = _logger;
					if (logger5 != null)
					{
						logger5.LogWarning((object)("Invalid random scale option for valuable '" + text2 + "': " + array3[4] + ". Must be 0 (disabled) or 1 (enabled)."));
					}
				}
				else
				{
					AdditionalValuables.Add(new ValuableDefinition(text2, result, result2));
					_scaleModifiers[text2] = ((BaseUnityPlugin)this).Config.Bind<float>("User Defined Valuables", text2 + " Scale Modifier", result3, "Scale modifier for " + text2 + " (1.0 = default size).");
					_randomScaleOptions[text2] = ((BaseUnityPlugin)this).Config.Bind<int>("User Defined Valuables", text2 + " Random Scale", result4, "Enable random scale for " + text2 + " (0 = disabled, 1 = enabled).");
				}
			}
		}

		private static void OnLevelStart()
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			ClearPreviousState();
			if (!_isCoroutineRunning)
			{
				InitialValuables? instance = _instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(SpawnValuables());
				}
			}
		}

		private static void ClearPreviousState()
		{
			InitialValuables? instance = _instance;
			if (instance != null)
			{
				((MonoBehaviour)instance).StopAllCoroutines();
			}
			_isCoroutineRunning = false;
			ManualLogSource? logger = _logger;
			if (logger != null)
			{
				logger.LogInfo((object)"Cleared previous state and stopped all coroutines.");
			}
		}

		[IteratorStateMachine(typeof(<SpawnValuables>d__17))]
		private static IEnumerator SpawnValuables()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SpawnValuables>d__17(0);
		}

		private static GameObject? FindTargetItem()
		{
			GameObject[] array = GameObject.FindGameObjectsWithTag("Cart");
			GameObject[] array2 = array;
			foreach (GameObject val in array2)
			{
				if (((Object)val).name == "In Cart")
				{
					return val;
				}
			}
			return null;
		}

		private static GameObject? SpawnValuable(string valuableName, Vector3 spawnPos)
		{
			//IL_007b: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			GameObject valuableByName = Misc.GetValuableByName(valuableName);
			if ((Object)(object)valuableByName == (Object)null)
			{
				ManualLogSource? logger = _logger;
				if (logger != null)
				{
					logger.LogError((object)("Could not find the valuable prefab for '" + valuableName + "'."));
				}
				return null;
			}
			string valuablePrefabPath = ResourcesHelper.GetValuablePrefabPath(valuableByName);
			if (string.IsNullOrEmpty(valuablePrefabPath))
			{
				ManualLogSource? logger2 = _logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Could not determine the prefab path for '" + valuableName + "'."));
				}
				return null;
			}
			GameObject val = PhotonNetwork.Instantiate(valuablePrefabPath, spawnPos, Quaternion.identity, (byte)0, (object[])null);
			if ((Object)(object)val != (Object)null)
			{
				ManualLogSource? logger3 = _logger;
				if (logger3 != null)
				{
					logger3.LogInfo((object)$"Successfully spawned '{valuableName}' at {spawnPos}.");
				}
				SetInvincibility(val);
				float num = 1f;
				InitialValuables? instance = _instance;
				if (instance != null && instance._randomScaleOptions.TryGetValue(valuableName, out ConfigEntry<int> value) && value.Value == 1)
				{
					num = Random.Range(0.1f, 2f);
				}
				else
				{
					InitialValuables? instance2 = _instance;
					if (instance2 != null && instance2._scaleModifiers.TryGetValue(valuableName, out ConfigEntry<float> value2))
					{
						num = value2.Value;
					}
				}
				Transform transform = val.transform;
				transform.localScale *= num;
				PhotonView component = val.GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null)
				{
					component.RPC("RPC_SetScale", (RpcTarget)1, new object[2]
					{
						((Object)val).name,
						num
					});
				}
			}
			else
			{
				ManualLogSource? logger4 = _logger;
				if (logger4 != null)
				{
					logger4.LogError((object)$"Failed to spawn '{valuableName}' at {spawnPos}.");
				}
			}
			return val;
		}

		[PunRPC]
		private void RPC_SetScale(string valuableName, float scaleModifier)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find(valuableName);
			if ((Object)(object)val != (Object)null)
			{
				Transform transform = val.transform;
				transform.localScale *= scaleModifier;
			}
		}

		[PunRPC]
		private void RPC_SetInvincibility(string valuableName, float duration)
		{
			GameObject val = GameObject.Find(valuableName);
			if ((Object)(object)val != (Object)null)
			{
				SurplusValuable component = val.GetComponent<SurplusValuable>();
				if ((Object)(object)component != (Object)null)
				{
					FieldInfo field = typeof(SurplusValuable).GetField("indestructibleTimer", BindingFlags.Instance | BindingFlags.NonPublic);
					if (field != null)
					{
						field.SetValue(component, duration);
						ManualLogSource? logger = _logger;
						if (logger != null)
						{
							logger.LogInfo((object)$"[RPC] Set invincibility timer to {duration} seconds for '{((Object)val).name}'.");
						}
					}
					else
					{
						ManualLogSource? logger2 = _logger;
						if (logger2 != null)
						{
							logger2.LogError((object)("[RPC] Could not find 'indestructibleTimer' field on '" + ((Object)val).name + "'."));
						}
					}
				}
				else
				{
					ManualLogSource? logger3 = _logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)("[RPC] No 'SurplusValuable' component found on '" + ((Object)val).name + "'."));
					}
				}
			}
			else
			{
				ManualLogSource? logger4 = _logger;
				if (logger4 != null)
				{
					logger4.LogWarning((object)("[RPC] Could not find valuable '" + valuableName + "' to set invincibility."));
				}
			}
		}

		private static void SetInvincibility(GameObject valuable)
		{
			SurplusValuable component = valuable.GetComponent<SurplusValuable>();
			if ((Object)(object)component == (Object)null)
			{
				ManualLogSource? logger = _logger;
				if (logger != null)
				{
					logger.LogWarning((object)("No 'SurplusValuable' component found on spawned valuable '" + ((Object)valuable).name + "'."));
				}
				return;
			}
			FieldInfo field = typeof(SurplusValuable).GetField("indestructibleTimer", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field != null)
			{
				float valueOrDefault = (_instance?._invincibilityDuration?.Value).GetValueOrDefault(5f);
				field.SetValue(component, valueOrDefault);
				ManualLogSource? logger2 = _logger;
				if (logger2 != null)
				{
					logger2.LogInfo((object)$"Set invincibility timer to {valueOrDefault} seconds for '{((Object)valuable).name}'.");
				}
				PhotonView component2 = valuable.GetComponent<PhotonView>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.RPC("RPC_SetInvincibility", (RpcTarget)1, new object[2]
					{
						((Object)valuable).name,
						valueOrDefault
					});
				}
			}
			else
			{
				ManualLogSource? logger3 = _logger;
				if (logger3 != null)
				{
					logger3.LogError((object)("Could not find 'indestructibleTimer' field on '" + ((Object)valuable).name + "'."));
				}
			}
		}
	}
}