using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Splatform; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("SettlementCharts")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.2.0")] [assembly: AssemblyInformationalVersion("0.1.2")] [assembly: AssemblyProduct("SettlementCharts")] [assembly: AssemblyTitle("Settlement Charts")] [assembly: AssemblyVersion("0.1.2.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SettlementCharts { internal struct ChartedSettlement { internal Vector3 Position; internal string Name; } internal static class ChartedPins { internal const string RpcName = "MW_ChartedSettlements"; private const float PollSeconds = 5f; private static float _nextPoll; private static string _lastSignature = null; private static readonly List OurPins = new List(); internal static void Register() { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register("MW_ChartedSettlements", (Action)OnReceive); } } internal static void ServerPoll() { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZDOMan.instance == null || Time.time < _nextPoll) { return; } _nextPoll = Time.time + 5f; List list = Collect(); string text = Signature(list); if (!(text == _lastSignature)) { _lastSignature = text; Broadcast(list); if (ChartsPlugin.Verbose.Value) { ChartsPlugin.Log.LogInfo((object)$"[charts] broadcasting {list.Count} charted settlement(s)."); } } } private static List Collect() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) List list = new List(); List list2 = new List(); int num = 0; while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative(ChartRegistry.TablePrefab, list2, ref num) && list2.Count <= 20000) { } foreach (ZDO item in list2) { if (item != null && item.IsValid() && item.GetBool(ChartRegistry.ChartedHash, false)) { list.Add(new ChartedSettlement { Position = item.GetPosition(), Name = item.GetString("MW_SettlementName", ChartsPlugin.DefaultPinName.Value) }); } } return list; } private static string Signature(List list) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); foreach (ChartedSettlement item in list) { stringBuilder.Append(item.Name).Append('@').Append(Mathf.RoundToInt(item.Position.x)) .Append(',') .Append(Mathf.RoundToInt(item.Position.z)) .Append(';'); } return stringBuilder.ToString(); } private static void Broadcast(List charted) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(charted.Count); foreach (ChartedSettlement item in charted) { val.Write(item.Position); val.Write(item.Name ?? string.Empty); } ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "MW_ChartedSettlements", new object[1] { val }); } private static void OnReceive(long sender, ZPackage pkg) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (pkg != null) { List list = new List(); int num = pkg.ReadInt(); for (int i = 0; i < num; i++) { Vector3 position = pkg.ReadVector3(); string name = pkg.ReadString(); list.Add(new ChartedSettlement { Position = position, Name = name }); } Apply(list); } } private static void Apply(List charted) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Minimap.instance == (Object)null) { return; } ClearPins(); PinType val = (PinType)ChartsPlugin.PinType.Value; foreach (ChartedSettlement item in charted) { string text = (string.IsNullOrEmpty(item.Name) ? ChartsPlugin.DefaultPinName.Value : item.Name); PinData val2 = Minimap.instance.AddPin(item.Position, val, text, false, false, 0L, default(PlatformUserID)); if (val2 != null) { val2.m_doubleSize = ChartsPlugin.PinDoubleSize.Value; OurPins.Add(val2); } } if (ChartsPlugin.Verbose.Value) { ChartsPlugin.Log.LogInfo((object)$"[charts] map now shows {OurPins.Count} charted settlement(s)."); } } internal static void ClearPins() { if ((Object)(object)Minimap.instance == (Object)null) { OurPins.Clear(); return; } foreach (PinData ourPin in OurPins) { if (ourPin != null) { Minimap.instance.RemovePin(ourPin); } } OurPins.Clear(); } } internal class ChartNameReceiver : TextReceiver { private readonly MapTable _table; internal ChartNameReceiver(MapTable table) { _table = table; } public string GetText() { string name = ChartRegistry.GetName(_table); if (!string.IsNullOrEmpty(name)) { return name; } return string.Empty; } public void SetText(string text) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) string text2 = (text ?? string.Empty).Trim(); if (string.IsNullOrEmpty(text2)) { text2 = ChartsPlugin.DefaultPinName.Value; } if (!ChartRegistry.ChartWithName(_table, text2)) { ChartsPlugin.Log.LogWarning((object)"[charts] could not chart the table — it went out of scope."); return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, ChartsPlugin.MessageLit.Value, 0, (Sprite)null); } ChartsPlugin.Log.LogInfo((object)$"[charts] charted '{text2}' at {((Component)_table).transform.position}."); } } [BepInPlugin("mistwalkers.settlementcharts", "Settlement Charts", "0.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class ChartsPlugin : BaseUnityPlugin { public const string GUID = "mistwalkers.settlementcharts"; public const string NAME = "Settlement Charts"; public const string VERSION = "0.1.2"; internal static ManualLogSource Log; internal static ConfigEntry ChartRadius; internal static ConfigEntry EventRadius; internal static ConfigEntry MinPlayers; internal static ConfigEntry ChartReach; internal static ConfigEntry ChartModifier; internal static ConfigEntry Verbose; internal static ConfigEntry HoverDark; internal static ConfigEntry HoverLit; internal static ConfigEntry MessageLit; internal static ConfigEntry MessageDark; internal static ConfigEntry MessageDarkDuringRaid; internal static ConfigEntry StatusSuffix; internal static ConfigEntry DefaultPinName; internal static ConfigEntry PinType; internal static ConfigEntry PinDoubleSize; internal static ConfigEntry NameCharLimit; internal static ConfigEntry DialogTopic; private bool _rpcRegistered; private void Awake() { //IL_0261: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ChartRadius = ((BaseUnityPlugin)this).Config.Bind("Charting", "chartRadius", 120f, "Max distance from a charted table for a settlement raid to be selected."); EventRadius = ((BaseUnityPlugin)this).Config.Bind("Charting", "eventRadius", 120f, "Raid area radius for settlement raids. Vanilla is 96. Match chartRadius to keep one circle."); MinPlayers = ((BaseUnityPlugin)this).Config.Bind("Charting", "minPlayersInRadius", 1, "Players required near a charted table for it to be raided. Set 2 to spare solo players."); ChartModifier = ((BaseUnityPlugin)this).Config.Bind("Keys", "chartModifierKey", (KeyCode)304, "Held with Use to chart a settlement. Better Cartography Table uses LeftShift too; change one if you enable guilds."); ChartReach = ((BaseUnityPlugin)this).Config.Bind("Charting", "chartReach", 15f, "Range of the 'chart' console command."); Verbose = ((BaseUnityPlugin)this).Config.Bind("Debug", "verboseLogging", true, "Log raid selection decisions."); HoverDark = ((BaseUnityPlugin)this).Config.Bind("Text", "hoverTextDark", "Chart this settlement", "Prompt shown on an uncharted table."); HoverLit = ((BaseUnityPlugin)this).Config.Bind("Text", "hoverTextLit", "Erase from the charts", "Prompt shown on a charted table."); MessageLit = ((BaseUnityPlugin)this).Config.Bind("Text", "messageLit", "This settlement is charted. It will be found.", "Message shown when charting."); MessageDark = ((BaseUnityPlugin)this).Config.Bind("Text", "messageDark", "Erased from the charts.", "Message shown when erasing."); MessageDarkDuringRaid = ((BaseUnityPlugin)this).Config.Bind("Text", "messageDarkDuringRaid", "Erased from the charts. What is already coming will not turn back.", "Message shown when erasing during a raid. Erasing never stops the raid already running."); DefaultPinName = ((BaseUnityPlugin)this).Config.Bind("Map", "defaultPinName", "Charted settlement", "Pin label when the name is left blank."); PinType = ((BaseUnityPlugin)this).Config.Bind("Map", "pinType", 3, "Minimap pin icon index, 0-4."); PinDoubleSize = ((BaseUnityPlugin)this).Config.Bind("Map", "pinDoubleSize", true, "Draw settlement pins at double size."); NameCharLimit = ((BaseUnityPlugin)this).Config.Bind("Map", "nameCharLimit", 24, "Max settlement name length."); DialogTopic = ((BaseUnityPlugin)this).Config.Bind("Text", "dialogTopic", "Name this settlement", "Naming dialog heading."); StatusSuffix = ((BaseUnityPlugin)this).Config.Bind("Text", "statusSuffix", " (charted)", "Appended to hover text while charted."); new Harmony("mistwalkers.settlementcharts").PatchAll(); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartListCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartCheckCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartEventsCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartForceCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartTimerCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartDiagCommand()); Log.LogInfo((object)"Settlement Charts 0.1.2 loaded."); } private void Update() { if (!_rpcRegistered && ZRoutedRpc.instance != null) { ChartedPins.Register(); _rpcRegistered = true; Log.LogInfo((object)"[charts] charted-settlement RPC registered."); } if (_rpcRegistered && ZRoutedRpc.instance == null) { _rpcRegistered = false; ChartedPins.ClearPins(); } ChartedPins.ServerPoll(); } } internal static class ChartRegistry { internal static readonly int ChartedHash = StringExtensionMethods.GetStableHashCode("MW_Charted"); internal const string NameKey = "MW_SettlementName"; private static bool _prefabLearned; private static readonly List Tables = new List(); private static readonly Dictionary SwitchOwners = new Dictionary(); internal static string TablePrefab { get; private set; } = "piece_cartographytable"; private static void LearnPrefab(MapTable table) { if (_prefabLearned || (Object)(object)table == (Object)null) { return; } ZNetView component = ((Component)table).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsValid() && AccessTools.Method(typeof(ZNetView), "GetPrefabName", (Type[])null, (Type[])null)?.Invoke(component, null) is string text && !string.IsNullOrEmpty(text)) { if (text != TablePrefab) { ChartsPlugin.Log.LogWarning((object)("[charts] table prefab is '" + text + "', not '" + TablePrefab + "'. Using the live value.")); } TablePrefab = text; _prefabLearned = true; } } internal static string GetName(MapTable table) { ZNetView val = View(table); if ((Object)(object)val == (Object)null) { return string.Empty; } return val.GetZDO().GetString("MW_SettlementName", string.Empty); } internal static bool ChartWithName(MapTable table, string name) { ZNetView val = View(table); if ((Object)(object)val == (Object)null) { return false; } val.ClaimOwnership(); val.GetZDO().Set("MW_SettlementName", name ?? string.Empty); val.GetZDO().Set(ChartedHash, true); return true; } internal static bool Erase(MapTable table) { ZNetView val = View(table); if ((Object)(object)val == (Object)null) { return false; } val.ClaimOwnership(); val.GetZDO().Set(ChartedHash, false); return true; } internal static void Register(MapTable table) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)table == (Object)null)) { if (!Tables.Contains(table)) { Tables.Add(table); } if ((Object)(object)table.m_readSwitch != (Object)null) { SwitchOwners[table.m_readSwitch] = table; } LearnPrefab(table); ChartsPlugin.Log.LogInfo((object)($"[charts] registered table at {((Component)table).transform.position} " + "(readSwitch=" + (((Object)(object)table.m_readSwitch != (Object)null) ? ((Object)table.m_readSwitch).name : "null") + ", writeSwitch=" + (((Object)(object)table.m_writeSwitch != (Object)null) ? ((Object)table.m_writeSwitch).name : "null") + ").")); } } internal static MapTable OwnerOf(Switch sw) { if ((Object)(object)sw == (Object)null) { return null; } if (!SwitchOwners.TryGetValue(sw, out var value)) { return null; } if ((Object)(object)value == (Object)null) { SwitchOwners.Remove(sw); return null; } return value; } private static ZNetView View(MapTable table) { if ((Object)(object)table == (Object)null) { return null; } ZNetView component = ((Component)table).GetComponent(); if (!((Object)(object)component != (Object)null) || !component.IsValid()) { return null; } return component; } internal static bool IsCharted(MapTable table) { ZNetView val = View(table); if ((Object)(object)val == (Object)null) { return false; } return val.GetZDO().GetBool(ChartedHash, false); } internal static bool Toggle(MapTable table, out bool lit) { lit = false; ZNetView val = View(table); if ((Object)(object)val == (Object)null) { return false; } val.ClaimOwnership(); lit = !val.GetZDO().GetBool(ChartedHash, false); val.GetZDO().Set(ChartedHash, lit); return true; } internal static MapTable FindLitTableNear(Vector3 pos, float radius) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) MapTable result = null; float num = radius * radius; for (int num2 = Tables.Count - 1; num2 >= 0; num2--) { MapTable val = Tables[num2]; if ((Object)(object)val == (Object)null) { Tables.RemoveAt(num2); } else if (IsCharted(val)) { Vector3 val2 = ((Component)val).transform.position - pos; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude <= num) { num = sqrMagnitude; result = val; } } } return result; } internal static MapTable FindNearestTable(Vector3 pos, float radius) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) MapTable result = null; float num = radius * radius; for (int num2 = Tables.Count - 1; num2 >= 0; num2--) { MapTable val = Tables[num2]; if ((Object)(object)val == (Object)null) { Tables.RemoveAt(num2); } else { Vector3 val2 = ((Component)val).transform.position - pos; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude <= num) { num = sqrMagnitude; result = val; } } } return result; } internal static List AllLive() { for (int num = Tables.Count - 1; num >= 0; num--) { if ((Object)(object)Tables[num] == (Object)null) { Tables.RemoveAt(num); } } return Tables; } internal static int CountPlayersNear(Vector3 pos, float radius) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) int num = 0; float num2 = radius * radius; foreach (Player allPlayer in Player.GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null)) { Vector3 val = ((Component)allPlayer).transform.position - pos; if (((Vector3)(ref val)).sqrMagnitude <= num2) { num++; } } } return num; } } [HarmonyPatch(typeof(MapTable), "Start")] internal static class MapTableStartPatch { private static void Postfix(MapTable __instance) { ChartRegistry.Register(__instance); } } [HarmonyPatch(typeof(MapTable), "GetReadHoverText")] internal static class MapTableReadHoverPatch { private static void Postfix(MapTable __instance, ref string __result) { HoverText.Append(__instance, ref __result); } } internal static class HoverText { internal static void Append(MapTable table, ref string result) { if ((Object)(object)table == (Object)null || result == null) { return; } bool num = ChartRegistry.IsCharted(table); string text = (num ? ChartsPlugin.HoverLit.Value : ChartsPlugin.HoverDark.Value); if (num && !string.IsNullOrEmpty(ChartsPlugin.StatusSuffix.Value)) { int num2 = result.IndexOf('\n'); if (num2 >= 0) { result = result.Insert(num2, ChartsPlugin.StatusSuffix.Value); } else { result += ChartsPlugin.StatusSuffix.Value; } } string text2 = "\n[" + ModifierLabel() + " + $KEY_Use] " + text; result += ((Localization.instance != null) ? Localization.instance.Localize(text2) : text2); } private static string ModifierLabel() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) string text = ((object)ChartsPlugin.ChartModifier.Value/*cast due to .constrained prefix*/).ToString(); if (text.StartsWith("Left")) { return text.Substring(4); } if (text.StartsWith("Right")) { return text.Substring(5); } return text; } } [HarmonyPatch(typeof(Switch), "Interact")] internal static class SwitchInteractPatch { private const float DebounceSeconds = 1f; private static float _lastToggle = -99f; private static bool Prefix(Switch __instance, Humanoid character, bool hold, bool alt, ref bool __result) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return true; } MapTable val = ChartRegistry.OwnerOf(__instance); if ((Object)(object)val == (Object)null) { return true; } bool key = Input.GetKey(ChartsPlugin.ChartModifier.Value); if (ChartsPlugin.Verbose.Value) { ChartsPlugin.Log.LogInfo((object)$"[charts] Switch.Interact on a cartography table: hold={hold}, alt={alt}, modifier={key}."); } if (!key && !hold) { return true; } if (Time.time - _lastToggle < 1f) { __result = false; return false; } _lastToggle = Time.time; if (ChartRegistry.IsCharted(val)) { if (!ChartRegistry.Erase(val)) { if (character != null) { ((Character)character).Message((MessageType)2, "The table is not ready yet.", 0, (Sprite)null); } __result = false; return false; } bool flag = RandEventSystem.HaveActiveEvent(); if (character != null) { ((Character)character).Message((MessageType)2, flag ? ChartsPlugin.MessageDarkDuringRaid.Value : ChartsPlugin.MessageDark.Value, 0, (Sprite)null); } ChartsPlugin.Log.LogInfo((object)$"[charts] table at {((Component)val).transform.position} erased from the charts."); } else if ((Object)(object)TextInput.instance == (Object)null) { ChartRegistry.ChartWithName(val, ChartsPlugin.DefaultPinName.Value); if (character != null) { ((Character)character).Message((MessageType)2, ChartsPlugin.MessageLit.Value, 0, (Sprite)null); } ChartsPlugin.Log.LogWarning((object)"[charts] TextInput unavailable, charted under the default name."); } else { TextInput.instance.RequestText((TextReceiver)(object)new ChartNameReceiver(val), ChartsPlugin.DialogTopic.Value, ChartsPlugin.NameCharLimit.Value); } __result = true; return false; } } [HarmonyPatch(typeof(RandEventSystem), "GetPossibleRandomEvents")] internal static class GetPossibleRandomEventsPatch { private static void Postfix(List> __result) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) if (__result == null || __result.Count == 0 || ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer())) { return; } bool value = ChartsPlugin.Verbose.Value; List> list = new List>(__result.Count); foreach (KeyValuePair item in __result) { RandomEvent key = item.Key; if (key == null) { continue; } if (!key.m_nearBaseOnly) { list.Add(item); continue; } MapTable val = ChartRegistry.FindLitTableNear(item.Value, ChartsPlugin.ChartRadius.Value); if ((Object)(object)val == (Object)null) { if (value) { ChartsPlugin.Log.LogInfo((object)$"[charts] '{key.m_name}' dropped: no charted table within {ChartsPlugin.ChartRadius.Value}m."); } continue; } Vector3 position = ((Component)val).transform.position; int num = ChartRegistry.CountPlayersNear(position, ChartsPlugin.EventRadius.Value); if (num < ChartsPlugin.MinPlayers.Value) { if (value) { ChartsPlugin.Log.LogInfo((object)$"[charts] '{key.m_name}' dropped: {num} player(s) at the charted table, needs {ChartsPlugin.MinPlayers.Value}."); } continue; } key.m_eventRange = ChartsPlugin.EventRadius.Value; list.Add(new KeyValuePair(key, position)); if (value) { ChartsPlugin.Log.LogInfo((object)$"[charts] '{key.m_name}' allowed at charted table {position}, range {ChartsPlugin.EventRadius.Value}m, {num} player(s) present."); } } __result.Clear(); __result.AddRange(list); } } internal class ChartCommand : ConsoleCommand { public override string Name => "chart"; public override string Help => "Chart or erase the nearest cartography table."; public override void Run(string[] args) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { Console.instance.Print("No local player."); return; } float value = ChartsPlugin.ChartReach.Value; MapTable val = ChartRegistry.FindNearestTable(((Component)localPlayer).transform.position, value); if ((Object)(object)val == (Object)null) { Console.instance.Print($"No cartography table within {value}m."); return; } if (!ChartRegistry.Toggle(val, out var lit)) { Console.instance.Print("That table is not ready yet, try again in a moment."); return; } string text = (lit ? "This settlement is charted. It will be found." : "Erased from the charts. This settlement is not a target."); Console.instance.Print(text); ((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null); ChartsPlugin.Log.LogInfo((object)string.Format("[charts] table at {0} set to {1}.", ((Component)val).transform.position, lit ? "LIT" : "DARK")); } } internal class ChartCheckCommand : ConsoleCommand { public override string Name => "chartcheck"; public override string Help => "Report whether a raid could fire here."; public override void Run(string[] args) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { Console.instance.Print("No local player."); return; } Vector3 position = ((Component)localPlayer).transform.position; float value = ChartsPlugin.ChartRadius.Value; float value2 = ChartsPlugin.EventRadius.Value; int value3 = ChartsPlugin.MinPlayers.Value; Console.instance.Print($"--- chart check at ({position.x:F0}, {position.z:F0}) ---"); Console.instance.Print($"chartRadius {value}m / eventRadius {value2}m / minPlayers {value3}"); MapTable val = ChartRegistry.FindLitTableNear(position, value); if ((Object)(object)val == (Object)null) { MapTable val2 = ChartRegistry.FindNearestTable(position, value); if ((Object)(object)val2 == (Object)null) { Console.instance.Print($"NO charted table within {value}m (no table at all in range)."); } else { Console.instance.Print($"NO charted table within {value}m (nearest table is {Vector3.Distance(position, ((Component)val2).transform.position):F0}m away and dark)."); } Console.instance.Print("VERDICT: settlement raids blocked here. Wilderness events unaffected."); return; } Vector3 position2 = ((Component)val).transform.position; float num = Vector3.Distance(position, position2); int num2 = ChartRegistry.CountPlayersNear(position2, value2); Console.instance.Print($"Charted table {num:F0}m away at ({position2.x:F0}, {position2.z:F0})."); Console.instance.Print($"Players within {value2}m of it: {num2} (needs {value3})."); if (num2 < value3) { Console.instance.Print("VERDICT: settlement raids blocked here, not enough players at the table."); } else { Console.instance.Print($"VERDICT: settlement raids ALLOWED, anchored on the table at range {value2}m."); } } } internal class ChartEventsCommand : ConsoleCommand { public override string Name => "chartevents"; public override string Help => "Print which events survive the filter."; public override void Run(string[] args) { //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) object obj = AccessTools.Field(typeof(RandEventSystem), "m_instance")?.GetValue(null); if (obj == null) { Console.instance.Print("RandEventSystem instance not available."); return; } MethodInfo methodInfo = AccessTools.Method(typeof(RandEventSystem), "GetPossibleRandomEvents", (Type[])null, (Type[])null); if (methodInfo == null) { Console.instance.Print("Could not resolve GetPossibleRandomEvents."); return; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length != 0) { Console.instance.Print($"GetPossibleRandomEvents expects {parameters.Length} argument(s) — cannot invoke blind:"); ParameterInfo[] array = parameters; foreach (ParameterInfo parameterInfo in array) { Console.instance.Print(" " + parameterInfo.ParameterType.Name + " " + parameterInfo.Name); } return; } object obj2; try { obj2 = methodInfo.Invoke(obj, null); } catch (Exception ex) { Console.instance.Print("Invoke failed: " + (ex.InnerException?.Message ?? ex.Message)); return; } if (!(obj2 is List> list)) { Console.instance.Print("Unexpected return type: " + (obj2?.GetType().Name ?? "null")); return; } if (list.Count == 0) { Console.instance.Print("No events survive the filter here. Chart a table and stand at it."); return; } Console.instance.Print($"{list.Count} event(s) currently possible:"); foreach (KeyValuePair item in list) { RandomEvent key = item.Key; Vector3 value = item.Value; string text = (key.m_nearBaseOnly ? "settlement" : "WILDERNESS"); Console.instance.Print($" {key.m_name} [{text}] anchor ({value.x:F0}, {value.z:F0}) range {key.m_eventRange:F0}m"); } } } internal class ChartForceCommand : ConsoleCommand { public override string Name => "chartforce"; public override string Help => "Roll for a raid now, through the filter."; public override void Run(string[] args) { RandEventSystem instance = RandEventSystem.instance; if ((Object)(object)instance == (Object)null) { Console.instance.Print("RandEventSystem not available."); return; } if (RandEventSystem.HaveActiveEvent()) { Console.instance.Print("An event is already running. Wait for it to finish."); return; } instance.StartRandomEvent(); RandomEvent currentRandomEvent = instance.GetCurrentRandomEvent(); if (currentRandomEvent == null) { Console.instance.Print("Rolled, but nothing survived the filter here. Chart a table and stand at it."); return; } Console.instance.Print($"Started '{currentRandomEvent.m_name}' at ({currentRandomEvent.m_pos.x:F0}, {currentRandomEvent.m_pos.z:F0}), range {currentRandomEvent.m_eventRange:F0}m."); } } internal class ChartTimerCommand : ConsoleCommand { public override string Name => "charttimer"; public override string Help => "Show or set roll interval in minutes and chance in percent."; public override void Run(string[] args) { RandEventSystem instance = RandEventSystem.instance; if ((Object)(object)instance == (Object)null) { Console.instance.Print("RandEventSystem not available."); return; } if (args.Length == 0) { Console.instance.Print($"interval {instance.m_eventIntervalMin} min / chance {instance.m_eventChance}%"); Console.instance.Print("Set with: charttimer [percent]"); return; } if (!float.TryParse(args[0], out var result)) { Console.instance.Print("'" + args[0] + "' is not a number."); return; } instance.m_eventIntervalMin = result; if (args.Length > 1) { if (!float.TryParse(args[1], out var result2)) { Console.instance.Print("'" + args[1] + "' is not a number."); return; } instance.m_eventChance = result2; } Console.instance.Print($"interval {instance.m_eventIntervalMin} min / chance {instance.m_eventChance}% — testing only, restore before this world matters."); } } internal class ChartDiagCommand : ConsoleCommand { public override string Name => "chartdiag"; public override string Help => "Probe prefab name and minimap availability."; public override void Run(string[] args) { //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) Console.instance.Print("--- prefab ---"); List list = ChartRegistry.AllLive(); if (list.Count == 0) { Console.instance.Print("No tables loaded — stand near one and run this again."); } else { ZNetView component = ((Component)list[0]).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { Console.instance.Print("Table has no valid ZNetView."); } else { string text = (AccessTools.Method(typeof(ZNetView), "GetPrefabName", (Type[])null, (Type[])null)?.Invoke(component, null) as string) ?? ""; Console.instance.Print("prefab name : " + text); Console.instance.Print($"prefab hash : {component.GetZDO().GetPrefab()}"); Console.instance.Print($"name hash : {StringExtensionMethods.GetStableHashCode(text)} (should match)"); } } Console.instance.Print("--- minimap ---"); if ((Object)(object)Minimap.instance == (Object)null) { Console.instance.Print("Minimap.instance is NULL — pins are impossible, we would need BCT's system."); return; } Console.instance.Print("Minimap.instance present."); try { Vector3 val = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero); PinData val2 = Minimap.instance.AddPin(val, (PinType)3, "chart test", false, false, 0L, default(PlatformUserID)); if (val2 == null) { Console.instance.Print("AddPin returned null — pins rejected under this configuration."); return; } Console.instance.Print("AddPin OK. Removing test pin."); Minimap.instance.RemovePin(val2); Console.instance.Print("RemovePin OK. Global markers are viable."); } catch (Exception ex) { Console.instance.Print("Pin test threw: " + ex.Message); } } } internal class ChartListCommand : ConsoleCommand { public override string Name => "chartlist"; public override string Help => "List loaded tables and their state."; public override void Run(string[] args) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) List list = ChartRegistry.AllLive(); if (list.Count == 0) { Console.instance.Print("No cartography tables loaded."); return; } Console.instance.Print($"{list.Count} table(s) loaded:"); foreach (MapTable item in list) { Vector3 position = ((Component)item).transform.position; string arg = (ChartRegistry.IsCharted(item) ? "LIT " : "dark"); Console.instance.Print($" [{arg}] ({position.x:F0}, {position.z:F0})"); } } } }