Decompiled source of ConfigurableDynamite v1.0.0

plugins/com.github.GABRlEL.ConfigurableDynamite.dll

Decompiled a day ago
using System;
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 UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.GABRlEL.ConfigurableDynamite")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("com.github.GABRlEL.ConfigurableDynamite")]
[assembly: AssemblyTitle("ConfigurableDynamite")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace ConfigurableDynamite
{
	[BepInPlugin("com.github.GABRlEL.ConfigurableDynamite", "ConfigurableDynamite", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal enum OverrideToggle
		{
			Vanilla,
			Enabled,
			Disabled
		}

		internal enum DamageTypeOverride
		{
			Vanilla = -1,
			Injury,
			Hunger,
			Cold,
			Poison,
			Crab,
			Curse,
			Drowsy,
			Weight,
			Hot,
			Thorns,
			Spores,
			Web
		}

		private sealed class DynamiteExplosionAoeMarker : MonoBehaviour
		{
			public bool IsDynamiteExplosion;

			public bool Applied;
		}

		private sealed class PendingThrowFuseMarker : MonoBehaviour
		{
		}

		private sealed class PendingUseFuseMarker : MonoBehaviour
		{
		}

		[HarmonyPatch(typeof(Dynamite), "Awake")]
		private static class Dynamite_Awake_Patch
		{
			private static void Postfix(Dynamite __instance)
			{
				try
				{
					ApplyFuseConfig(__instance);
					ApplyPocketConfig(__instance);
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}
		}

		[HarmonyPatch(typeof(Dynamite), "SetFlareLitRPC")]
		private static class Dynamite_SetFlareLitRPC_Patch
		{
			private static void Postfix(Dynamite __instance)
			{
				try
				{
					ApplyPocketConfig(__instance);
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}
		}

		[HarmonyPatch(typeof(Dynamite), "OnInstanceDataSet")]
		private static class Dynamite_OnInstanceDataSet_Patch
		{
			private static void Postfix(Dynamite __instance)
			{
				try
				{
					EnsureFullFuseIfNotLit(__instance);
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}
		}

		[HarmonyPatch(typeof(Item), "RPC_SetThrownData")]
		private static class Item_RPC_SetThrownData_Patch
		{
			private static void Postfix(Item __instance)
			{
				try
				{
					if (!AutoFuseEnabled.Value && FuseOnThrow.Value && !((Object)(object)__instance == (Object)null))
					{
						Dynamite component = ((Component)__instance).GetComponent<Dynamite>();
						if (!((Object)(object)component == (Object)null) && (Object)(object)((Component)__instance).gameObject.GetComponent<PendingThrowFuseMarker>() == (Object)null)
						{
							((Component)__instance).gameObject.AddComponent<PendingThrowFuseMarker>();
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}
		}

		[HarmonyPatch(typeof(Item), "SetItemInstanceDataRPC")]
		private static class Item_SetItemInstanceDataRPC_Patch
		{
			private static void Postfix(Item __instance)
			{
				try
				{
					object obj;
					if (__instance == null)
					{
						obj = null;
					}
					else
					{
						GameObject gameObject = ((Component)__instance).gameObject;
						obj = ((gameObject != null) ? gameObject.GetComponent<PendingThrowFuseMarker>() : null);
					}
					PendingThrowFuseMarker pendingThrowFuseMarker = (PendingThrowFuseMarker)obj;
					if ((Object)(object)pendingThrowFuseMarker == (Object)null)
					{
						return;
					}
					Object.Destroy((Object)(object)pendingThrowFuseMarker);
					if (!AutoFuseEnabled.Value && FuseOnThrow.Value)
					{
						Dynamite component = ((Component)__instance).GetComponent<Dynamite>();
						if (!((Object)(object)component == (Object)null))
						{
							TryLightFuse(component);
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}
		}

		[HarmonyPatch(typeof(Item), "StartUsePrimary")]
		private static class Item_StartUsePrimary_Patch
		{
			private static void Postfix(Item __instance)
			{
				try
				{
					if (!AutoFuseEnabled.Value && FuseOnUse.Value && !((Object)(object)__instance == (Object)null))
					{
						Dynamite component = ((Component)__instance).GetComponent<Dynamite>();
						if (!((Object)(object)component == (Object)null) && (Object)(object)((Component)__instance).gameObject.GetComponent<PendingUseFuseMarker>() == (Object)null)
						{
							((Component)__instance).gameObject.AddComponent<PendingUseFuseMarker>();
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}
		}

		[HarmonyPatch(typeof(Item), "FinishCastPrimary")]
		private static class Item_FinishCastPrimary_Patch
		{
			private static void Postfix(Item __instance)
			{
				try
				{
					object obj;
					if (__instance == null)
					{
						obj = null;
					}
					else
					{
						GameObject gameObject = ((Component)__instance).gameObject;
						obj = ((gameObject != null) ? gameObject.GetComponent<PendingUseFuseMarker>() : null);
					}
					PendingUseFuseMarker pendingUseFuseMarker = (PendingUseFuseMarker)obj;
					if ((Object)(object)pendingUseFuseMarker == (Object)null)
					{
						return;
					}
					Object.Destroy((Object)(object)pendingUseFuseMarker);
					if (!AutoFuseEnabled.Value && FuseOnUse.Value)
					{
						Dynamite component = ((Component)__instance).GetComponent<Dynamite>();
						if (!((Object)(object)component == (Object)null))
						{
							TryLightFuse(component);
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}
		}

		[HarmonyPatch(typeof(Item), "CancelUsePrimary")]
		private static class Item_CancelUsePrimary_Patch
		{
			private static void Postfix(Item __instance)
			{
				try
				{
					object obj;
					if (__instance == null)
					{
						obj = null;
					}
					else
					{
						GameObject gameObject = ((Component)__instance).gameObject;
						obj = ((gameObject != null) ? gameObject.GetComponent<PendingUseFuseMarker>() : null);
					}
					PendingUseFuseMarker pendingUseFuseMarker = (PendingUseFuseMarker)obj;
					if ((Object)(object)pendingUseFuseMarker != (Object)null)
					{
						Object.Destroy((Object)(object)pendingUseFuseMarker);
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}
		}

		[HarmonyPatch(typeof(Dynamite), "RPC_Explode")]
		private static class Dynamite_RPC_Explode_Patch
		{
			private static void Prefix()
			{
				if (HasExplosionOverrides())
				{
					_spawningDynamiteExplosion = true;
				}
			}

			private static void Finalizer(Exception? __exception)
			{
				_spawningDynamiteExplosion = false;
				if (__exception != null)
				{
					Log.LogError((object)__exception);
				}
			}
		}

		[HarmonyPatch(typeof(AOE), "OnEnable")]
		private static class AOE_OnEnable_Patch
		{
			private static void Prefix(AOE __instance)
			{
				try
				{
					if (_spawningDynamiteExplosion)
					{
						ApplyExplosionConfig(__instance);
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}
		}

		[HarmonyPatch(typeof(AOE), "Explode")]
		private static class AOE_Explode_Patch
		{
			private static void Prefix(AOE __instance)
			{
				try
				{
					DynamiteExplosionAoeMarker component = ((Component)__instance).gameObject.GetComponent<DynamiteExplosionAoeMarker>();
					if (!((Object)(object)component == (Object)null) && component.IsDynamiteExplosion)
					{
						ApplyExplosionConfig(__instance);
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}
		}

		private Harmony? _harmony;

		private static bool _spawningDynamiteExplosion;

		public const string Id = "com.github.GABRlEL.ConfigurableDynamite";

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<bool> AutoFuseEnabled { get; private set; }

		internal static ConfigEntry<float> AutoFuseDistance { get; private set; }

		internal static ConfigEntry<float> FuseLengthSeconds { get; private set; }

		internal static ConfigEntry<bool> FuseOnUse { get; private set; }

		internal static ConfigEntry<bool> FuseOnThrow { get; private set; }

		internal static ConfigEntry<float> DamageMultiplier { get; private set; }

		internal static ConfigEntry<float> RangeMultiplier { get; private set; }

		internal static ConfigEntry<DamageTypeOverride> DynamiteDamageType { get; private set; }

		internal static ConfigEntry<bool> UnlitDynamiteCanBePocketed { get; private set; }

		internal static ConfigEntry<OverrideToggle> ItemCooking { get; private set; }

		internal static ConfigEntry<OverrideToggle> ItemLaunching { get; private set; }

		internal static ConfigEntry<float> ItemLaunchDistanceMultiplier { get; private set; }

		public static string Name => "ConfigurableDynamite";

		public static string Version => "0.1.0";

		private void Awake()
		{
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			AutoFuseEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Fuse", "AutoFuseEnabled", true, "Vanilla behaviour is TRUE: the dynamite fuse lights automatically when a player gets close.\nSet to FALSE to disable proximity ignition.");
			AutoFuseDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Fuse", "AutoFuseDistance", -1f, "Distance (in Unity units) from a player to a dynamite for the fuse to light when AutoFuseEnabled is TRUE.\nSet to -1 to keep vanilla distance.");
			FuseLengthSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Fuse", "FuseLengthSeconds", -1f, "Fuse length in seconds.\nSet to -1 to keep vanilla fuse length.");
			FuseOnUse = ((BaseUnityPlugin)this).Config.Bind<bool>("Fuse", "StartFuseOnUse", false, "When AutoFuseEnabled is FALSE, start the fuse when the item is used (primary use).");
			FuseOnThrow = ((BaseUnityPlugin)this).Config.Bind<bool>("Fuse", "StartFuseOnThrow", false, "When AutoFuseEnabled is FALSE, start the fuse when the item is thrown.");
			DamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Explosion", "DamageMultiplier", 1f, "Multiplier applied to dynamite explosion damage (AOE.statusAmount).\n1 = vanilla.");
			RangeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Explosion", "RangeMultiplier", 1f, "Multiplier applied to dynamite explosion range (AOE.range).\n1 = vanilla.");
			DynamiteDamageType = ((BaseUnityPlugin)this).Config.Bind<DamageTypeOverride>("Explosion", "DamageType", DamageTypeOverride.Vanilla, "Controls the status/damage type dynamite applies (AOE.statusType). Vanilla keeps the game's original setting.\nCold = freeze, Hot = burn, Spores = shroom.");
			UnlitDynamiteCanBePocketed = ((BaseUnityPlugin)this).Config.Bind<bool>("Item", "UnlitDynamiteCanBePocketed", false, "If TRUE, unlit dynamite can be pocketed. Lit dynamite remains unpocketable. Default FALSE keeps vanilla behaviour.");
			ItemCooking = ((BaseUnityPlugin)this).Config.Bind<OverrideToggle>("Explosion", "ItemCooking", OverrideToggle.Vanilla, "Controls whether dynamite explosions cook items via AOE.cooksItems. Vanilla keeps the game's original setting.");
			ItemLaunching = ((BaseUnityPlugin)this).Config.Bind<OverrideToggle>("Explosion", "ItemLaunching", OverrideToggle.Vanilla, "Controls whether dynamite explosions can launch items via AOE.canLaunchItems. Vanilla keeps the game's original setting.");
			ItemLaunchDistanceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Explosion", "ItemLaunchDistanceMultiplier", 1f, "Multiplier applied to dynamite item-launch strength (AOE.itemKnockbackMultiplier). 1 = vanilla.");
			_harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
			_harmony.PatchAll();
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}

		private void OnDestroy()
		{
			try
			{
				Harmony? harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
		}

		private static void TryLightFuse(Dynamite dynamite)
		{
			if (!((ItemComponent)dynamite).GetData<BoolItemData>((DataEntryKey)3).Value)
			{
				dynamite.LightFlare();
			}
		}

		private static bool HasFuseOverride(out float fuseSeconds)
		{
			fuseSeconds = FuseLengthSeconds.Value;
			return fuseSeconds > 0f;
		}

		private static bool HasExplosionOverrides()
		{
			if (Mathf.Approximately(DamageMultiplier.Value, 1f) && Mathf.Approximately(RangeMultiplier.Value, 1f) && ItemCooking.Value == OverrideToggle.Vanilla && ItemLaunching.Value == OverrideToggle.Vanilla && DynamiteDamageType.Value == DamageTypeOverride.Vanilla)
			{
				return !Mathf.Approximately(ItemLaunchDistanceMultiplier.Value, 1f);
			}
			return true;
		}

		private static void ApplyFuseConfig(Dynamite dynamite)
		{
			if (!AutoFuseEnabled.Value)
			{
				dynamite.lightFuseRadius = 0f;
			}
			else if (AutoFuseDistance.Value > 0f)
			{
				dynamite.lightFuseRadius = AutoFuseDistance.Value;
			}
			if (HasFuseOverride(out var fuseSeconds))
			{
				dynamite.startingFuseTime = fuseSeconds;
			}
		}

		private static void ApplyPocketConfig(Dynamite dynamite)
		{
			if (UnlitDynamiteCanBePocketed.Value && ((ItemComponent)(dynamite?)).item?.UIData != null)
			{
				bool value = ((ItemComponent)dynamite).GetData<BoolItemData>((DataEntryKey)3).Value;
				((ItemComponent)dynamite).item.UIData.canPocket = !value;
			}
		}

		private static void EnsureFullFuseIfNotLit(Dynamite dynamite)
		{
			if (HasFuseOverride(out var fuseSeconds) && !((ItemComponent)dynamite).GetData<BoolItemData>((DataEntryKey)3).Value)
			{
				FloatItemData data = ((ItemComponent)dynamite).GetData<FloatItemData>((DataEntryKey)10, (Func<FloatItemData>)(() => new FloatItemData
				{
					Value = fuseSeconds
				}));
				data.Value = fuseSeconds;
			}
		}

		private static void ApplyExplosionConfig(AOE aoe)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if (!HasExplosionOverrides())
			{
				return;
			}
			DynamiteExplosionAoeMarker dynamiteExplosionAoeMarker = ((Component)aoe).gameObject.GetComponent<DynamiteExplosionAoeMarker>() ?? ((Component)aoe).gameObject.AddComponent<DynamiteExplosionAoeMarker>();
			if (!dynamiteExplosionAoeMarker.Applied)
			{
				dynamiteExplosionAoeMarker.IsDynamiteExplosion = true;
				dynamiteExplosionAoeMarker.Applied = true;
				if (!Mathf.Approximately(RangeMultiplier.Value, 1f))
				{
					aoe.range *= RangeMultiplier.Value;
				}
				if (!Mathf.Approximately(DamageMultiplier.Value, 1f))
				{
					aoe.statusAmount *= DamageMultiplier.Value;
				}
				if (DynamiteDamageType.Value != DamageTypeOverride.Vanilla)
				{
					aoe.illegalStatus = "";
					aoe.statusType = (STATUSTYPE)DynamiteDamageType.Value;
				}
				if (ItemCooking.Value != 0)
				{
					aoe.cooksItems = ItemCooking.Value == OverrideToggle.Enabled;
				}
				if (ItemLaunching.Value != 0)
				{
					aoe.canLaunchItems = ItemLaunching.Value == OverrideToggle.Enabled;
				}
				if (!Mathf.Approximately(ItemLaunchDistanceMultiplier.Value, 1f))
				{
					aoe.itemKnockbackMultiplier *= ItemLaunchDistanceMultiplier.Value;
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}