using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MapPinDeclutter")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("birdhimself")]
[assembly: AssemblyProduct("MapPinDeclutter")]
[assembly: AssemblyCopyright("Copyright 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.2.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.1.0")]
namespace MapPinDeclutter;
[BepInPlugin("birdhimself.MapPinDeclutter", "MapPinDeclutter", "0.2.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class MapPinDeclutter : BaseUnityPlugin
{
private class MinimapUpdatePinsState
{
public float OgPinSizeLarge;
}
[HarmonyPatch(typeof(Minimap), "UpdatePins")]
private class Minimap_UpdatePins_Patch
{
private static float _rememberedPinSizeLarge = -1f;
private static float ComputeIconSize(Minimap instance)
{
float largeZoom = instance.m_largeZoom;
float pinSizeLarge = instance.m_pinSizeLarge;
float value = PluginInstance.config.ZoomIconsThreshold.Value;
float value2 = PluginInstance.config.ZoomIconsMinimumSize.Value;
if (largeZoom <= value)
{
return 1f;
}
float num = (largeZoom - value) / (1f - value);
return (1f - num * (1f - value2)) * pinSizeLarge;
}
private static void Prefix(Minimap __instance, out MinimapUpdatePinsState __state)
{
__state = new MinimapUpdatePinsState
{
OgPinSizeLarge = __instance.m_pinSizeLarge
};
if (!ShouldZoomIcons(__instance))
{
return;
}
__instance.m_pinSizeLarge = ComputeIconSize(__instance);
if (__instance.m_pinSizeLarge == _rememberedPinSizeLarge)
{
return;
}
foreach (PinData pin in __instance.m_pins)
{
if (!((Object)(object)pin.m_uiElement == (Object)null))
{
float num = (pin.m_doubleSize ? (__instance.m_pinSizeLarge * 2f) : __instance.m_pinSizeLarge);
pin.m_uiElement.SetSizeWithCurrentAnchors((Axis)0, num);
pin.m_uiElement.SetSizeWithCurrentAnchors((Axis)1, num);
}
}
_rememberedPinSizeLarge = __instance.m_pinSizeLarge;
}
private static void Postfix(Minimap __instance, MinimapUpdatePinsState __state)
{
__instance.m_pinSizeLarge = __state.OgPinSizeLarge;
if (!ShouldHideNames(__instance))
{
return;
}
foreach (PinData pin in __instance.m_pins)
{
if (!ShouldAlwaysShowName(pin) && pin.m_NamePinData != null && (Object)(object)pin.m_NamePinData.PinNameGameObject != (Object)null)
{
pin.m_NamePinData.PinNameGameObject.SetActive(PluginInstance.config.HideNamesByDistanceEnabled.Value && ShouldShowNameForPin(__instance, pin));
}
}
}
}
[HarmonyPatch]
private class Minimap_DelayActivation_MoveNext_Patch
{
private static MethodBase TargetMethod()
{
return AccessTools.Method(AccessTools.FirstInner(typeof(Minimap), (Func<Type, bool>)((Type t) => t.Name.Contains("DelayActivation"))), "MoveNext", (Type[])null, (Type[])null);
}
private static void Postfix(object __instance)
{
object? value = AccessTools.Field(__instance.GetType(), "<>4__this").GetValue(__instance);
Minimap val = (Minimap)((value is Minimap) ? value : null);
if ((Object)(object)val == (Object)null || !ShouldHideNames(val))
{
return;
}
GameObject go = default(GameObject);
ref GameObject reference = ref go;
object? obj = AccessTools.Field(__instance.GetType(), "go")?.GetValue(__instance);
reference = (GameObject)((obj is GameObject) ? obj : null);
if (!((Object)(object)go == (Object)null) && go.activeSelf)
{
PinData val2 = ((IEnumerable<PinData>)val.m_pins).FirstOrDefault((Func<PinData, bool>)delegate(PinData p)
{
PinNameData namePinData = p.m_NamePinData;
return (Object)(object)((namePinData != null) ? namePinData.PinNameGameObject : null) != (Object)null && ((Object)p.m_NamePinData.PinNameGameObject).GetInstanceID() == ((Object)go).GetInstanceID();
});
if (val2 != null)
{
go.SetActive(PluginInstance.config.HideNamesByDistanceEnabled.Value ? ShouldShowNameForPin(val, val2) : ShouldAlwaysShowName(val2));
}
}
}
}
private static MapPinDeclutter PluginInstance;
private const string PluginGUID = "birdhimself.MapPinDeclutter";
private const string PluginName = "MapPinDeclutter";
public const string PluginVersion = "0.2.1";
private PluginConfiguration config;
public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();
private static bool ShouldHideNames(Minimap instance)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Invalid comparison between Unknown and I4
if (PluginInstance.config.HideNamesEnabled.Value && (int)instance.m_mode == 2)
{
return instance.m_largeZoom > PluginInstance.config.HideNamesThreshold.Value;
}
return false;
}
private static bool ShouldShowNameForPin(Minimap instance, PinData pin)
{
if (ShouldAlwaysShowName(pin))
{
return true;
}
float tolerance = (float)PluginInstance.config.HideNamesByDistanceThreshold.Value * instance.m_largeZoom;
float x = pin.m_pos.x;
float z = pin.m_pos.z;
return instance.m_pins.Count(delegate(PinData p)
{
float num = Math.Abs(p.m_pos.x - x);
float num2 = Math.Abs(p.m_pos.z - z);
return num <= tolerance && num2 <= tolerance;
}) <= 1;
}
private static bool ShouldAlwaysShowName(PinData pin)
{
//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_0009: Invalid comparison between Unknown and I4
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Invalid comparison between Unknown and I4
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Invalid comparison between Unknown and I4
PinType type = pin.m_type;
if ((int)type == 7 || (int)type == 10 || (int)type == 12)
{
return true;
}
return false;
}
private static bool ShouldZoomIcons(Minimap instance)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Invalid comparison between Unknown and I4
if (PluginInstance.config.ZoomIconsEnabled.Value && (int)instance.m_mode == 2)
{
return instance.m_largeZoom > PluginInstance.config.ZoomIconsThreshold.Value;
}
return false;
}
private void Awake()
{
PluginInstance = this;
config = new PluginConfiguration(((BaseUnityPlugin)this).Config);
Logger.LogInfo((object)"MapPinDeclutter has landed");
Harmony.CreateAndPatchAll(typeof(MapPinDeclutter).Assembly, "birdhimself.MapPinDeclutter");
}
}
public class PluginConfiguration
{
public readonly ConfigEntry<bool> HideNamesEnabled;
public readonly ConfigEntry<float> HideNamesThreshold;
public readonly ConfigEntry<bool> HideNamesByDistanceEnabled;
public readonly ConfigEntry<int> HideNamesByDistanceThreshold;
public readonly ConfigEntry<bool> ZoomIconsEnabled;
public readonly ConfigEntry<float> ZoomIconsThreshold;
public readonly ConfigEntry<float> ZoomIconsMinimumSize;
public PluginConfiguration(ConfigFile config)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Expected O, but got Unknown
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Expected O, but got Unknown
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Expected O, but got Unknown
HideNamesEnabled = config.Bind<bool>("General", "HideNamesEnabled", true, "Whether to hide names");
HideNamesThreshold = config.Bind<float>("General", "HideNamesThreshold", 0.02f, new ConfigDescription("Zoom threshold when names will be hidden", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.015f, 1f), Array.Empty<object>()));
HideNamesByDistanceEnabled = config.Bind<bool>("General", "HideNamesByDistanceEnabled", true, "Whether to hide names by distance to other pins instead of simply hiding all names");
HideNamesByDistanceThreshold = config.Bind<int>("General", "HideNamesByDistanceThreshold", 1000, new ConfigDescription("Pins that have other pins within this distance will have their names hidden (calculated relative to the current zoom level)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 3000), Array.Empty<object>()));
ZoomIconsEnabled = config.Bind<bool>("General", "ZoomIconsEnabled", true, "Whether to zoom icons");
ZoomIconsThreshold = config.Bind<float>("General", "ZoomIconsThreshold", 0.3f, new ConfigDescription("Zoom threshold when icon size will start to be reduced", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.015f, 1f), Array.Empty<object>()));
ZoomIconsMinimumSize = config.Bind<float>("General", "ZoomIconsMinimumSize", 0.3f, new ConfigDescription("Minimum icon size when zooming icons", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()));
}
}