Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Pathfinder v2.2.3
Pathfinder.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using ConditionalConfigSync; using HarmonyLib; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Pathfinder")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Crystal")] [assembly: AssemblyProduct("Pathfinder")] [assembly: AssemblyCopyright("Copyright © 2026 Crystal Ferrai")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("deb680b1-786f-4e93-8793-25e19b570fef")] [assembly: AssemblyFileVersion("2.2.3.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("2.2.3.0")] namespace Pathfinder; [BepInPlugin("dev.crystal.pathfinder", "Pathfinder", "2.2.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class PathfinderPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Minimap))] private static class Minimap_Patches { private enum TranspilerState { Searching, Checking, Finishing } [HarmonyPatch("UpdateExplore")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> UpdateExplore_Transpiler(IEnumerable<CodeInstruction> instructions) { TranspilerState state = TranspilerState.Searching; CodeInstruction previous = null; foreach (CodeInstruction instruction in instructions) { switch (state) { case TranspilerState.Searching: if (instruction.opcode == OpCodes.Ldarg_0) { previous = instruction; state = TranspilerState.Checking; } else { yield return instruction; } break; case TranspilerState.Checking: if (instruction.opcode == OpCodes.Ldfld && ((FieldInfo)instruction.operand).Name == "m_exploreRadius") { yield return new CodeInstruction(OpCodes.Ldarg_2, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)typeof(Minimap_Patches).GetMethod("GetExploreRadius", BindingFlags.Static | BindingFlags.NonPublic)); state = TranspilerState.Finishing; } else { yield return previous; yield return instruction; state = TranspilerState.Searching; } previous = null; break; case TranspilerState.Finishing: yield return instruction; break; } } } private static float GetExploreRadius(Player player) { //IL_0051: 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_00be: 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_0190: Unknown result type (might be due to invalid IL or missing references) float num; if (((Character)player).InInterior()) { num = Mathf.Max(LandExploreRadius.Value * 0.2f, 10f); sRadiusHudText.text = $"Pathfinder: radius={num:0.0}"; return num; } float num2 = 1f; List<Player> list = new List<Player>(); Player.GetPlayersInRange(((Component)player).transform.position, 21f, list); float num3 = ((!list.Any((Player p) => ((Character)p).IsAttachedToShip())) ? LandExploreRadius.Value : SeaExploreRadius.Value); float num4 = Mathf.Max(GetColorMagnitude(EnvMan.instance.m_dirLight.color * EnvMan.instance.m_dirLight.intensity), GetColorMagnitude(RenderSettings.ambientLight)); num2 += (num4 - 1f) * DaylightRadiusScale.Value; float num5 = 0f; GameObject[] psystems = EnvMan.instance.GetCurrentEnvironment().m_psystems; foreach (GameObject obj in psystems) { if (((Object)obj).name.Equals("Mist", StringComparison.InvariantCultureIgnoreCase)) { num5 += 0.5f; } if (((Object)obj).name.Equals("SnowStorm", StringComparison.InvariantCultureIgnoreCase)) { num5 += 0.7f * num4; } } float num7 = Mathf.Clamp(RenderSettings.fogDensity * 10f + num5, 0f, 1.5f); num2 -= num7 * WeatherRadiusScale.Value; float num8 = Mathf.Clamp(((Component)player).transform.position.y - ZoneSystem.instance.m_waterLevel, 0f, 400f) / 100f * Mathf.Max(0.05f, 1f - num5); num2 += num8 * AltitudeRadiusBonus.Value; float locationModifier = GetLocationModifier(player, num8); num2 += locationModifier; if (num2 > 5f) { num2 = 5f; } if (num2 < 0.2f) { num2 = 0.2f; } num = Mathf.Clamp(num3 * num2, MinimumRadius.Value, MaximumRadius.Value); if (DisplayVariables.Value) { sVariablesHudText.text = string.Format("Pathfinder Variables\nRadius: {0:0.0}\nBase: {1:0.#}\nMultiplier: {2:0.000}\n\nLight: {3}\nWeather: {4}\nAltitude: {5}\nLocation: {6}", num, num3, num2, ((num4 - 1f) * DaylightRadiusScale.Value).ToString("+0.000;-0.000;0.000"), ((0f - num7) * WeatherRadiusScale.Value).ToString("+0.000;-0.000;0.000"), (num8 * AltitudeRadiusBonus.Value).ToString("+0.000;-0.000;0.000"), locationModifier.ToString("+0.000;-0.000;0.000")); } if (DisplayCurrentRadiusValue.Value) { sRadiusHudText.text = $"Pathfinder: radius={num:0.0}"; } return num; } private static float GetColorMagnitude(Color color) { //IL_0000: 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_0013: 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_0021: Unknown result type (might be due to invalid IL or missing references) return Mathf.Sqrt(color.r * color.r + color.g * color.g + color.b * color.b); } private static float GetLocationModifier(Player player, float altitude) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_0053: 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_0030: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_006e: Unknown result type (might be due to invalid IL or missing references) float num = ForestRadiusPenalty.Value + altitude * AltitudeRadiusBonus.Value * ForestRadiusPenalty.Value; Biome currentBiome = player.GetCurrentBiome(); if ((int)currentBiome != 1) { if ((int)currentBiome != 8) { if ((int)currentBiome == 16) { return ((WorldGenerator.GetForestFactor(((Component)player).transform.position) < 0.8f) ? (0f - num) : 0f) + 0.1f * DaylightRadiusScale.Value; } return 0f; } return 0f - num - 0.25f * DaylightRadiusScale.Value; } if (!WorldGenerator.InForest(((Component)player).transform.position)) { return 0f; } return 0f - num; } } [HarmonyPatch(typeof(Hud))] private static class Hud_Patches { [HarmonyPatch("Awake")] [Harmony] [HarmonyPostfix] private static void Awake_Postfix(Hud __instance) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Pathfinder_RadiusText"); val.AddComponent<CanvasRenderer>(); val.transform.localPosition = Vector3.zero; RectTransform obj = val.AddComponent<RectTransform>(); ((Transform)obj).SetParent(__instance.m_rootObject.transform); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f, 0f); obj.anchorMax = val2; Vector2 pivot = (obj.anchorMin = val2); obj.pivot = pivot; obj.offsetMin = new Vector2(10f, 5f); obj.offsetMax = new Vector2(210f, 165f); sRadiusHudText = val.AddComponent<Text>(); ((Graphic)sRadiusHudText).raycastTarget = false; sRadiusHudText.font = Font.CreateDynamicFontFromOSFont(new string[3] { "Segoe UI", "Helvetica", "Arial" }, 12); sRadiusHudText.fontStyle = (FontStyle)1; ((Graphic)sRadiusHudText).color = Color.white; sRadiusHudText.fontSize = 12; sRadiusHudText.alignment = (TextAnchor)6; ((Shadow)val.AddComponent<Outline>()).effectColor = Color.black; val.SetActive(DisplayCurrentRadiusValue.Value); GameObject val4 = new GameObject("Pathfinder_VariableText"); val4.AddComponent<CanvasRenderer>(); val4.transform.localPosition = Vector3.zero; RectTransform obj2 = val4.AddComponent<RectTransform>(); ((Transform)obj2).SetParent(__instance.m_rootObject.transform); ((Vector2)(ref val2))..ctor(0f, 0f); obj2.anchorMax = val2; pivot = (obj2.anchorMin = val2); obj2.pivot = pivot; obj2.offsetMin = new Vector2(240f, 5f); obj2.offsetMax = new Vector2(440f, 165f); sVariablesHudText = val4.AddComponent<Text>(); ((Graphic)sVariablesHudText).raycastTarget = false; sVariablesHudText.font = Font.CreateDynamicFontFromOSFont(new string[3] { "Segoe UI", "Helvetica", "Arial" }, 12); sVariablesHudText.fontStyle = (FontStyle)1; ((Graphic)sVariablesHudText).color = Color.white; sVariablesHudText.fontSize = 12; sVariablesHudText.alignment = (TextAnchor)6; ((Shadow)val4.AddComponent<Outline>()).effectColor = Color.black; val4.SetActive(DisplayVariables.Value); } } public const string ModId = "dev.crystal.pathfinder"; public const string ModName = "Pathfinder"; public const string ModVersion = "2.2.3.0"; internal static readonly ConfigSync ConfigSync; public static ConfigEntry<float> MinimumRadius; public static ConfigEntry<float> MaximumRadius; public static ConfigEntry<float> LandExploreRadius; public static ConfigEntry<float> SeaExploreRadius; public static ConfigEntry<float> AltitudeRadiusBonus; public static ConfigEntry<float> ForestRadiusPenalty; public static ConfigEntry<float> DaylightRadiusScale; public static ConfigEntry<float> WeatherRadiusScale; public static ConfigEntry<bool> DisplayCurrentRadiusValue; public static ConfigEntry<bool> DisplayVariables; private static Harmony sMinimapHarmony; private static Harmony sHudHarmony; private static Text sRadiusHudText; private static Text sVariablesHudText; static PathfinderPlugin() { //IL_0005: 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_0015: 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_002b: 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_003e: Expected O, but got Unknown ConfigSync = new ConfigSync("dev.crystal.pathfinder") { DisplayName = "Pathfinder", CurrentVersion = "2.2.3.0", MinimumRequiredVersion = "2.2.3.0", ModRequired = true, ModRequirementMode = (ModRequirementMode)1 }; } private void Awake() { //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Expected O, but got Unknown MinimumRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Base", "MinimumRadius", 20f, "The minimum exploration radius allowed. If a lower radius is calculated, it will be increased to this value. Higher values may cause performance issues. Accepted range 0-10000. Must be equal or lower than MaximumRadius. [The value will be enforced on a server.]"); MinimumRadius.SettingChanged += MinimumRadius_SettingChanged; ((ConditionalConfigSync)ConfigSync).AddConfigEntry<float>(MinimumRadius, (ConfigSyncMode)0); MaximumRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Base", "MaximumRadius", 2000f, "The maximum exploration radius allowed. If a higher radius is calculated, it will be decreased to this value. Higher values may cause performance issues. Accepted range 0-10000. Must be equal or higher than MinimumRadius. [The value will be enforced on a server.]"); MaximumRadius.SettingChanged += MaximumRadius_SettingChanged; ((ConditionalConfigSync)ConfigSync).AddConfigEntry<float>(MaximumRadius, (ConfigSyncMode)0); LandExploreRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Base", "LandExploreRadius", 200f, "The radius around the player to uncover while travelling on land near sea level. Higher values may cause performance issues. Max allowed is 2000. Game default is 100. [The value will be enforced on a server.]"); LandExploreRadius.SettingChanged += Config_SettingChanged; ((ConditionalConfigSync)ConfigSync).AddConfigEntry<float>(LandExploreRadius, (ConfigSyncMode)0); SeaExploreRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Base", "SeaExploreRadius", 300f, "The radius around the player to uncover while travelling on a boat. Higher values may cause performance issues. Max allowed is 2000. Game default is 100. [The value will be enforced on a server.]"); SeaExploreRadius.SettingChanged += Config_SettingChanged; ((ConditionalConfigSync)ConfigSync).AddConfigEntry<float>(SeaExploreRadius, (ConfigSyncMode)0); AltitudeRadiusBonus = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "AltitudeRadiusBonus", 0.5f, "Bonus multiplier to apply to land exploration radius based on altitude. For every 100 units above sea level (smooth scale), add this value multiplied by LandExploreRadius to the total. For example, with a radius of 200 and a multiplier of 0.5, radius is 200 at sea level, 250 at 50 altitude, 300 at 100 altitude, 400 at 200 altitude, etc. For reference, a typical mountain peak is around 170 altitude. Accepted range 0-2. Set to 0 to disable. [The value will be enforced on a server.]"); AltitudeRadiusBonus.SettingChanged += Config_SettingChanged; ((ConditionalConfigSync)ConfigSync).AddConfigEntry<float>(AltitudeRadiusBonus, (ConfigSyncMode)0); ForestRadiusPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "ForestRadiusPenalty", 0.3f, "Penalty to apply to land exploration radius when in a forest (black forest, forested parts of meadows and plains). This value is multiplied by the base land exploration radius and subtraced from the total. Accepted range 0-1. Set to 0 to disable. [The value will be enforced on a server.]"); ForestRadiusPenalty.SettingChanged += Config_SettingChanged; ((ConditionalConfigSync)ConfigSync).AddConfigEntry<float>(ForestRadiusPenalty, (ConfigSyncMode)0); DaylightRadiusScale = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "DaylightRadiusScale", 0.2f, "Influences how much daylight (directional and ambient light) affects exploration radius. This value is multiplied by the base land or sea exploration radius and added to the total. Accepted range 0-1. Set to 0 to disable. [The value will be enforced on a server.]"); DaylightRadiusScale.SettingChanged += Config_SettingChanged; ((ConditionalConfigSync)ConfigSync).AddConfigEntry<float>(DaylightRadiusScale, (ConfigSyncMode)0); WeatherRadiusScale = ((BaseUnityPlugin)this).Config.Bind<float>("Multipliers", "WeatherRadiusScale", 0.5f, "Influences how much the current weather affects exploration radius. This value is multiplied by the base land or sea exploration radius and added to the total. Accepted range 0-1. Set to 0 to disable. [The value will be enforced on a server.]"); WeatherRadiusScale.SettingChanged += Config_SettingChanged; ((ConditionalConfigSync)ConfigSync).AddConfigEntry<float>(WeatherRadiusScale, (ConfigSyncMode)0); DisplayCurrentRadiusValue = ((BaseUnityPlugin)this).Config.Bind<bool>("Miscellaneous", "DisplayCurrentRadiusValue", false, "Enabling this will display the currently computed exploration radius in the bottom left of the in-game Hud. Useful if you are trying to tweak config values and want to see the result."); DisplayCurrentRadiusValue.SettingChanged += DisplayRadiusValue_SettingChanged; ((ConditionalConfigSync)ConfigSync).AddConfigEntry<bool>(DisplayCurrentRadiusValue, (ConfigSyncMode)2); DisplayVariables = ((BaseUnityPlugin)this).Config.Bind<bool>("Miscellaneous", "DisplayVariables", false, "Enabling this will display on the Hud the values of various variables that go into calculating the exploration radius. Mostly useful for debugging and tweaking the config."); DisplayVariables.SettingChanged += DisplayVariablesValue_SettingChanged; ((ConditionalConfigSync)ConfigSync).AddConfigEntry<bool>(DisplayVariables, (ConfigSyncMode)2); ClampConfig(); sMinimapHarmony = new Harmony("dev.crystal.pathfinder_Minimap"); sHudHarmony = new Harmony("dev.crystal.pathfinder_Hud"); sMinimapHarmony.PatchAll(typeof(Minimap_Patches)); sHudHarmony.PatchAll(typeof(Hud_Patches)); } private void Config_SettingChanged(object sender, EventArgs e) { ClampConfig(); } private void MinimumRadius_SettingChanged(object sender, EventArgs e) { if (MinimumRadius.Value > MaximumRadius.Value) { MaximumRadius.Value = MinimumRadius.Value; } ClampConfig(); } private void MaximumRadius_SettingChanged(object sender, EventArgs e) { if (MaximumRadius.Value < MinimumRadius.Value) { MinimumRadius.Value = MaximumRadius.Value; } ClampConfig(); } private void DisplayRadiusValue_SettingChanged(object sender, EventArgs e) { ((Component)sRadiusHudText).gameObject.SetActive(DisplayCurrentRadiusValue.Value); if (!DisplayCurrentRadiusValue.Value) { sRadiusHudText.text = string.Empty; } } private void DisplayVariablesValue_SettingChanged(object sender, EventArgs e) { ((Component)sVariablesHudText).gameObject.SetActive(DisplayVariables.Value); if (!DisplayVariables.Value) { sVariablesHudText.text = string.Empty; } } private void OnDestroy() { sMinimapHarmony.UnpatchSelf(); sHudHarmony.UnpatchSelf(); } private static void ClampConfig() { if (MinimumRadius.Value < 0f) { MinimumRadius.Value = 0f; } if (MinimumRadius.Value > 10000f) { MinimumRadius.Value = 10000f; } if (MaximumRadius.Value < 0f) { MaximumRadius.Value = 0f; } if (MaximumRadius.Value > 10000f) { MaximumRadius.Value = 10000f; } if (LandExploreRadius.Value < 0f) { LandExploreRadius.Value = 0f; } if (LandExploreRadius.Value > 2000f) { LandExploreRadius.Value = 2000f; } if (SeaExploreRadius.Value < 0f) { SeaExploreRadius.Value = 0f; } if (SeaExploreRadius.Value > 2000f) { SeaExploreRadius.Value = 2000f; } if (AltitudeRadiusBonus.Value < 0f) { AltitudeRadiusBonus.Value = 0f; } if (AltitudeRadiusBonus.Value > 2f) { AltitudeRadiusBonus.Value = 2f; } if (ForestRadiusPenalty.Value < 0f) { ForestRadiusPenalty.Value = 0f; } if (ForestRadiusPenalty.Value > 1f) { ForestRadiusPenalty.Value = 1f; } if (DaylightRadiusScale.Value < 0f) { DaylightRadiusScale.Value = 0f; } if (DaylightRadiusScale.Value > 1f) { DaylightRadiusScale.Value = 1f; } if (WeatherRadiusScale.Value < 0f) { WeatherRadiusScale.Value = 0f; } if (WeatherRadiusScale.Value > 1f) { WeatherRadiusScale.Value = 1f; } } }