TMushS Posted February 13, 2021 Share Posted February 13, 2021 Hey all, just need a bit of help please. I've had my mod out there for several years now and just trying to do some tweaks to it. I'm trying to turn this OnKeyDown event: Event OnKeyDown(Int KeyCode) if KeyCode == iHotkeyA SummonAllPriority() elseif KeyCode == iHotkeyB SummonAllGroupMenu() endif EndEvent to this: Event OnKeyDown(Int KeyCode) if KeyCode == iHotkeyA (start pseudo code) if the key is pressed for more than 1.5 seconds then do this function -> SummonAllGroupMenu() else do this function -> SummonAllPriority() endif (end pseudo code) endif EndEvent mind you, I'm not changing my original code etc. It works fine. I just wanted to take one of the other keys and combine it to have a long/short press. If i could find a function that would basically be equivalent to the old "GetSecondsPassed" function from oblivion that would be great. Then I could just plug in the function in those lines and it would work fine. Unless there is one and I'm just not seeing it. -Mush- Link to comment Share on other sites More sharing options...
IsharaMeradin Posted February 13, 2021 Share Posted February 13, 2021 There isn't a function to track how long a key has been pressed. Instead you could try something like: Event OnKeyDown(Int KeyCode) if KeyCode == iHotkeyA Float fStartTime = Utility.GetCurrentRealTime() While IsKeyPressed(iHotkeyA) Utility.Wait(0.25) EndWhile Float fEndTime = Utility.GetCurrentRealTime() If (fEndTime - fStartTime) > 1.5 SummonAllGroupMenu() else SummonAllPriority() endif endif EndEvent But I'm not sure how papyrus will behave with a key registered for the OnKeyDown event also being tracked for the length of being pressed. It is possible that the OnKeyDown event might be triggered multiple times. You will have to test for that and possibly use a separate key not registered for the OnKeyDown event. Link to comment Share on other sites More sharing options...
TMushS Posted February 13, 2021 Author Share Posted February 13, 2021 I'll try that, thank you. Amusingly, there is this : https://www.creationkit.com/index.php?title=OnControlUp_-_Form, which actually has a hold variable that's part of the event. Unfortunately, it only uses binds that are hard coded and used from the game. was hoping there would have been some undocumented 'hold variable' for iskeypressed or onkeydown. -Mush- Link to comment Share on other sites More sharing options...
TMushS Posted February 13, 2021 Author Share Posted February 13, 2021 I think this may work. This way it should detect once when down then again when up, in two different events. Going to test when I get the chance. float property fStartTime auto float property fEndTime auto Event OnKeyDown(Int KeyCode) if KeyCode == iHotkeyA fStartTime = Utility.GetCurrentRealTime() endif EndEvent Event OnKeyUp(Int KeyCode) fEndTime = Utility.GetCurrentRealTime() If (fEndTime - fStartTime) > 1.5 SummonAllGroupMenu() else SummonAllPriority() endif EndEvent edit: had to swap the properties. had the variable and property names in the wrong places. -Mush- Link to comment Share on other sites More sharing options...
IsharaMeradin Posted February 13, 2021 Share Posted February 13, 2021 That would work. Those variables do not need to be properties unless you need to access them for some reason on another script. They can just be local variables for that script. i.e. drop the word "property" and the word "auto" from the variable declaration line. Also make sure you check the KeyCode parameter to be the correct key in both events in case you have more than one key registered for that script. Link to comment Share on other sites More sharing options...
dylbill Posted February 13, 2021 Share Posted February 13, 2021 It looks like onKeyUp does have a hold time, or am I missing something? https://www.creationkit.com/index.php?title=OnKeyUp_-_Form Link to comment Share on other sites More sharing options...
TMushS Posted February 13, 2021 Author Share Posted February 13, 2021 Got it to work. Thank you both; You gave me the idea and I found out that the OnKeyUP event has a built in HoldTimer float. Here's the working Event block: Event OnKeyUp(Int KeyCode, float holdtime) if KeyCode == iHotkeyA if holdtime > 1.5 SummonAllGroupMenu() else SummonAllPriority() endif endif EndEvent -Mush- Link to comment Share on other sites More sharing options...
dylbill Posted February 13, 2021 Share Posted February 13, 2021 No problem, happy modding :) Link to comment Share on other sites More sharing options...
TMushS Posted February 14, 2021 Author Share Posted February 14, 2021 Just a bit of an update. I've got the full working code bit that I was looking for. now while OnKeyUp worked perfectly fine, the way it behaves leaves it up to the player to mentally count down in seconds before they release the button. i needed a menu to come up while the button was being pressed for so long. I took a bit of combing some functions and commands to come up with a valid working piece of code. Doing it this way also avoids polling by not using OnUpdate and keeps it as Events and called functions. Tested this thing at length for the last few days and here it is: function KeycodeBSummon() ;summon group menu function, the bools are used as a sort of on-off flag so both functions don't happen simultaneously. if bQuickTimer == False SummonAllGroupMenu() EndIf EndFunction Event OnKeyDown(Int KeyCode) if !IsInMenuMode() && Game.IsLookingControlsEnabled() && !Game.GetPlayer().GetAnimationVariableBool("bIsRiding") ; For the line above: only issue the event if the player is not riding a horse, is not in a menu, and is able to freely look around (not in a crafting menu) if KeyCode == iHotkey ;the main key to tag an npc ismSlotsFilled.Apply() ;this plays a small sound when tagging an npc if GetCurrentCrosshairRef() as Actor ;get the ref in the crosshair and make sure it's an actor only TagActor(GetCurrentCrosshairRef()) ;run the tag function EndIf elseif KeyCode == iHotkeyB ;if this hotkey for summon priority and summon group menu is pressed then fStartTime = Utility.GetCurrentRealTime() ;get the current real time and set the bool of bquicktimer to true so it defaults to summon priority function bQuickTimer = true ;defaults to true = summon priority While IsKeyPressed(iHotkeyb) ; while this key is being pressed then keep getting the current time and store that in a new variable called fEndTime fEndTime = Utility.GetCurrentRealTime() ftotalsec = (fEndtime - fStartTime) ; a float variable used to total the amount of time by subtracting the original float time with the updated float time. If (ftotalsec) > cshotkeytimerGV.getvalue() ;note <---turn this number into a priority global to be able to change in the MCM 0.10 (smallest) to 2.00 (longest.) integer stepss of 0.01 ;if the amount of seconds that the key is pressed is longer than the global float variable, then change the bQuickTimer bool to false, run the function, which will kick us out of the while loop. bQuickTimer = False ;not quick = long press - summon group menu KeycodeBSummon() endif EndWhile ;once the while loop is done check to see if bool bQuicktime is true or not and if true then issue the summon priority function else skip over it as it's not needed this time. if bQuickTimer == true SummonAllPriority() EndIf elseif KeyCode == iHotkeyC ; key for using the ulib.events and functions to enter in the name of the npc to search for in the tagged database EnterName() elseif KeyCode == iHotkeyD ; the next 5 keys are for assigning the different groups 1 - 5 SummonG1Priority() elseif KeyCode == iHotkeyE SummonG2Priority() elseif KeyCode == iHotkeyF SummonG3Priority() elseif KeyCode == iHotkeyG SummonG4Priority() elseif KeyCode == iHotkeyH SummonG5Priority() elseif KeyCode == iHotkeyJ ; SummonAllGroupMenu() ;erroneous extra code.. this needs to be removed. endif EndIf ;game mode only EndEvent Thanks everyone, -Mush- Link to comment Share on other sites More sharing options...
Recommended Posts