Decompiled source of OdinNeverMisses v1.0.1

OdinNeverMisses.dll

Decompiled 2 weeks 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.Logging;
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("OdinNeverMisses")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+7b6d0a4acfa11a8861a4ffe159e00e207dcb6660")]
[assembly: AssemblyProduct("OdinNeverMisses")]
[assembly: AssemblyTitle("OdinNeverMisses")]
[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 OdinNeverMisses
{
	[HarmonyPatch]
	internal static class AimPatches
	{
		private static int s_solids;

		private static readonly List<float> s_distances = new List<float>();

		[HarmonyPatch(typeof(Attack), "GetProjectileSpawnPoint")]
		[HarmonyPostfix]
		[HarmonyAfter(new string[] { "algo7.mountedarchery" })]
		private static void AimAtCrosshair(Humanoid ___m_character, ItemData ___m_weapon, ref Vector3 spawnPoint, ref Vector3 aimDir)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0072: 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)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_00ec: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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)
			try
			{
				if (!Casts.IsOurCast(___m_character, ___m_weapon))
				{
					return;
				}
				GameCamera instance = GameCamera.instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				Player val = (Player)___m_character;
				IDoodadController doodadController = val.GetDoodadController();
				Sadle val2 = (Sadle)(object)((doodadController is Sadle) ? doodadController : null);
				Character mount = (((Object)(object)val2 != (Object)null) ? val2.GetCharacter() : null);
				if (s_solids == 0)
				{
					s_solids = LayerMask.GetMask(AimRules.SolidLayers);
				}
				Transform transform = ((Component)instance).transform;
				s_distances.Clear();
				RaycastHit[] array = Physics.RaycastAll(transform.position, transform.forward, 600f, s_solids);
				for (int i = 0; i < array.Length; i++)
				{
					RaycastHit val3 = array[i];
					if (!IsSkipped(((RaycastHit)(ref val3)).collider, val, mount))
					{
						s_distances.Add(((RaycastHit)(ref val3)).distance);
					}
				}
				Vector3 target = AimRules.TargetPoint(transform.position, transform.forward, spawnPoint, s_distances);
				aimDir = AimRules.AimDirection(spawnPoint, target, aimDir);
			}
			catch (Exception arg)
			{
				Plugin.ErrorOnce("aim", $"Aiming Lightning Strike at the crosshair failed (logged once; the game's aim is kept): {arg}");
			}
		}

		private static bool IsSkipped(Collider collider, Player player, Character mount)
		{
			Rigidbody attachedRigidbody = collider.attachedRigidbody;
			if ((Object)(object)attachedRigidbody != (Object)null && (Object)(object)((Component)attachedRigidbody).gameObject == (Object)(object)((Component)player).gameObject)
			{
				return true;
			}
			Character val = (((Object)(object)attachedRigidbody != (Object)null) ? ((Component)attachedRigidbody).GetComponent<Character>() : ((Component)collider).GetComponent<Character>());
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if ((Object)(object)val == (Object)(object)player || (Object)(object)val == (Object)(object)mount)
			{
				return true;
			}
			BaseAI baseAI = val.GetBaseAI();
			return AimRules.ShotPassesThrough(((Character)player).IsPVPEnabled(), BaseAI.IsEnemy((Character)(object)player, val), (Object)(object)baseAI != (Object)null && baseAI.IsAggravatable());
		}
	}
	internal static class AimRules
	{
		public const string StaffPrefab = "StaffThunderBlood";

		public const float RayLength = 600f;

		public const float MinBeyondStart = 1f;

		public static readonly string[] SolidLayers = new string[12]
		{
			"Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox",
			"character_noenv", "vehicle"
		};

		public static bool IsLightningStrike(string prefabName)
		{
			return prefabName == "StaffThunderBlood";
		}

		public static bool ShotPassesThrough(bool casterPvp, bool isEnemy, bool aggravatable)
		{
			if (!casterPvp && !isEnemy)
			{
				return !aggravatable;
			}
			return false;
		}

		public static Vector3 TargetPoint(Vector3 origin, Vector3 direction, Vector3 start, IEnumerable<float> hitDistances)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			float num = Vector3.Dot(start - origin, direction) + 1f;
			float num2 = 600f;
			foreach (float hitDistance in hitDistances)
			{
				if (hitDistance >= num && hitDistance < num2)
				{
					num2 = hitDistance;
				}
			}
			return origin + direction * num2;
		}

		public static Vector3 AimDirection(Vector3 start, Vector3 target, Vector3 fallback)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			Vector3 val = target - start;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (!(magnitude < 0.01f))
			{
				return val / magnitude;
			}
			return fallback;
		}
	}
	internal static class Casts
	{
		public static bool IsOurCast(Humanoid character, ItemData weapon)
		{
			if ((Object)(object)character != (Object)null && (Object)(object)character == (Object)(object)Player.m_localPlayer && weapon != null && (Object)(object)weapon.m_dropPrefab != (Object)null)
			{
				return AimRules.IsLightningStrike(((Object)weapon.m_dropPrefab).name);
			}
			return false;
		}
	}
	[BepInPlugin("algo7.odinnevermisses", "OdinNeverMisses", "1.0.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "algo7.odinnevermisses";

		public const string Name = "OdinNeverMisses";

		public const string PluginVersion = "1.0.1";

		internal static ManualLogSource Log;

		private static readonly HashSet<string> s_logged = new HashSet<string>();

		private void Awake()
		{
			//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_0041: Expected O, but got Unknown
			//IL_0066: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			if (Application.isBatchMode)
			{
				Log.LogInfo((object)"OdinNeverMisses loaded (v1.0.1): dedicated server, nothing to do");
				return;
			}
			Harmony val = new Harmony("algo7.odinnevermisses");
			if (!TryPatch(val, typeof(StraightPatches), "straight-shot hooks"))
			{
				Log.LogWarning((object)"Lightning Strike keeps its spread and arc");
			}
			if (!TryPatch(val, typeof(AimPatches), "crosshair hook"))
			{
				Log.LogWarning((object)"Lightning Strike flies along the look direction, not to the crosshair");
			}
			Log.LogInfo((object)"OdinNeverMisses loaded (v1.0.1)");
		}

		private static bool TryPatch(Harmony harmony, Type patches, string what)
		{
			try
			{
				harmony.PatchAll(patches);
				return true;
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Could not install the {what}: {arg}");
				return false;
			}
		}

		internal static void ErrorOnce(string kind, string message)
		{
			if (s_logged.Add(kind))
			{
				Log.LogError((object)message);
			}
		}
	}
	[HarmonyPatch]
	internal static class StraightPatches
	{
		private static bool s_launching;

		[HarmonyPatch(typeof(Attack), "FireProjectileBurst")]
		[HarmonyPrefix]
		private static void Steady(Attack __instance, Humanoid ___m_character, ItemData ___m_weapon)
		{
			s_launching = false;
			try
			{
				if (Casts.IsOurCast(___m_character, ___m_weapon))
				{
					__instance.m_projectileAccuracy = 0f;
					__instance.m_projectileAccuracyMin = 0f;
					__instance.m_launchAngle = 0f;
					s_launching = true;
				}
			}
			catch (Exception arg)
			{
				Plugin.ErrorOnce("straight", $"Steadying the Lightning Strike shot failed (logged once; the game's shot is kept): {arg}");
			}
		}

		[HarmonyPatch(typeof(Attack), "FireProjectileBurst")]
		[HarmonyFinalizer]
		private static void EndLaunch()
		{
			s_launching = false;
		}

		[HarmonyPatch(typeof(Projectile), "Setup")]
		[HarmonyPostfix]
		private static void NoGravity(Projectile __instance)
		{
			if (s_launching)
			{
				__instance.m_gravity = 0f;
			}
		}
	}
	internal static class PluginInfo
	{
		public const string Version = "1.0.1";
	}
}