|
| 1 | +using System; |
| 2 | +using System.Linq; |
| 3 | +using System.Reflection; |
| 4 | +using Assets.Scripts; |
| 5 | +using Assets.Scripts.GridSystem; |
| 6 | +using Assets.Scripts.Inventory; |
| 7 | +using Assets.Scripts.Objects.Entities; |
| 8 | +using Assets.Scripts.Serialization; |
| 9 | +using Assets.Scripts.UI; |
| 10 | +using Harmony; |
| 11 | +using SEModLoader; |
| 12 | +using UnityEngine; |
| 13 | + |
| 14 | +namespace HelmetLockMod |
| 15 | +{ |
| 16 | + // HelmetLockMod: A simple mod that adds a button to the controls menu |
| 17 | + // to lock or unlock a helmet with a single keypress |
| 18 | + public class HelmetLockMod : MonoBehaviour, IMod // The IMod just makes it easy to find a valid class |
| 19 | + { |
| 20 | + // For now, just make the mod a Singleton. This may change in future versions |
| 21 | + |
| 22 | + // Instance variable and lock for (Thread-safe) Singleton pattern |
| 23 | + public static HelmetLockMod Instance; |
| 24 | + private static object _instanceLock = new object(); |
| 25 | + |
| 26 | + // The name for the mod |
| 27 | + public static string ModName = "HelmetLockMod"; |
| 28 | + |
| 29 | + public static KeyCode DefaultLockKey = KeyCode.U; |
| 30 | + |
| 31 | + // Stores the last state of the key for debouncing |
| 32 | + public bool _lastButtonState; |
| 33 | + |
| 34 | + // Init: The init function handles instantiating a gameobject |
| 35 | + // to contain the mod and to also register it with Unity |
| 36 | + public static void Init() |
| 37 | + { |
| 38 | + lock (_instanceLock) |
| 39 | + { |
| 40 | + if (Instance == null) |
| 41 | + { |
| 42 | + // Create the GameObject and keeps it alive through scene changes |
| 43 | + Debug.Log("HelmetLockMod: HelmetLockMod Loaded"); |
| 44 | + GameObject go = new GameObject(); |
| 45 | + go.name = ModName; |
| 46 | + Instance = go.AddComponent<HelmetLockMod>(); |
| 47 | + DontDestroyOnLoad(go); |
| 48 | + |
| 49 | + // Activate the Harmony Patcher to register the key |
| 50 | + var harmony = HarmonyInstance.Create("com.zylanx.helmetlockmod"); |
| 51 | + harmony.PatchAll(Assembly.GetExecutingAssembly()); |
| 52 | + |
| 53 | + // Hacky way to get the game to load in our new key |
| 54 | + // NOTE: it is possible that this could override settings |
| 55 | + // if the mod is loaded after the user has changed settings. |
| 56 | + // Once the modloader is more developed, it will have a proper way to |
| 57 | + // register keys as well as manage mod settings |
| 58 | + Settings.LoadSettings(); |
| 59 | + } |
| 60 | + } |
| 61 | + } |
| 62 | + |
| 63 | + // Unity has initialised the object. Set the initial values |
| 64 | + public void Awake() |
| 65 | + { |
| 66 | + _lastButtonState = false; |
| 67 | + } |
| 68 | + |
| 69 | + // Unity controlled. |
| 70 | + // Update: Each update, check if the game is running, |
| 71 | + // if the key is pressed, and then toggles the lock state of the helmet |
| 72 | + // as needed |
| 73 | + public void Update() |
| 74 | + { |
| 75 | + if (GameManager.GameState == GameState.Running) |
| 76 | + { |
| 77 | + // If the button is being pressed but was not pressed previously |
| 78 | + if (KeyManager.GetButtonDown(KeyManager.GetKey("Lock Helmet"))) |
| 79 | + { |
| 80 | + if (_lastButtonState == false) |
| 81 | + { |
| 82 | + // Find the local player |
| 83 | + var player = Human.AllHumans.FirstOrDefault(human => human.IsLocalPlayer); |
| 84 | + |
| 85 | + if (player == null) |
| 86 | + { |
| 87 | + Debug.LogError("HelmetLockMod: Could not find local player"); |
| 88 | + } |
| 89 | + else |
| 90 | + { |
| 91 | + // If the helmet slot has a helmet |
| 92 | + if (player.HelmetSlot.Occupant) |
| 93 | + { |
| 94 | + var helmet = player.HelmetSlot.Occupant; |
| 95 | + |
| 96 | + // Check the helmet can be locked |
| 97 | + if (helmet.HasLockState) |
| 98 | + { |
| 99 | + // Print a string to the console telling the player what is being done |
| 100 | + var consoleString = String.Format("{0}ing {1}...", |
| 101 | + helmet.IsLocked ? ActionStrings.Unlock : ActionStrings.Lock, |
| 102 | + helmet.DisplayName); |
| 103 | + |
| 104 | + ConsoleDebug.AddText(String.Format("<color=yellow>{0}</color>", consoleString)); |
| 105 | + |
| 106 | + // Get the index of the "Lock Item" action for the helmet |
| 107 | + // Then tell the player to send a command to the helmet to toggle its lock |
| 108 | + var helmetLockIndex = helmet.InteractLock.InteractableId; |
| 109 | + player.CallCmdInteractWith(helmetLockIndex, helmet.netId, player.netId, player.HelmetSlot.SlotId, false); |
| 110 | + } |
| 111 | + } |
| 112 | + } |
| 113 | + } |
| 114 | + } |
| 115 | + |
| 116 | + // Update the buttons last state |
| 117 | + _lastButtonState = KeyManager.GetButton(KeyManager.GetKey("Lock Helmet")); |
| 118 | + } |
| 119 | + } |
| 120 | + } |
| 121 | + |
| 122 | + // This is a Harmony Patch Class. |
| 123 | + // See the Harmony Github Wiki for more information |
| 124 | + [HarmonyPatch(typeof(KeyManager))] |
| 125 | + [HarmonyPatch("SetDefaultKeyboard")] |
| 126 | + class Patch_KeyManager_SetDefaultKeyboard |
| 127 | + { |
| 128 | + static void Postfix() |
| 129 | + { |
| 130 | + // Call the private method KeyManager.AddKey then refresh the input screen |
| 131 | + typeof(KeyManager).GetMethod("AddKey", BindingFlags.NonPublic | BindingFlags.Static) |
| 132 | + .Invoke(null, new object[] { "Lock Helmet", HelmetLockMod.DefaultLockKey }); |
| 133 | + KeyManager.RefreshStatusKeys(); |
| 134 | + } |
| 135 | + } |
| 136 | +} |
0 commit comments