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 AnActualCartographer v1.2.1
AnActualCartographer.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; 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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("AnActualCartographer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Use a cartography table and the map fog lifts 5x further as you explore. Configurable.")] [assembly: AssemblyFileVersion("1.2.1.0")] [assembly: AssemblyInformationalVersion("1.2.1+8eb0aedda7691ecd76f81201a62d1512fb4812be")] [assembly: AssemblyProduct("AnActualCartographer")] [assembly: AssemblyTitle("AnActualCartographer")] [assembly: AssemblyVersion("1.2.1.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 AnActualCartographer { internal static class CartographyState { private const string KeyPrefix = "AnActualCartographer.unlocked."; private static Minimap _capturedFrom; private static float _baseRadius; private static Player _cachedPlayer; private static long _cachedWorldUid; private static bool _cachedUnlocked; private static float _lastApplied = -1f; internal static bool IsWidening { get; private set; } internal static void ApplyTo(Minimap minimap, Player player) { if (!((Object)(object)minimap == (Object)null)) { float num = BaseRadiusFor(minimap); bool flag = (IsWidening = ModConfig.Enabled.Value && IsUnlocked(player)); float num2 = (minimap.m_exploreRadius = (flag ? Widen(minimap, num, ModConfig.ExploreRadiusMultiplier.Value) : num)); if (ModConfig.VerboseLogging.Value && !Mathf.Approximately(num2, _lastApplied)) { Plugin.Log.LogInfo((object)$"Explore radius {num2}m (vanilla {num}m, widened={flag})."); } _lastApplied = num2; } } private static float Widen(Minimap minimap, float baseRadius, float multiplier) { float pixelSize = minimap.m_pixelSize; if (pixelSize <= 0f) { return baseRadius * multiplier; } int num = Mathf.Max(1, Mathf.CeilToInt(baseRadius / pixelSize)); int num2 = Mathf.RoundToInt((float)num * multiplier); int num3 = Mathf.Max(num, minimap.m_textureSize); return (float)Mathf.Clamp(num2, num, num3) * pixelSize; } internal static bool Unlock(Player player) { if ((Object)(object)player == (Object)null) { return false; } long num = CurrentWorldUid(); if (num == 0L) { return false; } string key = KeyFor(num); if (player.m_customData.ContainsKey(key)) { return false; } player.m_customData[key] = "1"; InvalidateCache(); if (ModConfig.VerboseLogging.Value) { Plugin.Log.LogInfo((object)$"Cartography unlocked for world {num}."); } return true; } internal static bool IsUnlocked(Player player) { if ((Object)(object)player == (Object)null) { return false; } long num = CurrentWorldUid(); if (num == 0L) { return false; } if (_cachedPlayer == player && _cachedWorldUid == num) { return _cachedUnlocked; } _cachedPlayer = player; _cachedWorldUid = num; _cachedUnlocked = player.m_customData.ContainsKey(KeyFor(num)); return _cachedUnlocked; } private static float BaseRadiusFor(Minimap minimap) { if (_capturedFrom != minimap) { _capturedFrom = minimap; _baseRadius = minimap.m_exploreRadius; _lastApplied = -1f; InvalidateCache(); } return _baseRadius; } private static string KeyFor(long worldUid) { return "AnActualCartographer.unlocked." + worldUid.ToString(CultureInfo.InvariantCulture); } private static long CurrentWorldUid() { ZNet instance = ZNet.instance; if ((Object)(object)instance == (Object)null || ZNet.World == null) { return 0L; } return instance.GetWorldUID(); } private static void InvalidateCache() { _cachedPlayer = null; _cachedWorldUid = 0L; _cachedUnlocked = false; ExploreSkip.Invalidate(); } } internal static class ExploreSkip { private static FieldRef<Minimap, BitArray> _exploredRef; private static bool _resolved; private static int _lastPx = int.MinValue; private static int _lastPy = int.MinValue; private static int _lastNum = -1; internal static void Invalidate() { _lastPx = int.MinValue; _lastPy = int.MinValue; _lastNum = -1; } internal static bool CanSkip(Minimap minimap, Vector3 p, float radius) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)minimap == (Object)null) { return false; } if (!CartographyState.IsWidening) { return false; } BitArray bitArray = Explored(minimap); if (bitArray == null) { return false; } float pixelSize = minimap.m_pixelSize; if (pixelSize <= 0f) { return false; } int num = (int)Mathf.Ceil(radius / pixelSize); int num2 = minimap.m_textureSize / 2; int num3 = Utils.RoundToInt(p.x / pixelSize + (float)num2); int num4 = Utils.RoundToInt(p.z / pixelSize + (float)num2); bool num5 = num3 == _lastPx && num4 == _lastPy && num == _lastNum; _lastPx = num3; _lastPy = num4; _lastNum = num; if (!num5) { return false; } int num6 = num4 * minimap.m_textureSize + num3; if (num6 < 0 || num6 >= bitArray.Length) { return false; } return bitArray[num6]; } private static BitArray Explored(Minimap minimap) { if (!_resolved) { _resolved = true; try { _exploredRef = AccessTools.FieldRefAccess<Minimap, BitArray>("m_explored"); } catch (Exception ex) { _exploredRef = null; Plugin.Log.LogWarning((object)("Minimap.m_explored not found (" + ex.GetType().Name + "); explore-skip disabled, the map still works but large radii will cost more.")); } } FieldRef<Minimap, BitArray> exploredRef = _exploredRef; if (exploredRef == null) { return null; } return exploredRef.Invoke(minimap); } } internal static class ModConfig { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> ExploreRadiusMultiplier; internal static ConfigEntry<bool> ShowUnlockMessage; internal static ConfigEntry<string> UnlockMessage; internal static ConfigEntry<bool> VerboseLogging; internal static void Bind(ConfigFile config) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown Enabled = config.Bind<bool>("Cartography Table", "Enabled", true, "Widen the fog-lifting radius once you have used a cartography table in this world. Turn this off to play vanilla without uninstalling: while off the mod is inert, and will not widen anything, announce anything, or record a new unlock. An unlock already earned is kept and takes effect again when you turn this back on."); ExploreRadiusMultiplier = config.Bind<float>("Cartography Table", "ExploreRadiusMultiplier", 5f, new ConfigDescription("How much further the fog lifts once the table has been used. 5 means five times as far as vanilla, so the 128m the fog normally clears becomes 640m. Counted in whole fog-map pixels, which is how the game explores, so the multiplier lands on the distance you actually watch clear.\nCapped at 10. The game re-walks the whole circle every 2 seconds, and the cost grows with the square of this number: 10 is about 1,700 cells a tick, 30 was about 15,000 and showed up as a hitch every 2 seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>())); ShowUnlockMessage = config.Bind<bool>("Cartography Table", "ShowUnlockMessage", true, "Show a centre-screen message the first time you use a table in a world. Shown once per world, not on every use."); UnlockMessage = config.Bind<string>("Cartography Table", "UnlockMessage", "You read the land with a cartographer's eye", "Text for that message."); VerboseLogging = config.Bind<bool>("Advanced", "VerboseLogging", false, "Log the unlock and the resulting explore radius to the BepInEx console."); } } [BepInPlugin("com.ljindustries.valheim.anactualcartographer", "AnActualCartographer", "1.2.1")] public class Plugin : BaseUnityPlugin { public const string ModGuid = "com.ljindustries.valheim.anactualcartographer"; public const string ModName = "AnActualCartographer"; public const string ModVersion = "1.2.1"; internal static ManualLogSource Log; private Harmony _harmony; private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ModConfig.Bind(((BaseUnityPlugin)this).Config); _harmony = new Harmony("com.ljindustries.valheim.anactualcartographer"); Type[] types = typeof(Plugin).Assembly.GetTypes(); foreach (Type type in types) { try { _harmony.CreateClassProcessor(type).Patch(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Harmony skip " + type.FullName + ": " + ex.GetType().Name + ": " + ex.Message)); } } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } namespace AnActualCartographer.Patches { internal static class MapTableUse { internal static void Handle(Humanoid user, ItemData item) { if (ModConfig.Enabled.Value && item == null) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)user != (Object)(object)localPlayer) && CartographyState.Unlock(localPlayer) && ModConfig.ShowUnlockMessage.Value) { ((Character)localPlayer).Message((MessageType)2, ModConfig.UnlockMessage.Value, 0, (Sprite)null, false); } } } } [HarmonyPatch(typeof(MapTable), "OnRead", new Type[] { typeof(Switch), typeof(Humanoid), typeof(ItemData) })] internal static class MapTableReadPatch { private static void Postfix(Humanoid user, ItemData item) { MapTableUse.Handle(user, item); } } [HarmonyPatch(typeof(MapTable), "OnWrite", new Type[] { typeof(Switch), typeof(Humanoid), typeof(ItemData) })] internal static class MapTableWritePatch { private static void Postfix(Humanoid user, ItemData item) { MapTableUse.Handle(user, item); } } [HarmonyPatch(typeof(Minimap), "Explore", new Type[] { typeof(Vector3), typeof(float) })] internal static class MinimapExplorePatch { private static bool Prefix(Minimap __instance, Vector3 p, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return !ExploreSkip.CanSkip(__instance, p, radius); } } [HarmonyPatch(typeof(Minimap), "UpdateExplore", new Type[] { typeof(float), typeof(Player) })] internal static class MinimapUpdateExplorePatch { private static void Prefix(Minimap __instance, Player player) { CartographyState.ApplyTo(__instance, player); } } }