diff --git a/Auto Map Pins Configurable/AMP_Configurable.Commands.cs b/Auto Map Pins Configurable/AMP_Configurable.Commands.cs deleted file mode 100644 index fad7f51..0000000 --- a/Auto Map Pins Configurable/AMP_Configurable.Commands.cs +++ /dev/null @@ -1,694 +0,0 @@ -using AMP_Configurable.Modules; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using UnityEngine; -using Utilities; - - -namespace AMP_Configurable.Commands -{ - public static class AMP_Commands - { - public static int pageSize = 11; - private static Vector3 chatPos = new Vector3(0.0f, -99f); - private static ModConsoleOpt consoleOpt = null; - private static List filterList = new List() - { - "Berries", - "Blueberries", - "Carrot", - "Cloudberries", - "Copper", - "Crypt", - "DragonEgg", - "Draugr", - "Flametal", - "Greydwarf", - "Iron", - "Leviathan", - "Mushroom", - "Obsidian", - "Serpent", - "Silver", - "Skelton", - "SunkenCrypt", - "Surtling", - "Thistle", - "Tin", - "TrollCave", - "Turnip" - }; - - - public static Dictionary commandList = new Dictionary() - { - { - "/AMP-Clear", - "[PIN] - Clear the selected type of saved pins. No parameter provided will return a list of available pins. -1 will clear all saved pins." - }, - { - "/AMP-ClearAll", - "- Clear all pins created by the AMP mod (including temporary ones around you)." - }, - { - "/AMP-Filter", - "[PIN] - Filter the selected Pin. No parameter provided will list all pins. -1 will show all pins." - }, - { - "/AMP-FilterList", - "- Displays the list of currently filtered pins." - } - }; - - internal static ModConsoleOpt ConsoleOpt - { - get => consoleOpt; - set => consoleOpt = value; - } - - public static void Announce() - { - try - { - commandList = commandList.OrderBy(obj => obj.Key).ToDictionary((obj => obj.Key), (obj => obj.Value)); - filterList.Sort(); - Patches.AMPCommandPatcher.InitPatch(); - } - catch (Exception ex) - { - } - } - - public static void ProcessCommands( - string inCommand, - GameObject go = null) - { - if (string.IsNullOrEmpty(inCommand)) - return; - if (Console.instance != null) - Console.instance.SetPrivateField("m_lastEntry", inCommand); - string[] strArray = inCommand.Split(';'); - foreach (string str in strArray) - { - string inCommand1 = str.Trim(); - if (!ProcessCommand(inCommand1, go)) - { - if (strArray.Length > 1) - { - Console.instance.m_input.text = inCommand1; - Console.instance.InvokePrivateMethod("InputText", null); - } - Console.instance.m_input.text = string.Empty; - } - } - } - - public static bool ProcessCommand( - string inCommand, - GameObject go = null) - { - if (string.IsNullOrEmpty(inCommand) || string.IsNullOrWhiteSpace(inCommand)) - return true; - inCommand = inCommand.Trim(); - string[] strArray1 = inCommand.Split(' '); - if (inCommand.StartsWith("help")) - { - Console.instance.Print("/AMP? [Page] - AMP Commands - Ex /AMP? 1"); - return false; - } - if (strArray1[0].Equals("/AMP?")) - { - int result = 1; - if (strArray1.Length > 1 && int.TryParse(strArray1[1], out result)) - { - if (result > Mathf.Ceil((commandList.Count / pageSize)) + (commandList.Count % pageSize == 0 ? 0.0 : 1.0)) - result = Mathf.RoundToInt(Mathf.Ceil((float)(commandList.Count / pageSize)) + (commandList.Count % pageSize == 0 ? 0.0f : 1f)); - List stringList1 = new List(commandList.Keys); - List stringList2 = new List(commandList.Values); - PrintOut("Command List Page " + result + " / " + (float)(Mathf.Ceil((commandList.Count / pageSize)) + (commandList.Count % pageSize == 0 ? 0.0 : 1.0))); - for (int index = pageSize * result - pageSize; index < (commandList.Count > pageSize * (result + 1) - pageSize ? pageSize * (result + 1) - pageSize : commandList.Count); ++index) - PrintOut(stringList1[index] + " " + stringList2[index]); - } - else - PrintOut("Type /AMP? # to see the help for that page number. Ex. /? 1"); - return true; - } - if (commandList.ContainsKey(strArray1[0]) && Player.m_localPlayer == null) - { - PrintOut("Where are you trying to run these commands? We can't process them in the real world!"); - return true; - } - - if (strArray1[0].Equals("/AMP-Clear")) - { - if (strArray1.Length == 1) - { - foreach (string text in filterList.OrderBy((q => q)).ToList()) - PrintOut(text); - } - else if (strArray1.Length >= 2) - { - //display all pins - if (strArray1[1].Equals("-1")) - { - foreach (Minimap.PinData pins in Mod.savedPins) - { - if ((int)pins.m_type >= 100 && pins.m_save) - { - Minimap.instance.RemovePin(pins); - } - } - PrintOut("Cleared all saved pins."); - } - else - { - string str1 = string.Empty; - string str2; - if (strArray1.Length > 2) - { - foreach (string str3 in strArray1) - { - if (!str3.Equals(strArray1[0])) - str1 = str1 + " " + str3; - } - str2 = str1.Trim(); - } - else - str2 = strArray1[1]; - - if (filterList.Contains(str2)) - { - PinnedObject.loadData(null, str2); - - foreach (Minimap.PinData pins in Mod.savedPins) - { - if ((int)pins.m_type >= 100 && pins.m_save && (int)pins.m_type == PinnedObject.pType) - { - Minimap.instance.RemovePin(pins); - } - } - PrintOut("Cleared " + str2 + " pins"); - } - else - PrintOut("Failed to clear pins '" + str2 + "'. Check parameters! Ex. /AMP-Clear, /AMP-Clear -1, /AMP-Clear Berries"); - } - } - else - PrintOut("Failed to filter pins. Check parameters! Ex. /AMP-Clear, /AMP-Clear -1, /AMP-Clear Berries"); - return true; - } - - if (strArray1[0].Equals("/AMP-ClearAll")) - { - foreach (Minimap.PinData pins in Mod.savedPins) - { - if ((int)pins.m_type >= 100) - { - Minimap.instance.RemovePin(pins); - } - } - PrintOut("Cleared all AMP pins, included temporary ones near the player."); - return true; - } - - if (strArray1[0].Equals("/AMP-Filter")) - { - if (strArray1.Length == 1) - { - foreach (string text in filterList.OrderBy((q => q)).ToList()) - PrintOut(text); - } - else if (strArray1.Length >= 2) - { - //display all pins - if (strArray1[1].Equals("-1")) - { - foreach (Minimap.PinData pins in Mod.autoPins) - { - pins.m_uiElement.gameObject.SetActive(true); - } - Mod.filteredPins.Clear(); - PrintOut("Showing all pins"); - } - else - { - string str1 = string.Empty; - string str2; - if (strArray1.Length > 2) - { - foreach (string str3 in strArray1) - { - if (!str3.Equals(strArray1[0])) - str1 = str1 + " " + str3; - } - str2 = str1.Trim(); - } - else - str2 = strArray1[1]; - - if (filterList.Contains(str2)) - { - PinnedObject.loadData(null, str2); - - if (Mod.filteredPins.Contains(PinnedObject.pType.ToString())) - { - PrintOut("Showing Filtered Pin: " + str2); - Mod.filteredPins.Remove(PinnedObject.pType.ToString()); - } - else - { - Mod.filteredPins.Add(PinnedObject.pType.ToString()); - PrintOut("Filtering Pins: " + str2); - } - } - else - PrintOut("Failed to filter pins '" + str2 + "'. Check parameters! Ex. /AMP-Filter, /AMP-Filter -1, /AMP-Filter Berries"); - } - } - else - PrintOut("Failed to filter pins. Check parameters! Ex. /AMP-Filter, /AMP-Filter -1, /AMP-Filter Berries"); - return true; - } - - if (strArray1[0].Equals("/AMP-FilterList")) - { - string output = ""; - - for (int x = 0; x < Mod.filteredPins.Count(); x++) - { - PinnedObject.loadData(null, Mod.filteredPins[x]); - - - if (output == null || output == "") - output = PinnedObject.aName; - else - output += ", " + PinnedObject.aName; - } - - PrintOut("Currently filtering pins: " + output); - return true; - } - - return true; - } - - public static void PrintOut(string text) - { - if (text.Equals(string.Empty) || text.Equals(" ")) - return; - if (Console.instance != null) - { - Console.instance.Print("[AMP Commands] " + text); - } - } - } - - public class AMPLoader : MonoBehaviour - { - private static GameObject _AMPGameObject; - private static bool FirstLoad = true; - private static bool InitLogging = false; - private static AMPModuleController AMPModuleController; - - public static void Unload() - { - Destroy(_AMPGameObject, 0.0f); - _AMPGameObject = null; - } - - public static void Reload() - { - Unload(); - Init(); - } - - public static GameObject Load - { - get => _AMPGameObject; - set => _AMPGameObject = value; - } - - private void Start() => Init(); - - public static void Main(string[] args) => InitThreading(); - - public static void InitThreading() => new Thread(() => - { - Thread.Sleep(5000); - Init(); - }).Start(); - - public static void InitWithLog() - { - InitLogging = true; - Init(); - } - - public static void Init() - { - _AMPGameObject = new GameObject("AMP Commands"); - if (InitLogging) - InitLogging = false; - - if (FirstLoad) - ResourceUtils.Logz(new string[1] - { - "Commands" - }, new string[1] { "SUCCESS!" }); - - CheckForUnknownInstance(); - Load.transform.parent = null; - Transform parent = Load.transform.parent; - if (parent != null && parent.gameObject != Load) - parent.parent = Load.transform; - _AMPGameObject.AddComponent(); - DontDestroyOnLoad(_AMPGameObject); - FirstLoad = false; - } - - public static void CheckForUnknownInstance() - { - foreach (GameObject gameObject in ((IEnumerable)Resources.FindObjectsOfTypeAll()).Where(obj => obj.name == "AMP Commands")) - { - if (gameObject != _AMPGameObject) - { - Destroy(gameObject); - - } - } - } - - private void OnDestroy() => Unload(); - } - - public class AMPModuleController : MonoBehaviour - { - private static Version AMPMainVersion = new Version(1, 1, 3); - internal ResourceUtils.Status AMPMainStatus; - private bool FirstLoad = true; - private bool NeedLoadModules = true; - private bool NeedRetry; - private bool ErrorMonitor; - private int RetryCount = 1; - private int RetryCountMax = 3; - private ModConsoleOpt moduleConsole; - - private List MenuOptions { get; set; } = new List(); - - private List RetryModule { get; set; } = new List(); - - public void Start() - { - AMPMainStatus = ResourceUtils.Status.Loading; - //ResourceUtils.Logz(new string[2] - //{ - // "AMP", - // "NOTIFY" - //}, new string[2] { "LOADING...", "MODULE LOADING..." }); - BeginMainMenu(); - - Init(); - } - - public void Update() - { - if (!FirstLoad) - { - if (AMPMainStatus == ResourceUtils.Status.Loading && NeedLoadModules && !NeedRetry) - { - foreach (AMPBaseModule menuOption in MenuOptions) - { - //ResourceUtils.Logz(new string[3] - //{ - // "AMP", - // "MODULE", - // "NOTIFY" - //}, new string[2] - //{ - // "NAME: " + menuOption.ModuleName.ToUpper(), - // "STATUS: " + menuOption.ModuleStatus.ToString().ToUpper() - //}); - if (menuOption.ModuleStatus != ResourceUtils.Status.Ready) - { - NeedRetry = true; - RetryModule.Add(menuOption); - } - } - if (!NeedRetry) - { - AMPMainStatus = ResourceUtils.Status.Ready; - ErrorMonitor = true; - RetryCount = 1; - } - if (AMPMainStatus == ResourceUtils.Status.Ready && MenuOptions.Count > 0) - { - NeedLoadModules = false; - //ResourceUtils.Logz(new string[2] - //{ - // "AMP", - // "NOTIFY" - //}, new string[2] - //{ - // MenuOptions.Count.ToString() + " MODULES LOADED", - // "AMP READY." - //}); - } - else if (AMPMainStatus == ResourceUtils.Status.Error || MenuOptions.Count <= 0) - AMP_Commands.PrintOut("Failed to load commands"); - //ResourceUtils.Logz(new string[2] - //{ - // "AMP", - // "NOTIFY" - //}, new string[2] - //{ - // MenuOptions.Count.ToString() + " MODULES LOADED", - // "AMP FAILED TO LOAD MODULES." - //}, LogType.Error); - } - else if (AMPMainStatus == ResourceUtils.Status.Loading && NeedRetry) - { - if (RetryCount < RetryCountMax + 1) - { - int index = 0; - while (true) - { - int num = index; - int? count = RetryModule?.Count; - int valueOrDefault = count.GetValueOrDefault(); - if (num < valueOrDefault & count.HasValue) - { - //ResourceUtils.Logz(new string[4] - //{ - // "AMP", - // "MODULE", - // "NOTIFY", - // "RECHECK " + RetryCount - //}, new string[2] - //{ - // "NAME: " + RetryModule[index].ModuleName.ToUpper(), - // "STATUS: " + RetryModule[index].ModuleStatus.ToString().ToUpper() - //}); - if (RetryModule[index].ModuleStatus != ResourceUtils.Status.Ready) - { - AMPMainStatus = ResourceUtils.Status.Loading; - NeedRetry = true; - } - else if (RetryModule[index].ModuleStatus == ResourceUtils.Status.Ready) - { - RetryModule.Remove(RetryModule[index]); - if (RetryModule.Count == 0) - break; - } - ++index; - } - else - goto label_24; - } - AMPMainStatus = ResourceUtils.Status.Ready; - label_24: - ++RetryCount; - } - if (MenuOptions.Count <= 0) - AMPMainStatus = ResourceUtils.Status.Error; - if (AMPMainStatus == ResourceUtils.Status.Ready) - { - ErrorMonitor = true; - RetryCount = 1; - //ResourceUtils.Logz(new string[2] - //{ - // "AMP", - // "NOTIFY" - //}, new string[2] - //{ - // MenuOptions.Count.ToString() + " MODULES LOADED", - // "AMP READY." - //}); - } - else if (RetryCount >= RetryCountMax + 1) - { - //ResourceUtils.Logz(new string[2] - //{ - // "AMP", - // "NOTIFY" - //}, new string[2] - //{ - // "MODULE NOT MOVING TO READY STATUS.", - // "UNLOADING THE MODULE(S)." - //}, LogType.Warning); - foreach (AMPBaseModule ampBaseModule in RetryModule) - { - if (ampBaseModule.ModuleStatus != ResourceUtils.Status.Ready) - { - ampBaseModule.RemoveModule(); - MenuOptions.Remove(ampBaseModule); - } - } - RetryModule.Clear(); - NeedRetry = false; - AMPMainStatus = ResourceUtils.Status.Loading; - } - } - } - else - FirstLoad = false; - if (ErrorMonitor) - { - int index1 = 0; - while (true) - { - int num = index1; - int? count = MenuOptions?.Count; - int valueOrDefault = count.GetValueOrDefault(); - if (num < valueOrDefault & count.HasValue) - { - AMPBaseModule menuOption1 = MenuOptions[index1]; - if ((menuOption1 != null ? (menuOption1.ModuleStatus == ResourceUtils.Status.Error ? 1 : 0) : 0) != 0 && !RetryModule.Contains(MenuOptions[index1])) - { - //ResourceUtils.Logz(new string[2] - //{ - // "AMP", - // "NOTIFY" - //}, new string[2] - //{ - // "MODULE IN ERROR STATUS.", - // "CHECKING MODULE: " + MenuOptions[index1].ModuleName.ToUpper() - //}, LogType.Warning); - RetryModule.Add(MenuOptions[index1]); - } - else - { - AMPBaseModule menuOption2 = this.MenuOptions[index1]; - if ((menuOption2 != null ? (menuOption2.ModuleStatus == ResourceUtils.Status.Unload ? 1 : 0) : 0) != 0) - { - //ResourceUtils.Logz(new string[2] - //{ - // "AMP", - // "NOTIFY" - //}, new string[1] - //{ - // "MODULE READY TO UNLOAD. UNLOADING MODULE: " + this.MenuOptions[index1].ModuleName.ToUpper() - //}, LogType.Warning); - MenuOptions[index1].RemoveModule(); - MenuOptions.Remove(this.MenuOptions[index1]); - - } - } - ++index1; - } - else - break; - } - List retryModule1 = RetryModule; - // ISSUE: explicit non-virtual call - if ((retryModule1 != null ? ((retryModule1.Count) > 0 ? 1 : 0) : 0) != 0 && RetryCount < RetryCountMax + 1) - { - for (int index2 = 0; index2 < RetryModule.Count; ++index2) - { - if (this.RetryModule[index2].ModuleStatus == ResourceUtils.Status.Ready) - { - this.RetryModule.Remove(this.RetryModule[index2]); - //ResourceUtils.Logz(new string[2] - //{ - // "AMP", - // "NOTIFY" - //}, new string[2] - //{ - // "MODULE READY.", - // "MODULE: " + MenuOptions[index2].ModuleName.ToUpper() - //}); - if (RetryModule.Count == 0) - break; - } - } - ++RetryCount; - } - else - { - List retryModule2 = RetryModule; - // ISSUE: explicit non-virtual call - if ((retryModule2 != null ? ((retryModule2.Count) > 0 ? 1 : 0) : 0) != 0 && RetryCount >= RetryCountMax + 1) - { - foreach (AMPBaseModule ampBaseModule in RetryModule) - { - if (ampBaseModule.ModuleStatus != ResourceUtils.Status.Ready) - { - //ResourceUtils.Logz(new string[2] - //{ - // "AMP", - // "NOTIFY" - //}, new string[2] - //{ - // "COULD NOT RESOLVE ERROR.", - // "UNLOADING THE MODULE: " + ampBaseModule.ModuleName.ToUpper() - //}, LogType.Warning); - ampBaseModule.RemoveModule(); - MenuOptions.Remove(ampBaseModule); - } - } - RetryModule.Clear(); - RetryCount = 1; - if (MenuOptions.Count == 0) - { - this.AMPMainStatus = ResourceUtils.Status.Error; - //ResourceUtils.Logz(new string[2] - //{ - // "AMP", - // "NOTIFY" - //}, new string[2] - //{ - // "NO MODULES LOADED.", - // "TOOLBOX ENTERING ERROR STATE." - //}, LogType.Error); - } - } - } - } - OnUpdate(); - } - - internal List GetOptions() => MenuOptions; - - public void BeginMainMenu() - { - moduleConsole = gameObject.AddComponent(); - - MenuOptions.Add(moduleConsole); - } - - public static T ParseEnum(string value) => (T)Enum.Parse(typeof(T), value, true); - - private void Init() - { - } - - private void OnUpdate() - { - } - - public void OnGUI() - { - } - } -} diff --git a/Auto Map Pins Configurable/AMP_Configurable.Modules.cs b/Auto Map Pins Configurable/AMP_Configurable.Modules.cs index ff6728d..c337eca 100644 --- a/Auto Map Pins Configurable/AMP_Configurable.Modules.cs +++ b/Auto Map Pins Configurable/AMP_Configurable.Modules.cs @@ -1,5 +1,4 @@ -using AMP_Configurable.Commands; -using AMP_Configurable.Patches; +using AMP_Configurable.Patches; using System.Collections.Generic; using UnityEngine; using Utilities; @@ -20,7 +19,6 @@ public ModConsoleOpt() public void Start() { - AMP_Commands.ConsoleOpt = this; Ready(); } @@ -38,7 +36,6 @@ public void HandleConsole() if (Input.GetKeyDown(KeyCode.Return) && text.Equals(string.Empty) && !consoleLastMessage.Equals(string.Empty)) { consoleHistory.Add(consoleLastMessage); - AMP_Commands.ProcessCommands(consoleLastMessage); this.consoleLastMessage = string.Empty; } if (Input.GetKeyDown(KeyCode.UpArrow)) @@ -55,23 +52,16 @@ public void HandleConsole() Console.instance.m_input.caretPosition = Console.instance.m_input.text.Length; } - - private void Update() { HandleConsole(); - } private void OnDestroy() { - if (AMPCommandPatcher.Harmony == null) - return; - AMPCommandPatcher.Harmony.UnpatchSelf(); + } - - private class History { private List history = new List(); diff --git a/Auto Map Pins Configurable/AMP_Configurable.Patches.cs b/Auto Map Pins Configurable/AMP_Configurable.Patches.cs index 5e8770f..b416dbb 100644 --- a/Auto Map Pins Configurable/AMP_Configurable.Patches.cs +++ b/Auto Map Pins Configurable/AMP_Configurable.Patches.cs @@ -1,9 +1,7 @@ -using AMP_Configurable.Commands; -using AMP_Configurable.PinConfig; +using AMP_Configurable.PinConfig; using HarmonyLib; using System; using System.Collections.Generic; -using System.Linq; using UnityEngine; namespace AMP_Configurable.Patches @@ -12,6 +10,7 @@ internal class Minimap_Patch : MonoBehaviour { public static int count = 0; public static bool checkedSavedPins = false; + public static Minimap.MapMode mapMode = Minimap.MapMode.Small; [HarmonyReversePatch] [HarmonyPatch(typeof(Minimap), "ScreenToWorldPoint", new System.Type[] { typeof(Vector3) })] @@ -22,11 +21,7 @@ internal class Minimap_Patch : MonoBehaviour private static void Minimap_Awake() { checkedSavedPins = false; - Mod.addedPinLocs.Clear(); Mod.dupPinLocs.Clear(); - Mod.autoPins.Clear(); - Mod.pinRemList.Clear(); - Mod.savedPins.Clear(); } [HarmonyPatch(typeof(Minimap), "Start")] @@ -42,20 +37,50 @@ private static void Minimap_Awake() } } + // [HarmonyPatch(typeof(Minimap), "AddPin")] + // [HarmonyPrefix] + // private static bool Minimap_AddPin( + // ref Minimap __instance, + // List ___m_pins, + // Vector3 pos, + // Minimap.PinType type, + // string name, + // bool save, + // bool isChecked) + // { + // // bool shouldAddPin = ((type != Minimap.PinType.Death ? 0 : (Mod.SimilarPinExists(pos, type, ___m_pins, name, PinnedObject.aIcon, out Minimap.PinData _) ? 1 : 0)) & (save ? 1 : 0)) == 0; + // // if(shouldAddPin) Mod.Log.LogInfo($"Patches.Minimap.AddPin Attempting to pin {name} [{type}]"); + // // return shouldAddPin; + // Mod.Log.LogInfo($"Patches.Minimap.AddPin Attempting to pin {name} [{type}]"); + // return true; + // } + [HarmonyPatch(typeof(Minimap), "AddPin")] + [HarmonyPostfix] + private static Minimap.PinData Minimap_AddPin_PostFix(Minimap.PinData pin) + { + // Check if the pin is a part of AMPED pinItems and then set data accordingly + if (Mod.pinItems.TryGetValue(pin.m_pos, out PinType pinTypeData)) + { + Mod.pinItems[pin.m_pos].isPinned = true; + Mod.pinItems[pin.m_pos].minimapPin = pin; + Mod.autoPins.Add(pin); + } + return pin; + } + + [HarmonyPatch(typeof(Minimap), "RemovePin", new Type[] { typeof(Minimap.PinData) })] [HarmonyPrefix] - private static bool Minimap_AddPin( - ref Minimap __instance, - List ___m_pins, - Vector3 pos, - Minimap.PinType type, - string name, - bool save, - bool isChecked) + private static void Minimap_RemovePin(ref Minimap __instance, Minimap.PinData pin) { - bool shouldAddPin = ((type != Minimap.PinType.Death ? 0 : (Mod.SimilarPinExists(pos, type, ___m_pins, name, PinnedObject.aIcon, out Minimap.PinData _) ? 1 : 0)) & (save ? 1 : 0)) == 0; - if (Mod.loggingEnabled.Value && shouldAddPin) Mod.Log.LogInfo($"[AMP] Trying to add pin {type}"); - return shouldAddPin; + if (Mod.pinItems.ContainsKey(pin.m_pos)) + { + Mod.pinItems[pin.m_pos].minimapPin = null; + Mod.pinItems[pin.m_pos].isPinned = false; + } + + if(Mod.dupPinLocs.ContainsKey(pin.m_pos)) Mod.dupPinLocs.Remove(pin.m_pos); + if (Mod.autoPins.Contains(pin)) Mod.autoPins.Remove(pin); } [HarmonyPatch(typeof(Minimap), "UpdateProfilePins")] @@ -65,49 +90,84 @@ private static void Minimap_Awake() { if (!checkedSavedPins) { - foreach (Minimap.PinData pins in ___m_pins) + Mod.Log.LogDebug("Minimap.UpdateProfilePins checking saved pins"); + var watch = System.Diagnostics.Stopwatch.StartNew(); + foreach (Minimap.PinData pin in ___m_pins) { - if ((int)pins.m_type >= 100) + if ((int)pin.m_type >= 100) { - if (!Mod.savedPins.Contains(pins)) - Mod.savedPins.Add(pins); + PinnedObject.loadData(null, (int)pin.m_type); + if (PinnedObject.hidePin) + { + Minimap.instance.RemovePin(pin); + continue; + } - PinnedObject.loadData(null, pins.m_type.ToString()); + if (pin.m_type == (Minimap.PinType)PinnedObject.pType) + { + pin.m_icon = PinnedObject.aIcon; + pin.m_worldSize = PinnedObject.pinSize; + if (!PinnedObject.showName) pin.m_name = string.Empty; + } - if (pins.m_type == (Minimap.PinType)PinnedObject.pType && !Mod.filteredPins.Contains(PinnedObject.aName)) + if (Mod.mtypePins.TryGetValue((int)pin.m_type, out PinType pinTypeData)) { - pins.m_icon = PinnedObject.aIcon; - pins.m_worldSize = PinnedObject.pinSize; - if (!PinnedObject.showName) - { - pins.m_name = string.Empty; - } + Mod.pinItems[pin.m_pos] = pinTypeData; + Mod.pinItems[pin.m_pos].minimapPin = pin; } + Mod.autoPins.Add(pin); } } checkedSavedPins = true; - Mod.checkPins(Player_Patches.currPos); + Mod.checkPins(true); + watch.Stop(); + var elapsedMs = watch.ElapsedMilliseconds; + Mod.Log.LogDebug($"Minimap.UpdateProfilePins checking saved pins took {elapsedMs}ms"); } - } - [HarmonyPatch(typeof(Minimap), "UpdatePins")] - [HarmonyPrefix] - private static void Minimap_UpdatePins( + /** Keeping code in comment since UpdatePins will be used in creature tracking feature **/ + // [HarmonyPatch(typeof(Minimap), "UpdatePins")] + // [HarmonyPrefix] + // private static void Minimap_UpdatePins( + // Minimap __instance, + // ref List ___m_pins) + // { + // if (Mod.filteredPins.Count() == 0) + // return; + + // Mod.Log.LogDebug("Minimap: Update Pins - Filtering pins"); + // foreach (Minimap.PinData p in ___m_pins) + // { + // if (Mod.filteredPins.Contains(p.m_type.ToString())) + // { + // Mod.FilterPins(); + // } + // } + // } + + [HarmonyPatch(typeof(Minimap), "SetMapMode")] + [HarmonyPostfix] + private static void Minimap_ChangeMapMode( Minimap __instance, - ref List ___m_pins) + ref Minimap.MapMode ___m_mode) { - if (Mod.filteredPins.Count() == 0) - return; + Mod.Log.LogDebug($"Minimap.SetMapMode - Mode changed to {___m_mode}"); + var watch = System.Diagnostics.Stopwatch.StartNew(); - foreach (Minimap.PinData p in ___m_pins) + mapMode = ___m_mode; + foreach (Minimap.PinData pin in Mod.autoPins) { - if (Mod.filteredPins.Contains(p.m_type.ToString())) - { - Mod.FilterPins(); - } + if(!Mod.mtypePins.TryGetValue((int)pin.m_type, out PinType typeConf)) continue; + float new_size = typeConf.size; + if (___m_mode == Minimap.MapMode.Small) + new_size = (typeConf.minimapSize != 0 ? typeConf.minimapSize : typeConf.size) * Mod.minimapSizeMult.Value; + + pin.m_worldSize = new_size; } + watch.Stop(); + Mod.Log.LogDebug($"Minimap.SetMapMode timing {watch.ElapsedMilliseconds}ms"); } [HarmonyPatch(typeof(Minimap), "OnMapRightClick")] @@ -116,22 +176,16 @@ private static void Minimap_Awake() Minimap __instance, ref List ___m_pins) { + Mod.Log.LogDebug("Minimap.OnMapRightClick"); ZLog.Log("[AMP] Right click"); Vector3 worldPoint = ScreenToWorldPoint(__instance, Input.mousePosition); - - //Mod.Log.LogInfo(string.Format("WorldPoint = {0}", worldPoint)); - Minimap.PinData closestPin = Mod.GetNearestPin(worldPoint, 5, ___m_pins); - - //Mod.Log.LogInfo(string.Format("Pin Name - {0}, Pin Icon - {1}, Pin Type {2}", closestPin.m_name, closestPin.m_icon.name, closestPin.m_type)); + Minimap.PinData closestPin = Mod.GetNearestPin(worldPoint, 10, ___m_pins); if (closestPin == null || closestPin.m_icon.name == "mapicon_start" || closestPin.m_type == Minimap.PinType.Death) return true; __instance.RemovePin(closestPin); - Mod.addedPinLocs.Remove(closestPin.m_pos); - Mod.autoPins.Remove(closestPin); - Mod.remPinDict.Remove(closestPin.m_pos); return false; } @@ -141,196 +195,187 @@ private static void Minimap_Awake() Minimap __instance, ref List ___m_pins) { + Mod.Log.LogDebug("Minimap.OnMapLeftClick"); ZLog.Log("[AMP] Left click"); Vector3 worldPoint = ScreenToWorldPoint(__instance, Input.mousePosition); - Minimap.PinData closestPin = Mod.GetNearestPin(worldPoint, 5, ___m_pins); + Minimap.PinData closestPin = Mod.GetNearestPin(worldPoint, 10, ___m_pins); if (closestPin == null) return true; closestPin.m_checked = !closestPin.m_checked; return false; } - } - [HarmonyPatch(typeof(Destructible), "Start")] - internal class DestructiblePatchSpawn + internal class Pin_Registration_Patches : MonoBehaviour { - private static void Postfix(ref Destructible __instance) + [HarmonyPatch(typeof(Destructible), "Start")] + [HarmonyPostfix] + private static void DestructibleSpawnPatch(ref Destructible __instance) { if (!Mod.destructablesEnabled.Value) return; - HoverText hoverTextComp = __instance.GetComponent(); + HoverText comp = __instance.GetComponent(); + if (!comp) return; - if (!hoverTextComp) return; - - string hoverText = hoverTextComp.m_text; - hoverText = hoverText.Replace("(Clone)", ""); - - PinType type = null; - Mod.Log.LogDestructible(hoverText, hoverTextComp.transform.position); - - if (Mod.objectPins.ContainsKey(hoverText)) - type = Mod.mtypePins[Mod.objectPins[hoverText]]; - - if (type != null && !Mod.pinItems.ContainsKey(hoverTextComp.transform.position)) - Mod.pinItems.Add(hoverTextComp.transform.position, type); + string objectId = comp.m_text; + Vector3 position = comp.transform.position; + Mod.pinObject("Destructable Resource", objectId, position); } - } - [HarmonyPatch(typeof(Pickable), "Awake")] - internal class PickablePatchSpawn - { - private static void Postfix(ref Pickable __instance) + [HarmonyPatch(typeof(Pickable), "Awake")] + [HarmonyPostfix] + private static void PickableSpawnPatch(ref Pickable __instance) { if (!Mod.pickablesEnabled.Value) return; - Pickable pickableComp = __instance.GetComponent(); + Pickable comp = __instance.GetComponent(); + if (!comp) return; - if (!pickableComp) return; - - string pickableText = pickableComp.name; - pickableText = pickableText.Replace("(Clone)", ""); - PinType type = null; - Mod.Log.LogPickable(pickableText, pickableComp.transform.position); - - if (Mod.objectPins.ContainsKey(pickableText)) - type = Mod.mtypePins[Mod.objectPins[pickableText]]; - - if (type != null && !Mod.pinItems.ContainsKey(pickableComp.transform.position)) - Mod.pinItems.Add(pickableComp.transform.position, type); + string objectId = comp.name; + Vector3 position = comp.transform.position; + Mod.pinObject("Pickable", objectId, position); } - } - [HarmonyPatch(typeof(Location), "Awake")] - internal class LocationPatchSpawn - { - private static void Postfix(ref Location __instance) + [HarmonyPatch(typeof(Location), "Awake")] + [HarmonyPostfix] + private static void LocationSpawnPatch(ref Location __instance) { if (!Mod.locsEnabled.Value) return; - Location locComp = __instance.GetComponent(); + Location comp = __instance.GetComponent(); + if (!comp) return; - if (!locComp) return; - - string locText = locComp.name; - locText = locText.Replace("(Clone)", ""); - PinType type = null; - Mod.Log.LogLocation(locText, locComp.transform.position); + string objectId = comp.name; + Vector3 position = comp.transform.position; + Mod.pinObject("Location", objectId, position); + } - if (Mod.objectPins.ContainsKey(locText)) - type = Mod.mtypePins[Mod.objectPins[locText]]; + [HarmonyPatch(typeof(SpawnArea), "Awake")] + [HarmonyPostfix] + private static void SpawnAreaSpawnPatch(ref Location __instance) + { + if (!Mod.spwnsEnabled.Value) return; + HoverText comp = __instance.GetComponent(); + if (!comp) return; - if (type != null && !Mod.pinItems.ContainsKey(locComp.transform.position)) - Mod.pinItems.Add(locComp.transform.position, type); + string objectId = comp.m_text; + Vector3 position = comp.transform.position; + Mod.pinObject("Spawner", objectId, position); } - } - [HarmonyPatch(typeof(SpawnArea), "Awake")] - internal class SpawnAreaPatchSpawn - { - private static void Postfix(ref SpawnArea __instance) + [HarmonyPatch(typeof(Character), "Awake")] + [HarmonyPostfix] + private static void CharacterSpawnPatch(ref CreatureSpawner __instance) { - if (!Mod.spwnsEnabled.Value) return; - HoverText spawnComp = __instance.GetComponent(); - - if (!spawnComp) return; + if (!Mod.creaturesEnabled.Value) return; + Character comp = __instance.GetComponent(); + if (!comp) return; - string spawnText = spawnComp.m_text; - spawnText = spawnText.Replace("(Clone)", ""); - PinType type = null; - Mod.Log.LogSpawn(spawnText, spawnComp.transform.position); + string objectId = comp.name; + Vector3 position = comp.transform.position; + Mod.pinObject("Creature", objectId, position); + } - if (Mod.objectPins.ContainsKey(spawnText)) - type = Mod.mtypePins[Mod.objectPins[spawnText]]; + [HarmonyPatch(typeof(MineRock), "Start")] + [HarmonyPostfix] + private static void MineRockSpawnPatch(ref MineRock __instance) + { + if (!Mod.destructablesEnabled.Value) return; + MineRock comp = __instance.GetComponent(); + if (!comp) return; - if (type != null && !Mod.pinItems.ContainsKey(spawnComp.transform.position)) - Mod.pinItems.Add(spawnComp.transform.position, type); + string objectId = comp.name; + Vector3 position = comp.transform.position; + Mod.pinObject("Destructable Resource", objectId, position); } - } - [HarmonyPatch(typeof(Character), "Awake")] - internal class CharacterPatchSpawn - { - private static void Postfix(ref CreatureSpawner __instance) + [HarmonyPatch(typeof(Leviathan), "Awake")] + [HarmonyPostfix] + private static void LeviathanSpawnPatch(ref Leviathan __instance) { if (!Mod.creaturesEnabled.Value) return; - Character creatureComp = __instance.GetComponent(); - - if (!creatureComp) return; + Leviathan comp = __instance.GetComponent(); + if (!comp) return; - string creatureText = creatureComp.m_name; - creatureText = creatureText.Replace("(Clone)", ""); - PinType type = null; - Mod.Log.LogCreature(creatureText, creatureComp.transform.position); - - if (Mod.objectPins.ContainsKey(creatureText)) - type = Mod.mtypePins[Mod.objectPins[creatureText]]; - - if (type != null && !Mod.pinItems.ContainsKey(creatureComp.transform.position)) - Mod.pinItems.Add(creatureComp.transform.position, type); + string objectId = comp.name; + Vector3 position = comp.transform.position; + Mod.pinObject("Destructable Resource", objectId, position); } - } - [HarmonyPatch(typeof(MineRock), "Start")] - internal class MineRockPatchSpawn - { - private static void Postfix(ref MineRock __instance) + [HarmonyPatch(typeof(TreeBase), "Awake")] + [HarmonyPostfix] + private static void TreeBaseSpawnPatch(ref TreeBase __instance) { if (!Mod.destructablesEnabled.Value) return; - MineRock mineComp = __instance.GetComponent(); + TreeBase comp = __instance.GetComponent(); + if (!comp) return; - if (!mineComp) return; + string objectId = comp.name; + Vector3 position = comp.transform.position; + Mod.pinObject("Destructable Resource", objectId, position); + } - string mineText = mineComp.name; - PinType type = null; - Mod.Log.LogDestructible(mineText, mineComp.transform.position); + // [HarmonyPatch(typeof(Vagon), "Awake")] + // [HarmonyPostfix] + // private static void VagonSpawnPatch(ref Vagon __instance) + // { + // Vagon cartComp = __instance.GetComponent(); - if (Mod.objectPins.ContainsKey(mineText)) - type = Mod.mtypePins[Mod.objectPins[mineText]]; + // if (!cartComp) return; - if (type != null && !Mod.pinItems.ContainsKey(mineComp.transform.position)) - Mod.pinItems.Add(mineComp.transform.position, type); - } - } + // string cartText = cartComp.m_name; + // cartText = cartText.Replace("(Clone)", "").ToLower(); - [HarmonyPatch(typeof(Leviathan), "Awake")] - internal class LeviathanPatchSpawn - { - private static void Postfix(ref Leviathan __instance) - { - if (!Mod.creaturesEnabled.Value) return; - Leviathan levComp = __instance.GetComponent(); + // Mod.Log.LogDebug($"Found wagon: {cartText} at {cartComp.transform.position.ToString()}"); + // } - if (!levComp) return; + // [HarmonyPatch(typeof(Ship), "Awake")] + // [HarmonyPostfix] + // private static void ShipSpawnPatch(ref Ship __instance) + // { + // Ship shipComp = __instance.GetComponent(); - string levText = levComp.name; - levText = levText.Replace("(Clone)", ""); - PinType type = null; - Mod.Log.LogCreature(levText, levComp.transform.position); + // if (!shipComp) return; - if (Mod.objectPins.ContainsKey(levText)) - type = Mod.mtypePins[Mod.objectPins[levText]]; + // string shipText = shipComp.name; + // shipText = shipText.Replace("(Clone)", "").ToLower(); - if (type != null && !Mod.pinItems.ContainsKey(levComp.transform.position)) - Mod.pinItems.Add(levComp.transform.position, type); - } + // Mod.Log.LogDebug($"Found Ship: {shipText} at {shipComp.transform.position.ToString()}"); + // } + + // [HarmonyPatch(typeof(TeleportWorld), "Awake")] + // [HarmonyPostfix] + // private static void TeleportWorldSpawnPatch(ref TeleportWorld __instance) + // { + // TeleportWorld portalComp = __instance.GetComponent(); + + // if (!portalComp) return; + + // string portalText = portalComp.name; + // portalText = portalText.Replace("(Clone)", "").ToLower(); + + // HoverText hoverComp = __instance.GetComponent(); + // string portalDestination = hoverComp.m_text; + + // Mod.Log.LogDebug($"Found Portal: {portalText} ({portalDestination}) at {portalComp.transform.position.ToString()}"); + // } } + internal class Player_Patches { public static Vector3 currPos; public static Vector3 prevPos; - private const int interval = 30; + public const int interval = 120; [HarmonyPatch(typeof(Player), "Awake")] internal class PlayerAwakePatch { private static void Postfix(ref Player __instance) { - if (!Player.m_localPlayer) + if (!Player.m_localPlayer || !__instance.IsOwner() || Game.IsPaused() || Mod.checkingPins) return; currPos = __instance.transform.position; prevPos = __instance.transform.position; - } } @@ -339,68 +384,24 @@ internal class PlayerUpdatePatch { private static void Postfix(ref Player __instance) { - if (Game.IsPaused()) return; - if (!Player.m_localPlayer) - return; + if (!Player.m_localPlayer || !__instance.IsOwner() || Game.IsPaused() || Mod.checkingPins || Mod.hasMoved) return; Mod.currEnv = EnvMan.instance.GetCurrentEnvironment().m_name; if (Time.frameCount % interval == 0) { currPos = __instance.transform.position; - - if (Vector3.Distance(currPos, prevPos) > 5) - { - Mod.hasMoved = true; - prevPos = currPos; - } - else - { - Mod.hasMoved = false; - } + Mod.hasMoved = Vector3.Distance(currPos, prevPos) > 5; } if (Mod.hasMoved) { - Mod.checkPins(currPos); + Mod.hasMoved = false; + prevPos = currPos; + Mod.Log.LogDebug("Patches.PlayerUpdatePatch player movement detected. Check Pins"); + Mod.checkPins(); } } } } - - internal static class AMPCommandPatcher - { - private static Harmony harmony; - private static bool initComplete; - - public static Harmony Harmony - { - get => harmony; - set => harmony = value; - } - - public static bool InitComplete - { - get => initComplete; - set => initComplete = value; - } - - public static void InitPatch() - { - if (InitComplete) - return; - try - { - harmony = Harmony.CreateAndPatchAll(typeof(AMPCommandPatcher).Assembly, null); - } - catch (Exception ex) - { - AMP_Commands.PrintOut("Something failed, there is a strong possibility another mod blocked this operation."); - } - finally - { - InitComplete = true; - } - } - } } diff --git a/Auto Map Pins Configurable/AMP_Configurable.PinConfig.cs b/Auto Map Pins Configurable/AMP_Configurable.PinConfig.cs index 0cc8373..4e60d83 100644 --- a/Auto Map Pins Configurable/AMP_Configurable.PinConfig.cs +++ b/Auto Map Pins Configurable/AMP_Configurable.PinConfig.cs @@ -6,12 +6,16 @@ namespace AMP_Configurable.PinConfig [Serializable] public class PinType { - public int type; + public int type = 0; public string label; public string icon; - public Sprite sprite; - public int size; + public Sprite sprite = null; + public int size = 20; + public int minimapSize = 0; public string[] object_ids; + public Minimap.PinData minimapPin = null; + public bool isPinned = false; + public string pinCat = ""; } [Serializable] diff --git a/Auto Map Pins Configurable/AMP_Configurable.UI.cs b/Auto Map Pins Configurable/AMP_Configurable.UI.cs new file mode 100644 index 0000000..26984b4 --- /dev/null +++ b/Auto Map Pins Configurable/AMP_Configurable.UI.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; +using System.Reflection.Emit; +using UnityEngine; +using HarmonyLib; + +namespace AMP_Configurable.UI +{ +} diff --git a/Auto Map Pins Configurable/AMP_Configurable.cs b/Auto Map Pins Configurable/AMP_Configurable.cs index 8e4a81c..341b2b2 100644 --- a/Auto Map Pins Configurable/AMP_Configurable.cs +++ b/Auto Map Pins Configurable/AMP_Configurable.cs @@ -1,9 +1,9 @@ using AMP_Configurable.Patches; +using AMP_Configurable.PinConfig; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; -using System; using System.IO; using System.Collections.Generic; using System.Linq; @@ -12,7 +12,7 @@ namespace AMP_Configurable { - [BepInPlugin("amped.mod.auto_map_pins", "AMPED - Auto Map Pins Enhanced", "1.3.4")] + [BepInPlugin("amped.mod.auto_map_pins", "AMPED - Auto Map Pins Enhanced", "1.3.5")] [BepInProcess("valheim.exe")] public class Mod : BaseUnityPlugin { @@ -22,98 +22,159 @@ public class Mod : BaseUnityPlugin public static ConfigEntry modEnabled; public static ConfigEntry diagnosticsEnabled; public static ConfigEntry pinOverlapDistance; - public static ConfigEntry pinRange; + + + public static ConfigEntry pinRange; + public static ConfigEntry pinRangeExpRadiusMatching; + public static ConfigEntry minimapSizeMult; public static ConfigEntry hideAllLabels; public static ConfigEntry hidePinLabels; public static ConfigEntry hidePinTypes; public static ConfigEntry savePinTypes; public static ConfigEntry customPinSizes; public static ConfigEntry loggingEnabled; - public static ConfigEntry customConfigFiles; + public static ConfigEntry objectLogging; + public static ConfigEntry objectLogFilter; + public static ConfigEntry onlyLogUnique; + public static ConfigEntry logKnownPinObjects; - //***ORES***// + //** Pin Category control **// public static ConfigEntry destructablesEnabled; - public static ConfigEntry destructableLoggingEnabled; - - //***PICKABLES***// public static ConfigEntry pickablesEnabled; - public static ConfigEntry pickablesLoggingEnabled; - - //***LOCATIONS***// public static ConfigEntry locsEnabled; - public static ConfigEntry locsLoggingEnabled; - - //***SPAWNERS***// public static ConfigEntry spwnsEnabled; - public static ConfigEntry spwnsLoggingEnabled; - - //***CREATURES***// public static ConfigEntry creaturesEnabled; - public static ConfigEntry creaturesLoggingEnabled; //***PUBLIC VARIABLES***// - public static IDictionary mtypePins = new Dictionary(); - public static IDictionary objectPins = new Dictionary(); - public static List autoPins; - public static List savedPins; - public static List pinRemList; - public static List addedPinLocs; - public static List dupPinLocs; - public static List filteredPins; - public static Vector3 position; - public static Dictionary pinItems = new Dictionary(); - public static Dictionary remPinDict = new Dictionary(); public static bool hasMoved = false; public static bool checkingPins = false; public static string currEnv = ""; + public static string[] filterObjectIds; + public static List uniqueObjectIds = new List(); + + //*** PUBLIC PIN TRACKING VARIABLES ***// + /** mtypePins + * Quick PinType lookups for (int)Minimap.PinData.PinType + * AMPED PinTypes.type defined in .json files + */ + public static Dictionary mtypePins = new Dictionary(); + + /** objectPins + * Quick PinType lookups using objectIds + * AMPED PinTypes.object_ids defined in .json files + */ + public static Dictionary objectPins = new Dictionary(); + + /** Dictionary pinItems + * Collection of discovered pin types keyed by the object's position + * If pinned the pin will be added to the pinItems as PinType.minimapPin + */ + public static Dictionary pinItems = new Dictionary(); + + /** Dictionary pinItems + * Collection of discovered pin types keyed by the object's position + * If pinned the pin will be added to the pinItems as PinType.minimapPin + */ + public static List autoPins = new List(); + + /** dupPinLocs + * Collection of duplicate pins, this is when two objects are too close and only one pin should be created + * The distance is configurable using pinRange. Data managed mainly by the similarPinExists function + */ + public static Dictionary dupPinLocs = new Dictionary(); private void Awake() { Log.ModLogger = Logger; /** General Config **/ - nexusID = Config.Bind("_General_", "1. NexusID", 2199, "Nexus mod ID for updates"); - modEnabled = Config.Bind("_General_", "2. Enabled", true, "Enable this mod"); - - pinOverlapDistance = Config.Bind("1. Pins", "1. PinOverlapDistance", 10, "Distance around pins to prevent overlapping of similar pins"); - pinRange = Config.Bind("1. Pins", "2. Pin Range", 100, "Sets the range that pins will appear on the mini-map. Lower value means you need to be closer to set pin.\nMin 5\nMax 150\nRecommended 50-75"); - if (pinRange.Value < 5) pinRange.Value = 5; - if (pinRange.Value > 150) pinRange.Value = 150; - hideAllLabels = Config.Bind("1. Pins", "3. Hide All Labels", false, "Hide all pin labels.\n*THIS WILL OVERRIDE THE INDIVIDUAL SETTINGS*"); - hidePinLabels = Config.Bind("1. Pins", "4. Hide Pin Label", "", "Hide individual pin type labels.\nValue should be a comma seperated list of pin types."); - hidePinTypes = Config.Bind("1. Pins", "5. Hide Pin Label", "", "Hide individual pin types.\nValue should be a comma seperated list of pin types."); - string defaultSavePinTypes = "Crypt,Troll Cave,Sunken Crypt,Frost Cave,Infested Mine"; - savePinTypes = Config.Bind("1. Pins", "6. Save Pin Types", defaultSavePinTypes, "These Pin Types will persist on the map after the player as left the area.\nValue should be a comma seperated list of pin types."); - - destructablesEnabled = Config.Bind("2. Pins Enable/Disable", "1. Resources", true, "Enable/Disable pins for\nOres, Trees, and other destructable resource nodes"); - pickablesEnabled = Config.Bind("2. Pins Enable/Disable", "2. Pickables", true, "Enable/Disable pins for\nBerries, Mushrooms, and other pickable items"); - locsEnabled = Config.Bind("2. Pins Enable/Disable", "3. Locations", true, "Enable/Disable pins for\nCrypts, Troll Caves, and other discoverable locations"); - spwnsEnabled = Config.Bind("2. Pins Enable/Disable", "4. Spawners", true, "Enable/Disable pins for\nGreydwarf nests, Skeleton Bone Piles, and other creature spawners"); - creaturesEnabled = Config.Bind("2. Pins Enable/Disable", "5. Creatures", true, "Enable/Disable pins for\nSerpents, and other creatures when they spawn with in range of the player"); - - loggingEnabled = Config.Bind("3. Logging", "1. Enable Logging", true, "Enable Logging"); - destructableLoggingEnabled = Config.Bind("3. Logging", "2. Resource Logging", false, "Log object id and position of each destructable resource node in range of the player.\nUsed to get object Ids to assign to pin types"); - pickablesLoggingEnabled = Config.Bind("3. Logging", "3. Pickables Logging", false, "Log object id and position of each pickable item in range of the player.\nUsed to get object Ids to assign to pin types"); - locsLoggingEnabled = Config.Bind("3. Logging", "4. Locations Logging", false, "Log object id and position of each location object in range of the player.\nUsed to get object Ids to assign to pin types"); - spwnsLoggingEnabled = Config.Bind("3. Logging", "5. Spawners Logging", false, "Log object id and position of each creature spawner node in range of the player.\nUsed to get object Ids to assign to pin types"); - creaturesLoggingEnabled = Config.Bind("3. Logging", "6. Creatures Logging", false, "Log object id and position of creatures that spawn in range of the player.\nUsed to get object Ids to assign to pin types"); - diagnosticsEnabled = Config.Bind("3. Logging", "7. Enable Timing Diagnostics", false, "Enables log output with function timing diagnostics. Used for developer optimization purposes"); + nexusID = Config.Bind("_General_", "nexusID", 2199, + new ConfigDescription("Nexus mod ID for updates", null, new ConfigurationManagerAttributes { Order = 1, DispName = "NexusID" })); + modEnabled = Config.Bind("_General_", "modEnabled", true, + new ConfigDescription("Enable this mod", null, new ConfigurationManagerAttributes { Order = 2, DispName = "Enabled" })); + + /** Pin Config **/ + pinOverlapDistance = Config.Bind( + "1. Pins", "pinOverlapDistance", 10, + new ConfigDescription("Distance around pins to prevent overlapping of similar pins. \nRecommended values are 5-15", + new AcceptableValueRange(1, 50), + new ConfigurationManagerAttributes { Order = 8, DispName = "Pin Overlap Distance" })); + pinRangeExpRadiusMatching = Config.Bind("1. Pins", "pinRangeExpRadiusMatching", true, + new ConfigDescription("Match Pin Range to the Player's Map Discovery Radius.\nShould be compatible with mods that change explore radius.", null, + new ConfigurationManagerAttributes { Order = 7, DispName = "Match Pin Range to Explore Radius" })); + pinRange = Config.Bind( + "1. Pins", "pinRange", 50, + new ConfigDescription("Sets the range that pins will appear on the mini-map. Lower value means you need to be closer to set pin.\nDISABLED if Matching Player Explore Radius is enabled.\nRecommended 50-75", + new AcceptableValueRange(5, 150), + new ConfigurationManagerAttributes { Order = 6, DispName = "Pin Range" })); + hideAllLabels = Config.Bind("1. Pins", "hideAllLabels", false, + new ConfigDescription("Hide all pin labels.\n*THIS WILL OVERRIDE THE INDIVIDUAL SETTINGS*", null, + new ConfigurationManagerAttributes { Order = 5, DispName = "Hide ALL Labels" })); + hidePinLabels = Config.Bind("1. Pins", "hidePinLabels", "", + new ConfigDescription("Hide individual pin type labels.\nValue should be a comma seperated list of pin labels.", null, + new ConfigurationManagerAttributes { Order = 4, DispName = "Hide Individual Labels" })); + hidePinTypes = Config.Bind("1. Pins", "hidePinTypes", "", + new ConfigDescription("Disable individual pin types.\nValue should be a comma seperated list of pin labels.", null, + new ConfigurationManagerAttributes { Order = 3, DispName = "Disable Pins" })); + savePinTypes = Config.Bind("1. Pins", "savePinTypes", "Crypt,Troll Cave,Sunken Crypt,Frost Cave,Infested Mine", + new ConfigDescription("These Pin Types will persist on the map after the player as left the area.\nValue should be a comma seperated list of pin types.", null, + new ConfigurationManagerAttributes { Order = 2, DispName = "Save Pins" })); + minimapSizeMult = Config.Bind( + "1. Pins", "minimapSizeMult", (float)1.25, + new ConfigDescription( + "Pin sizes are multiplied by this number in the minimap.\nNote: Pins can also have a custom minimap size set in the pin packs .json config.\nThis multiplie will also be used on the custom minimap size of these pins.\nIf some pins seem to large please check any amp_*.json config files you have in your plugins folder and adjust the minimapSize acccordingly.", + new AcceptableValueRange((float)0.25, 5), + new ConfigurationManagerAttributes { Order = 1, DispName = "Minimap Size Multiplier" })); + + destructablesEnabled = Config.Bind("2. Pins Enable/Disable", "destructablesEnabled", true, + new ConfigDescription("Enable/Disable pins for\nOres, Trees, and other destructable resource nodes", null, + new ConfigurationManagerAttributes { Order = 5, DispName = "Resources" })); + pickablesEnabled = Config.Bind("2. Pins Enable/Disable", "pickablesEnabled", true, + new ConfigDescription("Enable/Disable pins for\nBerries, Mushrooms, and other pickable items", null, + new ConfigurationManagerAttributes { Order = 4, DispName = "Pickables" })); + locsEnabled = Config.Bind("2. Pins Enable/Disable", "locsEnabled", true, + new ConfigDescription("Enable/Disable pins for\nCrypts, Troll Caves, and other discoverable locations", null, + new ConfigurationManagerAttributes { Order = 3, DispName = "Locations" })); + spwnsEnabled = Config.Bind("2. Pins Enable/Disable", "spwnsEnabled", true, + new ConfigDescription("Enable/Disable pins for\nGreydwarf nests, Skeleton Bone Piles, and other creature spawners", null, + new ConfigurationManagerAttributes { Order = 2, DispName = "Spawners" })); + creaturesEnabled = Config.Bind("2. Pins Enable/Disable", "creaturesEnabled", true, + new ConfigDescription("Enable/Disable pins for\nSerpents, and other creatures when they spawn with in range of the player", null, + new ConfigurationManagerAttributes { Order = 1, DispName = "Creatures" })); + + /** Logging Config **/ + loggingEnabled = Config.Bind("3. Logging", "loggingEnabled", false, + new ConfigDescription("Toggle all logs from AMPED on/off", null, + new ConfigurationManagerAttributes { Order = 6, DispName = "Enable Logging" })); + objectLogging = Config.Bind("3. Logging", "objectLogging", false, + new ConfigDescription("Writes object ids to log.\nThese can be used to create AMPED PinTypes in json config files", null, + new ConfigurationManagerAttributes { Order = 5, DispName = "Object Id Logging" })); + onlyLogUnique = Config.Bind("3. Logging", "onlyLogUnique", true, + new ConfigDescription("Sets AMPED to only log out an objectId once, instead of every time an object spawns in.\nIt will logout a full list upon game exit.", null, + new ConfigurationManagerAttributes { Order = 4, DispName = "Unique Objects Only" })); + logKnownPinObjects = Config.Bind("3. Logging", "logKnownPinObjects", false, + new ConfigDescription("Allow logging of objects that currently have a configured Pin Type.", null, + new ConfigurationManagerAttributes { Order = 3, DispName = "Log Known Pin Objects" })); + objectLogFilter = Config.Bind("3. Logging", "objectLogFilter", "", + new ConfigDescription("Comma seperated list of object ids to filter out during logging process. Only applies when Object Logging is enabled", null, + new ConfigurationManagerAttributes { Order = 2, DispName = "Object Log Filter" })); + diagnosticsEnabled = Config.Bind("3. Logging", "diagnosticsEnabled", false, + new ConfigDescription("Enables log output with function timing diagnostics. Used for developer optimization purposes", null, + new ConfigurationManagerAttributes { Order = 1, DispName = "Enable Debug Diagnostics" })); + + filterObjectIds = objectLogFilter.Value.Split(','); /** Load Pin Type Config from JSON files **/ string defaultPinConfPath = ResourceUtils.GetDefaultPinConfig(); string[] configFiles = ResourceUtils.GetPinConfigFiles(); - objectPins = new Dictionary(); - mtypePins = new Dictionary(); - + objectPins = new Dictionary(); + mtypePins = new Dictionary(); + autoPins = new List(); if (configFiles != null) { - // Load defaults first incase of custom config overwrites LoadPinsFromConfig(defaultPinConfPath); - - // Load any custom configs that were found foreach (string confPath in configFiles) { - // Skip the default file, it's already loaded if (Path.GetFileName(confPath) == "amp_pin_types.json") continue; LoadPinsFromConfig(confPath); } @@ -125,45 +186,68 @@ private void Awake() return; } - new Harmony("materousapps.mods.automappins_configurable").PatchAll(); + new Harmony("amped.mod.auto_map_pins").PatchAll(); - Harmony.CreateAndPatchAll(typeof(Minimap_Patch), "materousapps.mods.automappins_configurable"); - Harmony.CreateAndPatchAll(typeof(DestructiblePatchSpawn), "materousapps.mods.automappins_configurable"); - Harmony.CreateAndPatchAll(typeof(PickablePatchSpawn), "materousapps.mods.automappins_configurable"); - Harmony.CreateAndPatchAll(typeof(LocationPatchSpawn), "materousapps.mods.automappins_configurable"); - Harmony.CreateAndPatchAll(typeof(SpawnAreaPatchSpawn), "materousapps.mods.automappins_configurable"); - Harmony.CreateAndPatchAll(typeof(MineRockPatchSpawn), "materousapps.mods.automappins_configurable"); - Harmony.CreateAndPatchAll(typeof(Player_Patches), "materousapps.mods.automappins_configurable"); + Harmony.CreateAndPatchAll(typeof(Minimap_Patch), "amped.mod.auto_map_pins"); + Harmony.CreateAndPatchAll(typeof(Pin_Registration_Patches), "amped.mod.auto_map_pins"); + Harmony.CreateAndPatchAll(typeof(Player_Patches), "amped.mod.auto_map_pins"); - addedPinLocs = new List(); - dupPinLocs = new List(); + pinItems = new Dictionary(); + dupPinLocs = new Dictionary(); autoPins = new List(); - pinRemList = new List(); - savedPins = new List(); - filteredPins = new List(); + + Config.SettingChanged += UpdatePinsFromSettings; Assets.Init(); } + private void OnDestroy() + { + if (objectLogging.Value && uniqueObjectIds.Count > 0) + { + Mod.Log.LogInfo($"AMP Found {uniqueObjectIds.Count} Object Ids"); + foreach (string objectId in uniqueObjectIds) + Mod.Log.LogInfo($"[AMP object_id] {objectId}"); + } + } + + public static void UpdatePinsFromSettings(object sender, SettingChangedEventArgs arg) + { + Log.LogDebug($"Setting change detected on {arg.ChangedSetting.Definition.Key}"); + + if (pinRangeExpRadiusMatching.Value) + if (Minimap.instance != null) + { + pinRange.Value = Minimap.instance.m_exploreRadius; + } else pinRange.Value = 50; + + filterObjectIds = objectLogFilter.Value.Split(','); + forcePinRefresh(); + } + private static void LoadPinsFromConfig(string confFilePath) { Mod.Log.LogInfo($"Loading pin config file: {Path.GetFileName(confFilePath)}"); - PinConfig.PinConfig pinTypes = null; - string[] hidePins = Mod.hidePinTypes.Value.Split(','); pinTypes = ResourceUtils.LoadPinConfig(confFilePath); - foreach (PinConfig.PinType pinType in pinTypes.pins) + foreach (PinType pinType in pinTypes.pins) { - if (hidePins.Contains(pinType.label)) continue; - // Load mtype and objectId referance dictionary mtypePins[pinType.type] = pinType; foreach (string objectId in pinType.object_ids) - objectPins[objectId] = pinType.type; + { + Mod.Log.LogDebug($"Adding {objectId.ToLower().Trim()} to pin type dictionary"); + objectPins[objectId.ToLower().Trim()] = pinType; + } } } + /** Log Class + * A middleware class for BepInEx logging + * Easy checking of logging config values before + * writing logs to the system. + */ public static class Log { public static ManualLogSource ModLogger; @@ -190,34 +274,34 @@ public static void LogError(string msg) ModLogger.LogError(msg); } - public static void LogDestructible(string name, Vector3 pos) + public static void LogObject(string type, string name, Vector3 pos) { - if (!Mod.destructableLoggingEnabled.Value && !Mod.objectPins.ContainsKey(name)) return; - LogInfo($"[AMP - Destructible Resource] Found {name} at {pos.x} {pos.y} {pos.z}"); - } - - public static void LogLocation(string name, Vector3 pos) - { - if (!Mod.locsLoggingEnabled.Value && !Mod.objectPins.ContainsKey(name)) return; - LogInfo($"[AMP - Location] Found {name} at {pos.x} {pos.y} {pos.z}"); - } - - public static void LogPickable(string name, Vector3 pos) - { - if (!Mod.pickablesLoggingEnabled.Value && !Mod.objectPins.ContainsKey(name)) return; - LogInfo($"[AMP - Pickable] Found {name} at {pos.x} {pos.y} {pos.z}"); - } - - public static void LogSpawn(string name, Vector3 pos) - { - if (!Mod.spwnsLoggingEnabled.Value && !Mod.objectPins.ContainsKey(name)) return; - LogInfo($"[AMP - Spawn] Found {name} at {pos.x} {pos.y} {pos.z}"); + if (!Mod.loggingEnabled.Value || !Mod.objectLogging.Value || filterObjectIds.Contains(name)) return; + if (!Mod.logKnownPinObjects.Value && Mod.objectPins.ContainsKey(name)) return; + if (Mod.onlyLogUnique.Value && !Mod.uniqueObjectIds.Contains(name)) + { + LogInfo($"[AMP - {type}] Found Object Id {name}"); + Mod.uniqueObjectIds.Add(name); + } + else if (!Mod.onlyLogUnique.Value) + { + LogInfo($"[AMP - {type}] Found {name} at {pos.ToString()} distance from player[{Player_Patches.currPos.ToString()}] {distanceFromPlayer(pos).ToString()}"); + } } + } - public static void LogCreature(string name, Vector3 pos) + public static void pinObject(string objectType, string objectId, Vector3 position) + { + string cleanedId = objectId.Replace("(Clone)", "").ToLower(); + Mod.Log.LogObject(objectType, cleanedId, position); + if (Mod.objectPins.TryGetValue(cleanedId, out PinType type)) { - if (!Mod.creaturesLoggingEnabled.Value && !Mod.objectPins.ContainsKey(name)) return; - LogInfo($"[AMP - Creature] Found {name} at {pos.x} {pos.y} {pos.z}"); + Mod.Log.LogDebug($"Mod.pinObject Adding {cleanedId} [{position}] to pinItems"); + type.isPinned = false; + type.pinCat = objectType; + Mod.pinItems[position] = type; + Mod.mtypePins[type.type].pinCat = objectType; + Mod.objectPins[cleanedId].pinCat = objectType; } } @@ -229,75 +313,112 @@ public static void LogCreature(string name, Vector3 pos) Sprite aIcon, out Minimap.PinData match) { + Mod.Log.LogDebug("Mod.SimilarPinExists"); + var watch = System.Diagnostics.Stopwatch.StartNew(); + foreach (Minimap.PinData pin in pins) { if (pos == pin.m_pos) { match = pin; + watch.Stop(); + Mod.Log.LogDebug($"Mod.SimilarPinExists: Found Similar Pin. took {watch.ElapsedMilliseconds}ms"); return true; } - else - - if ((double)Utils.DistanceXZ(pos, pin.m_pos) < pinOverlapDistance.Value + else if ((double)Utils.DistanceXZ(pos, pin.m_pos) < pinOverlapDistance.Value && type == pin.m_type && (aName == pin.m_name || aIcon == pin.m_icon)) { match = pin; + watch.Stop(); + Mod.Log.LogDebug($"Mod.SimilarPinExists: Found Similar Pin. took {watch.ElapsedMilliseconds}ms"); return true; } } match = null; + watch.Stop(); + Mod.Log.LogDebug($"Mod.SimilarPinExists took {watch.ElapsedMilliseconds}ms"); return false; } - public static void checkPins(Vector3 charPos) + public static void forcePinRefresh() + { + Mod.Log.LogDebug("Mod.forcePinRefresh settings changed, refreshing pins"); + + dupPinLocs.Clear(); + + // Reassess each pinItem's details + List tempPinList = new List(autoPins); + foreach (Minimap.PinData pin in tempPinList) + PinnedObject.updatePin(pin); + + // Now recheck pins to see if any need to be added / removed + checkPins(); + } + + public static float distanceFromPlayer(Vector3 pos) + { + return Vector3.Distance(Player_Patches.currPos, pos); + } + + public static void checkPins(bool firstLoad = false) { if (checkingPins) return; + checkingPins = true; + Mod.Log.LogDebug($"Mod.checkPins Looking for items to pin. Checking {pinItems.Count()} pinnable items"); + var watch = System.Diagnostics.Stopwatch.StartNew(); - foreach (KeyValuePair kvp in pinItems) + // Compatibility check for pinRange. Other mods can change the exploreRadius + if (pinRangeExpRadiusMatching.Value) { - checkingPins = true; - if (Vector3.Distance(charPos, kvp.Key) < pinRange.Value) + if (Minimap.instance != null) + { + pinRange.Value = Minimap.instance.m_exploreRadius; + } else pinRange.Value = 50; + } + + // Check if there are any pins to add + Dictionary tempPinItems = new Dictionary(pinItems); + foreach (KeyValuePair pinItem in tempPinItems) + { + if (dupPinLocs.TryGetValue(pinItem.Key, out Minimap.PinData dupPin)) continue; + + float distance = distanceFromPlayer(pinItem.Key); + + // Add pins within range + if (distance <= pinRange.Value) { - if (!addedPinLocs.Contains(kvp.Key) && !dupPinLocs.Contains(kvp.Key)) - { - PinnedObject.pinOb(kvp.Value, kvp.Key); - } + Mod.Log.LogDebug($"Mod.checkPins found pinnable item in range. Pinning {pinItem.Value.label}"); + PinnedObject.pinOb(pinItem.Value, pinItem.Key); } - else if (Vector3.Distance(charPos, kvp.Key) > pinRange.Value) + + // Clean pinItems of items that are far enough away to get re-added by objects "Awake" state + if (!firstLoad && distance >= 300) { - foreach (Minimap.PinData tempPin in autoPins) - { - - if (!remPinDict.ContainsKey(kvp.Key) && !tempPin.m_save) - { - remPinDict.Add(kvp.Key, tempPin); - pinRemList.Add(tempPin); - } - } + Mod.Log.LogDebug($"Mod.checkPins Distance is more than 300 for {pinItem.Value.label} [{pinItem.Key.ToString()}]. Distance: {distance.ToString()}. Removing from pinItems"); + pinItems.Remove(pinItem.Key); } } - checkingPins = false; - if (pinRemList != null) + Mod.Log.LogDebug($"Mod.checkPins checking for out of range items on {autoPins.Count()} registered auto pins"); + // Temp pin list is used to avoid enumeration errors when updating autoPins inside of loop + List tempPinList = new List(autoPins); + foreach (Minimap.PinData pin in tempPinList) { - foreach (Minimap.PinData tempRemPin in pinRemList) + if (!pin.m_save && distanceFromPlayer(pin.m_pos) > pinRange.Value) { - if (Vector3.Distance(charPos, tempRemPin.m_pos) < pinRange.Value) - return; - - Minimap.instance.RemovePin(tempRemPin); - autoPins.Remove(tempRemPin); - addedPinLocs.Remove(tempRemPin.m_pos); - remPinDict.Remove(tempRemPin.m_pos); + Mod.Log.LogDebug($"Mod.checkPins {pin.m_name}[{pin.m_type}] is out of range, removing pin."); + Minimap.instance.RemovePin(pin); } } - pinRemList.Clear(); + + watch.Stop(); + Mod.Log.LogDebug($"Mod.checkPins took {watch.ElapsedMilliseconds}ms"); + checkingPins = false; } public static Minimap.PinData GetNearestPin(Vector3 pos, float radius, List pins) { - Minimap.PinData pinData = null; float num1 = 999999f; foreach (Minimap.PinData pin in pins) @@ -312,22 +433,6 @@ public static Minimap.PinData GetNearestPin(Vector3 pos, float radius, List pin.m_uiElement?.gameObject.SetActive(ShouldPinRender(pin))); - } - - private static bool ShouldPinRender(Minimap.PinData pin) - { - if (filteredPins == null || filteredPins.Count == 0) - return true; - - if (!filteredPins.Contains(pin.m_type.ToString())) - return true; - - return false; - } - public Mod() { return; @@ -337,106 +442,159 @@ public Mod() internal class PinnedObject : MonoBehaviour { public static Minimap.PinData pin; + public static PinType pinType; public static bool aSave = false; public static bool showName = false; public static float pinSize = 20; public static Sprite aIcon; public static string aName = ""; public static int pType; + public static bool hidePin = false; - public static void pinOb(PinConfig.PinType tempPin, Vector3 aPos) + public static Minimap.PinData updatePin(Minimap.PinData pin) { - if (Mod.currEnv == "Crypt" || Mod.currEnv == "SunkenCrypt" || Mod.currEnv == "FrostCaves" || Mod.currEnv == "InfectedMine") - return; + Mod.Log.LogDebug($"PinnedObject.updatePin start"); + var watch = System.Diagnostics.Stopwatch.StartNew(); - if (tempPin != null) + loadData(null, (int)pin.m_type); + + // If the pin is set to be hidden remove it from the map + if (hidePin) { - loadData(tempPin); + Minimap.instance.RemovePin(pin); + return null; + } - //don't show filtered pins. - if (Mod.filteredPins.Contains(pType.ToString()) || aName == "") - return; + string pLabel = !Mod.hideAllLabels.Value && showName ? aName : string.Empty; + pin.m_name = pLabel; + pin.m_worldSize = pinSize; + pin.m_save = aSave; + if (aIcon) pin.m_icon = aIcon; - if (Mod.autoPins.Count > 0) - { - if (Mod.SimilarPinExists(aPos, (Minimap.PinType)pType, Mod.autoPins, aName, aIcon, out Minimap.PinData _)) - { - Mod.dupPinLocs.Add(aPos); - return; - } - } + // if (pin.m_pos != pos) // Saved in comment for future *creature tracking* feature + // pin.m_pos = Vector3.MoveTowards(pin.m_pos, pos, 200f * Time.deltaTime); - if (Mod.hideAllLabels.Value) - showName = false; + if (!pin.m_save) + { + // Double check unsaved pin distance from player, and remove if needed + if (Mod.distanceFromPlayer(pin.m_pos) > Mod.pinRange.Value) + Minimap.instance.RemovePin(pin); + } - if (showName) - { - pin = Minimap.instance.AddPin(aPos, (Minimap.PinType)pType, aName, aSave, false); - } - else - { - pin = Minimap.instance.AddPin(aPos, (Minimap.PinType)pType, string.Empty, aSave, false); - } + watch.Stop(); + Mod.Log.LogDebug($"PinnedObject.updatePin took {watch.ElapsedMilliseconds}ms"); + + return pin; + } - if (aIcon) - pin.m_icon = aIcon; + public static Minimap.PinData pinOb(PinType pinItem, Vector3 aPos) + { + if (pinItem == null || Mod.currEnv == "Crypt" || Mod.currEnv == "SunkenCrypt" || Mod.currEnv == "FrostCaves" || Mod.currEnv == "InfectedMine") + return null; + + Mod.Log.LogDebug($"PinnedObject.pinOb start"); + var watch = System.Diagnostics.Stopwatch.StartNew(); - pin.m_worldSize = pinSize; - pin.m_save = aSave; + loadData(pinItem); - if (!Mod.autoPins.Contains(pin)) - Mod.autoPins.Add(pin); - if (!Mod.addedPinLocs.Contains(aPos)) - Mod.addedPinLocs.Add(aPos); + // Don't pin if it's set to be hidden + if (hidePin) return null; - if (pin.m_save && !Mod.savedPins.Contains(pin)) - Mod.savedPins.Add(pin); + if (Mod.SimilarPinExists(aPos, (Minimap.PinType)pType, Mod.autoPins, aName, aIcon, out Minimap.PinData similarPin)) + { + Mod.dupPinLocs[aPos] = similarPin; + watch.Stop(); + Mod.Log.LogDebug($"PinnedObject.pinOb took {watch.ElapsedMilliseconds}ms. Similar pin exists."); + return similarPin; } - } - private void Update() - { + string pLabel = !Mod.hideAllLabels.Value && showName ? aName : string.Empty; + pin = Minimap.instance.AddPin(aPos, (Minimap.PinType)pType, pLabel, aSave, false); + if (aIcon) pin.m_icon = aIcon; + pin.m_worldSize = pinSize; + pin.m_save = aSave; + + //Mod.autoPins.Add(pin); + watch.Stop(); + Mod.Log.LogDebug($"PinnedObject.pinOb took {watch.ElapsedMilliseconds}ms. Added Pin"); + return pin; } + private void Update() { } + private void OnDestroy() { if (pin == null || Minimap.instance == null) return; - loadData(null, pin.m_type.ToString()); + Mod.Log.LogDebug($"PinnedObject.OnDestroy on type {pin.m_type.ToString()}"); + var watch = System.Diagnostics.Stopwatch.StartNew(); + + loadData(null, (int)pin.m_type); if (aSave || pin.m_save) { return; } - if (Vector3.Distance(pin.m_pos, Player_Patches.currPos) < Mod.pinRange.Value) + if (Mod.distanceFromPlayer(pin.m_pos) < Mod.pinRange.Value) return; + + watch.Stop(); + var elapsedMs = watch.ElapsedMilliseconds; + Mod.Log.LogDebug($"PinnedObject.OnDestroy took {elapsedMs}ms"); } - public static void loadData(PinConfig.PinType pin = null, string m_type = null) + public static void loadData(PinType pin = null, int m_type = 0) { + string pinLabel = pin == null ? m_type.ToString() : pin.label; + Mod.Log.LogDebug($"PinnedObject.loadData on type/label {pinLabel}"); + var watch = System.Diagnostics.Stopwatch.StartNew(); + /** loadData called with minimap pin type data **/ - if (pin == null && m_type != null) + if (pin == null && m_type > 0) { - pType = Int32.Parse(m_type); - if (!Mod.mtypePins.ContainsKey(pType)) + if (!Mod.mtypePins.ContainsKey(m_type)) { - if (Mod.loggingEnabled.Value) Mod.Log.LogInfo($"[AMP] Failed to load pin data from minimap pin type {pType}"); + if (Mod.loggingEnabled.Value) Mod.Log.LogInfo($"[AMP] Failed to load pin data from minimap pin type {m_type}"); aName = ""; return; } - pin = Mod.mtypePins[pType]; - if (Mod.loggingEnabled.Value) Mod.Log.LogInfo($"[AMP] Loading pin {pin.label} from minimap type {pType}"); + pin = Mod.mtypePins[m_type]; + if (Mod.loggingEnabled.Value) Mod.Log.LogInfo($"[AMP] Loading pin {pin.label} from minimap type {m_type}"); } + pinType = pin; aName = pin.label; pType = pin.type; aSave = Mod.savePinTypes.Value.Split(',').Contains(pin.label); aIcon = pin.sprite; showName = !Mod.hidePinLabels.Value.Split(',').Contains(pin.label); - pinSize = pin.size; + switch (Minimap_Patch.mapMode) + { + case Minimap.MapMode.Small: + pinSize = (pinType.minimapSize != 0 ? pinType.minimapSize : pinType.size) * Mod.minimapSizeMult.Value; + break; + case Minimap.MapMode.Large: + pinSize = pin.size; + break; + default: + pinSize = pin.size; + break; + } + + hidePin = Mod.hidePinTypes.Value != "" && Mod.hidePinTypes.Value.Split(',').Contains(pin.label); + + if(!Mod.destructablesEnabled.Value && pin.pinCat == "Destructable Resource") hidePin = true; + if(!Mod.pickablesEnabled.Value && pin.pinCat == "Pickable") hidePin = true; + if(!Mod.locsEnabled.Value && pin.pinCat == "Location") hidePin = true; + if(!Mod.spwnsEnabled.Value && pin.pinCat == "Spawner") hidePin = true; + if(!Mod.creaturesEnabled.Value && pin.pinCat == "Creature") hidePin = true; + + watch.Stop(); + var elapsedMs = watch.ElapsedMilliseconds; + Mod.Log.LogDebug($"PinnedObject.loadData took {elapsedMs}ms"); } public PinnedObject() @@ -449,7 +607,7 @@ public class Assets { public static void Init() { - foreach (KeyValuePair mtype in Mod.mtypePins) + foreach (KeyValuePair mtype in Mod.mtypePins) mtype.Value.sprite = LoadSprite(mtype.Value.icon); } diff --git a/Auto Map Pins Configurable/AMP_Configurable.csproj b/Auto Map Pins Configurable/AMP_Configurable.csproj index c83974b..3941b9f 100644 --- a/Auto Map Pins Configurable/AMP_Configurable.csproj +++ b/Auto Map Pins Configurable/AMP_Configurable.csproj @@ -97,8 +97,9 @@ - + + @@ -118,16 +119,16 @@ - + - xcopy "$(ProjectDir)\AMP_Enhanced\amp_pin_types.json" "C:\Users\Jordan\AppData\Roaming\r2modmanPlus-local\Valheim\profiles\Dev\BepInEx\plugins\raziell74-AMPED_Auto_Map_Pins_Enhanced\" /q /y /i -xcopy "$(ProjectDir)\AMP_Enhanced\pin-icons" "C:\Users\Jordan\AppData\Roaming\r2modmanPlus-local\Valheim\profiles\Dev\BepInEx\plugins\raziell74-AMPED_Auto_Map_Pins_Enhanced" /c /q /y /i -xcopy "$(ProjectDir)\icon.png" "$(ProjectDir)\bin\Release\AMPED-AutoMapPinsEnhanced_v1.3.4\" /q /y /i -xcopy "$(ProjectDir)\README.md" "$(ProjectDir)\bin\Release\AMPED-AutoMapPinsEnhanced_v1.3.4\" /q /y /i -xcopy "$(ProjectDir)\manifest.json" "$(ProjectDir)\bin\Release\AMPED-AutoMapPinsEnhanced_v1.3.4\" /q /y /i -xcopy "$(ProjectDir)\AMP_Enhanced\amp_pin_types.json" "$(ProjectDir)\bin\Release\AMPED-AutoMapPinsEnhanced_v1.3.4\plugins\AMPED_Enhanced\" /q /y /i -xcopy "$(ProjectDir)\AMP_Enhanced\pin-icons" "$(ProjectDir)\bin\Release\AMPED-AutoMapPinsEnhanced_v1.3.4\plugins\AMPED_Enhanced\pin-icons" /c /q /y /i + xcopy "$(ProjectDir)\AMP_Enhanced\amp_pin_types.json" "C:\Users\Jordan\AppData\Roaming\r2modmanPlus-local\Valheim\profiles\Dev\BepInEx\plugins\raziell74-AMPED_Auto_Map_Pins_Enhanced\AMP_Enhanced\" /q /y /i +xcopy "$(ProjectDir)\AMP_Enhanced\pin-icons" "C:\Users\Jordan\AppData\Roaming\r2modmanPlus-local\Valheim\profiles\Dev\BepInEx\plugins\raziell74-AMPED_Auto_Map_Pins_Enhanced\AMP_Enhanced\pin-icons\" /c /q /y /i +xcopy "$(ProjectDir)\icon.png" "$(ProjectDir)\bin\Release\AMPED-AutoMapPinsEnhanced_v1.3.5\" /q /y /i +xcopy "$(ProjectDir)\README.md" "$(ProjectDir)\bin\Release\AMPED-AutoMapPinsEnhanced_v1.3.5\" /q /y /i +xcopy "$(ProjectDir)\manifest.json" "$(ProjectDir)\bin\Release\AMPED-AutoMapPinsEnhanced_v1.3.5\" /q /y /i +xcopy "$(ProjectDir)\AMP_Enhanced\amp_pin_types.json" "$(ProjectDir)\bin\Release\AMPED-AutoMapPinsEnhanced_v1.3.5\plugins\AMP_Enhanced\" /q /y /i +xcopy "$(ProjectDir)\AMP_Enhanced\pin-icons" "$(ProjectDir)\bin\Release\AMPED-AutoMapPinsEnhanced_v1.3.5\plugins\AMP_Enhanced\pin-icons" /c /q /y /i diff --git a/Auto Map Pins Configurable/AMP_Enhanced/amp_pin_types.json b/Auto Map Pins Configurable/AMP_Enhanced/amp_pin_types.json index 1531af4..54753ea 100644 --- a/Auto Map Pins Configurable/AMP_Enhanced/amp_pin_types.json +++ b/Auto Map Pins Configurable/AMP_Enhanced/amp_pin_types.json @@ -103,6 +103,7 @@ "label": "Crypt", "icon": "surtling_core.png", "size": 25, + "minimapSize": 50, "object_ids": ["Crypt1", "Crypt2", "Crypt3", "Crypt4"] }, { @@ -110,6 +111,7 @@ "label": "Sunken Crypt", "icon": "witheredbone.png", "size": 25, + "minimapSize": 50, "object_ids": [ "SunkenCrypt1", "SunkenCrypt2", @@ -122,6 +124,7 @@ "label": "Troll Cave", "icon": "TrophyFrostTroll.png", "size": 25, + "minimapSize": 50, "object_ids": ["TrollCave01", "TrollCave02", "TrollCave"] }, { @@ -136,27 +139,33 @@ "label": "Skeleton", "icon": "TrophySkeleton.png", "size": 25, - "object_ids": ["Evil bone pile"] + "object_ids": ["BonePileSpawner"] }, { "type": 118, "label": "Draugr", "icon": "TrophyDraugr.png", "size": 25, - "object_ids": ["Body Pile"] + "object_ids": ["Spawner_DraugrPile"] }, { "type": 119, - "label": "Greydwarf", + "label": "Greydwarf Nest", "icon": "TrophyGreydwarf.png", "size": 25, - "object_ids": ["Greydwarf nest", "Greydwarf_camp1"] + "object_ids": [ + "Greydwarf nest", + "Greydwarf_camp1", + "Spawner_GreydwarfNest", + "Greydwarf_camp2" + ] }, { "type": 120, "label": "Serpent", "icon": "TrophySerpent.png", "size": 25, + "minimapSize": 50, "object_ids": ["$enemy_serpent"] }, { @@ -178,6 +187,7 @@ "label": "Fuling Camp", "icon": "TrophyGoblin.png", "size": 25, + "minimapSize": 50, "object_ids": ["GoblinCamp1", "GoblinCamp2", "GoblinCamp3", "GoblinCamp4"] }, { @@ -185,6 +195,7 @@ "label": "Frost Cave", "icon": "TrophyGolem.png", "size": 25, + "minimapSize": 50, "object_ids": [ "MountainCave01", "MountainCave02", @@ -225,6 +236,7 @@ "label": "Infested Tree", "icon": "InfestedTree01.png", "size": 20, + "minimapSize": 35, "object_ids": ["InfestedTree01"] }, { @@ -322,6 +334,7 @@ "label": "Infested Mine", "icon": "Mistlands_DvergrTownEntrance2.png", "size": 20, + "minimapSize": 50, "object_ids": [ "Mistlands_DvergrTownEntrance1", "Mistlands_DvergrTownEntrance2" @@ -422,6 +435,7 @@ "label": "Fuling Tower", "icon": "StoneTower1.png", "size": 20, + "minimapSize": 35, "object_ids": ["Ruin3", "StoneTower1", "StoneTower3"] }, { diff --git a/Auto Map Pins Configurable/Change Log.md b/Auto Map Pins Configurable/Change Log.md index 5eb46c4..a7e585b 100644 --- a/Auto Map Pins Configurable/Change Log.md +++ b/Auto Map Pins Configurable/Change Log.md @@ -1,13 +1,29 @@ -## Change Log +# Change Log -# Version v1.3.4 +### Version v1.3.5 + * Performance Overhaul! Updated and refactored a large portion of the mod to run faster as to not cause as much FPS drops for potato computers. Lots of legacy code updated. + * Updated and reorganized configuration. My sincerest apologies but this will require you to redo your configuration settings, my first go at it a lot of the naming is bad and would cause issues and I now know a ton more about the inner workings of BepInEx configurations. If you experience issues, delete your `amped.mod.auto_map_pins.cfg` and restart the game to generate a clean config. Thank you for your patience, this is my first time doing any BepInEx modding. + * Mod will now properly refresh pins if making changes to configuration values while in game. No more need to restart the game for the new values to take effect! + * Added new config value for "Minimap Pin Size Multiplier". The mod will multiply the pin size by this multiplier for the minimap so that players can better control the pin size in the minimap + * Added minimapSize for Pin Type configuration. JSON configs now support a new optional value "minimapSize" which allows you to custom set the minimap Pin Size. If set the new Minimap Pin Size Multiplier config will use this minimapSize value to multiply the pin size in the minimap so you can better differentiate important pins + * Combined all of the object id logger configs into a single "objectLogging" config value. This new config will toggle all object id logs + * Added Object Id filter for object logging. This is a comma delimited list of object ids you don't want the mod to report when it encounters them. This helps clean up the logs and only shows you the object ids you want + * Added "Unique Objects Only". If enabled the mod will only report an object id once when it first encounters it instead of for every object. When the game exists it will log out the full list of unique object ids that were discovered during the session + * Removed a lot of broken code around Commands. Using the Configuration Manager almost all the previous "Commands" are possible without having to remember chat commands (that didn't even work) + * pinRange now is defaulted to using the Players Explore Radius. This can be disabled for a custom pinRange and will be compatible with any mods that change the explore radius dynamically like the Cartography skill or mods that increase the explore radius while on boats. The pinning range will update dynamically as the radius changes + * BugFix - Oak Trees are now correctly detected, Thanks to LuxZg for helping out with this one + * BugFix - Fixed the issue where Saved Pins would get additional pins overlaid on top of them when you save and reload the game near one. Now you can see if you've checked (x'ed out) a pin or not and it will persist until the pin is removed + * BugFix - Manually removing pins from the map is easier now, increased pin detection radius when clicking to remove a pin from the map + * BugFix - Corrected Draugr and Skeleton spawner object ids + +### Version v1.3.4 * New config for hiding pin types by label has been added. Users can now entered a comma seperated list of pin labels that they don't want to be autopinned * Multiple pin type configuration json files can now be loaded. Opening up the possibility of other authors to release their own pin and icon packs * Pin Config file has been made dynamic. AMPED will now load any json file with the prefix 'amp_' and attempt to use it as a pin type config file * Overhauled sprite loading to instead search the plugins folder and use the first file that matches the file name * Refactored some internal code to be more maintainable -# Version v1.3.3 +### Version v1.3.3 * Added new pins * New Pin: Infested Tree (Guck Trees) * New Pin: Road Post @@ -35,11 +51,12 @@ * New Pin: Shipwreck * New Pin: Farm House -# Version v1.3.1/1.3.2 +### Version v1.3.1/1.3.2 * Fixed an error with r2modmanager not finding assets -# Version v1.3.0 +### Version v1.3.0 * Overhauled configuration of map pin types * Speed optimizations for loading in pins * Ability to toggle logging. Users can now enable the logging to print out object id's that come within range of the player so that players can add custom map pins to the new amp_pin_types.json file and pin what ever they would like, even provide their own custom icon for it. - * New Pins added: Mountain Caves, Tar Pits, Fuling Camps, Jotun Puffs, Mage Caps, and Black Cores \ No newline at end of file + * New Pins added: Mountain Caves, Tar Pits, Fuling Camps, Jotun Puffs, Mage Caps, and Black Cores + \ No newline at end of file diff --git a/Auto Map Pins Configurable/ConfigurationManagerAttributes.cs b/Auto Map Pins Configurable/ConfigurationManagerAttributes.cs new file mode 100644 index 0000000..9b85603 --- /dev/null +++ b/Auto Map Pins Configurable/ConfigurationManagerAttributes.cs @@ -0,0 +1,103 @@ +/// +/// Class that specifies how a setting should be displayed inside the ConfigurationManager settings window. +/// +/// Usage: +/// This class template has to be copied inside the plugin's project and referenced by its code directly. +/// make a new instance, assign any fields that you want to override, and pass it as a tag for your setting. +/// +/// If a field is null (default), it will be ignored and won't change how the setting is displayed. +/// If a field is non-null (you assigned a value to it), it will override default behavior. +/// +/// +/// +/// Here's an example of overriding order of settings and marking one of the settings as advanced: +/// +/// // Override IsAdvanced and Order +/// Config.Bind("X", "1", 1, new ConfigDescription("", null, new ConfigurationManagerAttributes { IsAdvanced = true, Order = 3 })); +/// // Override only Order, IsAdvanced stays as the default value assigned by ConfigManager +/// Config.Bind("X", "2", 2, new ConfigDescription("", null, new ConfigurationManagerAttributes { Order = 1 })); +/// Config.Bind("X", "3", 3, new ConfigDescription("", null, new ConfigurationManagerAttributes { Order = 2 })); +/// +/// +/// +/// +/// You can read more and see examples in the readme at https://github.com/BepInEx/BepInEx.ConfigurationManager +/// You can optionally remove fields that you won't use from this class, it's the same as leaving them null. +/// +#pragma warning disable 0169, 0414, 0649 +internal sealed class ConfigurationManagerAttributes +{ + /// + /// Should the setting be shown as a percentage (only use with value range settings). + /// + public bool? ShowRangeAsPercent; + + /// + /// Custom setting editor (OnGUI code that replaces the default editor provided by ConfigurationManager). + /// See below for a deeper explanation. Using a custom drawer will cause many of the other fields to do nothing. + /// + public System.Action CustomDrawer; + + /// + /// Show this setting in the settings screen at all? If false, don't show. + /// + public bool? Browsable; + + /// + /// Category the setting is under. Null to be directly under the plugin. + /// + public string Category; + + /// + /// If set, a "Default" button will be shown next to the setting to allow resetting to default. + /// + public object DefaultValue; + + /// + /// Force the "Reset" button to not be displayed, even if a valid DefaultValue is available. + /// + public bool? HideDefaultButton; + + /// + /// Force the setting name to not be displayed. Should only be used with a to get more space. + /// Can be used together with to gain even more space. + /// + public bool? HideSettingName; + + /// + /// Optional description shown when hovering over the setting. + /// Not recommended, provide the description when creating the setting instead. + /// + public string Description; + + /// + /// Name of the setting. + /// + public string DispName; + + /// + /// Order of the setting on the settings list relative to other settings in a category. + /// 0 by default, higher number is higher on the list. + /// + public int? Order; + + /// + /// Only show the value, don't allow editing it. + /// + public bool? ReadOnly; + + /// + /// If true, don't show the setting by default. User has to turn on showing advanced settings or search for it. + /// + public bool? IsAdvanced; + + /// + /// Custom converter from setting type to string for the built-in editor textboxes. + /// + public System.Func ObjToStr; + + /// + /// Custom converter from string to setting type for the built-in editor textboxes. + /// + public System.Func StrToObj; +} \ No newline at end of file diff --git a/Auto Map Pins Configurable/Properties/AssemblyInfo.cs b/Auto Map Pins Configurable/Properties/AssemblyInfo.cs index 1e0ec61..fce9b87 100644 --- a/Auto Map Pins Configurable/Properties/AssemblyInfo.cs +++ b/Auto Map Pins Configurable/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.3.4")] -[assembly: AssemblyFileVersion("1.3.4")] +[assembly: AssemblyVersion("1.3.5")] +[assembly: AssemblyFileVersion("1.3.5")] diff --git a/Auto Map Pins Configurable/README.md b/Auto Map Pins Configurable/README.md index de2ba1c..4f92d04 100644 --- a/Auto Map Pins Configurable/README.md +++ b/Auto Map Pins Configurable/README.md @@ -1,4 +1,4 @@ -# AMPED - Auto Map Pins Enhanced v1.3.1 - Configuration overhaul +# AMPED - Auto Map Pins Enhanced Author: JordanRichmeier Nexus: [AMPED - Auto Map Pins Enhanced](https://www.nexusmods.com/valheim/mods/2199) Source: [Github](https://github.com/raziell74/Valheim-Auto-Map-Pins-Configurable/) @@ -14,16 +14,32 @@ Contibutions from the following modders was invaluable and appreciated: * [Materous](https://www.nexusmods.com/valheim/users/6021662) - for the original mod and providing access/permission to the source code * [LuxZg](https://www.nexusmods.com/users/1014505) - For doing all the leg work in adding a ton of new pins for various structures as well as new mistland objects -## Change Log +# Change Log -# Version v1.3.4 +### Version v1.3.5 + * Performance Overhaul! Updated and refactored a large portion of the mod to run faster as to not cause as much FPS drops for potato computers. Lots of legacy code updated. + * Updated and reorganized configuration. My sincerest apologies but this will require you to redo your configuration settings, my first go at it a lot of the naming is bad and would cause issues and I now know a ton more about the inner workings of BepInEx configurations. If you experience issues, delete your `amped.mod.auto_map_pins.cfg` and restart the game to generate a clean config. Thank you for your patience, this is my first time doing any BepInEx modding. + * Mod will now properly refresh pins if making changes to configuration values while in game. No more need to restart the game for the new values to take effect! + * Added new config value for "Minimap Pin Size Multiplier". The mod will multiply the pin size by this multiplier for the minimap so that players can better control the pin size in the minimap + * Added minimapSize for Pin Type configuration. JSON configs now support a new optional value "minimapSize" which allows you to custom set the minimap Pin Size. If set the new Minimap Pin Size Multiplier config will use this minimapSize value to multiply the pin size in the minimap so you can better differentiate important pins + * Combined all of the object id logger configs into a single "objectLogging" config value. This new config will toggle all object id logs + * Added Object Id filter for object logging. This is a comma delimited list of object ids you don't want the mod to report when it encounters them. This helps clean up the logs and only shows you the object ids you want + * Added "Unique Objects Only". If enabled the mod will only report an object id once when it first encounters it instead of for every object. When the game exists it will log out the full list of unique object ids that were discovered during the session + * Removed a lot of broken code around Commands. Using the Configuration Manager almost all the previous "Commands" are possible without having to remember chat commands (that didn't even work) + * pinRange now is defaulted to using the Players Explore Radius. This can be disabled for a custom pinRange and will be compatible with any mods that change the explore radius dynamically like the Cartography skill or mods that increase the explore radius while on boats. The pinning range will update dynamically as the radius changes + * BugFix - Oak Trees are now correctly detected, Thanks to LuxZg for helping out with this one + * BugFix - Fixed the issue where Saved Pins would get additional pins overlaid on top of them when you save and reload the game near one. Now you can see if you've checked (x'ed out) a pin or not and it will persist until the pin is removed + * BugFix - Manually removing pins from the map is easier now, increased pin detection radius when clicking to remove a pin from the map + * BugFix - Corrected Draugr and Skeleton spawner object ids + +### Version v1.3.4 * New config for hiding pin types by label has been added. Users can now entered a comma seperated list of pin labels that they don't want to be autopinned * Multiple pin type configuration json files can now be loaded. Opening up the possibility of other authors to release their own pin and icon packs * Pin Config file has been made dynamic. AMPED will now load any json file with the prefix 'amp_' and attempt to use it as a pin type config file * Overhauled sprite loading to instead search the plugins folder and use the first file that matches the file name * Refactored some internal code to be more maintainable -# Version 1.3.3 +### Version v1.3.3 * Added new pins * New Pin: Infested Tree (Guck Trees) * New Pin: Road Post @@ -51,15 +67,15 @@ Contibutions from the following modders was invaluable and appreciated: * New Pin: Shipwreck * New Pin: Farm House -# Version 1.3.1/1.3.2 +### Version v1.3.1/1.3.2 * Fixed an error with r2modmanager not finding assets -# Version 1.3.0 +### Version v1.3.0 * Overhauled configuration of map pin types * Speed optimizations for loading in pins * Ability to toggle logging. Users can now enable the logging to print out object id's that come within range of the player so that players can add custom map pins to the new amp_pin_types.json file and pin what ever they would like, even provide their own custom icon for it. * New Pins added: Mountain Caves, Tar Pits, Fuling Camps, Jotun Puffs, Mage Caps, and Black Cores - + ## TODO * New UI interface on the world map that will give users the ability to easily hide, toggle labels, set detection range, and save pins @@ -68,6 +84,7 @@ Contibutions from the following modders was invaluable and appreciated: * Include Auga UI compatibility * Separate pin sizing options for the world map and the minimap * Label font sizing per pin type - * Add a separate json file for custom user pins, this is so people can put out their own icon and pin packs without having to worry about my updates overriding their changes to amp_pin_types.json + * Add a separate json file for custom user pins, this is so people can put out their own icon and pin packs without having to worry about my updates overriding their changes to amp_pin_types.json * Live tracking of creature pins (could be FPS intensive) * Automatic unpinning: when pickable has been picked, after ore has been completely mined, after a location has been destroyed. + * Allow users to pick from any loaded pin-icon image to make their own manual pins. diff --git a/Auto Map Pins Configurable/Utilities.cs b/Auto Map Pins Configurable/Utilities.cs index d7e0b21..635e9ce 100644 --- a/Auto Map Pins Configurable/Utilities.cs +++ b/Auto Map Pins Configurable/Utilities.cs @@ -31,7 +31,7 @@ public static byte[] GetResource(string spriteName) // If there are multiple of the same name, AMPED will use the first asset it finds in the plugins folder string spritePath = spriteSearch[0]; - if (Mod.loggingEnabled.Value) Mod.Log.LogInfo($"Successfully loaded sprite: {spriteName}"); + Mod.Log.LogDebug($"Successfully loaded sprite: {spriteName}"); return File.ReadAllBytes(spritePath); } @@ -53,7 +53,7 @@ public static string[] GetPinConfigFiles() { string[] configs = null; - if (Mod.loggingEnabled.Value) Mod.Log.LogInfo("Looking for pin configuration json files..."); + Mod.Log.LogInfo("Looking for pin configuration json files..."); configs = Directory.GetFiles(Paths.PluginPath, "amp_*.json", SearchOption.AllDirectories); if (configs.Length == 0) Mod.Log.LogWarning("Could not find any AMP config files. No automatic pins will be added..."); diff --git a/Auto Map Pins Configurable/manifest.json b/Auto Map Pins Configurable/manifest.json index 6160056..705659a 100644 --- a/Auto Map Pins Configurable/manifest.json +++ b/Auto Map Pins Configurable/manifest.json @@ -1,6 +1,6 @@ { "name": "AMPED_Auto_Map_Pins_Enhanced", - "version_number": "1.3.4", + "version_number": "1.3.5", "website_url": "https://www.nexusmods.com/valheim/mods/2199", "description": "This is the successor to Materous' AutoMapPins with Configuration. Absolutely loved his edition but it needed to be a bit more dynamic and updated for Mistlands.", "dependencies": ["denikson-BepInExPack_Valheim-5.4.1700"]