IsharaMeradin Posted February 27, 2017 Share Posted February 27, 2017 I had a secondary quest script that resided on my MCM quest which used the OnKeyDown event while the key registration was handled on the MCM script within an OnUpdate event which is registered for during the OnConfigClose event. While tweaking some features, I realized that if the OnKeyDown event were on a player alias that I could handle some additional things (i.e. toggling a bool variable with the key press that would allow certain code to run during the OnItemRemoved event that would ordinarily be blocked). Anyway, since the alias script doesn't get the key registration from the MCM I came up with this solution. MCM script Int OldMAK ;variable is set to -1.0 inside the OnConfigInit event -- same value as initial hot key dxscancode Event OnKeyDown(Int KeyCode) If KeyCode == abim_IMS_ModActKeyGV.GetValue() If OldMAK != KeyCode OldMAK = KeyCode SendModEvent("abim_HotKeyInitiateEvent") Debug.Notification("Initiating secondary script hot key registration") EndIf UnRegisterForAllKeys() EndIf EndEvent Alias script Event OnPlayerLoadGame() RegisterForModEvent("abim_HotKeyInitiateEvent","OnHotKeyInitiate") EndEvent ;mod event is also registered in the OnInit event Event OnHotKeyInitiate(string eventName, string strArg, float numArg, Form sender) UnregisterForAllKeys() Int MAK = abim_IMS_ModActKeyGV.GetValue() as Int If MAK != -1.0 RegisterForKey(MAK) Debug.Notification("Hot key registration complete") OnKeyDown(MAK) EndIf EndEvent Result: Player picks a hotkey in the MCM. On first use, the event is sent and the alias script processes it and registers for the designated key and then calls the OnKeyDown event so that the user doesn't have to perform a double press to achieve the function they wanted to perform with the hotkey. From then on the key press triggers the OnKeyDown event on the alias. Thought this was rather ingenious myself as I'd never used the mod event feature from SKSE before. However, if there is a better way, I'd like to know. Link to comment Share on other sites More sharing options...
cdcooley Posted February 27, 2017 Share Posted February 27, 2017 Very creative. You could also create and fill a property to that alias in the MCM script and trigger the registration directly. I would put this in the alias script. Event RegisterHotkey(int keyCode) UnregisterForAllKeys() if keyCode != -1 RegisterForKey(keyCode) endif EndEvent Technically you could do all of those checks and calls from the MCM script, but at a minimum it would mean calling both Unregister and Register remotely which is slower than calling a function which can then call them on its own object. And you don't actually need that global variable with this scheme since you would be passing the new keycode directly through the function. Link to comment Share on other sites More sharing options...
PeterMartyr Posted February 27, 2017 Share Posted February 27, 2017 You could also create and fill a property to that alias in the MCM script and trigger the registration directly. I would put this in the alias script.Technically you could do all of those checks and calls from the MCM script, but at a minimum it would mean calling both Unregister and Register remotely which is slower than calling a function which can then call them on its own object. And you don't actually need that global variable with this scheme since you would be passing the new keycode directly through the function. @ cdcooley For my own personal reference, is this what you mean? MCM ReferenceAlias Property PlayerAlias Auto Int Property nKeyInt = -1 Auto State BindKey Event OnKeyMapChangeST(int aiNewkeyCode, string asConflictControl, string asConflictName) If KeyConflict(aiNewKeyCode, asConflictControl, asConflictName) nKeyInt = aiNewKeyCode (PlayerAlias as AliasPlayerScript).UnregisterForKey(aiNewKeyCode) self.SetKeyMapOptionValueST(nKeyInt) (PlayerAlias as AliasPlayerScript).RegisterForKey(aiNewKeyCode) EndIf EndEvent Event OnDefaultST() (PlayerAlias as AliasPlayerScript).UnregisterForKey(nKeyInt) nKeyInt = -1 self.SetKeyMapOptionValueST(nKeyInt) EndEvent Event OnHighlightST() SetInfoText("Assign a Hot Key to ....\nDefault will unbind Hot Key") EndEvent EndStateAlias ModConfigMenuScript Property Config Auto Event OnKeyDown(Int KeyCode) If(KeyCode == Config.nKeyInt) ; .... EndIf EventSo the MCM Key is neat & tidy, with the Keycode Int changed from private variable to a property? So the Alias can use it. The code is untested for function or compilation, be kind, I'm self taught. Link to comment Share on other sites More sharing options...
IsharaMeradin Posted February 27, 2017 Author Share Posted February 27, 2017 @ cdcooleyI should have thought of that since I have called functions on other scripts like that before. At least I got to learn how to use something that was new to me. Is there any harm in leaving it the way it is (at least until I need to make more than just a minor edit)? Link to comment Share on other sites More sharing options...
cdcooley Posted February 28, 2017 Share Posted February 28, 2017 @ cdcooleyI should have thought of that since I have called functions on other scripts like that before. At least I got to learn how to use something that was new to me. Is there any harm in leaving it the way it is (at least until I need to make more than just a minor edit)?No problem I can see. Link to comment Share on other sites More sharing options...
cdcooley Posted February 28, 2017 Share Posted February 28, 2017 @ cdcooley For my own personal reference, is this what you mean?No, because now the alias script has to access the MCM quest script which is a lot slower than accessing a global variable. Ideally you should never store your actual mod state information in the MCM script itself. The MCM script should always be using values form other scripts or global variables. I personally love using custom properties in the other scripts to keep things simple for the MCM (and to ensure they always have sane values). MCM AliasPlayerScript Property PlayerAlias Auto ; when setting up the menu in OnPageReset ; AddKeyMapOptionST("BindKey", "Hot Key", PlayerAlias.hotkeyCode, OPTION_FLAG_WITH_UNMAP) State BindKey Event OnKeyMapChangeST(int newKeyCode, string conflictControl, string conflictName) ; whatever conflict resolution checks you feel are needed here PlayerAlias.hotkeyCode = newKeyCode SetKeyMapOptionValueST(newKeyCode) endEvent Event OnDefaultST() PlayerAlias.hotkeyCode = -1 ; unmap it EndEvent Event OnHighlightST() SetInfoText("Assign a Hot Key to ....\nDefault will unbind Hot Key") EndEvent EndState Alias ScriptName AliasPlayerScript extends ReferenceAlias int hotkeyCode_var = -1 ; initially unmapped int Property hotkeyCode Hidden int Function get() return hotkeyCode_var EndFunction Function set(int newCode) ; unregister old key and register the new one if hotkeyCode_var > -1 UnregisterForKey(hotkeyCode_var) endif hotkeyCode_var = newCode if hotkeyCode_var > -1 RegisterForKey(hotkeyCode_var) elseif hotkeyCode_var < -1 hotkeyCode_var = -1 ; so it displays correctly in the MCM endif EndFunction EndProperty Event OnKeyDown(int keyCode) if keycode == hotkeyCode_var ; do something interesting endif EndEvent That property may look complicated but if you wanted multiple hotkeys you can duplicate it and replace the hotkeyCode and hotkeyCode_var names to make as many different hotkeys as you wanted and they would all handle their own registrations independently. And yes, you can safely change the hotkey registrations while the MCM is open. They don't require game mode or block the MCM script processing in any way. Link to comment Share on other sites More sharing options...
PeterMartyr Posted February 28, 2017 Share Posted February 28, 2017 @ IsharaMeradinSorry for hijacking but your post, but it really pique my interest. @ cdcooleyYour a gentleman as always, thank you, & no I understand the property works, thanks again. Link to comment Share on other sites More sharing options...
Recommended Posts