using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using LethalBots.AI; using LethalBots.AI.AIStates; using LethalBots.Managers; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace Erskine.LethalBotsWheel; [BepInPlugin("Erskine.LethalBotsWheel", "LethalBotsWheel", "1.17.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal enum OpenMode { Keyboard, MouseForward, MouseBack, MouseMiddle, MouseLeft, MouseRight } public const string GUID = "Erskine.LethalBotsWheel"; public const string NAME = "LethalBotsWheel"; public const string VERSION = "1.17.0"; internal static Plugin Instance; internal static ManualLogSource Log; internal ConfigEntry cOpenKey; internal ConfigEntry cActivation; internal ConfigEntry cRadius; internal ConfigEntry cDeadzone; internal ConfigEntry cCursorSize; internal ConfigEntry cFreezeView; internal OpenMode Mode = OpenMode.MouseForward; internal Key KbKey = (Key)36; [CompilerGenerated] private static Dictionary <>f__switch$map0; internal bool IsToggle { [CompilerGenerated] get { return cActivation != null && string.Equals((cActivation.Value ?? "").Trim(), "toggle", StringComparison.OrdinalIgnoreCase); } } private void ParseOpen(string s) { //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) s = (s ?? "").Trim().ToLower(); if (s != null) { if (<>f__switch$map0 == null) { Dictionary dictionary = new Dictionary(21); dictionary.Add("mouse5", 0); dictionary.Add("mb5", 0); dictionary.Add("forward", 0); dictionary.Add("forwardbutton", 0); dictionary.Add("mouse4", 1); dictionary.Add("mb4", 1); dictionary.Add("back", 1); dictionary.Add("backbutton", 1); dictionary.Add("mouse3", 2); dictionary.Add("mb3", 2); dictionary.Add("middle", 2); dictionary.Add("middlebutton", 2); dictionary.Add("mousemiddle", 2); dictionary.Add("mouse1", 3); dictionary.Add("mb1", 3); dictionary.Add("left", 3); dictionary.Add("mouseleft", 3); dictionary.Add("mouse2", 4); dictionary.Add("mb2", 4); dictionary.Add("right", 4); dictionary.Add("mouseright", 4); <>f__switch$map0 = dictionary; } if (<>f__switch$map0.TryGetValue(s, out var value)) { switch (value) { case 0: Mode = OpenMode.MouseForward; return; case 1: Mode = OpenMode.MouseBack; return; case 2: Mode = OpenMode.MouseMiddle; return; case 3: Mode = OpenMode.MouseLeft; return; case 4: Mode = OpenMode.MouseRight; return; } } } if (Enum.TryParse(s, ignoreCase: true, out Key result)) { Mode = OpenMode.Keyboard; KbKey = result; } else { Log.LogWarning((object)$"Couldn't parse OpenKey '{s}', defaulting to V."); Mode = OpenMode.Keyboard; KbKey = (Key)36; } } internal bool IsOpenHeld() { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) switch (Mode) { case OpenMode.MouseForward: { Mouse current6 = Mouse.current; return current6 != null && current6.forwardButton.isPressed; } case OpenMode.MouseBack: { Mouse current2 = Mouse.current; return current2 != null && current2.backButton.isPressed; } case OpenMode.MouseMiddle: { Mouse current4 = Mouse.current; return current4 != null && current4.middleButton.isPressed; } case OpenMode.MouseLeft: { Mouse current3 = Mouse.current; return current3 != null && current3.leftButton.isPressed; } case OpenMode.MouseRight: { Mouse current5 = Mouse.current; return current5 != null && current5.rightButton.isPressed; } default: { Keyboard current = Keyboard.current; return current != null && ((ButtonControl)current[KbKey]).isPressed; } } } internal bool IsOpenPressed() { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) switch (Mode) { case OpenMode.MouseForward: { Mouse current6 = Mouse.current; return current6 != null && current6.forwardButton.wasPressedThisFrame; } case OpenMode.MouseBack: { Mouse current2 = Mouse.current; return current2 != null && current2.backButton.wasPressedThisFrame; } case OpenMode.MouseMiddle: { Mouse current4 = Mouse.current; return current4 != null && current4.middleButton.wasPressedThisFrame; } case OpenMode.MouseLeft: { Mouse current3 = Mouse.current; return current3 != null && current3.leftButton.wasPressedThisFrame; } case OpenMode.MouseRight: { Mouse current5 = Mouse.current; return current5 != null && current5.rightButton.wasPressedThisFrame; } default: { Keyboard current = Keyboard.current; return current != null && ((ButtonControl)current[KbKey]).wasPressedThisFrame; } } } private void Awake() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; cOpenKey = ((BaseUnityPlugin)this).Config.Bind("General", "OpenKey", "V", "Hold this to open the command wheel; release on a slice to run it. Default is the keyboard key V. If your mouse has extra buttons you can use: Mouse5 (forward thumb button), Mouse4 (back thumb button), Mouse3 (middle/scroll click), Mouse1/Mouse2 (left/right). Any keyboard key name also works (C, LeftAlt, F, ...)."); cActivation = ((BaseUnityPlugin)this).Config.Bind("General", "Activation", "Hold", "How the open button works. 'Hold' = the wheel is open only while you hold the button and fires the slice you're pointing at when you release. 'Toggle' = press once to open (it stays open), then press again to fire the selected slice."); cRadius = ((BaseUnityPlugin)this).Config.Bind("General", "WheelSize", 210f, "Size of the wheel, in pixels (this is the radius, so the wheel is roughly twice this across). Bigger = larger wheel."); cDeadzone = ((BaseUnityPlugin)this).Config.Bind("General", "Deadzone", 45f, "How far (in pixels) you must move the mouse from center before a slice is selected. Release inside this dead zone to cancel without running anything."); cCursorSize = ((BaseUnityPlugin)this).Config.Bind("General", "CursorSize", 16f, "Size (in pixels) of the aiming cursor dot in the middle of the wheel. Bigger = easier to see."); cFreezeView = ((BaseUnityPlugin)this).Config.Bind("General", "FreezeViewWhileOpen", true, "Freeze your camera while the wheel is open, so aiming at a slice doesn't also spin your view. Recommended on."); ParseOpen(cOpenKey.Value); cOpenKey.SettingChanged += delegate { ParseOpen(cOpenKey.Value); }; GameObject val = new GameObject("LethalBotsWheel_Runner"); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent(); Log.LogInfo((object)string.Concat("LethalBotsWheel v1.17.0 active. [", cOpenKey.Value, "] (", Mode, ", ", cActivation.Value, "); scroll = target, right-click = page.")); } } public class WheelRunner : MonoBehaviour { private struct Cmd { public string Name; public Action Run; public Cmd(string n, Action r) { Name = n; Run = r; } } private enum TKind { All, Nearest, Named } private struct Target { public TKind Kind; public string Name; public string Label; } private readonly List> _pages = new List>(); private int _page; private readonly List _targets = new List(); private int _tIdx; private float _lastScroll; private TKind _savedKind = TKind.All; private string _savedName; private bool _open; private Vector2 _sel; private int _selIndex = -1; private readonly List _suspended = new List(); private Quaternion _bodyRot; private Quaternion _camLocalRot; private Transform _camTf; private Transform _bodyTf; private GUIStyle _pillDark; private GUIStyle _pillSel; private GUIStyle _center; private GUIStyle _sub; private GUIStyle _hint; private GUIStyle _num; private Texture2D _solid; private Texture2D _texBase; private Texture2D _texHi; private Texture2D _texNum; private bool _texTried; private static readonly LethalBotAI[] Empty = (LethalBotAI[])(object)new LethalBotAI[0]; private bool _warmed; private void Awake() { _pages.Add(new List { new Cmd("Follow", CmdFollow), new Cmd("Lead Way", CmdLeadWay), new Cmd("Wait Here", CmdWait), new Cmd("Regroup", CmdRegroup), new Cmd("To Ship", CmdToShip), new Cmd("Gear Up", CmdGearUp), new Cmd("Man Ship", CmdManShip), new Cmd("Go To Bot", CmdGoToBot) }); _pages.Add(new List { new Cmd("Transfer", CmdTransfer), new Cmd("Drop Item", delegate(LethalBotAI[] t) { ChatCmd(t, "drop your held item"); }), new Cmd("Change Suit", CmdChangeSuit), new Cmd("Monitor Me", delegate(LethalBotAI[] t) { ChatCmd(t, "request monitoring"); }), new Cmd("Teleport Me", delegate(LethalBotAI[] t) { ChatCmd(t, "request teleport"); }), new Cmd("Stop Monitor", delegate(LethalBotAI[] t) { ChatCmd(t, "clear monitoring"); }), new Cmd("Hop Off", delegate(LethalBotAI[] t) { ChatCmd(t, "hop off the terminal"); }), new Cmd("Report", CmdReport) }); } private List Cur() { return _pages[Mathf.Clamp(_page, 0, _pages.Count - 1)]; } private PlayerControllerB LocalPlayer() { GameNetworkManager instance = GameNetworkManager.Instance; return (!((Object)(object)instance != (Object)null)) ? null : instance.localPlayerController; } private bool CanOpen(PlayerControllerB lp) { return (Object)(object)lp != (Object)null && !lp.isPlayerDead && !lp.inTerminalMenu && !lp.isTypingChat && lp.isPlayerControlled; } private LethalBotAI[] OwnedBots() { LethalBotManager instance = LethalBotManager.Instance; LethalBotAI[] array = ((!((Object)(object)instance != (Object)null)) ? null : instance.GetLethalBotsAIOwnedByLocal()); return array ?? Empty; } private static string SafeName(LethalBotAI b) { try { if ((Object)(object)b != (Object)null && b.LethalBotIdentity != null) { string name = b.LethalBotIdentity.Name; if (!string.IsNullOrEmpty(name)) { return name; } } } catch { } try { if ((Object)(object)b != (Object)null && b.NpcController != null && (Object)(object)b.NpcController.Npc != (Object)null) { string playerUsername = b.NpcController.Npc.playerUsername; if (!string.IsNullOrEmpty(playerUsername)) { return playerUsername; } } } catch { } return "Bot"; } private void Update() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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) PlayerControllerB lp = LocalPlayer(); bool isToggle = Plugin.Instance.IsToggle; if (!_open) { if (((!isToggle) ? Plugin.Instance.IsOpenHeld() : Plugin.Instance.IsOpenPressed()) && CanOpen(lp)) { OpenWheel(lp); } return; } if (!CanOpen(lp)) { CloseWheel(fire: false); return; } Mouse current = Mouse.current; Keyboard current2 = Keyboard.current; if (current != null) { _sel += ((InputControl)(object)((Pointer)current).delta).ReadValue(); float y = ((InputControl)(object)current.scroll).ReadValue().y; if (Mathf.Abs(y) > 0.01f && Time.unscaledTime - _lastScroll > 0.12f && _targets.Count > 0) { _tIdx = (_tIdx + ((!(y > 0f)) ? 1 : (-1)) + _targets.Count) % _targets.Count; _lastScroll = Time.unscaledTime; RememberTarget(); } } if (((current != null && current.rightButton.wasPressedThisFrame) || (current != null && current.backButton.wasPressedThisFrame) || (current2 != null && ((ButtonControl)current2.tabKey).wasPressedThisFrame)) && _pages.Count > 1) { _page = (_page + 1) % _pages.Count; _selIndex = -1; } RecomputeSelection(); int num = NumberPressed(current2); if (num >= 1 && num <= Cur().Count) { Fire(num - 1); _selIndex = -1; } if ((!isToggle) ? (!Plugin.Instance.IsOpenHeld()) : Plugin.Instance.IsOpenPressed()) { CloseWheel(fire: true); } } private void LateUpdate() { //IL_0038: 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) if (_open && Plugin.Instance.cFreezeView.Value) { if ((Object)(object)_bodyTf != (Object)null) { _bodyTf.rotation = _bodyRot; } if ((Object)(object)_camTf != (Object)null) { _camTf.localRotation = _camLocalRot; } } } private void OpenWheel(PlayerControllerB lp) { //IL_0008: 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) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) _open = true; _sel = Vector2.zero; _selIndex = -1; if (_page < 0 || _page >= _pages.Count) { _page = 0; } _bodyTf = ((Component)lp).transform; _camTf = ((!((Object)(object)lp.gameplayCamera != (Object)null)) ? null : ((Component)lp.gameplayCamera).transform); _bodyRot = _bodyTf.rotation; if ((Object)(object)_camTf != (Object)null) { _camLocalRot = _camTf.localRotation; } SuspendGameInput(lp); _targets.Clear(); _targets.Add(new Target { Kind = TKind.All, Label = "All Bots" }); _targets.Add(new Target { Kind = TKind.Nearest, Label = "Nearest" }); LethalBotAI[] array = OwnedBots(); foreach (LethalBotAI b in array) { string text = SafeName(b); _targets.Add(new Target { Kind = TKind.Named, Name = text, Label = text }); } _tIdx = 0; for (int j = 0; j < _targets.Count; j++) { Target target = _targets[j]; if (target.Kind == _savedKind && (target.Kind != TKind.Named || string.Equals(target.Name, _savedName, StringComparison.OrdinalIgnoreCase))) { _tIdx = j; break; } } } private void RememberTarget() { if (_tIdx >= 0 && _tIdx < _targets.Count) { Target target = _targets[_tIdx]; _savedKind = target.Kind; _savedName = target.Name; } } private void CloseWheel(bool fire) { _open = false; ResumeGameInput(); if (fire) { Fire(_selIndex); } _selIndex = -1; } private void SuspendGameInput(PlayerControllerB lp) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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) _suspended.Clear(); try { PlayerActions val = ((!((Object)(object)lp != (Object)null)) ? null : lp.playerActions); InputActionAsset val2 = ((val == null) ? null : val.asset); if ((Object)(object)val2 == (Object)null) { return; } Enumerator enumerator = val2.actionMaps.GetEnumerator(); try { while (enumerator.MoveNext()) { InputActionMap current = enumerator.Current; if (current != null && current.enabled) { string text = current.name ?? ""; if (text.IndexOf("menu", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("ui", StringComparison.OrdinalIgnoreCase) < 0) { _suspended.Add(current); current.Disable(); } } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("suspend input: " + ex.Message)); } } private void ResumeGameInput() { try { for (int i = 0; i < _suspended.Count; i++) { if (_suspended[i] != null) { _suspended[i].Enable(); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("resume input: " + ex.Message)); } _suspended.Clear(); } private void OnDisable() { if (_open) { _open = false; ResumeGameInput(); } } private void Fire(int idx) { List list = Cur(); if (idx < 0 || idx >= list.Count) { return; } LethalBotAI[] array = ResolveTargets(); string text = ((_tIdx < 0 || _tIdx >= _targets.Count) ? "?" : _targets[_tIdx].Label); Plugin.Log.LogInfo((object)("[wheel] firing '" + list[idx].Name + "' on '" + text + "' (" + array.Length + " bot(s)).")); try { list[idx].Run(array); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Wheel command '" + list[idx].Name + "' failed: " + ex)); } } private static int NumberPressed(Keyboard kb) { if (kb == null) { return -1; } if (((ButtonControl)kb.digit1Key).wasPressedThisFrame || ((ButtonControl)kb.numpad1Key).wasPressedThisFrame) { return 1; } if (((ButtonControl)kb.digit2Key).wasPressedThisFrame || ((ButtonControl)kb.numpad2Key).wasPressedThisFrame) { return 2; } if (((ButtonControl)kb.digit3Key).wasPressedThisFrame || ((ButtonControl)kb.numpad3Key).wasPressedThisFrame) { return 3; } if (((ButtonControl)kb.digit4Key).wasPressedThisFrame || ((ButtonControl)kb.numpad4Key).wasPressedThisFrame) { return 4; } if (((ButtonControl)kb.digit5Key).wasPressedThisFrame || ((ButtonControl)kb.numpad5Key).wasPressedThisFrame) { return 5; } if (((ButtonControl)kb.digit6Key).wasPressedThisFrame || ((ButtonControl)kb.numpad6Key).wasPressedThisFrame) { return 6; } if (((ButtonControl)kb.digit7Key).wasPressedThisFrame || ((ButtonControl)kb.numpad7Key).wasPressedThisFrame) { return 7; } if (((ButtonControl)kb.digit8Key).wasPressedThisFrame || ((ButtonControl)kb.numpad8Key).wasPressedThisFrame) { return 8; } return -1; } private LethalBotAI[] ResolveTargets() { LethalBotAI[] array = OwnedBots(); if (_tIdx < 0 || _tIdx >= _targets.Count) { return array; } Target target = _targets[_tIdx]; if (target.Kind == TKind.All) { return array; } if (target.Kind == TKind.Nearest) { LethalBotAI val = NearestBot(array); return (LethalBotAI[])((!((Object)(object)val != (Object)null)) ? ((Array)Empty) : ((Array)new LethalBotAI[1] { val })); } LethalBotAI[] array2 = array; foreach (LethalBotAI val2 in array2) { if ((Object)(object)val2 != (Object)null && string.Equals(SafeName(val2), target.Name, StringComparison.OrdinalIgnoreCase)) { return (LethalBotAI[])(object)new LethalBotAI[1] { val2 }; } } return Empty; } private LethalBotAI NearestBot(LethalBotAI[] all) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = LocalPlayer(); if ((Object)(object)val == (Object)null) { return null; } Vector3 position = ((Component)val).transform.position; LethalBotAI result = null; float num = float.MaxValue; foreach (LethalBotAI val2 in all) { if (!((Object)(object)val2 == (Object)null) && val2.NpcController != null && !((Object)(object)val2.NpcController.Npc == (Object)null)) { Vector3 val3 = ((Component)val2.NpcController.Npc).transform.position - position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val2; } } } return result; } private void RecomputeSelection() { if (((Vector2)(ref _sel)).magnitude < Plugin.Instance.cDeadzone.Value) { _selIndex = -1; return; } Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(_sel.x, 0f - _sel.y); float num = Mathf.Atan2(val.y, val.x); int count = Cur().Count; int selIndex = 0; float num2 = float.MaxValue; for (int i = 0; i < count; i++) { float num3 = (float)Math.PI * 2f * (float)i / (float)count - (float)Math.PI / 2f; float num4 = Mathf.Abs(Mathf.DeltaAngle(num3 * 57.29578f, num * 57.29578f)); if (num4 < num2) { num2 = num4; selIndex = i; } } _selIndex = selIndex; } private void EnsureAssets() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0029: 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_0052: Expected O, but got Unknown //IL_0088: 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_00a3: Expected O, but got Unknown //IL_00ca: 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_00db: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_01e6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_solid != (Object)null)) { _solid = new Texture2D(1, 1, (TextureFormat)5, false); _solid.SetPixel(0, 0, Color.white); _solid.Apply(); ((Object)_solid).hideFlags = (HideFlags)61; GUIStyle val = new GUIStyle(); val.alignment = (TextAnchor)4; val.fontSize = 16; val.fontStyle = (FontStyle)1; _pillDark = val; _pillDark.normal.textColor = new Color(0.93f, 0.86f, 0.72f); _pillSel = new GUIStyle(_pillDark); _pillSel.fontSize = 17; _pillSel.normal.textColor = new Color(0.1f, 0.07f, 0.03f); val = new GUIStyle(); val.alignment = (TextAnchor)4; val.fontSize = 28; val.fontStyle = (FontStyle)1; _center = val; _center.normal.textColor = new Color(0.98f, 0.74f, 0.36f); val = new GUIStyle(); val.alignment = (TextAnchor)4; val.fontSize = 19; val.fontStyle = (FontStyle)1; _sub = val; _sub.normal.textColor = new Color(0.66f, 0.88f, 0.56f); val = new GUIStyle(); val.alignment = (TextAnchor)4; val.fontSize = 14; val.fontStyle = (FontStyle)1; _hint = val; _hint.normal.textColor = new Color(0.78f, 0.68f, 0.48f); val = new GUIStyle(); val.alignment = (TextAnchor)4; val.fontSize = 17; val.fontStyle = (FontStyle)1; _num = val; _num.normal.textColor = new Color(0.99f, 0.8f, 0.38f); } } private void EnsureWheels() { if (_texTried) { return; } _texTried = true; try { string directoryName = Path.GetDirectoryName(typeof(Plugin).Assembly.Location); _texBase = LoadPng(Path.Combine(directoryName, "wheel_base.png")); _texHi = LoadPng(Path.Combine(directoryName, "wheel_hi.png")); _texNum = LoadPng(Path.Combine(directoryName, "wheel_num.png")); Plugin.Log.LogInfo((object)("Wheel textures: base=" + ((Object)(object)_texBase != (Object)null) + " hi=" + ((Object)(object)_texHi != (Object)null) + " num=" + ((Object)(object)_texNum != (Object)null))); } catch (Exception ex) { Plugin.Log.LogWarning((object)("wheel texture load error: " + ex.Message)); } } private static Texture2D LoadPng(string path) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if (!File.Exists(path)) { Plugin.Log.LogWarning((object)("Missing " + Path.GetFileName(path))); return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false); ((Object)val).hideFlags = (HideFlags)61; if (ImageConversion.LoadImage(val, File.ReadAllBytes(path))) { ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; return val; } Plugin.Log.LogWarning((object)("Failed to decode " + Path.GetFileName(path))); return null; } private void Rect2(Rect r) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) GUI.DrawTexture(r, (Texture)(object)_solid); } private void DrawFit(Rect rect, string text, GUIStyle style, float maxW, int baseSize, bool shadow) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_00c1: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) int fontSize = style.fontSize; style.fontSize = baseSize; float x = style.CalcSize(new GUIContent(text ?? "")).x; if (x > maxW && x > 1f) { style.fontSize = Mathf.Max(9, Mathf.FloorToInt((float)baseSize * (maxW / x))); } if (shadow) { Color textColor = style.normal.textColor; Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.85f * color.a); style.normal.textColor = new Color(0f, 0f, 0f, 1f); Rect val = rect; ((Rect)(ref val)).x = ((Rect)(ref val)).x + 2f; ((Rect)(ref val)).y = ((Rect)(ref val)).y + 2f; GUI.Label(val, text, style); style.normal.textColor = textColor; GUI.color = color; } GUI.Label(rect, text, style); style.fontSize = fontSize; } private static string Abbrev(string s) { if (string.IsNullOrEmpty(s)) { return "?"; } int num = s.IndexOf(' '); string text = ((num <= 0) ? s : s.Substring(0, num)); if (text.Length > 9) { text = text.Substring(0, 8) + "."; } return text; } private void WarmUp() { //IL_000c: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00df: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) try { EnsureAssets(); EnsureWheels(); Color color = GUI.color; GUI.color = new Color(1f, 1f, 1f, 0f); Rect val = default(Rect); ((Rect)(ref val))..ctor(-9999f, -9999f, 64f, 64f); if ((Object)(object)_texBase != (Object)null) { GUI.DrawTexture(val, (Texture)(object)_texBase); } if ((Object)(object)_texHi != (Object)null) { GUI.DrawTexture(val, (Texture)(object)_texHi); } if ((Object)(object)_texNum != (Object)null) { GUI.DrawTexture(val, (Texture)(object)_texNum); } Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(-9999f, -9999f, 200f, 30f); GUI.Label(val2, "warmup", _pillDark); GUI.Label(val2, "warmup", _pillSel); GUI.Label(val2, "warmup", _center); GUI.Label(val2, "warmup", _sub); GUI.Label(val2, "warmup", _hint); GUI.Label(val2, "8", _num); GUI.color = color; } catch (Exception ex) { Plugin.Log.LogWarning((object)("wheel warmup: " + ex.Message)); } } private void OnGUI() { //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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_04bb: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0456: Unknown result type (might be due to invalid IL or missing references) //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_0514: Unknown result type (might be due to invalid IL or missing references) //IL_0561: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0287: 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_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_0693: Unknown result type (might be due to invalid IL or missing references) //IL_06cf: Unknown result type (might be due to invalid IL or missing references) //IL_071a: Unknown result type (might be due to invalid IL or missing references) //IL_0791: Unknown result type (might be due to invalid IL or missing references) //IL_07ec: Unknown result type (might be due to invalid IL or missing references) if (!_open) { if (!_warmed) { _warmed = true; WarmUp(); } return; } EnsureAssets(); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.55f); Rect2(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height)); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor((float)Screen.width / 2f, (float)Screen.height / 2f); float value = Plugin.Instance.cRadius.Value; List list = Cur(); int count = list.Count; EnsureWheels(); float num = (value + 55f) * 2f; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(val.x - num / 2f, val.y - num / 2f, num, num); GUI.color = Color.white; if ((Object)(object)_texBase != (Object)null) { GUI.DrawTexture(val2, (Texture)(object)_texBase); if (_selIndex >= 0 && (Object)(object)_texHi != (Object)null) { Matrix4x4 matrix = GUI.matrix; GUIUtility.RotateAroundPivot(360f * (float)_selIndex / (float)count, val); GUI.DrawTexture(val2, (Texture)(object)_texHi); GUI.matrix = matrix; } float num2 = value * 0.8f; float num3 = 1.45f * num2 * Mathf.Sin((float)Math.PI / (float)count); float num4 = num3 + 24f; float num5 = 34f; float num6 = (value + 55f) * 0.928f; float num7 = Mathf.Clamp((value + 55f) * 0.11f, 24f, 34f); Vector2 val3 = default(Vector2); Rect rect = default(Rect); Rect val6 = default(Rect); for (int i = 0; i < count; i++) { float num8 = (float)Math.PI * 2f * (float)i / (float)count - (float)Math.PI / 2f; ((Vector2)(ref val3))..ctor(Mathf.Cos(num8), Mathf.Sin(num8)); Vector2 val4 = val + val3 * num2; ((Rect)(ref rect))..ctor(val4.x - num4 / 2f, val4.y - num5 / 2f, num4, num5); bool flag = i == _selIndex; DrawFit(rect, list[i].Name, (!flag) ? _pillDark : _pillSel, num3, (!flag) ? 20 : 22, !flag); Vector2 val5 = val + val3 * num6; ((Rect)(ref val6))..ctor(val5.x - num7 / 2f, val5.y - num7 / 2f, num7, num7); if ((Object)(object)_texNum != (Object)null) { GUI.DrawTexture(val6, (Texture)(object)_texNum); } GUI.Label(val6, (i + 1).ToString(), _num); } } else { float num9 = 132f; float num10 = 40f; Rect val8 = default(Rect); for (int j = 0; j < count; j++) { float num11 = (float)Math.PI * 2f * (float)j / (float)count - (float)Math.PI / 2f; Vector2 val7 = val + new Vector2(Mathf.Cos(num11), Mathf.Sin(num11)) * value; ((Rect)(ref val8))..ctor(val7.x - num9 / 2f, val7.y - num10 / 2f, num9, num10); bool flag2 = j == _selIndex; GUI.color = ((!flag2) ? new Color(0.1f, 0.08f, 0.05f, 0.92f) : new Color(0.95f, 0.68f, 0.28f, 0.97f)); Rect2(val8); GUI.color = Color.white; GUI.Label(val8, list[j].Name, (!flag2) ? _pillDark : _pillSel); } } float num12 = value + 34f; Vector2 val9 = _sel; if (((Vector2)(ref val9)).magnitude > num12) { val9 *= num12 / ((Vector2)(ref val9)).magnitude; } Vector2 val10 = default(Vector2); ((Vector2)(ref val10))..ctor(val.x + val9.x, val.y - val9.y); float num13 = Mathf.Max(6f, Plugin.Instance.cCursorSize.Value); float num14 = num13 * 0.6f; GUI.color = new Color(0f, 0f, 0f, 0.8f); Rect2(new Rect(val10.x - num13 / 2f, val10.y - num13 / 2f, num13, num13)); GUI.color = ((_selIndex < 0) ? new Color(0.97f, 0.97f, 0.97f, 0.95f) : new Color(0.74f, 0.98f, 0.55f, 1f)); Rect2(new Rect(val10.x - num14 / 2f, val10.y - num14 / 2f, num14, num14)); GUI.color = Color.white; string text = ((_selIndex < 0) ? "cancel" : list[_selIndex].Name); int num15 = ((_targets.Count <= 0) ? 1 : _targets.Count); string text2 = "All Bots"; if (_tIdx >= 0 && _tIdx < _targets.Count) { Target target = _targets[_tIdx]; if (target.Kind == TKind.Nearest) { LethalBotAI val11 = NearestBot(OwnedBots()); text2 = "Nearest (" + ((!((Object)(object)val11 != (Object)null)) ? "none" : Abbrev(SafeName(val11))) + ")"; } else { text2 = target.Label; } } float maxW = (value + 55f) * 0.72f; DrawFit(new Rect(val.x - 170f, val.y - 50f, 340f, 36f), text, _center, maxW, 29, shadow: true); DrawFit(new Rect(val.x - 170f, val.y - 13f, 340f, 26f), "◄ " + text2 + " ►", _sub, maxW, 20, shadow: true); DrawFit(new Rect(val.x - 170f, val.y + 15f, 340f, 18f), "scroll: target (" + (_tIdx + 1) + "/" + num15 + ")", _hint, maxW, 15, shadow: true); DrawFit(new Rect(val.x - 170f, val.y + 36f, 340f, 18f), "R-click: page " + (_page + 1) + "/" + _pages.Count + " · 1-8", _hint, maxW, 15, shadow: true); GUI.color = color; } private void CmdReport(LethalBotAI[] targets) { if (targets != null && targets.Length != 0) { LethalBotAI val = targets[0]; int valueOfAllScrapOnShip = LethalBotManager.GetValueOfAllScrapOnShip(val, true); TimeOfDay instance = TimeOfDay.Instance; string text = ((!((Object)(object)instance != (Object)null)) ? $"Ship scrap: ${valueOfAllScrapOnShip}." : $"Ship scrap: ${valueOfAllScrapOnShip}. Quota: ${instance.quotaFulfilled}/${instance.profitQuota}."); val.SendChatMessage(text, false); } } private void CmdRegroup(LethalBotAI[] targets) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = LocalPlayer(); if ((Object)(object)val == (Object)null || targets == null) { return; } foreach (LethalBotAI val2 in targets) { if ((Object)(object)val2 != (Object)null) { val2.SyncTeleportLethalBot(((Component)val).transform.position, (bool?)(!val.isInsideFactory), (EntranceTeleport)null, false, 0f, false, false); } } } private void CmdGoToBot(LethalBotAI[] targets) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) PlayerControllerB val = LocalPlayer(); if ((Object)(object)val == (Object)null || targets == null || targets.Length == 0) { return; } LethalBotAI val2 = NearestBot(targets); if ((Object)(object)val2 == (Object)null || val2.NpcController == null || (Object)(object)val2.NpcController.Npc == (Object)null) { return; } PlayerControllerB npc = val2.NpcController.Npc; Vector3 position = ((Component)npc).transform.position; val.TeleportPlayer(position, false, 0f, false, false); bool isInsideFactory = npc.isInsideFactory; val.isInElevator = false; val.isInHangarShipRoom = false; val.isInsideFactory = isInsideFactory; try { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.occlusionCuller != (Object)null && ((Behaviour)instance.occlusionCuller).enabled) { instance.occlusionCuller.SetToStartTile(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("GoToBot culling refresh: " + ex.Message)); } } private void CmdToShip(LethalBotAI[] targets) { //IL_0008: 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) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (targets == null) { return; } Vector3 val = ShipPos(); foreach (LethalBotAI val2 in targets) { if ((Object)(object)val2 != (Object)null) { val2.SyncTeleportLethalBot(val, (bool?)true, (EntranceTeleport)null, false, 0f, false, false); } } } private Vector3 ShipPos() { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0063: Unknown result type (might be due to invalid IL or missing references) StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null) { if ((Object)(object)instance.middleOfShipNode != (Object)null) { return instance.middleOfShipNode.position; } if (instance.playerSpawnPositions != null && instance.playerSpawnPositions.Length > 0 && (Object)(object)instance.playerSpawnPositions[0] != (Object)null) { return instance.playerSpawnPositions[0].position; } if ((Object)(object)instance.elevatorTransform != (Object)null) { return instance.elevatorTransform.position; } } PlayerControllerB val = LocalPlayer(); return (!((Object)(object)val != (Object)null)) ? Vector3.zero : ((Component)val).transform.position; } private void CmdTransfer(LethalBotAI[] targets) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown if (targets == null) { return; } foreach (LethalBotAI val in targets) { if ((Object)(object)val != (Object)null && val.State != null) { val.State = (AIState)new TransferLootState(val.State); } } } private void CmdLeadWay(LethalBotAI[] targets) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown PlayerControllerB val = LocalPlayer(); if (targets == null) { return; } GroupManager instance = GroupManager.Instance; foreach (LethalBotAI val2 in targets) { if (!((Object)(object)val2 == (Object)null) && val2.State != null) { PlayerControllerB val3 = ((val2.NpcController == null) ? null : val2.NpcController.Npc); if ((Object)(object)instance != (Object)null && (Object)(object)val != (Object)null && (Object)(object)val3 != (Object)null && instance.ArePlayersInSameGroup(val3, val)) { instance.RemoveFromCurrentGroupAndSync(val3); } val2.State = (AIState)new SearchingForScrapState(val2.State, (EntranceTeleport)null); } } } private void CmdChangeSuit(LethalBotAI[] targets) { PlayerControllerB val = LocalPlayer(); if ((Object)(object)val == (Object)null || targets == null) { return; } int currentSuitID = val.currentSuitID; foreach (LethalBotAI val2 in targets) { if (!((Object)(object)val2 == (Object)null) && val2.NpcController != null && !((Object)(object)val2.NpcController.Npc == (Object)null)) { val2.ChangeSuitLethalBotServerRpc(val2.NpcController.Npc.playerClientId, currentSuitID, true); } } } private void CmdFollow(LethalBotAI[] targets) { PlayerControllerB val = LocalPlayer(); if ((Object)(object)val == (Object)null || targets == null) { return; } GroupManager instance = GroupManager.Instance; foreach (LethalBotAI val2 in targets) { if (!((Object)(object)val2 == (Object)null)) { PlayerControllerB val3 = ((val2.NpcController == null) ? null : val2.NpcController.Npc); if ((Object)(object)instance != (Object)null && (Object)(object)val3 != (Object)null) { instance.CreateOrJoinGroupWithMembersAndSync(val, (PlayerControllerB[])(object)new PlayerControllerB[1] { val3 }, false); } val2.SyncAssignTargetAndSetMovingTo(val); } } } private void CmdWait(LethalBotAI[] targets) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown if (targets == null) { return; } foreach (LethalBotAI val in targets) { if ((Object)(object)val != (Object)null && val.NpcController != null && (Object)(object)val.NpcController.Npc != (Object)null) { val.State = (AIState)new HoldPositionState(val.State, ((Component)val.NpcController.Npc).transform.position); } } } private void CmdGearUp(LethalBotAI[] targets) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown if (targets == null) { return; } foreach (LethalBotAI val in targets) { if ((Object)(object)val != (Object)null) { val.State = (AIState)new GrabLoadoutState(val.State, (AIState)null); } } } private void CmdManShip(LethalBotAI[] targets) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown LethalBotManager instance = LethalBotManager.Instance; PlayerControllerB val = LocalPlayer(); if ((Object)(object)instance == (Object)null || (Object)(object)val == (Object)null || targets == null) { return; } foreach (LethalBotAI val2 in targets) { if (!((Object)(object)val2 == (Object)null) && val2.State != null) { instance.MissionControlPlayer = val; val2.State = (AIState)new MissionControlState(val2.State); } } } private void ChatCmd(LethalBotAI[] targets, string keyword) { PlayerControllerB val = LocalPlayer(); if (targets == null || (Object)(object)val == (Object)null) { return; } foreach (LethalBotAI val2 in targets) { if (!((Object)(object)val2 == (Object)null) && val2.State != null) { try { bool flag = ChatCommandsManager.OnPlayerChatMessageReceived(val2.State, keyword, val, true); Plugin.Log.LogInfo((object)("[wheel] voice '" + keyword + "' -> " + SafeName(val2) + ": handled=" + flag)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("voice cmd '" + keyword + "' failed: " + ex)); } } } } }