using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace BifrostBeacon; [BepInPlugin("com.drakosdj.bifrostbeacon", "BifrostBeacon", "1.0.0")] public class BifrostBeaconPlugin : BaseUnityPlugin { public static ConfigEntry configModifierKey; public static ConfigEntry configShowHudMessage; public static ConfigEntry configShowVisualBeam; public static ConfigEntry configPlayAudioBeeps; public static ConfigEntry configAudioRange; public static ConfigEntry configAudioPitch; public static Vector3? activeBeaconPosition = null; public static string activeBeaconName = ""; public static WorldTextInstance activeBeaconWorldText = null; public static BifrostBeam beamInstance = null; public static readonly long BeaconTalkerID = 20260708L; public static float audioTimer = 0f; public static BifrostBeaconPlugin instance; private void Awake() { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown instance = this; configModifierKey = ((BaseUnityPlugin)this).Config.Bind("Keybinds", "ModifierKey", (KeyCode)304, "Modifier key held during map middle-click to set or toggle the beacon waypoint."); configShowHudMessage = ((BaseUnityPlugin)this).Config.Bind("General", "ShowHudMessage", true, "If true, displays the distance and height difference to the beacon on the 3D HUD waypoint text."); configShowVisualBeam = ((BaseUnityPlugin)this).Config.Bind("General", "ShowVisualBeam", true, "If true, projects a vertical shifting rainbow light beam from the beacon waypoint."); configPlayAudioBeeps = ((BaseUnityPlugin)this).Config.Bind("Audio", "PlayAudioBeeps", true, "If true, plays proximity audio beeps (wishbone sound) that speed up and get sharper as you approach."); configAudioRange = ((BaseUnityPlugin)this).Config.Bind("Audio", "AudioRange", 100f, "Maximum distance in meters at which the proximity audio beeping starts."); configAudioPitch = ((BaseUnityPlugin)this).Config.Bind("Audio", "AudioPitch", 1.5f, "Pitch of the proximity audio beep (1.0 is default wishbone, higher is sharper/more distinct)."); Harmony val = new Harmony("com.drakosdj.bifrostbeacon"); val.PatchAll(); Debug.Log((object)"[BifrostBeacon] Plugin loaded successfully!"); } public static void SetBeacon(Vector3 position, string name) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) float y = position.y; float num = default(float); if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(position, ref num)) { y = num + 1.5f; } position.y = y; Debug.Log((object)string.Concat("[BifrostBeacon] Setting beacon at ", position, " named: ", name)); ClearBeacon(); activeBeaconPosition = position; activeBeaconName = (string.IsNullOrEmpty(name) ? "Beacon" : name); if (configShowVisualBeam.Value) { GameObject val = new GameObject("BifrostBeaconBeam"); beamInstance = val.AddComponent(); beamInstance.SetPositions(position, position + Vector3.up * 1000f); } } public static void ClearBeacon() { Debug.Log((object)"[BifrostBeacon] Clearing active beacon"); activeBeaconPosition = null; activeBeaconName = ""; if ((Object)(object)Chat.instance != (Object)null && activeBeaconWorldText != null) { if ((Object)(object)activeBeaconWorldText.m_gui != (Object)null) { Object.Destroy((Object)(object)activeBeaconWorldText.m_gui); } GetWorldTexts(Chat.instance)?.Remove(activeBeaconWorldText); activeBeaconWorldText = null; } if ((Object)(object)beamInstance != (Object)null) { Object.Destroy((Object)(object)((Component)beamInstance).gameObject); beamInstance = null; } } public static bool MyGetKey(KeyCode key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Invalid comparison between Unknown and I4 //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Invalid comparison between Unknown and I4 //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Invalid comparison between Unknown and I4 //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Invalid comparison between Unknown and I4 //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Invalid comparison between Unknown and I4 //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Invalid comparison between Unknown and I4 //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Invalid comparison between Unknown and I4 //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Invalid comparison between Unknown and I4 //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Invalid comparison between Unknown and I4 if (Input.GetKey(key)) { return true; } if (ZInput.GetKey(key, true)) { return true; } try { Keyboard current = Keyboard.current; if (current != null) { if ((int)key == 280) { return ((ButtonControl)current.pageUpKey).isPressed; } if ((int)key == 281) { return ((ButtonControl)current.pageDownKey).isPressed; } if ((int)key == 273) { return ((ButtonControl)current.upArrowKey).isPressed; } if ((int)key == 274) { return ((ButtonControl)current.downArrowKey).isPressed; } if ((int)key == 278) { return ((ButtonControl)current.homeKey).isPressed; } if ((int)key == 27) { return ((ButtonControl)current.escapeKey).isPressed; } if ((int)key == 304) { return ((ButtonControl)current.leftShiftKey).isPressed; } if ((int)key == 303) { return ((ButtonControl)current.rightShiftKey).isPressed; } if ((int)key == 306) { return ((ButtonControl)current.leftCtrlKey).isPressed; } if ((int)key == 305) { return ((ButtonControl)current.rightCtrlKey).isPressed; } if ((int)key == 308) { return ((ButtonControl)current.leftAltKey).isPressed; } if ((int)key == 307) { return ((ButtonControl)current.rightAltKey).isPressed; } } } catch (Exception) { } return false; } public static Vector3 ScreenToWorldPoint(Minimap minimap, Vector3 mousePos) { //IL_0023: 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) //IL_0038: Unknown result type (might be due to invalid IL or missing references) MethodInfo method = typeof(Minimap).GetMethod("ScreenToWorldPoint", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (Vector3)method.Invoke(minimap, new object[1] { mousePos }); } public static PinData GetClosestPin(Minimap minimap, Vector3 pos, float radius) { //IL_0041: 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) List minimapPins = GetMinimapPins(minimap); if (minimapPins == null) { return null; } PinData result = null; float num = radius; foreach (PinData item in minimapPins) { if (item != null) { float num2 = Utils.DistanceXZ(pos, item.m_pos); if (num2 < num) { num = num2; result = item; } } } return result; } public static void AddInworldText(Chat chat, Vector3 position, string text) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) MethodInfo method = typeof(Chat).GetMethod("AddInworldText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); method.Invoke(chat, new object[6] { null, BeaconTalkerID, position, (object)(Type)3, UserInfo.GetLocalUser(), text }); } public static WorldTextInstance FindExistingWorldText(Chat chat, long talkerID) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown MethodInfo method = typeof(Chat).GetMethod("FindExistingWorldText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (WorldTextInstance)method.Invoke(chat, new object[1] { talkerID }); } public static List GetWorldTexts(Chat chat) { FieldInfo field = typeof(Chat).GetField("m_worldTexts", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (List)field.GetValue(chat); } public static List GetMinimapPins(Minimap minimap) { FieldInfo field = typeof(Minimap).GetField("m_pins", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (List)field.GetValue(minimap); } public static float GetLargeZoom(Minimap minimap) { FieldInfo field = typeof(Minimap).GetField("m_largeZoom", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (float)field.GetValue(minimap); } public static float GetRemoveRadius(Minimap minimap) { FieldInfo field = typeof(Minimap).GetField("m_removeRadius", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (float)field.GetValue(minimap); } } [HarmonyPatch(typeof(Minimap), "OnMapMiddleClick", new Type[] { typeof(UIInputHandler) })] public static class Minimap_OnMapMiddleClick_Patch { public static bool Prefix(Minimap __instance, UIInputHandler handler) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_015e: 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) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null) { return true; } KeyCode value = BifrostBeaconPlugin.configModifierKey.Value; bool flag = BifrostBeaconPlugin.MyGetKey(value); Debug.Log((object)string.Concat("[BifrostBeacon] OnMapMiddleClick Prefix. ModifierKey: ", value, ", Pressed: ", flag)); if (flag) { Vector3 mousePosition = ZInput.mousePosition; Vector3 val = BifrostBeaconPlugin.ScreenToWorldPoint(__instance, mousePosition); Debug.Log((object)string.Concat("[BifrostBeacon] MousePos: ", mousePosition, ", Click WorldPoint: ", val)); float largeZoom = BifrostBeaconPlugin.GetLargeZoom(__instance); float removeRadius = BifrostBeaconPlugin.GetRemoveRadius(__instance); float num = removeRadius * largeZoom * 2f; num = Mathf.Clamp(num, 5f, 100f); PinData closestPin = BifrostBeaconPlugin.GetClosestPin(__instance, val, num); if (closestPin != null) { Debug.Log((object)("[BifrostBeacon] Found closest pin: " + closestPin.m_name + " at position: " + closestPin.m_pos)); if (BifrostBeaconPlugin.activeBeaconPosition.HasValue && Utils.DistanceXZ(BifrostBeaconPlugin.activeBeaconPosition.Value, closestPin.m_pos) < 1f) { BifrostBeaconPlugin.ClearBeacon(); MessageHud.instance.ShowMessage((MessageType)2, "Waypoint cleared", 0, (Sprite)null, false); } else { BifrostBeaconPlugin.SetBeacon(closestPin.m_pos, closestPin.m_name); MessageHud.instance.ShowMessage((MessageType)2, "Waypoint set: " + (string.IsNullOrEmpty(closestPin.m_name) ? "Pin" : closestPin.m_name), 0, (Sprite)null, false); } } else { Debug.Log((object)("[BifrostBeacon] No pin found within zoom-scaled radius of " + num + "m.")); if (BifrostBeaconPlugin.activeBeaconPosition.HasValue) { BifrostBeaconPlugin.ClearBeacon(); MessageHud.instance.ShowMessage((MessageType)2, "Waypoint cleared", 0, (Sprite)null, false); } } return false; } return true; } } [HarmonyPatch(typeof(Chat), "UpdateWorldTexts", new Type[] { typeof(float) })] public static class Chat_UpdateWorldTexts_Patch { public static void Postfix(Chat __instance, float dt) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null || !BifrostBeaconPlugin.activeBeaconPosition.HasValue) { return; } Vector3 position = ((Component)Player.m_localPlayer).transform.position; Vector3 value = BifrostBeaconPlugin.activeBeaconPosition.Value; float num = Utils.DistanceXZ(position, value); if (num < 5f) { BifrostBeaconPlugin.ClearBeacon(); MessageHud.instance.ShowMessage((MessageType)2, "Waypoint reached", 0, (Sprite)null, false); return; } if (BifrostBeaconPlugin.activeBeaconWorldText == null || (Object)(object)BifrostBeaconPlugin.activeBeaconWorldText.m_gui == (Object)null) { BifrostBeaconPlugin.AddInworldText(__instance, value, "PING"); BifrostBeaconPlugin.activeBeaconWorldText = BifrostBeaconPlugin.FindExistingWorldText(__instance, BifrostBeaconPlugin.BeaconTalkerID); Debug.Log((object)"[BifrostBeacon] Spawned new 3D world text tracker."); } if (BifrostBeaconPlugin.activeBeaconWorldText != null) { BifrostBeaconPlugin.activeBeaconWorldText.m_timer = 0f; BifrostBeaconPlugin.activeBeaconWorldText.m_position = value; string text = BifrostBeaconPlugin.activeBeaconName; if (BifrostBeaconPlugin.configShowHudMessage.Value) { float num2 = value.y - position.y; string text2 = ((num2 > 0f) ? ("+" + num2.ToString("F0") + "m") : (num2.ToString("F0") + "m")); string text3 = text; text = text3 + "\n" + num.ToString("F0") + "m, " + text2; } BifrostBeaconPlugin.activeBeaconWorldText.m_text = text; ((TMP_Text)BifrostBeaconPlugin.activeBeaconWorldText.m_textMeshField).text = text; } if (BifrostBeaconPlugin.configPlayAudioBeeps.Value && num <= BifrostBeaconPlugin.configAudioRange.Value) { BifrostBeaconPlugin.audioTimer += dt; float num3 = Mathf.Clamp01(num / BifrostBeaconPlugin.configAudioRange.Value); float num4 = Mathf.Lerp(0.5f, 4f, num3); if (BifrostBeaconPlugin.audioTimer >= num4) { BifrostBeaconPlugin.audioTimer = 0f; PlayProximityBeep(num3, position); } } } private static void PlayProximityBeep(float pct, Vector3 playerPos) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ObjectDB.instance == (Object)null) { return; } SE_Finder val = ObjectDB.instance.m_StatusEffects.OfType().FirstOrDefault(); if (!((Object)(object)val != (Object)null)) { return; } EffectList val2 = ((pct < 0.2f) ? val.m_pingEffectNear : ((pct < 0.6f) ? val.m_pingEffectMed : val.m_pingEffectFar)); if (val2 == null) { return; } GameObject[] array = val2.Create(playerPos, ((Component)Player.m_localPlayer).transform.rotation, ((Component)Player.m_localPlayer).transform, 1f, -1); if (array == null) { return; } float value = BifrostBeaconPlugin.configAudioPitch.Value; GameObject[] array2 = array; foreach (GameObject val3 in array2) { if ((Object)(object)val3 == (Object)null) { continue; } MonoBehaviour[] componentsInChildren = val3.GetComponentsInChildren(); foreach (MonoBehaviour val4 in componentsInChildren) { if ((Object)(object)val4 == (Object)null || ((object)val4).GetType().Name != "ZSFX") { continue; } try { Type type = ((object)val4).GetType(); FieldInfo field = type.GetField("m_minPitch", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = type.GetField("m_maxPitch", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(val4, value); } if (field2 != null) { field2.SetValue(val4, value); } } catch (Exception) { } } AudioSource[] componentsInChildren2 = val3.GetComponentsInChildren(); foreach (AudioSource val5 in componentsInChildren2) { if (!((Object)(object)val5 == (Object)null)) { val5.pitch = value; } } } } } [HarmonyPatch(typeof(Player), "OnDestroy")] public static class Player_OnDestroy_Patch { public static void Postfix() { BifrostBeaconPlugin.ClearBeacon(); } } public class BifrostBeam : MonoBehaviour { private LineRenderer lineRenderer; private float hueOffset = 0f; private void Awake() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown lineRenderer = ((Component)this).gameObject.AddComponent(); lineRenderer.useWorldSpace = true; lineRenderer.positionCount = 2; lineRenderer.startWidth = 1.5f; lineRenderer.endWidth = 1.5f; Shader val = Shader.Find("Sprites/Default"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Particles/Standard Unlit"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Standard"); } if ((Object)(object)val != (Object)null) { ((Renderer)lineRenderer).material = new Material(val); } else { Debug.LogWarning((object)"[BifrostBeacon] Failed to find a suitable shader for the beam LineRenderer!"); } } public void SetPositions(Vector3 start, Vector3 end) { //IL_001c: 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) if ((Object)(object)lineRenderer != (Object)null) { lineRenderer.SetPosition(0, start); lineRenderer.SetPosition(1, end); } } private void Update() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)lineRenderer == (Object)null)) { hueOffset += Time.deltaTime * 0.15f; if (hueOffset > 1f) { hueOffset -= 1f; } Gradient val = new Gradient(); GradientColorKey[] array = (GradientColorKey[])(object)new GradientColorKey[5]; for (int i = 0; i < array.Length; i++) { float num = (float)i / (float)(array.Length - 1); float num2 = (num + hueOffset) % 1f; ref GradientColorKey reference = ref array[i]; reference = new GradientColorKey(Color.HSVToRGB(num2, 0.9f, 1f), num); } val.SetKeys(array, (GradientAlphaKey[])(object)new GradientAlphaKey[2] { new GradientAlphaKey(0.7f, 0f), new GradientAlphaKey(0f, 1f) }); lineRenderer.colorGradient = val; } } private void OnDestroy() { if ((Object)(object)lineRenderer != (Object)null && (Object)(object)((Renderer)lineRenderer).material != (Object)null) { Object.Destroy((Object)(object)((Renderer)lineRenderer).material); } } }