using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DarkSpider.MapTracker.Patches; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 DarkSpider.MapTracker { internal enum ArrowColorPreset { Red, Orange, Yellow, Green, Cyan, Blue, Purple, Pink, White, Black, Gray, CustomHex } internal enum PlayerArrowColorMode { PlayerHeadColor, Red, Orange, Yellow, Green, Cyan, Blue, Purple, Pink, White, Black, Gray, CustomHex } internal enum MapZoomInputMode { MouseWheel, Keyboard, MouseWheelAndKeyboard, Disabled } internal sealed class PluginConfig { internal ConfigEntry ModEnabled { get; } internal ConfigEntry ShowEnemies { get; } internal ConfigEntry EnemyColor { get; } internal ConfigEntry EnemyCustomHex { get; } internal ConfigEntry EnemyArrowScale { get; } internal ConfigEntry ShowPlayers { get; } internal ConfigEntry PlayerColor { get; } internal ConfigEntry PlayerCustomHex { get; } internal ConfigEntry PlayerArrowScale { get; } internal ConfigEntry OutlineEnabled { get; } internal ConfigEntry OutlineColor { get; } internal ConfigEntry OutlineCustomHex { get; } internal ConfigEntry OutlineScale { get; } internal ConfigEntry MapZoomMultiplier { get; } internal ConfigEntry ZoomInputMode { get; } internal ConfigEntry ZoomInKey { get; } internal ConfigEntry ZoomOutKey { get; } internal ConfigEntry ZoomStep { get; } internal PluginConfig(ConfigFile config) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Expected O, but got Unknown //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Expected O, but got Unknown //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Expected O, but got Unknown ModEnabled = config.Bind("General", "ModEnabled", true, "Enable or disable the whole map tracker mod."); ShowEnemies = config.Bind("Enemies", "ShowEnemyArrows", true, "Show enemy arrows on the map."); EnemyColor = config.Bind("Enemies", "EnemyArrowColor", ArrowColorPreset.Red, "Enemy arrow color. Select CustomHex to use EnemyCustomHex."); EnemyCustomHex = config.Bind("Enemies", "EnemyCustomHex", "#FF0000", "Custom enemy arrow color used when EnemyArrowColor is CustomHex."); EnemyArrowScale = config.Bind("Enemies", "EnemyArrowScale", 0.25f, new ConfigDescription("Enemy arrow size. 0.25 is the original small triangle size.", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 3f), Array.Empty())); ShowPlayers = config.Bind("Players", "ShowPlayerArrows", true, "Show player arrows on the map."); PlayerColor = config.Bind("Players", "PlayerArrowColor", PlayerArrowColorMode.PlayerHeadColor, "Player arrow color. PlayerHeadColor uses HeadTopMesh color. Select CustomHex to use PlayerCustomHex."); PlayerCustomHex = config.Bind("Players", "PlayerCustomHex", "#00FFFF", "Custom player arrow color used when PlayerArrowColor is CustomHex."); PlayerArrowScale = config.Bind("Players", "PlayerArrowScale", 0.25f, new ConfigDescription("Player arrow size. 0.25 is the original small triangle size.", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 3f), Array.Empty())); OutlineEnabled = config.Bind("Outline", "OutlineEnabled", true, "Draw an outline behind map arrows. Useful for white/gray player colors."); OutlineColor = config.Bind("Outline", "OutlineColor", ArrowColorPreset.Black, "Outline color. Select CustomHex to use OutlineCustomHex."); OutlineCustomHex = config.Bind("Outline", "OutlineCustomHex", "#000000", "Custom outline color used when OutlineColor is CustomHex."); OutlineScale = config.Bind("Outline", "OutlineScale", 1.35f, new ConfigDescription("Outline size relative to the main arrow.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 2f), Array.Empty())); MapZoomMultiplier = config.Bind("Map Zoom", "MapZoomMultiplier", 1f, new ConfigDescription("1.0 = vanilla. Bigger values zoom out, smaller values zoom in.", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 5f), Array.Empty())); ZoomInputMode = config.Bind("Map Zoom", "ZoomInputMode", MapZoomInputMode.MouseWheel, "How map zoom is controlled while the map is open."); ZoomInKey = config.Bind("Map Zoom", "ZoomInKey", "Equals", "Keyboard zoom-in key while the map is open. Examples: Equals, KeypadPlus, PageUp."); ZoomOutKey = config.Bind("Map Zoom", "ZoomOutKey", "Minus", "Keyboard zoom-out key while the map is open. Examples: Minus, KeypadMinus, PageDown."); ZoomStep = config.Bind("Map Zoom", "ZoomStep", 0.1f, new ConfigDescription("How much each mouse-wheel notch or hotkey press changes MapZoomMultiplier.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 1f), Array.Empty())); } internal Color GetEnemyColor() { //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_0024: Unknown result type (might be due to invalid IL or missing references) return ColorTools.ResolvePreset(EnemyColor.Value, EnemyCustomHex.Value, Color.red); } internal Color GetOutlineColor() { //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_0024: Unknown result type (might be due to invalid IL or missing references) return ColorTools.ResolvePreset(OutlineColor.Value, OutlineCustomHex.Value, Color.black); } } internal static class ColorTools { internal static Color ResolvePreset(ArrowColorPreset preset, string customHex, Color fallback) { //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_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_006a: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) return (Color)(preset switch { ArrowColorPreset.Red => Color.red, ArrowColorPreset.Orange => new Color(1f, 0.5f, 0f, 1f), ArrowColorPreset.Yellow => Color.yellow, ArrowColorPreset.Green => Color.green, ArrowColorPreset.Cyan => new Color(0f, 0.85f, 1f, 1f), ArrowColorPreset.Blue => new Color(0.05f, 0.2f, 1f, 1f), ArrowColorPreset.Purple => new Color(0.55f, 0f, 1f, 1f), ArrowColorPreset.Pink => new Color(1f, 0.1f, 0.65f, 1f), ArrowColorPreset.White => Color.white, ArrowColorPreset.Black => Color.black, ArrowColorPreset.Gray => new Color(0.28f, 0.28f, 0.28f, 1f), ArrowColorPreset.CustomHex => ParseHex(customHex, fallback), _ => fallback, }); } internal static Color ResolvePlayerColor(PlayerArrowColorMode mode, string customHex, PlayerAvatar playerAvatar) { //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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_006e: 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_002a: Unknown result type (might be due to invalid IL or missing references) switch (mode) { case PlayerArrowColorMode.PlayerHeadColor: return (Color)(((??)ReflectionCache.TryReadPlayerHeadTopColor(playerAvatar)) ?? Color.cyan); case PlayerArrowColorMode.CustomHex: return ParseHex(customHex, Color.cyan); default: { if (Enum.TryParse(mode.ToString(), out var result)) { return ResolvePreset(result, customHex, Color.cyan); } return Color.cyan; } } } private static Color ParseHex(string htmlColor, Color fallback) { //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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (!string.IsNullOrWhiteSpace(htmlColor) && ColorUtility.TryParseHtmlString(htmlColor.Trim(), ref result)) { return result; } return fallback; } } internal sealed class MapTrackerController { private readonly PluginConfig _config; private readonly List _enemyTrackers = new List(); private readonly List _playerTrackers = new List(); private readonly Sprite _arrowSprite; private Map _lastMap; internal MapTrackerController(PluginConfig config) { _config = config; _arrowSprite = TriangleSpriteFactory.Create("DarkSpiderMapTracker.Triangle", 64); } internal void OnMapAwake(Map map) { if (!((Object)(object)map == (Object)null)) { _lastMap = map; Clear(); } } internal void Tick(Map map) { if (!((Object)(object)map == (Object)null) && !((Object)(object)Map.Instance == (Object)null)) { if ((Object)(object)_lastMap != (Object)(object)map) { OnMapAwake(map); } UpdateTrackers(_enemyTrackers, isPlayerTracker: false); UpdateTrackers(_playerTrackers, isPlayerTracker: true); } } internal void Register(object source) { if (source == null || (Object)(object)Map.Instance == (Object)null || (Object)(object)Map.Instance.CustomObject == (Object)null || (Object)(object)Map.Instance.OverLayerParent == (Object)null) { return; } bool flag = source is EnemyParent; bool flag2 = source is PlayerAvatar; if (!flag && !flag2) { return; } if (flag2) { object obj = source; PlayerAvatar playerAvatar = (PlayerAvatar)((obj is PlayerAvatar) ? obj : null); if (IsLocalPlayer(playerAvatar)) { return; } } List list = (flag2 ? _playerTrackers : _enemyTrackers); if (list.Any((TrackedMapEntity entry) => entry.Source == source)) { return; } GameObject visualObject = GetVisualObject(source); if ((Object)(object)visualObject == (Object)null) { return; } GameObject val = Object.Instantiate(Map.Instance.CustomObject, Map.Instance.OverLayerParent); ((Object)val).name = "DarkSpider Map Tracker - " + ((Object)visualObject).name; MapCustomEntity component = val.GetComponent(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val); return; } SpriteRenderer val2 = (((Object)(object)component.spriteRenderer != (Object)null) ? component.spriteRenderer : val.GetComponentInChildren(true)); if ((Object)(object)val2 == (Object)null) { Object.Destroy((Object)(object)val); return; } component.Parent = visualObject.transform; val2.sprite = _arrowSprite; ((Renderer)val2).enabled = false; ((Renderer)val2).sortingOrder = ((Renderer)val2).sortingOrder + 10; SpriteRenderer outlineRenderer = CreateOutlineRenderer(((Component)component).transform, val2); list.Add(new TrackedMapEntity { Source = source, MapEntity = component, ArrowRenderer = val2, OutlineRenderer = outlineRenderer, Visible = false, IsPlayer = flag2 }); } internal void Show(object source) { TrackedMapEntity trackedMapEntity = Find(source); if (trackedMapEntity == null) { return; } if (trackedMapEntity.IsPlayer) { PlayerAvatar val = (PlayerAvatar)((source is PlayerAvatar) ? source : null); if (val != null && IsPlayerDead(val)) { return; } } trackedMapEntity.Visible = true; } internal void Hide(object source) { TrackedMapEntity trackedMapEntity = Find(source); if (trackedMapEntity != null) { trackedMapEntity.Visible = false; } } internal void SetAllVisible(bool visible) { SetTrackersVisible(_enemyTrackers, visible); SetTrackersVisible(_playerTrackers, visible); } internal void Clear() { DestroyTrackers(_enemyTrackers); DestroyTrackers(_playerTrackers); _enemyTrackers.Clear(); _playerTrackers.Clear(); } private void UpdateTrackers(List trackers, bool isPlayerTracker) { //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) bool flag = (isPlayerTracker ? _config.ShowPlayers.Value : _config.ShowEnemies.Value); for (int num = trackers.Count - 1; num >= 0; num--) { TrackedMapEntity trackedMapEntity = trackers[num]; if (!IsValid(trackedMapEntity)) { DestroyTracker(trackedMapEntity); trackers.RemoveAt(num); continue; } Transform parent = trackedMapEntity.MapEntity.Parent; if ((Object)(object)parent == (Object)null) { SetRendererPairEnabled(trackedMapEntity, visible: false); continue; } if (isPlayerTracker) { object source = trackedMapEntity.Source; PlayerAvatar val = (PlayerAvatar)((source is PlayerAvatar) ? source : null); if (val != null && IsLocalPlayer(val)) { DestroyTracker(trackedMapEntity); trackers.RemoveAt(num); continue; } } if (Map.Instance.Active) { Map.Instance.CustomPositionSet(((Component)trackedMapEntity.MapEntity).transform, parent); } int num2; if (!isPlayerTracker) { object source2 = trackedMapEntity.Source; EnemyParent val2 = (EnemyParent)((source2 is EnemyParent) ? source2 : null); num2 = ((val2 != null && IsEnemyActive(val2)) ? 1 : 0); } else { object source3 = trackedMapEntity.Source; PlayerAvatar val3 = (PlayerAvatar)((source3 is PlayerAvatar) ? source3 : null); num2 = ((val3 == null || !IsPlayerDead(val3)) ? 1 : 0); } bool flag2 = (byte)num2 != 0; bool flag3 = flag && trackedMapEntity.Visible && flag2; Color val4 = (isPlayerTracker ? ColorTools.ResolvePlayerColor(_config.PlayerColor.Value, _config.PlayerCustomHex.Value, (PlayerAvatar)/*isinst with value type is only supported in some contexts*/) : _config.GetEnemyColor()); float num3 = Mathf.Clamp(isPlayerTracker ? _config.PlayerArrowScale.Value : _config.EnemyArrowScale.Value, 0.25f, 3f); ApplyRenderer(trackedMapEntity.ArrowRenderer, val4, num3, flag3); ApplyOutline(trackedMapEntity, val4.a, num3, flag3); } } private void ApplyRenderer(SpriteRenderer renderer, Color color, float scale, bool visible) { //IL_001b: 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_002e: Unknown result type (might be due to invalid IL or missing references) color.a = 1f; renderer.sprite = _arrowSprite; renderer.color = color; ((Component)renderer).transform.localScale = Vector3.one * scale; ((Renderer)renderer).enabled = visible; } private void ApplyOutline(TrackedMapEntity entry, float alpha, float mainScale, bool mainVisible) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) SpriteRenderer outlineRenderer = entry.OutlineRenderer; if (!((Object)(object)outlineRenderer == (Object)null)) { Color outlineColor = _config.GetOutlineColor(); outlineColor.a = Mathf.Clamp01(alpha); float num = Mathf.Clamp(_config.OutlineScale.Value, 1f, 2f); float num2 = (((Object)(object)entry.ArrowRenderer != (Object)null && (Object)(object)((Component)outlineRenderer).transform.parent == (Object)(object)((Component)entry.ArrowRenderer).transform) ? num : (mainScale * num)); outlineRenderer.sprite = _arrowSprite; outlineRenderer.color = outlineColor; ((Component)outlineRenderer).transform.localScale = Vector3.one * num2; ((Renderer)outlineRenderer).enabled = _config.OutlineEnabled.Value && mainVisible; } } private SpriteRenderer CreateOutlineRenderer(Transform mapEntityTransform, SpriteRenderer arrowRenderer) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0074: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DarkSpider Map Tracker Outline"); val.transform.SetParent(mapEntityTransform, false); val.transform.localPosition = ((Component)arrowRenderer).transform.localPosition; val.transform.localRotation = ((Component)arrowRenderer).transform.localRotation; val.transform.localScale = Vector3.one; SpriteRenderer val2 = val.AddComponent(); val2.sprite = _arrowSprite; val2.color = _config.GetOutlineColor(); ((Renderer)val2).sortingLayerID = ((Renderer)arrowRenderer).sortingLayerID; ((Renderer)val2).sortingOrder = ((Renderer)arrowRenderer).sortingOrder - 1; ((Renderer)val2).enabled = false; return val2; } private static GameObject GetVisualObject(object source) { PlayerAvatar val = (PlayerAvatar)((source is PlayerAvatar) ? source : null); if (val != null) { return ((Object)(object)val.playerAvatarVisuals != (Object)null) ? ((Component)val.playerAvatarVisuals).gameObject : ((Component)val).gameObject; } EnemyParent val2 = (EnemyParent)((source is EnemyParent) ? source : null); if (val2 == null) { return null; } Enemy enemy = ReflectionCache.GetEnemy(val2); if ((Object)(object)enemy == (Object)null) { return null; } GameObject val3 = null; if (val2.enemyName != "Bella") { val3 = TryGetVisionObject(enemy); if ((Object)(object)val3 == (Object)null) { val3 = TryGetAnimatorObject(val2.EnableObject); } } else { val3 = TryGetTricycleTargetObject(enemy); } return ((Object)(object)val3 != (Object)null) ? val3 : ((Component)enemy).gameObject; } private static GameObject TryGetVisionObject(Enemy enemy) { try { EnemyVision componentInChildren = ((Component)enemy).GetComponentInChildren(); return ((Object)(object)componentInChildren?.VisionTransform != (Object)null) ? ((Component)componentInChildren.VisionTransform).gameObject : null; } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)("Failed to read enemy vision transform: " + ex.Message)); } return null; } } private static GameObject TryGetTricycleTargetObject(Enemy enemy) { try { EnemyTricycle componentInChildren = ((Component)enemy).GetComponentInChildren(); return ((Object)(object)componentInChildren?.followTargetTransform != (Object)null) ? ((Component)componentInChildren.followTargetTransform).gameObject : null; } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)("Failed to read EnemyTricycle target: " + ex.Message)); } return null; } } private static GameObject TryGetAnimatorObject(GameObject rootObject) { if ((Object)(object)rootObject == (Object)null) { return null; } Component[] componentsInChildren = rootObject.GetComponentsInChildren(true); Component[] array = componentsInChildren; foreach (Component val in array) { if (!((Object)(object)val == (Object)null)) { Type type = ((object)val).GetType(); if (type.FullName == "UnityEngine.Animator" || type.Name == "Animator") { return val.gameObject; } } } return null; } private static bool IsLocalPlayer(PlayerAvatar playerAvatar) { return (Object)(object)playerAvatar != (Object)null && (ReflectionCache.IsPlayerLocal(playerAvatar) || (Object)(object)playerAvatar == (Object)(object)PlayerAvatar.instance || (Object)(object)playerAvatar == (Object)(object)PlayerController.instance?.playerAvatarScript); } private static bool IsEnemyActive(EnemyParent enemyParent) { return (Object)(object)enemyParent != (Object)null && (Object)(object)enemyParent.EnableObject != (Object)null && enemyParent.EnableObject.activeInHierarchy; } private static bool IsPlayerDead(PlayerAvatar playerAvatar) { return (Object)(object)playerAvatar == (Object)null || ReflectionCache.IsPlayerDisabled(playerAvatar); } private TrackedMapEntity Find(object source) { if (source == null) { return null; } return _enemyTrackers.FirstOrDefault((TrackedMapEntity entry) => entry.Source == source) ?? _playerTrackers.FirstOrDefault((TrackedMapEntity entry) => entry.Source == source); } private static bool IsValid(TrackedMapEntity entry) { return entry != null && entry.Source != null && (Object)(object)entry.MapEntity != (Object)null && (Object)(object)entry.ArrowRenderer != (Object)null; } private static void SetTrackersVisible(List trackers, bool visible) { foreach (TrackedMapEntity tracker in trackers) { SetRendererPairEnabled(tracker, visible); } } private static void SetRendererPairEnabled(TrackedMapEntity entry, bool visible) { if ((Object)(object)entry?.ArrowRenderer != (Object)null) { ((Renderer)entry.ArrowRenderer).enabled = visible; } if ((Object)(object)entry?.OutlineRenderer != (Object)null) { ((Renderer)entry.OutlineRenderer).enabled = visible; } } private static void DestroyTrackers(List trackers) { foreach (TrackedMapEntity tracker in trackers) { DestroyTracker(tracker); } } private static void DestroyTracker(TrackedMapEntity entry) { if ((Object)(object)entry?.MapEntity != (Object)null) { Object.Destroy((Object)(object)((Component)entry.MapEntity).gameObject); } } } internal sealed class MapZoomController { private readonly PluginConfig _config; internal MapZoomController(PluginConfig config) { _config = config; } internal void CaptureDefaultZoom() { if ((Object)(object)MapPatch.MapCamera != (Object)null && MapPatch.DefaultMapZoom <= 0f) { MapPatch.DefaultMapZoom = MapPatch.MapCamera.orthographicSize; } } internal void Tick() { HandleZoomInput(); ApplyZoom(); } internal void ResetZoom() { if (!((Object)(object)MapPatch.MapCamera == (Object)null) && !(MapPatch.DefaultMapZoom <= 0f)) { MapPatch.MapCamera.orthographicSize = MapPatch.DefaultMapZoom; } } private void ApplyZoom() { if (!((Object)(object)MapPatch.MapCamera == (Object)null) && !(MapPatch.DefaultMapZoom <= 0f)) { MapPatch.MapCamera.orthographicSize = MapPatch.DefaultMapZoom * Mathf.Clamp(_config.MapZoomMultiplier.Value, 0.25f, 5f); } } private void HandleZoomInput() { if (!IsMapOpen()) { return; } MapZoomInputMode value = _config.ZoomInputMode.Value; if (value == MapZoomInputMode.Disabled) { return; } float num = _config.MapZoomMultiplier.Value; float num2 = Mathf.Clamp(_config.ZoomStep.Value, 0.05f, 1f); bool flag = false; if (value == MapZoomInputMode.MouseWheel || value == MapZoomInputMode.MouseWheelAndKeyboard) { float mouseWheelDelta = GetMouseWheelDelta(); if (Mathf.Abs(mouseWheelDelta) > 0.01f) { num -= mouseWheelDelta * num2; flag = true; } } if (value == MapZoomInputMode.Keyboard || value == MapZoomInputMode.MouseWheelAndKeyboard) { if (IsConfiguredKeyDown(_config.ZoomInKey.Value)) { num -= num2; flag = true; } if (IsConfiguredKeyDown(_config.ZoomOutKey.Value)) { num += num2; flag = true; } } if (flag) { _config.MapZoomMultiplier.Value = Mathf.Clamp(num, 0.25f, 5f); } } private static bool IsMapOpen() { if ((Object)(object)Map.Instance != (Object)null && Map.Instance.Active) { return true; } Camera mapCamera = MapPatch.MapCamera; return (Object)(object)mapCamera != (Object)null && ((Component)mapCamera).gameObject.activeInHierarchy && ((Behaviour)mapCamera).enabled; } private static float GetMouseWheelDelta() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Input.mouseScrollDelta.y; } private static bool IsConfiguredKeyDown(string keyName) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrWhiteSpace(keyName)) { return false; } string value = NormalizeKeyName(keyName); if (!Enum.TryParse(value, ignoreCase: true, out KeyCode result)) { return false; } return Input.GetKeyDown(result); } private static string NormalizeKeyName(string keyName) { string text = keyName.Trim(); if (text == "+" || text == "=") { return "Equals"; } if (text == "-" || text == "_") { return "Minus"; } if (text.Equals("Plus", StringComparison.OrdinalIgnoreCase)) { return "Equals"; } return text; } } internal static class ReflectionCache { private static readonly FieldInfo EnemyParentEnemyField = AccessTools.Field(typeof(EnemyParent), "Enemy"); private static readonly FieldInfo EnemyEnemyParentField = AccessTools.Field(typeof(Enemy), "EnemyParent"); private static readonly FieldInfo PlayerLocalField = AccessTools.Field(typeof(PlayerAvatar), "isLocal"); private static readonly FieldInfo PlayerDisabledField = AccessTools.Field(typeof(PlayerAvatar), "isDisabled"); private static readonly FieldInfo PlayerCosmeticsField = AccessTools.Field(typeof(PlayerAvatar), "playerCosmetics"); private static readonly FieldInfo PlayerCosmeticsColorsField = AccessTools.Field(typeof(PlayerCosmetics), "colorsEquipped"); private static readonly FieldInfo MetaManagerInstanceField = AccessTools.Field(typeof(MetaManager), "instance"); private static readonly FieldInfo MetaManagerColorsField = AccessTools.Field(typeof(MetaManager), "colors"); private static readonly FieldInfo SemiColorColorField = AccessTools.Field(typeof(SemiColor), "color"); internal static Enemy GetEnemy(EnemyParent enemyParent) { if ((Object)(object)enemyParent == (Object)null) { return null; } try { object? obj = EnemyParentEnemyField?.GetValue(enemyParent); return (Enemy)((obj is Enemy) ? obj : null); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)("Failed to read EnemyParent.Enemy: " + ex.Message)); } return null; } } internal static EnemyParent GetEnemyParent(Enemy enemy) { if ((Object)(object)enemy == (Object)null) { return null; } try { object? obj = EnemyEnemyParentField?.GetValue(enemy); return (EnemyParent)((obj is EnemyParent) ? obj : null); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)("Failed to read Enemy.EnemyParent: " + ex.Message)); } return null; } } internal static bool IsPlayerDisabled(PlayerAvatar playerAvatar) { if ((Object)(object)playerAvatar == (Object)null) { return true; } try { object obj = PlayerDisabledField?.GetValue(playerAvatar); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)("Failed to read PlayerAvatar.isDisabled: " + ex.Message)); } return false; } } internal static bool IsPlayerLocal(PlayerAvatar playerAvatar) { if ((Object)(object)playerAvatar == (Object)null) { return false; } try { object obj = PlayerLocalField?.GetValue(playerAvatar); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)("Failed to read PlayerAvatar.isLocal: " + ex.Message)); } return false; } } internal static Color? TryReadPlayerHeadTopColor(PlayerAvatar playerAvatar) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) try { object? obj = PlayerCosmeticsField?.GetValue(playerAvatar); PlayerCosmetics obj2 = (PlayerCosmetics)((obj is PlayerCosmetics) ? obj : null); if (!(PlayerCosmeticsColorsField?.GetValue(obj2) is int[] array) || array.Length <= 5) { return null; } int num = array[5]; object? obj3 = MetaManagerInstanceField?.GetValue(null); MetaManager obj4 = (MetaManager)((obj3 is MetaManager) ? obj3 : null); if (!(MetaManagerColorsField?.GetValue(obj4) is List list) || list.Count == 0) { return null; } if (num < 0 || num >= list.Count) { num = 0; } object obj5 = SemiColorColorField?.GetValue(list[num]); if (obj5 is Color) { Color value = (Color)obj5; if (true) { return value; } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogDebug((object)("Failed to read player HeadTopMesh color: " + ex.Message)); } } return null; } } internal sealed class TrackedMapEntity { internal object Source; internal MapCustomEntity MapEntity; internal SpriteRenderer ArrowRenderer; internal SpriteRenderer OutlineRenderer; internal bool Visible; internal bool IsPlayer; } [BepInPlugin("DarkSpider90.MapTracker", "DarkSpider Map Tracker", "0.3.1")] internal sealed class Plugin : BaseUnityPlugin { private const string ModGuid = "DarkSpider90.MapTracker"; private const string ModName = "DarkSpider Map Tracker"; private const string ModVersion = "0.3.1"; private Harmony _harmony; private PluginConfig _config; private MapZoomController _zoomController; private MapTrackerController _trackerController; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; _config = new PluginConfig(((BaseUnityPlugin)this).Config); _zoomController = new MapZoomController(_config); _trackerController = new MapTrackerController(_config); _harmony = new Harmony("DarkSpider90.MapTracker"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); ((BaseUnityPlugin)this).Logger.LogInfo((object)"DarkSpider Map Tracker 0.3.1 loaded."); } private void OnDestroy() { _zoomController?.ResetZoom(); _trackerController?.Clear(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal void OnMapAwake(Map map) { _trackerController?.OnMapAwake(map); _zoomController?.CaptureDefaultZoom(); } internal void TickMap(Map map) { if (!((Object)(object)map == (Object)null) && !((Object)(object)Map.Instance == (Object)null)) { if (!IsLevelReady() || !_config.ModEnabled.Value) { _trackerController?.SetAllVisible(visible: false); _zoomController?.ResetZoom(); } else { _zoomController?.Tick(); _trackerController?.Tick(map); } } } internal void RegisterToMap(object source) { _trackerController?.Register(source); } internal void ShowToMap(object source) { _trackerController?.Show(source); } internal void HideFromMap(object source) { _trackerController?.Hide(source); } private static bool IsLevelReady() { try { return SemiFunc.RunIsLevel(); } catch { return false; } } } internal static class TriangleSpriteFactory { internal static Sprite Create(string name, int size) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)5, false); ((Object)val).name = name; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 1f, 1f, 0f); Color white = Color.white; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { val.SetPixel(j, i, val2); } } Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor((float)size * 0.5f, (float)size * 0.88f); Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor((float)size * 0.18f, (float)size * 0.18f); Vector2 val5 = default(Vector2); ((Vector2)(ref val5))..ctor((float)size * 0.82f, (float)size * 0.18f); Vector2[] polygon = (Vector2[])(object)new Vector2[3] { val3, val5, val4 }; Vector2 point = default(Vector2); for (int k = 0; k < size; k++) { for (int l = 0; l < size; l++) { ((Vector2)(ref point))..ctor((float)l + 0.5f, (float)k + 0.5f); if (IsInsidePolygon(point, polygon)) { val.SetPixel(l, k, white); } } } val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), (float)size); } private static bool IsInsidePolygon(Vector2 point, Vector2[] polygon) { //IL_001d: 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) //IL_0060: 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) bool flag = false; int num = polygon.Length - 1; for (int i = 0; i < polygon.Length; i++) { if (polygon[i].y > point.y != polygon[num].y > point.y) { float num2 = (polygon[num].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[num].y - polygon[i].y) + polygon[i].x; if (point.x < num2) { flag = !flag; } } num = i; } return flag; } } } namespace DarkSpider.MapTracker.Patches { [HarmonyPatch(typeof(EnemyDirector))] internal static class EnemyDirectorPatch { [HarmonyPatch("FirstSpawnPointAdd")] [HarmonyPostfix] private static void FirstSpawnPointAdd(EnemyParent _enemyParent) { if (!((Object)(object)_enemyParent == (Object)null)) { Plugin.Instance?.RegisterToMap(_enemyParent); Plugin.Instance?.ShowToMap(_enemyParent); } } } [HarmonyPatch(typeof(EnemyHealth))] internal static class EnemyHealthPatch { [HarmonyPatch("DeathRPC")] [HarmonyPostfix] private static void DeathRPC(Enemy ___enemy) { EnemyParent enemyParent = ReflectionCache.GetEnemyParent(___enemy); if ((Object)(object)enemyParent != (Object)null) { Plugin.Instance?.HideFromMap(enemyParent); } } } [HarmonyPatch(typeof(EnemyParent))] internal static class EnemyParentPatch { [HarmonyPatch("Setup")] [HarmonyPostfix] private static void Setup(EnemyParent __instance) { Plugin.Instance?.RegisterToMap(__instance); } [HarmonyPatch("Spawn")] [HarmonyPostfix] private static void Spawn(EnemyParent __instance) { Plugin.Instance?.RegisterToMap(__instance); Plugin.Instance?.ShowToMap(__instance); } [HarmonyPatch("SpawnRPC")] [HarmonyPostfix] private static void SpawnRPC(EnemyParent __instance) { Plugin.Instance?.RegisterToMap(__instance); Plugin.Instance?.ShowToMap(__instance); } [HarmonyPatch("DespawnRPC")] [HarmonyPostfix] private static void DespawnRPC(EnemyParent __instance) { Plugin.Instance?.HideFromMap(__instance); } } [HarmonyPatch(typeof(Map))] internal static class MapPatch { internal static Camera MapCamera; internal static float DefaultMapZoom; [HarmonyPatch("Awake")] [HarmonyPostfix] private static void Awake(Map __instance, ref Transform ___playerTransformTarget) { if ((Object)(object)___playerTransformTarget != (Object)null) { MapCamera = ((Component)___playerTransformTarget).GetComponentInChildren(); if ((Object)(object)MapCamera != (Object)null) { DefaultMapZoom = MapCamera.orthographicSize; } } Plugin.Instance?.OnMapAwake(__instance); } [HarmonyPatch("Update")] [HarmonyPostfix] private static void Update(Map __instance) { Plugin.Instance?.TickMap(__instance); } } [HarmonyPatch(typeof(PlayerAvatar))] internal static class PlayerAvatarPatch { [HarmonyPatch("LateStart")] [HarmonyPostfix] private static void LateStart(PlayerAvatar __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance == (Object)(object)PlayerController.instance?.playerAvatarScript)) { Plugin.Instance?.RegisterToMap(__instance); Plugin.Instance?.ShowToMap(__instance); } } [HarmonyPatch("ReviveRPC")] [HarmonyPostfix] private static void ReviveRPC(PlayerAvatar __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance == (Object)(object)PlayerController.instance?.playerAvatarScript)) { Plugin.Instance?.RegisterToMap(__instance); Plugin.Instance?.ShowToMap(__instance); } } [HarmonyPatch("PlayerDeathRPC")] [HarmonyPostfix] private static void PlayerDeathRPC(PlayerAvatar __instance) { Plugin.Instance?.HideFromMap(__instance); } } [HarmonyPatch(typeof(EnemySlowMouth))] internal static class SpewerAttachmentPatch { [HarmonyPatch("UpdateStateRPC")] [HarmonyPostfix] private static void UpdateStateRPC(EnemySlowMouth __instance, Enemy ___enemy) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null || (Object)(object)___enemy == (Object)null) { return; } EnemyParent enemyParent = ReflectionCache.GetEnemyParent(___enemy); if (!((Object)(object)enemyParent == (Object)null)) { if ((int)__instance.currentState == 9) { Plugin.Instance?.HideFromMap(enemyParent); } else if ((int)__instance.currentState == 11) { Plugin.Instance?.ShowToMap(enemyParent); } } } } }