Decompiled source of EnemyGrapple v1.0.1

EnemyGrapple.dll

Decompiled 20 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ConditionalConfigSync;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("EnemyGrapple")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EnemyGrapple")]
[assembly: AssemblyTitle("EnemyGrapple")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EnemyGrapple
{
	[BepInPlugin("com.dreich.enemygrapple", "Enemy Grapple", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class EnemyGrapple : BaseUnityPlugin
	{
		public const string Guid = "com.dreich.enemygrapple";

		public const string Name = "Enemy Grapple";

		public const string Version = "1.0.0";

		internal const string ConfigSyncGuid = "_shudnal.ConditionalConfigSync";

		internal static ManualLogSource Log;

		internal static bool ConfigSyncAvailable;

		private static ConfigEntry<bool> ConfigLockedEntry;

		private static ConfigEntry<bool> EnabledEntry;

		private static ConfigEntry<string> TargetCreaturesEntry;

		private static string parsedFrom;

		private static HashSet<string> targetCreatures = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		internal static bool Enabled => EnabledEntry.Value;

		private void Awake()
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigSyncAvailable = Chainloader.PluginInfos.ContainsKey("_shudnal.ConditionalConfigSync");
			if (ConfigSyncAvailable)
			{
				ConfigSyncCompat.Initialize("com.dreich.enemygrapple", "Enemy Grapple", "1.0.0");
			}
			else
			{
				Log.LogInfo((object)"ConditionalConfigSync not found; configuration will not be synced from the server.");
			}
			ConfigLockedEntry = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Lock Configuration", true, "If on, the configuration is locked and can be changed by server admins only. Requires ConditionalConfigSync.");
			if (ConfigSyncAvailable)
			{
				ConfigSyncCompat.AddLockingConfigEntry(ConfigLockedEntry);
			}
			EnabledEntry = BindShared("General", "Enabled", defaultValue: true, "Hitting one of the listed creatures with the grappling hook attaches to it and pulls you toward it.");
			TargetCreaturesEntry = BindShared("General", "TargetCreatures", "Gjall", "Comma-separated creature prefab names the grappling hook can attach to. Names are not case-sensitive.");
			new Harmony("com.dreich.enemygrapple").PatchAll();
		}

		private ConfigEntry<T> BindShared<T>(string section, string key, T defaultValue, string description)
		{
			ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, description);
			if (ConfigSyncAvailable)
			{
				ConfigSyncCompat.AddConfigEntry<T>(val, serverControlled: true);
			}
			return val;
		}

		internal static bool IsTarget(Character character)
		{
			string text = TargetCreaturesEntry.Value ?? "";
			if (text != parsedFrom)
			{
				HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
				string[] array = text.Split(new char[1] { ',' });
				for (int i = 0; i < array.Length; i++)
				{
					string text2 = array[i].Trim();
					if (text2.Length > 0)
					{
						hashSet.Add(text2);
					}
				}
				targetCreatures = hashSet;
				parsedFrom = text;
			}
			return targetCreatures.Contains(Utils.GetPrefabName(((Component)character).gameObject));
		}
	}
	internal static class ConfigSyncCompat
	{
		private static object configSync;

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void Initialize(string guid, string name, string version)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			configSync = (object)new ConfigSync(guid)
			{
				DisplayName = name,
				CurrentVersion = version,
				MinimumRequiredVersion = version,
				ModRequired = false,
				ModRequirementMode = (ModRequirementMode)1
			};
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void AddLockingConfigEntry(ConfigEntry<bool> entry)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			((ConditionalConfigSync)(ConfigSync)configSync).AddLockingConfigEntry<bool>(entry);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void AddConfigEntry<T>(ConfigEntry<T> entry, bool serverControlled)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			((ConditionalConfigSync)(ConfigSync)configSync).AddConfigEntry<T>(entry, (ConfigSyncMode)((!serverControlled) ? 2 : 0));
		}
	}
	internal class GrappleTargetFollower : MonoBehaviour
	{
		internal const string TargetKey = "EnemyGrapple_Target";

		internal const string OffsetKey = "EnemyGrapple_Offset";

		private ZNetView nview;

		private GrapplingPoint point;

		private ZDOID targetId = ZDOID.None;

		private Transform target;

		private Character targetCharacter;

		private Vector3 localOffset;

		private bool broken;

		private bool IsOwner
		{
			get
			{
				if ((Object)(object)nview != (Object)null && nview.IsValid())
				{
					return nview.IsOwner();
				}
				return false;
			}
		}

		private void Awake()
		{
			nview = ((Component)this).GetComponent<ZNetView>();
			point = ((Component)this).GetComponent<GrapplingPoint>();
		}

		public void Attach(Character character, Vector3 worldPoint)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			targetCharacter = character;
			target = ((Component)character).transform;
			targetId = character.GetZDOID();
			localOffset = target.InverseTransformPoint(worldPoint);
			if (IsOwner)
			{
				ZDO zDO = nview.GetZDO();
				zDO.Set("EnemyGrapple_Target", targetId);
				zDO.Set("EnemyGrapple_Offset", localOffset);
			}
		}

		public void Track(ZDOID id, Vector3 offset)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			targetId = id;
			localOffset = offset;
		}

		private bool Resolve()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (((ZDOID)(ref targetId)).IsNone() || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return false;
			}
			GameObject val = ZNetScene.instance.FindInstance(targetId);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			targetCharacter = val.GetComponent<Character>();
			target = val.transform;
			return true;
		}

		private void BreakGrapple()
		{
			if (!broken && !((Object)(object)point == (Object)null) && IsOwner)
			{
				broken = true;
				point.Break(true);
			}
		}

		private void LateUpdate()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (broken)
			{
				return;
			}
			if ((Object)(object)target == (Object)null && !Resolve())
			{
				BreakGrapple();
				return;
			}
			if ((Object)(object)targetCharacter != (Object)null && targetCharacter.IsDead())
			{
				BreakGrapple();
				return;
			}
			Vector3 position = target.TransformPoint(localOffset);
			((Component)this).transform.position = position;
			if (IsOwner)
			{
				nview.GetZDO().SetPosition(position);
			}
		}
	}
	[HarmonyPatch(typeof(Projectile), "OnHit")]
	internal static class GrappleHitPatch
	{
		private static readonly FieldRef<Projectile, Character> OwnerRef = AccessTools.FieldRefAccess<Projectile, Character>("m_owner");

		private static void Prefix(out GrapplingPoint __state)
		{
			__state = GrapplingPoint.m_localGrappler;
		}

		private static void Postfix(Projectile __instance, Collider collider, Vector3 hitPoint, GrapplingPoint __state)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!EnemyGrapple.Enabled || (Object)(object)collider == (Object)null)
				{
					return;
				}
				GameObject spawnOnHit = __instance.m_spawnOnHit;
				if ((Object)(object)spawnOnHit == (Object)null || (Object)(object)spawnOnHit.GetComponent<GrapplingPoint>() == (Object)null)
				{
					return;
				}
				Character val = OwnerRef.Invoke(__instance);
				if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
				{
					return;
				}
				GrapplingPoint localGrappler = GrapplingPoint.m_localGrappler;
				if (!((Object)(object)localGrappler != (Object)null) || !((Object)(object)localGrappler != (Object)(object)__state))
				{
					GameObject val2 = Projectile.FindHitObject(collider);
					Character val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<Character>() : null);
					if ((Object)(object)val3 == (Object)null)
					{
						val3 = ((Component)collider).GetComponentInParent<Character>();
					}
					if (!((Object)(object)val3 == (Object)null) && !val3.IsDead() && EnemyGrapple.IsTarget(val3))
					{
						GameObject obj = Object.Instantiate<GameObject>(spawnOnHit, hitPoint, Quaternion.identity);
						GrapplingPoint component = obj.GetComponent<GrapplingPoint>();
						obj.AddComponent<GrappleTargetFollower>().Attach(val3, hitPoint);
						component.Activate(val);
					}
				}
			}
			catch (Exception ex)
			{
				EnemyGrapple.Log.LogWarning((object)("Could not attach the grappling hook: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(GrapplingPoint), "Awake")]
	internal static class RemoteGrapplePatch
	{
		private static void Postfix(GrapplingPoint __instance)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid() && !component.IsOwner() && !((Object)(object)((Component)__instance).GetComponent<GrappleTargetFollower>() != (Object)null))
			{
				ZDO zDO = component.GetZDO();
				ZDOID zDOID = zDO.GetZDOID("EnemyGrapple_Target");
				if (!((ZDOID)(ref zDOID)).IsNone())
				{
					((Component)__instance).gameObject.AddComponent<GrappleTargetFollower>().Track(zDOID, zDO.GetVec3("EnemyGrapple_Offset", Vector3.zero));
				}
			}
		}
	}
}