Decompiled source of FishTracker v1.1.0

FishTracker.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Koendertjh.Shared;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[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("FishTracker")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+f7ba504173c8baf3016192861cacfb2a4bba9570")]
[assembly: AssemblyProduct("FishTracker")]
[assembly: AssemblyTitle("FishTracker")]
[assembly: AssemblyVersion("1.1.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 Koendertjh.Shared
{
	internal static class AchievementStats
	{
		private static readonly Dictionary<object, KeyValuePair<int, HashSet<string>>> s_keys = new Dictionary<object, KeyValuePair<int, HashSet<string>>>();

		internal static Achievement Find(string id)
		{
			if ((Object)(object)Achievements.m_instance == (Object)null)
			{
				return null;
			}
			foreach (AchievementList achievementList in Achievements.m_instance.m_achievementLists)
			{
				foreach (Achievement achievement in achievementList.m_achievements)
				{
					if ((Object)(object)achievement != (Object)null && achievement.m_id == id)
					{
						return achievement;
					}
				}
			}
			return null;
		}

		internal static PlayerStats StatsFor(Achievement achievement)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			Game instance = Game.instance;
			PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null);
			if (val == null || (Object)(object)achievement == (Object)null)
			{
				return null;
			}
			return val.m_playerStats[achievement.m_difficultyRequirement];
		}

		internal static HashSet<string> Keys(List<DictStatRequirement> triggers)
		{
			//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_0047: Unknown result type (might be due to invalid IL or missing references)
			if (triggers == null)
			{
				return new HashSet<string>();
			}
			if (s_keys.TryGetValue(triggers, out var value) && value.Key == triggers.Count)
			{
				return value.Value;
			}
			HashSet<string> hashSet = new HashSet<string>();
			foreach (DictStatRequirement trigger in triggers)
			{
				hashSet.Add(trigger.m_stat);
			}
			s_keys[triggers] = new KeyValuePair<int, HashSet<string>>(triggers.Count, hashSet);
			return hashSet;
		}

		internal static HashSet<string> Keys(List<EnemyStatRequirement> triggers)
		{
			//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_0047: Unknown result type (might be due to invalid IL or missing references)
			if (triggers == null)
			{
				return new HashSet<string>();
			}
			if (s_keys.TryGetValue(triggers, out var value) && value.Key == triggers.Count)
			{
				return value.Value;
			}
			HashSet<string> hashSet = new HashSet<string>();
			foreach (EnemyStatRequirement trigger in triggers)
			{
				hashSet.Add(trigger.m_stat);
			}
			s_keys[triggers] = new KeyValuePair<int, HashSet<string>>(triggers.Count, hashSet);
			return hashSet;
		}

		internal static bool Has(Dictionary<string, float> stats, string key)
		{
			if (stats != null && stats.TryGetValue(key, out var value))
			{
				return value >= 1f;
			}
			return false;
		}

		internal static int CountDone(HashSet<string> keys, Dictionary<string, float> stats)
		{
			int num = 0;
			foreach (string key in keys)
			{
				if (Has(stats, key))
				{
					num++;
				}
			}
			return num;
		}
	}
}
namespace FishTracker
{
	[HarmonyPatch]
	internal static class Chum
	{
		private const string PrefabPrefix = "Chum_";

		private const string TetraPrefab = "Fish4_cave";

		private static GameObject s_holder;

		private static readonly Dictionary<GameObject, GameObject> s_chums = new Dictionary<GameObject, GameObject>();

		private static readonly Dictionary<string, string> s_baitOf = new Dictionary<string, string>();

		private static readonly List<Recipe> s_recipes = new List<Recipe>();

		internal static string BaitOf(string chumName)
		{
			if (!s_baitOf.TryGetValue(chumName, out var value))
			{
				return null;
			}
			return value;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private static void ObjectDBAwake(ObjectDB __instance)
		{
			AddToObjectDB(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		private static void ObjectDBCopy(ObjectDB __instance)
		{
			if (AddToObjectDB(__instance))
			{
				AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null).Invoke(__instance, null);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		private static void ZNetSceneAwake(ZNetScene __instance)
		{
			if (!FishTrackerPlugin.ChumEnabled.Value)
			{
				return;
			}
			CreateChums(__instance.m_prefabs);
			foreach (GameObject key in s_chums.Keys)
			{
				if (!__instance.m_prefabs.Contains(key))
				{
					__instance.m_prefabs.Add(key);
				}
			}
		}

		private static bool AddToObjectDB(ObjectDB db)
		{
			if (!FishTrackerPlugin.ChumEnabled.Value || db.m_items == null || db.m_items.Count == 0)
			{
				return false;
			}
			CreateChums(db.m_items);
			bool result = false;
			foreach (GameObject key in s_chums.Keys)
			{
				if (!db.m_items.Contains(key))
				{
					db.m_items.Add(key);
					result = true;
				}
			}
			foreach (Recipe s_recipe in s_recipes)
			{
				if (!db.m_recipes.Contains(s_recipe))
				{
					db.m_recipes.Add(s_recipe);
				}
			}
			return result;
		}

		private static void CreateChums(List<GameObject> prefabs)
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Expected O, but got Unknown
			if ((Object)(object)s_holder != (Object)null)
			{
				return;
			}
			List<GameObject> list = new List<GameObject>();
			foreach (GameObject prefab in prefabs)
			{
				Fish val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Fish>() : null);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				foreach (BaitSetting bait in val.m_baits)
				{
					if ((Object)(object)bait.m_bait != (Object)null && !list.Contains(((Component)bait.m_bait).gameObject))
					{
						list.Add(((Component)bait.m_bait).gameObject);
					}
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			s_holder = new GameObject("FishTracker_Chum");
			s_holder.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)s_holder);
			foreach (GameObject item in list)
			{
				GameObject val2 = Object.Instantiate<GameObject>(item, s_holder.transform);
				((Object)val2).name = "Chum_" + ((Object)item).name;
				SharedData shared = item.GetComponent<ItemDrop>().m_itemData.m_shared;
				SharedData shared2 = val2.GetComponent<ItemDrop>().m_itemData.m_shared;
				shared2.m_name = ChumName(shared.m_name);
				shared2.m_description = "Bait, mashed up and ready to throw into the water. Use it while facing the water and the fish that take this bait come to you.";
				shared2.m_itemType = (ItemType)1;
				shared2.m_ammoType = "";
				shared2.m_maxStackSize = 20;
				s_chums[val2] = item;
				s_baitOf[shared2.m_name] = shared.m_name;
				Recipe val3 = ScriptableObject.CreateInstance<Recipe>();
				((Object)val3).name = "Recipe_" + ((Object)val2).name;
				val3.m_item = val2.GetComponent<ItemDrop>();
				val3.m_amount = 1;
				val3.m_enabled = true;
				val3.m_minStationLevel = 1;
				val3.m_resources = (Requirement[])(object)new Requirement[1]
				{
					new Requirement
					{
						m_resItem = item.GetComponent<ItemDrop>(),
						m_amount = FishTrackerPlugin.BaitPerChum.Value,
						m_recover = true
					}
				};
				s_recipes.Add(val3);
			}
			FishTrackerPlugin.Log.LogInfo((object)$"Added {s_chums.Count} kinds of chum.");
		}

		private static string ChumName(string baitName)
		{
			string text = ((Localization.instance != null) ? Localization.instance.Localize(baitName) : baitName);
			if (text.StartsWith("$"))
			{
				return "Chum";
			}
			if (!text.Contains("Fishing Bait"))
			{
				return text + " Chum";
			}
			return text.Replace("Fishing Bait", "Chum");
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Humanoid), "UseItem")]
		private static bool UseItem(Humanoid __instance, Inventory inventory, ItemData item)
		{
			if (item?.m_shared == null || !s_baitOf.TryGetValue(item.m_shared.m_name, out var value) || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			Player localPlayer = Player.m_localPlayer;
			if (inventory == null)
			{
				inventory = ((Humanoid)localPlayer).GetInventory();
			}
			if (TrySpawnFish(localPlayer, value))
			{
				inventory.RemoveOneItem(item);
			}
			return false;
		}

		private static bool TrySpawnFish(Player player, string bait)
		{
			//IL_0022: 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_0028: 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)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_00bb: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			if (!FindWater(player, out var point, out var waterLevel))
			{
				((Character)player).Message((MessageType)2, "Face deeper water to throw the chum in.", 0, (Sprite)null, false);
				return false;
			}
			Biome biome = WorldGenerator.instance.GetBiome(point);
			List<FishInfo> list = new List<FishInfo>();
			foreach (FishInfo item in FishData.All)
			{
				if (item.Baits.ContainsKey(bait) && LivesIn(item, biome))
				{
					list.Add(item);
				}
			}
			if (list.Count == 0)
			{
				((Character)player).Message((MessageType)2, "No fish here take this chum. Try another biome.", 0, (Sprite)null, false);
				return false;
			}
			Vector3 val2 = default(Vector3);
			for (int i = 0; i < FishTrackerPlugin.FishPerChum.Value; i++)
			{
				FishInfo fishInfo = Pick(list, bait);
				Vector2 val = Random.insideUnitCircle * 3f;
				((Vector3)(ref val2))..ctor(point.x + val.x, waterLevel - 1f, point.z + val.y);
				GameObject val3 = Object.Instantiate<GameObject>(fishInfo.Prefab, val2, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f));
				int num = RollLevel();
				if (num > 1)
				{
					ItemDrop component = val3.GetComponent<ItemDrop>();
					if (component != null)
					{
						component.SetQuality(num);
					}
				}
			}
			((Character)player).Message((MessageType)2, "The water stirs...", 0, (Sprite)null, false);
			return true;
		}

		private static bool LivesIn(FishInfo fish, Biome biome)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			if ((fish.Biomes & biome) == 0)
			{
				if ((int)biome == 64 && FishTrackerPlugin.TetraInDeepNorth.Value)
				{
					return ((Object)fish.Prefab).name == "Fish4_cave";
				}
				return false;
			}
			return true;
		}

		private static bool FindWater(Player player, out Vector3 point, out float waterLevel)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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)
			Vector3 forward = ((Component)player).transform.forward;
			forward.y = 0f;
			((Vector3)(ref forward)).Normalize();
			for (float num = 4f; num <= 14f; num += 2f)
			{
				point = ((Component)player).transform.position + forward * num;
				waterLevel = Floating.GetLiquidLevel(point, 1f, (LiquidType)0);
				float groundHeight = ZoneSystem.instance.GetGroundHeight(point);
				if (waterLevel - groundHeight >= 2f)
				{
					return true;
				}
			}
			point = Vector3.zero;
			waterLevel = 0f;
			return false;
		}

		private static FishInfo Pick(List<FishInfo> candidates, string bait)
		{
			float num = 0f;
			float[] array = new float[candidates.Count];
			for (int i = 0; i < candidates.Count; i++)
			{
				float num2 = Mathf.Max(0.05f, candidates[i].Baits[bait]);
				if (!FishData.IsCaught(candidates[i]))
				{
					num2 *= FishTrackerPlugin.UncaughtWeight.Value;
				}
				array[i] = num2;
				num += num2;
			}
			float num3 = Random.Range(0f, num);
			for (int j = 0; j < candidates.Count; j++)
			{
				num3 -= array[j];
				if (num3 <= 0f)
				{
					return candidates[j];
				}
			}
			return candidates[candidates.Count - 1];
		}

		private static int RollLevel()
		{
			int i;
			for (i = 1; i < FishTrackerPlugin.MaxLevel.Value; i++)
			{
				if (!(Random.value < FishTrackerPlugin.LevelUpChance.Value))
				{
					break;
				}
			}
			return i;
		}
	}
	internal class FishInfo
	{
		public GameObject Prefab;

		public Fish Fish;

		public string ItemName;

		public Biome Biomes;

		public readonly Dictionary<string, float> Baits = new Dictionary<string, float>();
	}
	internal static class FishData
	{
		internal const string FishermanId = "GrindFish";

		private static readonly List<FishInfo> NoFish = new List<FishInfo>();

		private static List<FishInfo> s_fish;

		private static readonly Dictionary<string, FishInfo> s_byItem = new Dictionary<string, FishInfo>();

		private static readonly Dictionary<string, List<FishInfo>> s_byBait = new Dictionary<string, List<FishInfo>>();

		private static bool s_biomesLoaded;

		private static float s_nextBiomeTry;

		private static Achievement s_fisherman;

		internal static Achievement Fisherman
		{
			get
			{
				if (!((Object)(object)s_fisherman != (Object)null))
				{
					return s_fisherman = AchievementStats.Find("GrindFish");
				}
				return s_fisherman;
			}
		}

		internal static List<FishInfo> All
		{
			get
			{
				if (s_fish == null || s_fish.Count == 0)
				{
					Build();
				}
				if (!s_biomesLoaded && Time.time >= s_nextBiomeTry)
				{
					s_nextBiomeTry = Time.time + 5f;
					LoadBiomes();
				}
				return s_fish;
			}
		}

		internal static bool IsCaught(FishInfo fish)
		{
			return AchievementStats.Has(AchievementStats.StatsFor(Fisherman)?.m_pickableStats, fish.Fish.m_name);
		}

		internal static FishInfo ByItemName(string itemName)
		{
			if (All.Count == 0)
			{
				return null;
			}
			s_byItem.TryGetValue(itemName, out var value);
			return value;
		}

		internal static List<FishInfo> BitersOf(string baitName)
		{
			if (All.Count == 0)
			{
				return NoFish;
			}
			if (!s_byBait.TryGetValue(baitName, out var value))
			{
				return NoFish;
			}
			return value;
		}

		internal static int CaughtCount()
		{
			return AchievementStats.CountDone(AchievementStats.Keys(Fisherman?.m_pickableTriggers), AchievementStats.StatsFor(Fisherman)?.m_pickableStats);
		}

		internal static int TotalCount()
		{
			return AchievementStats.Keys(Fisherman?.m_pickableTriggers).Count;
		}

		private static void Build()
		{
			s_fish = new List<FishInfo>();
			s_byItem.Clear();
			s_byBait.Clear();
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				Fish val = (((Object)(object)item != (Object)null) ? item.GetComponent<Fish>() : null);
				ItemDrop val2 = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
				{
					continue;
				}
				FishInfo fishInfo = new FishInfo
				{
					Prefab = item,
					Fish = val,
					ItemName = val2.m_itemData.m_shared.m_name
				};
				foreach (BaitSetting bait in val.m_baits)
				{
					if ((Object)(object)bait.m_bait != (Object)null)
					{
						fishInfo.Baits[bait.m_bait.m_itemData.m_shared.m_name] = bait.m_chance;
					}
				}
				s_fish.Add(fishInfo);
				s_byItem[fishInfo.ItemName] = fishInfo;
				foreach (string key in fishInfo.Baits.Keys)
				{
					if (!s_byBait.TryGetValue(key, out var value))
					{
						value = (s_byBait[key] = new List<FishInfo>());
					}
					value.Add(fishInfo);
				}
			}
			s_biomesLoaded = false;
		}

		private static void LoadBiomes()
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			SpawnSystemList[] array = Resources.FindObjectsOfTypeAll<SpawnSystemList>();
			if (array.Length == 0)
			{
				return;
			}
			s_biomesLoaded = true;
			SpawnSystemList[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				foreach (SpawnData spawn in array2[i].m_spawners)
				{
					if (!((Object)(object)spawn?.m_prefab == (Object)null) && spawn.m_enabled)
					{
						FishInfo fishInfo = s_fish.Find((FishInfo f) => ((Object)f.Prefab).name == ((Object)spawn.m_prefab).name);
						if (fishInfo != null)
						{
							fishInfo.Biomes |= spawn.m_biome;
						}
					}
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class FishingIndicator
	{
		private const float HookWindow = 0.5f;

		private static readonly Color WaitColor = new Color(0.85f, 0.85f, 0.85f, 0.8f);

		private static readonly Color PullColor = new Color(0.4f, 1f, 0.4f, 1f);

		private static readonly Color HoldColor = new Color(1f, 0.35f, 0.3f, 1f);

		private static readonly FieldRef<FishingFloat, Fish> s_nibbler = AccessTools.FieldRefAccess<FishingFloat, Fish>("m_nibbler");

		private static readonly FieldRef<FishingFloat, float> s_nibbleTime = AccessTools.FieldRefAccess<FishingFloat, float>("m_nibbleTime");

		private static readonly FieldRef<FishingFloat, ZNetView> s_floatView = AccessTools.FieldRefAccess<FishingFloat, ZNetView>("m_nview");

		private static TMP_Text s_label;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Hud), "Awake")]
		private static void HudAwake(Hud __instance)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_004e: 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_005a: 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)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = ((Graphic)__instance.m_crosshair).rectTransform;
			GameObject val = new GameObject("FishTracker_FishingIndicator", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(((Transform)rectTransform).parent, false);
			val2.anchorMin = rectTransform.anchorMin;
			val2.anchorMax = rectTransform.anchorMax;
			val2.pivot = new Vector2(0.5f, 1f);
			val2.sizeDelta = new Vector2(400f, 40f);
			val2.anchoredPosition = rectTransform.anchoredPosition + new Vector2(0f, -40f);
			s_label = (TMP_Text)(object)val.GetComponent<TextMeshProUGUI>();
			s_label.font = ((TMP_Text)__instance.m_hoverName).font;
			s_label.fontSharedMaterial = ((TMP_Text)__instance.m_hoverName).fontSharedMaterial;
			s_label.fontSize = 26f;
			s_label.fontStyle = (FontStyles)1;
			s_label.alignment = (TextAlignmentOptions)258;
			((Graphic)s_label).raycastTarget = false;
			val.SetActive(false);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Hud), "Update")]
		private static void HudUpdate()
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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)
			if ((Object)(object)s_label == (Object)null)
			{
				return;
			}
			FishingFloat val = (FishTrackerPlugin.FishingIndicator.Value ? FindLocalFloat() : null);
			if ((Object)(object)val == (Object)null || !val.IsInWater())
			{
				((Component)s_label).gameObject.SetActive(false);
				return;
			}
			Fish val2 = val.GetCatch();
			if ((Object)(object)val2 != (Object)null)
			{
				if (val2.IsEscaping())
				{
					Show("Fish is fighting, wait", HoldColor);
				}
				else
				{
					Show("Reel in", PullColor);
				}
			}
			else if ((Object)(object)s_nibbler.Invoke(val) != (Object)null && Time.time - s_nibbleTime.Invoke(val) < 0.5f)
			{
				Show("Bite! Reel in to hook it", PullColor);
			}
			else
			{
				Show("Wait for a bite", WaitColor);
			}
		}

		private static void Show(string text, Color color)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			s_label.text = text;
			((Graphic)s_label).color = color;
			((Component)s_label).gameObject.SetActive(true);
		}

		private static FishingFloat FindLocalFloat()
		{
			//IL_0012: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return null;
			}
			ZDOID zDOID = ((Character)localPlayer).GetZDOID();
			long userID = ((ZDOID)(ref zDOID)).UserID;
			foreach (FishingFloat allInstance in FishingFloat.GetAllInstances())
			{
				ZNetView val = s_floatView.Invoke(allInstance);
				if ((Object)(object)val != (Object)null && val.IsValid() && val.GetZDO().GetLong(ZDOVars.s_rodOwner, 0L) == userID)
				{
					return allInstance;
				}
			}
			return null;
		}
	}
	[HarmonyPatch]
	internal static class HandCatch
	{
		private static readonly HashSet<GameObject> s_rodCatches = new HashSet<GameObject>();

		[HarmonyPrefix]
		[HarmonyPatch(typeof(FishingFloat), "Catch")]
		private static void RodCatch(Fish fish)
		{
			s_rodCatches.RemoveWhere((GameObject go) => (Object)(object)go == (Object)null);
			if ((Object)(object)fish != (Object)null)
			{
				s_rodCatches.Add(((Component)fish).gameObject);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Humanoid), "Pickup")]
		private static void PickupPrefix(Humanoid __instance, GameObject go, out Fish __state)
		{
			__state = null;
			if (FishTrackerPlugin.HandCatchCounts.Value && !((Object)(object)go == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !s_rodCatches.Remove(go))
			{
				Fish component = go.GetComponent<Fish>();
				if ((Object)(object)component != (Object)null && (Object)(object)FishingFloat.FindFloat(component) != (Object)null)
				{
					__state = component;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Humanoid), "Pickup")]
		private static void PickupPostfix(bool __result, Fish __state)
		{
			if (__result && !((Object)(object)__state == (Object)null) && !((Object)(object)Game.instance == (Object)null))
			{
				Game.instance.GetPlayerProfile().IncrementStatPickable(__state.GetHoverName(), 1f, false);
				Game.instance.IncrementPlayerStat((PlayerStatType)160, 1f, false);
				ItemDrop component = ((Component)__state).GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null && component.m_itemData.m_quality <= 6)
				{
					Game.instance.IncrementPlayerStat((PlayerStatType)(161 + component.m_itemData.m_quality), 1f, false);
				}
			}
		}
	}
	[BepInPlugin("com.koendertjh.fishtracker", "FishTracker", "1.1.0")]
	public class FishTrackerPlugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.koendertjh.fishtracker";

		public const string ModName = "FishTracker";

		public const string ModVersion = "1.1.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> TooltipHints;

		internal static ConfigEntry<bool> HideUnknownFish;

		internal static ConfigEntry<bool> ChumEnabled;

		internal static ConfigEntry<int> BaitPerChum;

		internal static ConfigEntry<int> FishPerChum;

		internal static ConfigEntry<float> UncaughtWeight;

		internal static ConfigEntry<float> LevelUpChance;

		internal static ConfigEntry<int> MaxLevel;

		internal static ConfigEntry<bool> TetraInDeepNorth;

		internal static ConfigEntry<bool> FishingIndicator;

		internal static ConfigEntry<bool> HandCatchCounts;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			TooltipHints = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Tooltips", "TooltipHints", true, "Fish tooltips say when you haven't caught the fish yet; bait tooltips list the fish that bite on it.");
			HideUnknownFish = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Tooltips", "HideUnknownFish", false, "Bait tooltips show '???' for fish you have never had, instead of their name.");
			ChumEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Chum", "Enabled", true, "Add chum, crafted by hand from fishing bait. Needs a restart. Chum disappears from inventories and chests when this is off or the mod is removed.");
			BaitPerChum = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Chum", "BaitPerChum", 5, new ConfigDescription("Bait needed for one chum. Needs a restart.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
			FishPerChum = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Chum", "FishPerChum", 3, new ConfigDescription("Fish that show up for one chum.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
			UncaughtWeight = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Chum", "UncaughtWeight", 3f, new ConfigDescription("Fish you haven't caught yet are this many times more likely to show up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
			LevelUpChance = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Chum", "LevelUpChance", 0.25f, new ConfigDescription("Chance for a chum fish to gain a star, rolled again for each star.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			MaxLevel = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Chum", "MaxLevel", 4, new ConfigDescription("Highest fish level from chum. Level 4 (3 stars) is what A Catch Worthy of Njord needs.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), Array.Empty<object>()));
			TetraInDeepNorth = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Chum", "TetraInDeepNorth", false, "Chum can also bring Tetra (a Mountain fish) in the Deep North, where the snowy peaks count as Deep North instead of Mountain.");
			FishingIndicator = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Fishing", "Indicator", true, "Show under the crosshair when to reel in (block) while fishing: when a fish bites, and while a hooked fish is calm. Says to wait while a hooked fish fights, when reeling costs double stamina.");
			HandCatchCounts = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Fishing", "HandCatchCounts", false, "Picking up a fish by hand while it is hooked on a fishing line counts as catching it, like reeling it in: for The Fisherman, A Catch Worthy of Njord and the fish caught stats.");
			_harmony = new Harmony("com.koendertjh.fishtracker");
			_harmony.PatchAll(typeof(FishTrackerPlugin).Assembly);
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
	{
		typeof(ItemData),
		typeof(int),
		typeof(bool),
		typeof(float),
		typeof(int),
		typeof(bool)
	})]
	internal static class TooltipPatch
	{
		private const string HintColor = "#ffb347";

		private const string ProgressColor = "#a0a0a0";

		private static void Postfix(ItemData item, ref string __result)
		{
			if (!FishTrackerPlugin.TooltipHints.Value || item?.m_shared == null || (Object)(object)Game.instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			string name = item.m_shared.m_name;
			FishInfo fishInfo = FishData.ByItemName(name);
			if (fishInfo != null)
			{
				StringBuilder stringBuilder = new StringBuilder(__result);
				if (!FishData.IsCaught(fishInfo))
				{
					stringBuilder.Append("\n\n<color=#ffb347>You haven't caught this fish yet.</color>");
				}
				if ((Object)(object)FishData.Fisherman != (Object)null)
				{
					stringBuilder.Append("\n<color=#a0a0a0>" + Localization.instance.Localize(FishData.Fisherman.m_name) + ": " + $"{FishData.CaughtCount()} / {FishData.TotalCount()}</color>");
				}
				__result = stringBuilder.ToString();
				return;
			}
			List<FishInfo> list = FishData.BitersOf(Chum.BaitOf(name) ?? name);
			if (list.Count == 0)
			{
				return;
			}
			StringBuilder stringBuilder2 = new StringBuilder(__result);
			stringBuilder2.Append("\n\nFish that bite:");
			Player localPlayer = Player.m_localPlayer;
			foreach (FishInfo item2 in list)
			{
				bool flag = FishData.IsCaught(item2);
				string text = ((flag || ((Object)(object)localPlayer != (Object)null && localPlayer.IsMaterialKnown(item2.ItemName)) || !FishTrackerPlugin.HideUnknownFish.Value) ? Localization.instance.Localize(item2.Fish.m_name) : "???");
				stringBuilder2.Append(flag ? ("\n  " + text) : ("\n  <color=#ffb347>" + text + " (not caught yet)</color>"));
			}
			__result = stringBuilder2.ToString();
		}
	}
	internal static class PluginInfo
	{
		public const string Version = "1.1.0";
	}
}