Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of DeathHelper v0.2.0
DeathHelper.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] namespace DeathHelper; [BepInPlugin("com.burks.deathhelper", "Death Helper", "0.2.0")] public class DeathHelperPlugin : BaseUnityPlugin { public const string GUID = "com.burks.deathhelper"; public const string NAME = "Death Helper"; public const string VERSION = "0.2.0"; public static ConfigEntry<bool> ShowArrow; public static ConfigEntry<bool> RemoveEmpty; public static ConfigEntry<float> ArrowMaxDistance; public static ConfigEntry<float> CheckRange; public static ConfigEntry<float> TombRadius; public static ConfigEntry<float> ConfirmSeconds; public static ConfigEntry<KeyCode> ToggleKey; public static ConfigEntry<KeyCode> TeleportKey; public static ConfigEntry<bool> TeleportOn; public static ConfigEntry<int> TeleportCost; public static DeathHelperPlugin Instance; private bool _cmd; private bool _btnFailed; private GameObject _button; private static readonly FieldRef<Minimap, List<PinData>> Pins = AccessTools.FieldRefAccess<Minimap, List<PinData>>("m_pins"); private float _next; private readonly Dictionary<PinData, float> _emptySince = new Dictionary<PinData, float>(); private readonly List<PinData> _deaths = new List<PinData>(); private PinData _target; private Texture2D _arrow; private GUIStyle _style; private void Awake() { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Invalid comparison between Unknown and I4 ShowArrow = ((BaseUnityPlugin)this).Config.Bind<bool>("Arrow", "ShowArrow", true, "Show an arrow and distance to your nearest death marker at the top of the screen."); ArrowMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Arrow", "MaxDistance", 0f, "Hide the arrow when the marker is further than this many metres. 0 = always show."); ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Arrow", "ToggleKey", (KeyCode)0, "Optional key to switch the arrow on and off."); RemoveEmpty = ((BaseUnityPlugin)this).Config.Bind<bool>("Cleanup", "RemoveMarkersWithoutTombstone", true, "Remove a death marker from the map once you can see there is no tombstone at it."); CheckRange = ((BaseUnityPlugin)this).Config.Bind<float>("Cleanup", "CheckRange", 30f, "A marker is only checked while it is this close to you, so the area is certain to be loaded."); TombRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Cleanup", "TombstoneRadius", 15f, "A tombstone within this many metres of the marker counts as belonging to it (tombstones float and slide a little)."); ConfirmSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Cleanup", "ConfirmSeconds", 5f, "The spot must be seen empty for this long before the marker is removed."); TeleportOn = ((BaseUnityPlugin)this).Config.Bind<bool>("Teleport", "Enabled", true, "Allow paying to teleport to your nearest death marker (Esc menu button, the 'grave' console command, or the key below)."); TeleportCost = ((BaseUnityPlugin)this).Config.Bind<int>("Teleport", "Cost", 100, "Price in value: coins count 1 each, other valuables count what the trader pays for them (amber 5, amber pearl 10, ruby 20, silver necklace 30)."); TeleportKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Teleport", "Key", (KeyCode)0, "Optional hotkey."); Instance = this; if ((int)SystemInfo.graphicsDeviceType == 4) { ((Behaviour)this).enabled = false; } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Death Helper 0.2.0 loaded."); } } private void Update() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) if ((int)ToggleKey.Value != 0 && Input.GetKeyDown(ToggleKey.Value) && !Console.IsVisible() && ((Object)(object)Chat.instance == (Object)null || !Chat.instance.HasFocus())) { ShowArrow.Value = !ShowArrow.Value; } if ((Object)(object)Player.m_localPlayer != (Object)null) { if (!_cmd) { _cmd = true; try { new ConsoleCommand("grave", "pay to teleport to your nearest death marker", (ConsoleEvent)delegate(ConsoleEventArgs a) { Teleport(a.Context); }, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not add the 'grave' command: " + ex.Message)); } } if ((int)TeleportKey.Value != 0 && Input.GetKeyDown(TeleportKey.Value) && !Console.IsVisible() && ((Object)(object)Chat.instance == (Object)null || !Chat.instance.HasFocus())) { Teleport(null); } try { EnsureButton(); } catch (Exception ex2) { if (!_btnFailed) { _btnFailed = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not add the menu button: " + ex2.Message)); } } } if (Time.unscaledTime < _next) { return; } _next = Time.unscaledTime + 1f; try { Check(); } catch (Exception ex3) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Check failed: " + ex3.Message)); _next = Time.unscaledTime + 30f; } } private void Check() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Invalid comparison between Unknown and I4 //IL_00cf: 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) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0346: 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_0151: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) _target = null; _deaths.Clear(); if ((Object)(object)Minimap.instance == (Object)null || (Object)(object)ZNet.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)Game.instance == (Object)null) { _emptySince.Clear(); return; } List<PinData> list = Pins.Invoke(Minimap.instance); if (list == null) { return; } foreach (PinData item in list) { if (item != null && (int)item.m_type == 4) { _deaths.Add(item); } } Player localPlayer = Player.m_localPlayer; Vector3 val = (((Object)(object)localPlayer != (Object)null) ? ((Component)localPlayer).transform.position : ZNet.instance.GetReferencePosition()); if (RemoveEmpty.Value && !Game.instance.IsShuttingDown()) { float num = Mathf.Clamp(CheckRange.Value, 10f, 60f); float num2 = Mathf.Clamp(TombRadius.Value, 3f, 40f); TombStone[] array = null; List<PinData> list2 = null; foreach (PinData death in _deaths) { Vector3 val2 = death.m_pos - val; val2.y = 0f; if (((Vector3)(ref val2)).magnitude > num || !ZNetScene.instance.IsAreaReady(death.m_pos)) { _emptySince.Remove(death); continue; } if (array == null) { array = Object.FindObjectsByType<TombStone>((FindObjectsSortMode)0); } bool flag = false; TombStone[] array2 = array; foreach (TombStone val3 in array2) { if (!((Object)(object)val3 == (Object)null)) { Vector3 val4 = ((Component)val3).transform.position - death.m_pos; val4.y = 0f; if (((Vector3)(ref val4)).magnitude <= num2) { flag = true; break; } } } float value; if (flag) { _emptySince.Remove(death); } else if (!_emptySince.TryGetValue(death, out value)) { _emptySince[death] = Time.unscaledTime; } else if (Time.unscaledTime - value >= Mathf.Max(1f, ConfirmSeconds.Value)) { if (list2 == null) { list2 = new List<PinData>(); } list2.Add(death); } } if (list2 != null) { foreach (PinData item2 in list2) { Minimap.instance.RemovePin(item2); _emptySince.Remove(item2); _deaths.Remove(item2); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Removed a death marker with no tombstone at " + ((Vector3)(ref item2.m_pos)).ToString("0") + ".")); } } } if ((Object)(object)localPlayer == (Object)null) { return; } float num3 = float.MaxValue; foreach (PinData death2 in _deaths) { Vector3 val5 = death2.m_pos - val; val5.y = 0f; if (((Vector3)(ref val5)).sqrMagnitude < num3) { num3 = ((Vector3)(ref val5)).sqrMagnitude; _target = death2; } } } private void EnsureButton() { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown if (_btnFailed || (Object)(object)Menu.instance == (Object)null) { return; } if ((Object)(object)_button == (Object)null) { Button settingsButton = Menu.instance.m_settingsButton; if ((Object)(object)settingsButton == (Object)null) { throw new Exception("no Settings button to copy"); } GameObject val = Object.Instantiate<GameObject>(((Component)settingsButton).gameObject, ((Component)settingsButton).transform.parent); ((Object)val).name = "GraveTeleportButton"; val.transform.SetSiblingIndex(((Component)settingsButton).transform.GetSiblingIndex() + 1); Button component = val.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { try { Menu.instance.Hide(); } catch (Exception) { } Teleport(null); }); _button = val; } bool flag = TeleportOn.Value && _target != null; if (_button.activeSelf != flag) { _button.SetActive(flag); } if (!flag || !Menu.IsVisible()) { return; } string text = "Go to grave (" + Mathf.Max(0, TeleportCost.Value) + ")"; TMP_Text[] componentsInChildren = _button.GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val2 in componentsInChildren) { if (val2.text != text) { val2.text = text; } } } private static void Tell(Terminal ctx, string text) { if ((Object)(object)ctx != (Object)null) { ctx.AddString(text); } if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false, true); } } private static bool Valuable(ItemData i) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 if (i != null && i.m_shared != null && i.m_shared.m_value > 0 && !i.m_equipped) { return (int)i.m_shared.m_itemType == 1; } return false; } private void Teleport(Terminal ctx) { //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (!TeleportOn.Value) { Tell(ctx, "Grave teleport is switched off."); return; } if (_target == null) { Tell(ctx, "You have no death marker."); return; } if (((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).InBed() || ((Character)localPlayer).IsAttached()) { Tell(ctx, "You can't do that right now."); return; } if (localPlayer.IsTargeted() || localPlayer.IsSensed()) { Tell(ctx, "Not while enemies are aware of you."); return; } if (!((Humanoid)localPlayer).IsTeleportable((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey((GlobalKeys)35))) { Tell(ctx, "You are carrying something that can't be teleported."); return; } int num = Mathf.Max(0, TeleportCost.Value); Inventory inventory = ((Humanoid)localPlayer).GetInventory(); List<ItemData> list = new List<ItemData>(); int num2 = 0; foreach (ItemData allItem in inventory.GetAllItems()) { if (Valuable(allItem)) { list.Add(allItem); num2 += allItem.m_shared.m_value * allItem.m_stack; } } if (num2 < num) { Tell(ctx, "You need " + num + " in coins or valuables (you carry " + num2 + ")."); return; } Vector3 val = _target.m_pos + Vector3.up * 0.5f; if (!((Character)localPlayer).TeleportTo(val, ((Component)localPlayer).transform.rotation, true)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"The game refused the teleport; nothing was charged."); Tell(ctx, "The teleport failed."); return; } list.Sort((ItemData a, ItemData b) => a.m_shared.m_value.CompareTo(b.m_shared.m_value)); int num3 = num; foreach (ItemData item in list) { if (num3 <= 0) { break; } int value = item.m_shared.m_value; int num4 = Mathf.Min(item.m_stack, (num3 + value - 1) / value); if (num4 > 0) { inventory.RemoveItem(item, num4); num3 -= num4 * value; } } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Teleported to the death marker at " + ((Vector3)(ref _target.m_pos)).ToString("0") + " for " + (num - num3) + " value.")); } private void OnGUI() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) if (!ShowArrow.Value || _target == null || (int)Event.current.type != 7) { return; } Player localPlayer = Player.m_localPlayer; Camera main = Camera.main; if ((Object)(object)localPlayer == (Object)null || (Object)(object)main == (Object)null || ((Character)localPlayer).IsDead() || Hud.IsUserHidden() || Minimap.IsOpen() || Menu.IsVisible() || InventoryGui.IsVisible()) { return; } Vector3 val = _target.m_pos - ((Component)localPlayer).transform.position; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; float value = ArrowMaxDistance.Value; if (!(value > 0f) || !(magnitude > value)) { Vector3 forward = ((Component)main).transform.forward; forward.y = 0f; float num = ((magnitude > 1f && ((Vector3)(ref forward)).sqrMagnitude > 0.0001f) ? Vector3.SignedAngle(forward, val, Vector3.up) : 0f); if ((Object)(object)_arrow == (Object)null) { _arrow = MakeArrow(); } if (_style == null) { _style = new GUIStyle(GUI.skin.label); _style.alignment = (TextAnchor)3; _style.fontStyle = (FontStyle)1; } float num2 = Mathf.Max(1f, (float)Screen.height / 1080f); _style.fontSize = Mathf.RoundToInt(18f * num2); float num3 = 34f * num2; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor((float)Screen.width / 2f - 70f * num2, 70f * num2, num3, num3); Matrix4x4 matrix = GUI.matrix; GUIUtility.RotateAroundPivot(num, ((Rect)(ref val2)).center); GUI.DrawTexture(val2, (Texture)(object)_arrow); GUI.matrix = matrix; string text = "Grave " + ((magnitude >= 1000f) ? ((magnitude / 1000f).ToString("0.0") + " km") : (Mathf.RoundToInt(magnitude) + " m")); Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(((Rect)(ref val2)).xMax + 8f * num2, ((Rect)(ref val2)).y, 240f * num2, num3); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.8f); GUI.Label(new Rect(((Rect)(ref val3)).x + 1.5f, ((Rect)(ref val3)).y + 1.5f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height), text, _style); GUI.color = new Color(1f, 0.86f, 0.55f, 1f); GUI.Label(val3, text, _style); GUI.color = color; } } private static Texture2D MakeArrow() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 0.86f, 0.55f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0f, 0f, 0f, 0.85f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < 64; i++) { float num; float num3; int num4; int num5; bool flag; bool flag2; for (int j = 0; j < 64; flag = (byte)num5 != 0, flag2 = num4 != 0 && Mathf.Abs(num) < num3, val.SetPixel(j, i, flag ? val2 : (flag2 ? val3 : val4)), j++) { num = ((float)j + 0.5f) / 64f - 0.5f; float num2 = ((float)i + 0.5f) / 64f; num3 = 0.36f * Mathf.InverseLerp(0.94f, 0.12f, num2); if (num2 > 0.12f) { num4 = ((num2 < 0.94f) ? 1 : 0); if (num4 != 0 && Mathf.Abs(num) < num3 - 0.045f) { num5 = ((num2 > 0.17f) ? 1 : 0); continue; } } else { num4 = 0; } num5 = 0; } } val.Apply(); return val; } }