Decompiled source of ElderStaffMod v1.0.4

plugins\ElderStaffMod\ElderStaffMod.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ElderStaffMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Lethal Company Mod: Elder Staff (Avada Kedavra Stab)")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ElderStaffMod")]
[assembly: AssemblyTitle("ElderStaffMod")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ElderStaffMod
{
	[BepInPlugin("ElderStaffMod", "ElderStaffMod", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		private const string AssetBundleName = "elderstaffbundle";

		private const int ScrapRarity = 30;

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"ElderStaffMod v1.0.0 loaded.");
			try
			{
				RegisterElderStaff();
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"ElderStaff registration failed: {arg}");
			}
		}

		private void RegisterElderStaff()
		{
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? "", "elderstaffbundle");
			if (!File.Exists(text))
			{
				Logger.LogWarning((object)("Asset bundle not found: " + text + ". Build the bundle in Lethal Company Unity Template and place it next to the DLL. See README."));
				return;
			}
			AssetBundle val = AssetBundle.LoadFromFile(text);
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogError((object)"Failed to load Elder Staff asset bundle.");
				return;
			}
			Object val2 = null;
			string[] array = new string[5] { "assets/elderstaff/elderstaffitemdata.asset", "assets/elderstaffitemdata.asset", "elderstaffitemdata.asset", "assets/elderstaffitem.asset", "elderstaffitem" };
			foreach (string text2 in array)
			{
				val2 = val.LoadAsset(text2);
				if (val2 != (Object)null)
				{
					break;
				}
			}
			if (val2 == (Object)null)
			{
				Object[] array2 = val.LoadAllAssets();
				foreach (Object val3 in array2)
				{
					if (!(val3 == (Object)null))
					{
						PropertyInfo property = ((object)val3).GetType().GetProperty("spawnPrefab");
						if (property != null && property.GetValue(val3) is GameObject)
						{
							val2 = val3;
							break;
						}
					}
				}
			}
			if (val2 == (Object)null)
			{
				Logger.LogWarning((object)"Item data not found in bundle. Check bundle contents or possiblePaths in Plugin.cs.");
				val.Unload(false);
				return;
			}
			PropertyInfo property2 = ((object)val2).GetType().GetProperty("spawnPrefab");
			if (property2 == null)
			{
				Logger.LogError((object)"Item data has no spawnPrefab property.");
				val.Unload(false);
				return;
			}
			object? value = property2.GetValue(val2);
			GameObject val4 = (GameObject)((value is GameObject) ? value : null);
			if ((Object)(object)val4 == (Object)null)
			{
				Logger.LogError((object)"Item spawnPrefab is null.");
				val.Unload(false);
				return;
			}
			Type type = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				type = assembly.GetType("GameNetcodeStuff.Item") ?? assembly.GetType("Item");
				if (type != null)
				{
					break;
				}
			}
			if (type == null)
			{
				Logger.LogError((object)"Could not find Item type (Lethal Company).");
				val.Unload(false);
				return;
			}
			if (!type.IsInstanceOfType(val2))
			{
				Logger.LogWarning((object)"Bundle Item type differs from game; LethalLib may require game Item type. Trying RegisterScrap anyway.");
			}
			Assembly assembly2 = null;
			assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly3 in assemblies)
			{
				if (assembly3.GetName().Name == "LethalLib")
				{
					assembly2 = assembly3;
					break;
				}
			}
			if (assembly2 == null)
			{
				Logger.LogError((object)"LethalLib not found. Install LethalLib from Thunderstore.");
				val.Unload(false);
				return;
			}
			Type type2 = assembly2.GetType("LethalLib.Modules.Utilities");
			if (type2 != null)
			{
				type2.GetMethod("FixMixerGroups", new Type[1] { typeof(GameObject) })?.Invoke(null, new object[1] { val4 });
			}
			(assembly2.GetType("LethalLib.Modules.NetworkPrefabs")?.GetMethod("RegisterNetworkPrefab", new Type[1] { typeof(GameObject) }))?.Invoke(null, new object[1] { val4 });
			Type type3 = assembly2.GetType("LethalLib.Modules.Levels+LevelTypes");
			object obj = ((type3 != null) ? Enum.Parse(type3, "All") : null);
			Type type4 = assembly2.GetType("LethalLib.Modules.Items");
			MethodInfo methodInfo = type4?.GetMethod("RegisterScrap", new Type[3]
			{
				type,
				typeof(int),
				type3
			});
			if (methodInfo != null && obj != null)
			{
				try
				{
					methodInfo.Invoke(null, new object[3] { val2, 30, obj });
					Logger.LogInfo((object)"Elder Staff registered as scrap.");
				}
				catch (Exception ex)
				{
					Logger.LogError((object)("RegisterScrap failed: " + ex.Message + ". Bundle Item type may not match game. Check BepInEx log."));
				}
			}
			else
			{
				Logger.LogWarning((object)"RegisterScrap method not found or levelAll null.");
			}
			MethodInfo methodInfo2 = type4?.GetMethod("RegisterShopItem", new Type[2]
			{
				type,
				typeof(int)
			});
			if (methodInfo2 != null)
			{
				try
				{
					methodInfo2.Invoke(null, new object[2] { val2, 0 });
					Logger.LogInfo((object)"Elder Staff registered in shop for 0 credits.");
				}
				catch (Exception ex2)
				{
					Logger.LogWarning((object)("RegisterShopItem failed: " + ex2.Message + ". Shop item may not appear."));
				}
			}
			val.Unload(false);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ElderStaffMod";

		public const string PLUGIN_NAME = "ElderStaffMod";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace GameNetcodeStuff
{
	public class ElderStaffItem : GrabbableObject
	{
		[CompilerGenerated]
		private sealed class <DestroyVfxAfterDelay>d__19 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public float delay;

			public GameObject vfxInstance;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (delay > 0f)
					{
						<>2__current = (object)new WaitForSeconds(delay);
						<>1__state = 1;
						return true;
					}
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)vfxInstance != (Object)null)
				{
					Object.Destroy((Object)(object)vfxInstance);
				}
				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();
			}
		}

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

			private object <>2__current;

			public Light lightComp;

			public float duration;

			public float peak;

			private float <startIntensity>5__2;

			private float <elapsed>5__3;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if ((Object)(object)lightComp == (Object)null || duration <= 0f)
					{
						return false;
					}
					<startIntensity>5__2 = lightComp.intensity;
					<elapsed>5__3 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsed>5__3 < duration)
				{
					<elapsed>5__3 += Time.deltaTime;
					float num = Mathf.Clamp01(<elapsed>5__3 / duration);
					lightComp.intensity = Mathf.Lerp(<startIntensity>5__2, peak, num);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				lightComp.intensity = <startIntensity>5__2;
				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();
			}
		}

		[Header("Referenzen")]
		[SerializeField]
		private Transform muzzleTransform;

		[SerializeField]
		private GameObject avadaVfxPrefab;

		[Tooltip("Optional: Wird bei Aktivierung des Stabs abgespielt (z. B. Avada Kedavra).")]
		[SerializeField]
		private AudioClip activationClip;

		[Header("Raycast & Reichweite")]
		[SerializeField]
		private float rangeMeters = 20f;

		[Header("Cooldown & VFX-Laufzeit")]
		[SerializeField]
		private float cooldownSeconds = 45f;

		[SerializeField]
		private float vfxLifetimeSeconds = 0.5f;

		[Header("Schaden (optional, wenn Entity getroffen)")]
		[SerializeField]
		private int damageAmount = 9999;

		[Header("Light-Flash (Fallback wenn kein AvadaVfxController)")]
		[SerializeField]
		private float peakIntensity = 18f;

		[SerializeField]
		private float flashDuration = 0.22f;

		private float _cooldownEndTime;

		private bool IsOnCooldown => Time.time < _cooldownEndTime;

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (!buttonDown)
			{
				return;
			}
			if (IsOnCooldown)
			{
				Debug.Log((object)"[ElderStaffItem] Noch Cooldown – bitte warten.");
				return;
			}
			if ((Object)(object)base.playerHeldBy == (Object)null)
			{
				Debug.LogWarning((object)"[ElderStaffItem] Kein Spieler (playerHeldBy == null).");
				return;
			}
			if ((Object)(object)muzzleTransform == (Object)null)
			{
				Debug.LogWarning((object)"[ElderStaffItem] muzzleTransform nicht gesetzt.");
				return;
			}
			if ((Object)(object)avadaVfxPrefab == (Object)null)
			{
				Debug.LogWarning((object)"[ElderStaffItem] avadaVfxPrefab nicht gesetzt.");
				return;
			}
			Camera playerCamera = GetPlayerCamera((Component)(object)base.playerHeldBy);
			if ((Object)(object)playerCamera == (Object)null)
			{
				Debug.LogWarning((object)"[ElderStaffItem] Keine Kamera gefunden.");
				return;
			}
			Vector3 position = ((Component)playerCamera).transform.position;
			Vector3 forward = ((Component)playerCamera).transform.forward;
			float num = rangeMeters;
			RaycastHit hit = default(RaycastHit);
			Vector3 end = ((!Physics.Raycast(position, forward, ref hit, num)) ? (position + forward * num) : ((RaycastHit)(ref hit)).point);
			Vector3 position2 = muzzleTransform.position;
			if ((Object)(object)activationClip != (Object)null)
			{
				AudioSource.PlayClipAtPoint(activationClip, position2, 1f);
			}
			GameObject val = Object.Instantiate<GameObject>(avadaVfxPrefab, position2, Quaternion.identity);
			if (!((Object)(object)val == (Object)null))
			{
				SetupVfxBeam(val, position2, end);
				TriggerVfxFlash(val);
				TryApplyDamageOrStun(hit, (Component)(object)base.playerHeldBy);
				((MonoBehaviour)this).StartCoroutine(DestroyVfxAfterDelay(val, vfxLifetimeSeconds));
				_cooldownEndTime = Time.time + cooldownSeconds;
			}
		}

		private static Camera GetPlayerCamera(Component player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			Camera val = (Camera)(object)((player is Camera) ? player : null);
			if (val != null)
			{
				return val;
			}
			Type type = ((object)player).GetType();
			PropertyInfo property = type.GetProperty("gameplayCamera");
			if (property != null)
			{
				object? value = property.GetValue(player);
				Camera val2 = (Camera)((value is Camera) ? value : null);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			property = type.GetProperty("mainCamera");
			if (property != null)
			{
				object? value2 = property.GetValue(player);
				Camera val3 = (Camera)((value2 is Camera) ? value2 : null);
				if ((Object)(object)val3 != (Object)null)
				{
					return val3;
				}
			}
			Transform val4 = player.transform.Find("ScalingContainer/CameraContainer/MainCamera");
			if ((Object)(object)val4 != (Object)null)
			{
				Camera component = ((Component)val4).GetComponent<Camera>();
				if ((Object)(object)component != (Object)null)
				{
					return component;
				}
			}
			return Camera.main;
		}

		private void SetupVfxBeam(GameObject vfxInstance, Vector3 start, Vector3 end)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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)
			if ((Object)(object)vfxInstance == (Object)null)
			{
				return;
			}
			Type typeByName = GetTypeByName("AvadaVfxController");
			if (typeByName != null)
			{
				Component componentInChildren = vfxInstance.GetComponentInChildren(typeByName);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					MethodInfo method = typeByName.GetMethod("Init", new Type[2]
					{
						typeof(Vector3),
						typeof(Vector3)
					});
					if (method != null)
					{
						method.Invoke(componentInChildren, new object[2] { start, end });
						return;
					}
				}
			}
			LineRenderer componentInChildren2 = vfxInstance.GetComponentInChildren<LineRenderer>();
			if ((Object)(object)componentInChildren2 != (Object)null)
			{
				componentInChildren2.positionCount = 2;
				componentInChildren2.SetPosition(0, start);
				componentInChildren2.SetPosition(1, end);
			}
		}

		private void TriggerVfxFlash(GameObject vfxInstance)
		{
			if ((Object)(object)vfxInstance == (Object)null)
			{
				return;
			}
			Type typeByName = GetTypeByName("AvadaVfxController");
			if (typeByName != null)
			{
				Component componentInChildren = vfxInstance.GetComponentInChildren(typeByName);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					MethodInfo method = typeByName.GetMethod("TriggerFlash", Type.EmptyTypes);
					if (method != null)
					{
						method.Invoke(componentInChildren, null);
						return;
					}
				}
			}
			Light componentInChildren2 = vfxInstance.GetComponentInChildren<Light>();
			if ((Object)(object)componentInChildren2 != (Object)null)
			{
				((MonoBehaviour)this).StartCoroutine(FlashLightCoroutine(componentInChildren2, peakIntensity, flashDuration));
			}
		}

		private static Type GetTypeByName(string typeName)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					Type type = assembly.GetType(typeName);
					if (type != null)
					{
						return type;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		[IteratorStateMachine(typeof(<FlashLightCoroutine>d__17))]
		private static IEnumerator FlashLightCoroutine(Light lightComp, float peak, float duration)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FlashLightCoroutine>d__17(0)
			{
				lightComp = lightComp,
				peak = peak,
				duration = duration
			};
		}

		private void TryApplyDamageOrStun(RaycastHit hit, Component localPlayer)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)((RaycastHit)(ref hit)).collider))
			{
				return;
			}
			GameObject gameObject = ((Component)((RaycastHit)(ref hit)).collider).gameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				return;
			}
			Type typeByName = GetTypeByName("EnemyAI");
			if (typeByName != null)
			{
				Component component = gameObject.GetComponent(typeByName);
				if ((Object)(object)component != (Object)null)
				{
					MethodInfo method = typeByName.GetMethod("HitEnemy");
					if (!(method != null))
					{
						return;
					}
					ParameterInfo[] parameters = method.GetParameters();
					if (parameters.Length < 1)
					{
						return;
					}
					try
					{
						Vector3 val = ((RaycastHit)(ref hit)).point - (((Object)(object)muzzleTransform != (Object)null) ? muzzleTransform.position : ((RaycastHit)(ref hit)).point);
						if (parameters.Length == 1)
						{
							method.Invoke(component, new object[1] { damageAmount });
						}
						else if (parameters.Length >= 2)
						{
							method.Invoke(component, new object[2] { damageAmount, val });
						}
						else if (parameters.Length >= 3)
						{
							method.Invoke(component, new object[3] { damageAmount, val, localPlayer });
						}
						else
						{
							method.Invoke(component, new object[4] { damageAmount, val, localPlayer, true });
						}
						return;
					}
					catch (Exception ex)
					{
						Debug.LogWarning((object)("[ElderStaffItem] HitEnemy-Aufruf fehlgeschlagen: " + ex.Message));
						return;
					}
				}
			}
			MonoBehaviour[] components = gameObject.GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val2 in components)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				Type type = ((object)val2).GetType();
				MethodInfo methodInfo = type.GetMethod("Stun", Type.EmptyTypes) ?? type.GetMethod("Stun", new Type[1] { typeof(float) });
				if (!(methodInfo != null))
				{
					continue;
				}
				try
				{
					if (methodInfo.GetParameters().Length == 0)
					{
						methodInfo.Invoke(val2, null);
						break;
					}
					methodInfo.Invoke(val2, new object[1] { 5f });
					break;
				}
				catch (Exception ex2)
				{
					Debug.LogWarning((object)("[ElderStaffItem] Stun-Aufruf fehlgeschlagen: " + ex2.Message));
					break;
				}
			}
		}

		[IteratorStateMachine(typeof(<DestroyVfxAfterDelay>d__19))]
		private static IEnumerator DestroyVfxAfterDelay(GameObject vfxInstance, float delay)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DestroyVfxAfterDelay>d__19(0)
			{
				vfxInstance = vfxInstance,
				delay = delay
			};
		}
	}
}