using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using HarmonyLib;
using Purps.Valheim.Framework;
using Purps.Valheim.Framework.Commands;
using Purps.Valheim.Framework.Config;
using Purps.Valheim.Framework.Data;
using Purps.Valheim.Framework.Utils;
using Purps.Valheim.Locator.Components;
using Purps.Valheim.Locator.Data;
using Purps.Valheim.Locator.Exceptions;
using Purps.Valheim.Locator.Utils;
using TMPro;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LocatorPlugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LocatorPlugin")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3a28ca24-e72a-4d3b-ae30-21ff135ff61a")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Purps.Valheim.Framework
{
public abstract class BasePlugin : BaseUnityPlugin
{
protected static BaseConfig BaseConfig;
public static CommandProcessor CommandProcessor;
private readonly string PluginGuid;
protected BasePlugin(string pluginGuid)
{
PluginGuid = pluginGuid;
}
private void Awake()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
CommandProcessor = new CommandProcessor();
BaseConfig = GetConfig();
PluginAwake();
new Harmony(PluginGuid).PatchAll();
}
private void OnDestroy()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
new Harmony(PluginGuid).UnpatchSelf();
BaseConfig.configDatas.Clear();
BaseConfig = null;
CommandProcessor.ClearCommands();
CommandProcessor = null;
PluginDestroy();
}
protected abstract BaseConfig GetConfig();
protected abstract void PluginAwake();
protected abstract void PluginDestroy();
public static ConfigData<T> GetConfigData<T>(string key)
{
return BaseConfig.configDatas.GetValue<ConfigData<T>>(key);
}
public static void ExecuteCommand(string text)
{
CommandProcessor.ExecuteCommand(text);
}
public static List<ICommand> GetCommands()
{
return CommandProcessor.Commands;
}
}
}
namespace Purps.Valheim.Framework.Utils
{
public static class ConsoleUtils
{
public static void WriteToConsole(params string[] textElements)
{
string text2 = "";
if (textElements.Length == 1)
{
text2 = textElements.First();
}
else if (textElements.Length > 1)
{
text2 = textElements.Aggregate(text2, (string current, string text) => current + text + " ");
}
if (text2 != "")
{
Console.instance.Print(text2);
}
}
}
}
namespace Purps.Valheim.Framework.Data
{
public class GenericDictionary
{
private readonly Dictionary<string, object> Dictionary = new Dictionary<string, object>();
public Dictionary<string, object>.KeyCollection Keys => Dictionary.Keys;
public void Add<T>(string key, T value) where T : class
{
Dictionary.Add(key, value);
}
public object GetValue(string key)
{
return Dictionary[key];
}
public T GetValue<T>(string key) where T : class
{
return Dictionary[key] as T;
}
public void Clear()
{
Dictionary.Clear();
}
}
}
namespace Purps.Valheim.Framework.Config
{
public abstract class BaseConfig
{
public readonly GenericDictionary configDatas = new GenericDictionary();
protected readonly BasePlugin plugin;
protected BaseConfig(BasePlugin plugin)
{
this.plugin = plugin;
}
protected abstract void handleCustomData<T>(ConfigData<T> configData);
protected ConfigData<T> ReadValueFromConfig<T>(ConfigData<T> configData, bool shouldFetch = true)
{
if (shouldFetch)
{
configData.value = ((BaseUnityPlugin)plugin).Config.Bind<T>(configData.Section, configData.Key, configData.value, configData.Description).Value;
}
configDatas.Add(configData.Key, configData);
return configData;
}
protected void CreateCommandFromConfig<T>(ConfigData<T> configData, Action<string[]> action = null)
{
BasePlugin.CommandProcessor.AddCommand(new Command("/" + configData.Key, configData.Description, action ?? ((Action<string[]>)delegate(string[] parameters)
{
SetValue(configData, parameters);
})));
}
private void SetValue<T>(ConfigData<T> configData, string[] parameters)
{
T value = configData.value;
if (value is bool)
{
object obj = value;
bool flag = (bool)((obj is bool) ? obj : null);
flag = !flag;
configData.value = (T)(object)flag;
}
else if (value is float)
{
if ((float)parameters.Length > 0f && float.TryParse(parameters[0], out var result))
{
configData.value = (T)(object)result;
}
}
else
{
handleCustomData(configData);
}
}
}
public class ConfigData<T>
{
public readonly string Description;
public readonly string Key;
public readonly string Section;
public T value;
public ConfigData(string section, string key, string description, T value)
{
Section = section;
Key = key;
Description = description;
this.value = value;
}
public override string ToString()
{
return $"{GetType().Name}[Description={Description}, Key={Key}, Section={Section}, Value={value}]";
}
}
}
namespace Purps.Valheim.Framework.Commands
{
public class Command : ICommand
{
public string Name { get; }
public string Description { get; }
public Action<string[]> Action { get; }
public bool ShouldPrint { get; }
public Command(string name, string description, Action<string[]> action, bool shouldPrint = true)
{
Name = name;
Description = description;
Action = action;
ShouldPrint = shouldPrint;
}
public void Execute(string commandStr)
{
string[] array = string.Join(" ", commandStr.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries)).Split(new char[1] { ' ' }).Skip(1)
.ToArray();
array = Array.ConvertAll(array, (string c) => c.ToLower());
Action(array);
}
}
public class CommandProcessor
{
public List<ICommand> Commands { get; } = new List<ICommand>();
public void AddCommand(ICommand command)
{
Commands.Add(command);
}
public void ClearCommands()
{
Commands.Clear();
}
public void PrintCommands(string[] parameters)
{
Commands.FindAll((ICommand command) => command.ShouldPrint).ForEach(delegate(ICommand command)
{
ConsoleUtils.WriteToConsole(command.Name + " => " + command.Description);
});
}
public void ExecuteCommand(string commandStr)
{
Commands.FirstOrDefault((ICommand e) => e.Name.ToLower().Equals(commandStr.Split(new char[1] { ' ' }).First().ToLower()))?.Execute(commandStr.ToLower());
}
}
public interface ICommand
{
string Name { get; }
string Description { get; }
Action<string[]> Action { get; }
bool ShouldPrint { get; }
void Execute(string commandStr);
}
}
namespace Purps.Valheim.Locator
{
public class LocatorConfig : BaseConfig
{
public LocatorConfig(BasePlugin plugin)
: base(plugin)
{
CreateCommandFromConfig(ReadValueFromConfig(new ConfigData<bool>("General", "debug", "Prints useful information to configure your own pinnable item types.", value: false)));
CreateCommandFromConfig(ReadValueFromConfig(new ConfigData<bool>("AutoPin", "pinEnabled", "Enables entity auto-pinning.", value: true)));
CreateCommandFromConfig(ReadValueFromConfig(new ConfigData<float>("AutoPin", "pinDistance", "The allowed distance between two entities for auto-pinning.", 30f)));
CreateCommandFromConfig(ReadValueFromConfig(new ConfigData<float>("AutoPin", "pinRayDistance", "How close the to the entity the player must be for it to be auto-pinned.", 25f)));
CreateCommandFromConfig(ReadValueFromConfig(new ConfigData<bool>("AutoPin", "pinDestructibles", "Toggles the pinning of destructible items.", value: true)));
CreateCommandFromConfig(ReadValueFromConfig(new ConfigData<bool>("AutoPin", "pinMineRocks", "Toggles the pinning of mineable rocks.", value: true)));
CreateCommandFromConfig(ReadValueFromConfig(new ConfigData<bool>("AutoPin", "pinLocations", "Toggles the pinning of dungeons, caves, altars, runestones, etc.", value: true)));
CreateCommandFromConfig(ReadValueFromConfig(new ConfigData<bool>("AutoPin", "pinPickables", "Toggle the pinning of plants and fungi", value: true)));
CreateCommandFromConfig(ReadValueFromConfig(new ConfigData<bool>("AutoPin", "pinSpawners", "Toggles the pinning of spawners.", value: true)));
CreateCommandFromConfig(ReadValueFromConfig(new ConfigData<bool>("AutoPin", "pinVegvisirs", "Toggles the pinning of boss runestones.", value: true)));
CreateCommandFromConfig(ReadValueFromConfig(new ConfigData<bool>("AutoPin", "pinLeviathans", "Toggles the pinning of leviathans.", value: true)));
CreateCommandFromConfig(ReadValueFromConfig(GetPinFilters("filterPins", "Default pin filters."), shouldFetch: false), MinimapUtils.SetPinFilters);
ReadValueFromConfig(GetInclusionList("destructibleInclusions", "{silvervein,Silver,true}{rock3_silver,Silver,true}{MineRock_Tin,Tin,true}{rock4_copper,Copper,true}{MineRock_Obsidian,Obsidian,true}", "Inclusion list for destructible items."), shouldFetch: false);
ReadValueFromConfig(GetInclusionList("mineRockInclusions", "{MineRock_Meteorite,Meteorite,true}", "Inclusion list for minable rocks."), shouldFetch: false);
ReadValueFromConfig(GetInclusionList("locationInclusions", "{DrakeLorestone,Runestone,true}{TrollCave,Troll,true}{Crypt,Crypt,true}{SunkenCrypt,Crypt,true}{Grave,Grave,true}{DrakeNest,Egg,true}{Runestone,Runestone,true}{Eikthyrnir,Eikthyr,true}{GDKing,The Elder,true}{Bonemass,Bonemass,true}{Dragonqueen,Moder,true}{GoblinKing,Yagluth,true}", "Inclusion list for locations."), shouldFetch: false);
ReadValueFromConfig(GetInclusionList("pickableInclusions", "{BlueberryBush,BlueBerry,true}{CloudberryBush,Cloudberry,true}{RaspberryBush,Raspberry,true}{Pickable_Barley,Barley,true}{Pickable_Flax,Flax,true}{Pickable_Thistle,Thistle,true}{Pickable_Mushroom,Mushroom,true}{Pickable_SeedCarrot,Carrot,true}{Pickable_Dandelion,Dandelion,true}{Pickable_SeedTurnip,Turnip,true}", "Inclusion list for pickable items."), shouldFetch: false);
ReadValueFromConfig(GetInclusionList("spawnerInclusions", "{Spawner,Spawner,true}", "Inclusion list for spawners."), shouldFetch: false);
ReadValueFromConfig(GetInclusionList("vegvisirInclusions", "{Vegvisir,Runestone,true}", "Inclusion list for boss runestones."), shouldFetch: false);
ReadValueFromConfig(GetInclusionList("leviathanInclusions", "{Leviathan,Leviathan,true}", "Inclusion list for leviathans."), shouldFetch: false);
}
private ConfigData<string[]> GetPinFilters(string name, string description)
{
string value = ((BaseUnityPlugin)plugin).Config.Bind<string>("Pins", name, "", description).Value;
string[] value2 = null;
if (!string.IsNullOrWhiteSpace(value))
{
value2 = string.Join(" ", value.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries)).Split(new char[1] { ' ' });
}
return new ConfigData<string[]>("Pins", name, description, value2);
}
private ConfigData<List<TrackedObject>> GetInclusionList(string name, string defaultValue, string description)
{
string text = ((BaseUnityPlugin)plugin).Config.Bind<string>("Inclusions", name, "", description).Value;
if (string.IsNullOrWhiteSpace(text))
{
text = defaultValue;
}
List<TrackedObject> value = (from i in (from Match m in new Regex("\\b[A-Za-z-'_, 0-9]+\\b").Matches(text)
select m.Groups[0].Value).ToList()
select GetInclusionObject(name, i)).ToList();
return new ConfigData<List<TrackedObject>>("Inclusions", name, description, value);
}
private static TrackedObject GetInclusionObject(string name, string data)
{
string[] array = data.Split(new char[1] { ',' });
if (array.Length == 3 && bool.TryParse(array[2], out var result))
{
return new TrackedObject(array[0], array[1], result);
}
throw new MappingException("Failed to load property " + name + ".");
}
protected override void handleCustomData<T>(ConfigData<T> configData)
{
if ((object)configData.value is string[] pinFilters)
{
MinimapUtils.SetPinFilters(pinFilters);
}
}
}
[BepInPlugin("purps.valheim.locator", "Locator", "1.1.0")]
[BepInProcess("valheim.exe")]
public class LocatorPlugin : BasePlugin
{
private const string PluginGuid = "purps.valheim.locator";
private const string PluginName = "Locator";
private const string PluginVersion = "1.1.0";
public static readonly int CastMask = LayerMask.GetMask(new string[14]
{
"item", "player", "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net",
"character_ghost", "hitbox", "character_noenv", "vehicle"
});
private static readonly GUIStyle DebugStyle = new GUIStyle();
public static string DebugText = "";
public static Rect DebugTextLocation = new Rect(10f, 5f, (float)Screen.width, 20f);
public static LocatorConfig Config => (LocatorConfig)BasePlugin.BaseConfig;
public LocatorPlugin()
: base("purps.valheim.locator")
{
}
private void Update()
{
DebugText = "";
MinimapUtils.Update();
}
private void OnGUI()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
GuiUtils.DrawOutline(DebugTextLocation, DebugText, DebugStyle);
}
protected override void PluginAwake()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
DebugStyle.normal.textColor = Color.green;
DebugStyle.fontSize = 15;
CreateCommands();
MinimapUtils.OnAwake();
}
protected override void PluginDestroy()
{
MinimapUtils.OnDestroy();
}
private void CreateCommands()
{
BasePlugin.CommandProcessor.AddCommand(new Command("/locator-commands", "Displays all commands provided by the Locator plugin.", BasePlugin.CommandProcessor.PrintCommands, shouldPrint: false));
BasePlugin.CommandProcessor.AddCommand(new Command("/locatemerchant", "Pins the BlackForest Merchant on your Minimap.", delegate
{
WorldUtils.Locate((PinType)3, new List<Tuple<string, string>> { Tuple.Create("Vendor_BlackForest", "Merchant") }, multiple: false);
}));
BasePlugin.CommandProcessor.AddCommand(new Command("/locatebosses", "Pins all boss altars on your Minimap.", delegate
{
WorldUtils.Locate((PinType)9, new List<Tuple<string, string>>
{
Tuple.Create("Eikthyrnir", "Eikthyr"),
Tuple.Create("GDKing", "The Elder"),
Tuple.Create("Bonemass", "Bonemass"),
Tuple.Create("Dragonqueen", "Moder"),
Tuple.Create("GoblinKing", "Yagluth")
}, multiple: true);
}));
BasePlugin.CommandProcessor.AddCommand(new Command("/listlocations", "Lists all the locations in the Console. Does not work on servers.", WorldUtils.ListLocations));
BasePlugin.CommandProcessor.AddCommand(new Command("/listpins", "Lists all your Pins in the Console.", MinimapUtils.ListPins));
BasePlugin.CommandProcessor.AddCommand(new Command("/clearpins", "Clears all your Pins.", MinimapUtils.ClearPins));
BasePlugin.CommandProcessor.AddCommand(new Command("/filterpins", "Filters your minimap pins using the provided names.", MinimapUtils.SetPinFilters));
}
protected override BaseConfig GetConfig()
{
return new LocatorConfig(this);
}
}
}
namespace Purps.Valheim.Locator.Utils
{
public static class GuiUtils
{
public static void DrawOutline(Rect position, string text, GUIStyle style)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: 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_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
Color textColor = style.normal.textColor;
style.normal.textColor = Color.black;
float x = ((Rect)(ref position)).x;
((Rect)(ref position)).x = x - 1f;
GUI.Label(position, text, style);
((Rect)(ref position)).x = ((Rect)(ref position)).x + 2f;
GUI.Label(position, text, style);
x = ((Rect)(ref position)).x;
((Rect)(ref position)).x = x - 1f;
x = ((Rect)(ref position)).y;
((Rect)(ref position)).y = x - 1f;
GUI.Label(position, text, style);
((Rect)(ref position)).y = ((Rect)(ref position)).y + 2f;
GUI.Label(position, text, style);
x = ((Rect)(ref position)).y;
((Rect)(ref position)).y = x - 1f;
style.normal.textColor = textColor;
GUI.Label(position, text, style);
}
}
public static class MinimapUtils
{
private static readonly HashSet<Component> TrackedComponents = new HashSet<Component>();
private static Dictionary<Type, Tuple<bool, List<TrackedObject>>> TrackedTypes => new Dictionary<Type, Tuple<bool, List<TrackedObject>>>
{
{
typeof(Destructible),
Tuple.Create(BasePlugin.GetConfigData<bool>("pinDestructibles").value, BasePlugin.GetConfigData<List<TrackedObject>>("destructibleInclusions").value)
},
{
typeof(MineRock),
Tuple.Create(BasePlugin.GetConfigData<bool>("pinMineRocks").value, BasePlugin.GetConfigData<List<TrackedObject>>("mineRockInclusions").value)
},
{
typeof(Location),
Tuple.Create(BasePlugin.GetConfigData<bool>("pinLocations").value, BasePlugin.GetConfigData<List<TrackedObject>>("locationInclusions").value)
},
{
typeof(Pickable),
Tuple.Create(BasePlugin.GetConfigData<bool>("pinPickables").value, BasePlugin.GetConfigData<List<TrackedObject>>("pickableInclusions").value)
},
{
typeof(SpawnArea),
Tuple.Create(BasePlugin.GetConfigData<bool>("pinSpawners").value, BasePlugin.GetConfigData<List<TrackedObject>>("spawnerInclusions").value)
},
{
typeof(Vegvisir),
Tuple.Create(BasePlugin.GetConfigData<bool>("pinVegvisirs").value, BasePlugin.GetConfigData<List<TrackedObject>>("vegvisirInclusions").value)
},
{
typeof(Leviathan),
Tuple.Create(BasePlugin.GetConfigData<bool>("pinLeviathans").value, BasePlugin.GetConfigData<List<TrackedObject>>("leviathanInclusions").value)
}
};
public static List<PinData> MapPins
{
get
{
Traverse obj = Traverse.Create((object)Minimap.instance);
return ((obj != null) ? obj.Field("m_pins").GetValue<List<PinData>>() : null) ?? new List<PinData>();
}
}
public static string[] GetPinFilters()
{
return ((Component)Minimap.instance).GetComponent<CustomMinimapData>().PinFilters;
}
public static void SetPinFilters(string[] parameters)
{
if (StatusUtils.IsPlayerLoaded() && IsMinimapAvailable())
{
((Component)Minimap.instance).GetComponent<CustomMinimapData>().PinFilters = parameters;
}
}
public static bool IsMinimapAvailable()
{
return (Object)(object)Minimap.instance != (Object)null;
}
public static void Update()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
RaycastHit val = default(RaycastHit);
if (!IsMinimapAvailable() || !BasePlugin.GetConfigData<bool>("pinEnabled").value || !Physics.Raycast(((Component)GameCamera.instance).transform.position, ((Component)GameCamera.instance).transform.forward, ref val, BasePlugin.GetConfigData<float>("pinRayDistance").value, LocatorPlugin.CastMask))
{
return;
}
foreach (Type key in TrackedTypes.Keys)
{
Component componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent(key, false);
if ((Object)(object)componentInParent != (Object)null)
{
if (BasePlugin.GetConfigData<bool>("debug").value)
{
LocatorPlugin.DebugText = $"name={((Object)componentInParent).name}, type={((object)componentInParent).GetType()}";
}
Tuple<bool, List<TrackedObject>> valueSafe = GeneralExtensions.GetValueSafe<Type, Tuple<bool, List<TrackedObject>>>(TrackedTypes, key);
if (valueSafe != null && valueSafe.Item1)
{
AddTrackedPin(componentInParent, valueSafe.Item2);
}
}
}
}
public static void ListPins(string[] parameters)
{
if (!StatusUtils.IsPlayerLoaded() || !IsMinimapAvailable())
{
return;
}
List<PinData> list = MapPins;
if (parameters != null && parameters.Length != 0)
{
list = list.FindAll((PinData pin) => parameters.Any(pin.m_name.ToLower().Replace(' ', '_').Contains));
}
list.ForEach(delegate(PinData pin)
{
ConsoleUtils.WriteToConsole(pin.m_name, ((object)(Vector3)(ref pin.m_pos)).ToString(), "(" + ((object)(PinType)(ref pin.m_type)).ToString() + ") " + ((Object)pin.m_icon).name);
});
}
public static void AddPin(string name, Vector3 position, PinType type)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
Minimap.instance.AddPin(position, type, name, true, false, 0L);
}
public static void RemovePin(PinData pin)
{
if (IsMinimapAvailable())
{
Minimap.instance.RemovePin(pin);
}
}
public static void RemovePin(Vector3 position)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
if (TrackedComponents.RemoveWhere((Component component) => (Object)(object)component != (Object)null && (Object)(object)component.transform != (Object)null && Vector2DDistance(component.transform.position, position) < BasePlugin.GetConfigData<float>("pinDistance").value) == 0)
{
Minimap.instance.RemovePin(position, 1f);
}
}
public static void ClearPins(string[] parameters)
{
if (IsMinimapAvailable())
{
new List<PinData>(MapPins).FindAll((PinData pin) => ((Object)pin.m_icon).name != "mapicon_start" && ((Object)pin.m_icon).name != "mapicon_trader").ForEach(RemovePin);
TrackedComponents.Clear();
}
}
public static void AddTrackedPin(Component component, List<TrackedObject> trackedObjects)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
if (IsMinimapAvailable())
{
TrackedObject trackedObject = Track(component, trackedObjects);
if (trackedObject != null)
{
AddPin(trackedObject.PinName, component.transform.position, GetPinType(component));
}
}
}
private static PinType GetPinType(Component component)
{
return (PinType)3;
}
private static TrackedObject GetTrackedObject(Component component, List<TrackedObject> typeTrackedObjects)
{
TrackedObject trackedObject = (from typeTrackedObject in typeTrackedObjects.FindAll((TrackedObject typeTrackedObject) => ((Object)component).name.Contains(typeTrackedObject.Name))
orderby TrackedObject.QueryOrder(typeTrackedObject.Name, ((Object)component).name)
select typeTrackedObject).FirstOrDefault();
if (trackedObject == null || !trackedObject.ShouldTrack)
{
return null;
}
return trackedObject;
}
private static TrackedObject Track(Component component, List<TrackedObject> trackedObjects)
{
if (!IsMinimapAvailable())
{
return null;
}
TrackedObject trackedObject = GetTrackedObject(component, trackedObjects);
if (trackedObject == null)
{
return trackedObject;
}
bool flag = MapPins.FindAll((PinData pin) => pin.m_name == trackedObject.PinName && Vector2DDistance(pin.m_pos, component.transform.position) < BasePlugin.GetConfigData<float>("pinDistance").value).Count == 0;
if (TrackedComponents.Count == 0)
{
TrackedComponents.Add(component);
if (!flag)
{
return null;
}
return trackedObject;
}
if (TrackedComponents.Where((Component t) => (Object)(object)t != (Object)null && (Object)(object)component != (Object)null && Vector3.Distance(t.transform.position, component.transform.position) < BasePlugin.GetConfigData<float>("pinDistance").value).Count() != 0)
{
if (!flag)
{
return null;
}
return trackedObject;
}
TrackedComponents.Add(component);
return trackedObject;
}
private static float Vector2DDistance(Vector3 v1, Vector3 v2)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: 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)
return Mathf.Sqrt(Mathf.Pow(Mathf.Abs(v1.x - v2.x), 2f) + Mathf.Pow(Mathf.Abs(v1.z - v2.z), 2f));
}
public static void OnDestroy()
{
Minimap instance = Minimap.instance;
Object.Destroy((Object)(object)((instance != null) ? ((Component)instance).gameObject.GetComponent<CustomMinimapData>() : null));
TrackedComponents?.Clear();
}
public static void OnAwake()
{
Minimap instance = Minimap.instance;
if (instance != null)
{
((Component)instance).gameObject.AddComponent<CustomMinimapData>();
}
}
private static bool ShouldPinRender(PinData pin)
{
string[] pinFilters = GetPinFilters();
if (pinFilters == null || pinFilters.Length == 0)
{
return true;
}
return pinFilters.Count((string filter) => pin.m_name.ToLower().Replace(' ', '_').Contains(filter)) != 0;
}
public static void FilterPins()
{
MapPins.ForEach(delegate(PinData pin)
{
bool active = ShouldPinRender(pin);
PinNameData namePinData = pin.m_NamePinData;
if (namePinData != null)
{
GameObject pinNameGameObject = namePinData.PinNameGameObject;
if (pinNameGameObject != null)
{
pinNameGameObject.SetActive(active);
}
}
RectTransform uiElement = pin.m_uiElement;
if (uiElement != null)
{
((Component)uiElement).gameObject.SetActive(active);
}
});
}
}
public static class StatusUtils
{
public static bool IsPlayerLoaded()
{
if ((Object)(object)Player.m_localPlayer != (Object)null)
{
return true;
}
ConsoleUtils.WriteToConsole("Player must be in-game for commands to work!");
return false;
}
public static bool IsPlayerOffline()
{
if (ZNet.instance.GetConnectedPeers().Count == 0)
{
return true;
}
ConsoleUtils.WriteToConsole("This command does not work on a server.");
return false;
}
}
public static class WorldUtils
{
private static readonly List<Vector3> locationPoints = GenerateLocationPoints();
private static List<LocationInstance> MapLocations => ZoneSystem.instance.GetLocationList().ToList();
private static List<Vector3> GenerateLocationPoints()
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
List<Vector3> list = new List<Vector3>();
for (int i = 1666; i <= 10000; i += 3332)
{
for (double num = 0.0; num <= 360.0; num += 60.0)
{
float num2 = (float)((double)i * Math.Cos(num * (Math.PI / 180.0)));
float num3 = (float)((double)i * Math.Sin(num * (Math.PI / 180.0)));
list.Add(new Vector3(num2, 0f, num3));
}
}
return list;
}
public static void Locate(PinType pinType, List<Tuple<string, string>> names, bool multiple)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: 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)
if (!StatusUtils.IsPlayerLoaded())
{
return;
}
foreach (Tuple<string, string> name in names)
{
if (multiple)
{
locationPoints.ForEach(delegate(Vector3 point)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
Locate(name, point, pinType);
});
}
else
{
Locate(name, ((Component)Player.m_localPlayer).transform.position, pinType);
}
}
}
private static void Locate(Tuple<string, string> name, Vector3 position, PinType pinType)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected I4, but got Unknown
Game.instance.DiscoverClosestLocation(name.Item1, position, name.Item2, (int)pinType, true, false);
}
public static void ListLocations(string[] parameters)
{
if (!StatusUtils.IsPlayerLoaded() || !StatusUtils.IsPlayerOffline())
{
return;
}
List<LocationInstance> list = MapLocations;
if (parameters != null && parameters.Length != 0)
{
list = list.FindAll((LocationInstance location) => parameters.Any(location.m_location.m_prefabName.ToLower().Replace(' ', '-').Contains));
}
list.ForEach(delegate(LocationInstance location)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
ConsoleUtils.WriteToConsole(location.m_location.m_prefabName, ((object)(Vector3)(ref location.m_position)).ToString());
});
}
}
}
namespace Purps.Valheim.Locator.Patches
{
[HarmonyPatch(typeof(Terminal), "TryRunCommand")]
public class TerminalPatch
{
[HarmonyPrefix]
internal static bool Prefix(Terminal __instance, string text)
{
if (BasePlugin.GetCommands().Any((ICommand command) => text.StartsWith(command.Name)))
{
BasePlugin.ExecuteCommand(((TMP_InputField)__instance.m_input).text);
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Minimap), "OnMapRightClick")]
public static class MinimapPatch
{
[HarmonyPostfix]
internal static void Postfix(Minimap __instance)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
MinimapUtils.RemovePin((Vector3)((object)__instance).GetType().GetMethod("ScreenToWorldPoint", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[1] { Input.mousePosition }));
}
[HarmonyPatch(typeof(Minimap), "UpdatePins")]
[HarmonyPostfix]
internal static void UpdatePins(Minimap __instance)
{
MinimapUtils.FilterPins();
}
[HarmonyPatch(typeof(Minimap), "Awake")]
[HarmonyPostfix]
internal static void Awake(Minimap __instance)
{
MinimapUtils.OnAwake();
}
[HarmonyPatch(typeof(Minimap), "OnDestroy")]
[HarmonyPostfix]
internal static void OnDestroy(Minimap __instance)
{
MinimapUtils.OnDestroy();
}
}
}
namespace Purps.Valheim.Locator.Exceptions
{
public class MappingException : Exception
{
public MappingException(string message)
: base(message)
{
}
public MappingException(string message, Exception inner)
: base(message, inner)
{
}
}
}
namespace Purps.Valheim.Locator.Data
{
public class TrackedObject
{
public string Name { get; set; }
public string PinName { get; set; }
public bool ShouldTrack { get; set; } = true;
public TrackedObject(string name, string pinName, bool shouldTrack)
{
Name = name;
PinName = pinName;
ShouldTrack = shouldTrack;
}
public static int QueryOrder(string name, string query)
{
if (name == query)
{
return -1;
}
if (!name.Contains(query))
{
return 1;
}
return 0;
}
public override string ToString()
{
return $"{GetType().Name}[Name={Name}, PinName={PinName}, ShouldTrack={ShouldTrack}]";
}
}
}
namespace Purps.Valheim.Locator.Components
{
public class CustomMinimapData : MonoBehaviour
{
public string[] PinFilters { get; set; } = BasePlugin.GetConfigData<string[]>("filterPins").value ?? null;
}
}