Decompiled source of FishCam v1.0.0

FishCam.dll

Decompiled 3 days ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
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: AssemblyTitle("FishCam")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: AssemblyProduct("FishCam")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("E0B05DDB-285E-4F36-B8B5-BA1301B6E6D9")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 FishCam
{
	internal static class FishCamController
	{
		private enum Phase
		{
			Inactive,
			Projectile,
			Fish,
			Return
		}

		private const float SlowTimeScale = 0.15f;

		private const float FishDuration = 3f;

		private const float ReturnDuration = 0.6f;

		private const float ProjectileBackOffset = 1.4f;

		private const float ProjectileSideOffset = 0.5f;

		private const float ProjectileUpOffset = 0.35f;

		private const float PredictionRange = 600f;

		private static Phase phase;

		private static Projectile? projectile;

		private static Creature? predictedCreature;

		private static Player? player;

		private static Transform? gameplayCamera;

		private static Transform? renderedCamera;

		private static Transform? fishTarget;

		private static Vector3 fishLocalHitPoint;

		private static Vector3 fishCameraOffset;

		private static Vector3 cameraPosition;

		private static Quaternion cameraRotation;

		private static Vector3 returnPosition;

		private static Quaternion returnRotation;

		private static float phaseStartTime;

		private static float lastTriggerTime = float.NegativeInfinity;

		private static float previousTimeScale = 1f;

		private static bool timeScaleOverridden;

		internal static bool Active => phase != Phase.Inactive;

		internal static bool BlockPlayerInputs
		{
			get
			{
				Phase phase = FishCamController.phase;
				if ((uint)(phase - 1) <= 1u)
				{
					return true;
				}
				return false;
			}
		}

		internal static void OnProjectileAdded(ProjectileManager manager, Projectile newProjectile)
		{
			//IL_0077: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if (!FishCamPlugin.IsEnabled || Active || !newProjectile.IsLocal || newProjectile.FromNpc || !Object.op_Implicit((Object)(object)newProjectile.Owner) || (Object)(object)newProjectile.Owner != (Object)(object)Player.LocalPlayer)
			{
				return;
			}
			ProjectileType type = manager.GetType(newProjectile.TypeId);
			if (type.IsHitScan || !TryPredictKill(newProjectile, type, out Creature creature, out Vector3 hitPoint))
			{
				return;
			}
			Transform camObject = newProjectile.Owner.CamObject;
			if (!Object.op_Implicit((Object)(object)camObject))
			{
				return;
			}
			float num = Vector3.Distance(camObject.position, hitPoint);
			if (!(num < FishCamPlugin.minimumDistance.Value) && !(Time.unscaledTime - lastTriggerTime < FishCamPlugin.cooldown.Value))
			{
				float value = FishCamPlugin.guaranteedDistance.Value;
				if (!(value > 0f) || !(num < value) || !(Random.value * 100f >= FishCamPlugin.triggerChance.Value))
				{
					projectile = newProjectile;
					predictedCreature = creature;
					AttachCameraProxy(newProjectile.Owner, camObject);
					cameraPosition = camObject.position;
					cameraRotation = camObject.rotation;
					previousTimeScale = Time.timeScale;
					Time.timeScale = 0.15f;
					timeScaleOverridden = true;
					phase = Phase.Projectile;
					phaseStartTime = Time.unscaledTime;
					lastTriggerTime = phaseStartTime;
					FishCamPlugin.FishCamLogger.LogInfo((object)("FishCam predicted a lethal shot on '" + ((Object)creature).name + "'."));
				}
			}
		}

		internal static void OnProjectileRemoved(Projectile removedProjectile)
		{
			if (phase == Phase.Projectile && projectile == removedProjectile)
			{
				BeginReturn();
			}
		}

		internal static void OnCreatureKilled(Creature creature, Player player, Vector3 hitPoint)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (phase == Phase.Projectile && !((Object)(object)creature != (Object)(object)predictedCreature) && Object.op_Implicit((Object)(object)player) && !((Object)(object)player != (Object)(object)Player.LocalPlayer))
			{
				fishTarget = ((Component)creature).transform;
				fishLocalHitPoint = fishTarget.InverseTransformPoint(hitPoint);
				fishCameraOffset = cameraPosition - hitPoint;
				projectile = null;
				predictedCreature = null;
				RestoreTimeScale();
				phase = Phase.Fish;
				phaseStartTime = Time.unscaledTime;
				FishCamPlugin.FishCamLogger.LogInfo((object)("FishCam impact handoff: '" + ((Object)creature).name + "'."));
			}
		}

		internal static void UpdateCamera(PlayerCamera playerCamera)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00eb: 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)
			if (!Active)
			{
				return;
			}
			Transform camTransform = playerCamera.CamTransform;
			Vector3 position = camTransform.position;
			Quaternion rotation = camTransform.rotation;
			if (Object.op_Implicit((Object)(object)gameplayCamera))
			{
				gameplayCamera.SetPositionAndRotation(position, rotation);
			}
			switch (phase)
			{
			case Phase.Projectile:
				if (Time.unscaledTime - phaseStartTime >= FishCamPlugin.maximumFlightTime.Value)
				{
					BeginReturn();
				}
				else
				{
					UpdateProjectileCamera();
				}
				break;
			case Phase.Fish:
				UpdateFishCamera();
				if (Time.unscaledTime - phaseStartTime >= 3f)
				{
					BeginReturn();
				}
				break;
			case Phase.Return:
			{
				float num = Mathf.Clamp01((Time.unscaledTime - phaseStartTime) / 0.6f);
				cameraPosition = Vector3.Lerp(returnPosition, position, SmoothStep(num));
				cameraRotation = Quaternion.Slerp(returnRotation, rotation, SmoothStep(num));
				if (num >= 1f)
				{
					Stop();
					return;
				}
				break;
			}
			}
			camTransform.SetPositionAndRotation(cameraPosition, cameraRotation);
		}

		internal static void Stop()
		{
			RestoreTimeScale();
			phase = Phase.Inactive;
			projectile = null;
			predictedCreature = null;
			fishTarget = null;
			DetachCameraProxy();
		}

		private static bool TryPredictKill(Projectile shot, ProjectileType type, out Creature creature, out Vector3 hitPoint)
		{
			//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_0008: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0097: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = shot.Position;
			Vector3 val2 = shot.Velocity;
			float num2;
			RaycastHit val3 = default(RaycastHit);
			for (float num = 0f; num < 600f; num += num2)
			{
				if (!(val.y >= WaterManager.WaterHeight - 0.5f))
				{
					break;
				}
				num2 = ((Vector3)(ref val2)).magnitude * Time.fixedDeltaTime;
				if (Physics.SphereCast(val, type.WidthRadius, val2, ref val3, num2, LayerMask.op_Implicit(GameInfo.ProjectileHitLayer)))
				{
					Item obj = ItemManager.Get(((RaycastHit)(ref val3)).collider);
					hitPoint = ((RaycastHit)(ref val3)).point;
					Creature val4 = (Creature)(object)((obj is Creature) ? obj : null);
					if (val4 != null && val4._localHp > 0 && shot.Damage >= val4._localHp)
					{
						creature = val4;
						return true;
					}
					creature = null;
					return false;
				}
				val += val2 * Time.fixedDeltaTime;
				val2 += Vector3.down * (shot.GravityForce * Time.fixedDeltaTime);
			}
			creature = null;
			hitPoint = default(Vector3);
			return false;
		}

		private static void UpdateProjectileCamera()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_004e: 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_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)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			if (projectile == null)
			{
				BeginReturn();
				return;
			}
			Vector3 val = ((((Vector3)(ref projectile.Velocity)).sqrMagnitude > 0.001f) ? ((Vector3)(ref projectile.Velocity)).normalized : Vector3.forward);
			Vector3 val2 = Vector3.Cross(Vector3.up, val);
			Vector3 normalized = ((Vector3)(ref val2)).normalized;
			Vector3 val3 = projectile.Position - val * 1.4f + normalized * 0.5f + Vector3.up * 0.35f;
			float num = 1f - Mathf.Exp(-10f * Time.unscaledDeltaTime);
			cameraPosition = Vector3.Lerp(cameraPosition, val3, num);
			cameraRotation = Quaternion.LookRotation(projectile.Position + val * 4f - cameraPosition, Vector3.up);
		}

		private static void UpdateFishCamera()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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)
			//IL_0022: 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_0044: 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)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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 (!Object.op_Implicit((Object)(object)fishTarget))
			{
				BeginReturn();
				return;
			}
			Vector3 val = fishTarget.TransformPoint(fishLocalHitPoint);
			Vector3 val2 = val + fishCameraOffset;
			float num = 1f - Mathf.Exp(-6f * Time.unscaledDeltaTime);
			cameraPosition = Vector3.Lerp(cameraPosition, val2, num);
			Vector3 val3 = val - cameraPosition;
			if (((Vector3)(ref val3)).sqrMagnitude > 0.001f)
			{
				cameraRotation = Quaternion.LookRotation(val3, Vector3.up);
			}
		}

		private static void BeginReturn()
		{
			//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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (Active && phase != Phase.Return)
			{
				RestoreTimeScale();
				returnPosition = cameraPosition;
				returnRotation = cameraRotation;
				phase = Phase.Return;
				phaseStartTime = Time.unscaledTime;
				projectile = null;
				predictedCreature = null;
				fishTarget = null;
			}
		}

		private static void RestoreTimeScale()
		{
			if (timeScaleOverridden)
			{
				Time.timeScale = previousTimeScale;
				timeScaleOverridden = false;
			}
		}

		private static void AttachCameraProxy(Player targetPlayer, Transform cameraTransform)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			DetachCameraProxy();
			player = targetPlayer;
			renderedCamera = cameraTransform;
			gameplayCamera = new GameObject("FishCam Gameplay Camera").transform;
			gameplayCamera.SetPositionAndRotation(cameraTransform.position, cameraTransform.rotation);
			targetPlayer.CamObject = gameplayCamera;
		}

		private static void DetachCameraProxy()
		{
			if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)renderedCamera) && (Object)(object)player.CamObject == (Object)(object)gameplayCamera)
			{
				player.CamObject = renderedCamera;
			}
			if (Object.op_Implicit((Object)(object)gameplayCamera))
			{
				Object.Destroy((Object)(object)((Component)gameplayCamera).gameObject);
			}
			player = null;
			gameplayCamera = null;
			renderedCamera = null;
		}

		private static float SmoothStep(float value)
		{
			return value * value * (3f - 2f * value);
		}
	}
	[BepInPlugin("Azumatt.FishCam", "FishCam", "1.0.0")]
	public class FishCamPlugin : BaseUnityPlugin
	{
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		internal const string ModName = "FishCam";

		internal const string ModVersion = "1.0.0";

		internal const string Author = "Azumatt";

		private const string ModGUID = "Azumatt.FishCam";

		private const string ConfigFileName = "Azumatt.FishCam.cfg";

		private static readonly string ConfigFileFullPath;

		internal static readonly ManualLogSource FishCamLogger;

		private readonly Harmony harmony = new Harmony("Azumatt.FishCam");

		private FileSystemWatcher? configWatcher;

		internal static ConfigEntry<Toggle> modEnabled;

		internal static ConfigEntry<float> minimumDistance;

		internal static ConfigEntry<float> cooldown;

		internal static ConfigEntry<float> triggerChance;

		internal static ConfigEntry<float> guaranteedDistance;

		internal static ConfigEntry<float> maximumFlightTime;

		internal static bool IsEnabled
		{
			get
			{
				ConfigEntry<Toggle> val = modEnabled;
				if (val != null)
				{
					return val.Value == Toggle.On;
				}
				return false;
			}
		}

		public void Awake()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			modEnabled = config("1 - General", "Enabled", Toggle.On, "Turn the whole mod off without unloading it.");
			minimumDistance = config("1 - General", "Minimum Distance", 20f, new ConfigDescription("Minimum shot distance required to trigger FishCam.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
			cooldown = config("1 - General", "Cooldown", 25f, new ConfigDescription("Minimum real-time seconds between FishCam sequences.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 300f), Array.Empty<object>()));
			triggerChance = config("1 - General", "Trigger Chance", 40f, new ConfigDescription("Chance for an eligible kill to trigger FishCam.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			guaranteedDistance = config("1 - General", "Guaranteed Distance", 60f, new ConfigDescription("Shots at or beyond this distance ignore Trigger Chance. Set to 0 to guarantee every eligible shot.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1000f), Array.Empty<object>()));
			maximumFlightTime = config("1 - General", "Maximum Flight Time", 8f, new ConfigDescription("Maximum real-time seconds FishCam will follow a projectile.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
			harmony.PatchAll();
			SetupWatcher();
			if (saveOnConfigSet)
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet;
				((BaseUnityPlugin)this).Config.Save();
			}
		}

		private void Update()
		{
			if (!IsEnabled)
			{
				FishCamController.Stop();
			}
		}

		private void OnDestroy()
		{
			FishCamController.Stop();
			configWatcher?.Dispose();
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			configWatcher = new FileSystemWatcher(Paths.ConfigPath, "Azumatt.FishCam.cfg");
			configWatcher.Changed += ReadConfigValues;
			configWatcher.Created += ReadConfigValues;
			configWatcher.Renamed += ReadConfigValues;
			configWatcher.IncludeSubdirectories = true;
			configWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			configWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				FishCamLogger.LogError((object)"There was an issue loading your Azumatt.FishCam.cfg");
				FishCamLogger.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description)
		{
			return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description);
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		static FishCamPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + "Azumatt.FishCam.cfg";
			FishCamLogger = Logger.CreateLogSource("FishCam");
			modEnabled = null;
			minimumDistance = null;
			cooldown = null;
			triggerChance = null;
			guaranteedDistance = null;
			maximumFlightTime = null;
		}
	}
	internal static class Patches
	{
		[HarmonyPatch(typeof(Creature), "LocalHit")]
		internal static class CreatureLocalHitPatch
		{
			private static void Prefix(Creature __instance, ref int __state)
			{
				__state = __instance._localHp;
			}

			private static void Postfix(Creature __instance, Vector3 point, Player player, bool rangedHit, bool fromNpc, int __state)
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				if (!(__state <= 0 || __instance._localHp > 0 || !rangedHit || fromNpc) && Object.op_Implicit((Object)(object)player) && !((Object)(object)player != (Object)(object)Player.LocalPlayer))
				{
					FishCamController.OnCreatureKilled(__instance, player, point);
				}
			}
		}

		[HarmonyPatch(typeof(ProjectileManager), "AddProjectile")]
		internal static class ProjectileAdded
		{
			private static void Prefix(ProjectileManager __instance, WeaponInfo weaponInfo, ref int __state)
			{
				__state = __instance.GetType(weaponInfo.ProjectileType).Projectiles.Count;
			}

			private static void Postfix(ProjectileManager __instance, WeaponInfo weaponInfo, int __state)
			{
				ProjectileType type = __instance.GetType(weaponInfo.ProjectileType);
				if (type.Projectiles.Count > __state)
				{
					FishCamController.OnProjectileAdded(__instance, type.Projectiles[type.Projectiles.Count - 1]);
				}
			}
		}

		[HarmonyPatch(typeof(ProjectileManager), "RemoveQueued")]
		internal static class ProjectileRemoved
		{
			private static void Prefix(ProjectileType type)
			{
				foreach (Projectile item in type.ProjectilesToRemove)
				{
					FishCamController.OnProjectileRemoved(item);
				}
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		internal static class PlayerBlockInputs
		{
			private static void Postfix(Player __instance, ref bool __result)
			{
				if ((Object)(object)__instance == (Object)(object)Player.LocalPlayer && FishCamController.BlockPlayerInputs)
				{
					__result = true;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerCamera), "SetCamPosRot")]
		internal static class PlayerCameraSetCamPosRotPatch
		{
			private static void Postfix(PlayerCamera __instance)
			{
				FishCamController.UpdateCamera(__instance);
			}
		}
	}
}