scn 1SSQSMenuManagementfloat fQuestDelayTime; Static variables. They should always contain the same value, and never be changed.float fQuestDelayTime ; fQuestDelayTime: used to control how often the script is processed; Configuration variables. They have a default value, but can be changed in the configuration menu.short MenuKey ; MenuKey: stores one of the keys used to open the Configuration Menushort MenuModKey ; MenuModKey: stores one of the keys used to open the Configuration Menushort LeftStackKey ; LeftStackKey: stores one of the Stack hotkeys used to auto-confirm transactions in the barter/container screenshort RightStackKey ; RightStackKey: stores one of the Stack hotkeys used to auto-confirm transactions in the barter/container screenshort LeftSingleKey ; LeftSingleKey: stores one of the Single hotkeys used to auto-confirm transactions in the barter/container screenshort RightSingleKey ; RightSingleKey: stores one of the Single hotkeys used to auto-confirm transactions in the barter/container screenshort InvLeftStackKey ; InvLeftStackKey: stores one of the Stack hotkeys used to auto-confirm transactions in the inventory screenshort InvRightStackKey ; InvRightStackKey: stores one of the Stack hotkeys used to auto-confirm transactions in the inventory screenshort InvLeftSingleKey ; InvLeftSingleKey: stores one of the Single hotkeys used to auto-confirm transactions in the inventory screenshort InvRightSingleKey ; InvRightSingleKey: stores one of the Single hotkeys used to auto-confirm transactions in the inventory screenshort bAutoGiveAway ; bAutoGiveAway: specifies whether to auto-confirm transactions where the item is being given awayshort DefaultAction ; DefaultAction: specifies which action to take when none of the above keys are pressed ; DefaultAction == 0, NO items will be auto-confirmed when no button is pressed, and the prompt will appear if NONE of the hotkeys are pressed ; DefaultAction == 1, ONE item will be auto-confirmed when no button is pressed, and the prompt will appear if any of the SINGLE hotkeys are pressed ; DefaultAction == 2, ALL items will be auto-confirmed when no button is pressed, and the prompt will appear if any of the STACK hotkeys are pressed; Operational variables. Their contents are dynamically set as needed.short bStackPressed ; bStackPressed: used to cache whether if a Stack hotkey was pressedshort bSinglePressed ; bSinglePressed: used to cache whether if a Single hotkey was pressedshort promptAmount ; promptAmount: used to manipulate the quantity prompt amountshort cMenu ; cMenu: used to track which menu screen is openshort CheckKeyStates ; CheckKeyStates: used to determine how to check the keyboard.string_var sCheck1 ; sCheck1: used to compare temporary stringsstring_var sCheck2 ; sCheck2: used to compare temporary stringsShort DoOnceBegin GameMode If DoOnce Return Else Set DoOnce to 1 Set LeftStackKey to 42 ; Left Shift Set LeftSingleKey to 29 ; Left Control EndifEndBegin MenuMode 1008 Set fQuestDelayTime to 0.01 If OnKeyDown 30 ; Press "A" If GetMenuFloatValue "user8" 1008 == 2 ClickMenuButton "#32" 1008 Endif EndifEndBegin MenuMode 1001 ;confirm buy/sell ; cMenu serves as a temporary variable before it is set. ; cMenu == 1, Barter is open, and something is being bought. Use sBuy gamesetting. ; cMenu == 2, Barter is open, and something is being sold. Use sSell gamesetting. ; cMenu == 3, SpellPurchase is open, and a spell is being bought. Use sConfirmBuySpell gamesetting. set cMenu to GetMenuFloatValue "user8" 1008 If cMenu == 0 ; Barter/Container NOT visible! See if SpellPurchase is. set cMenu to GetMenuFloatValue "locus" 1037 If cMenu ; SpellPurchase Visible! set cMenu to 3 Else ; SpellPurchase NOT visible! set CheckKeyStates to 0 Return EndIf ElseIf cMenu == 2 ; Container Visible! set CheckKeyStates to 0 Return Else ; cMenu == 3 If GetMenuHasTrait "user9" 1008 == 0 MessageBoxEX "Error: TQP couldn't read a menu element!%r%rBarter\Container%ruser9%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf set cMenu to GetMenuFloatValue "user9" 1008 If cMenu == 2 ; Barter Visible! If GetMenuHasTrait "user7" 1008 == 0 MessageBoxEX "Error: TQP couldn't read a menu element!%r%rBarter\Container%ruser7%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf set cMenu to GetMenuFloatValue "user7" 1008 If cMenu == 2 ; Buying! set cMenu to 1 Else ; Selling! set cMenu to 2 EndIf EndIf EndIf ; CheckKeyStates == 0 on the first pass, unless it is being auto-confirmed by the quantity prompt ; It is otherwise set while the prompt is open, and reset to 0 when done. ; If the prompt is cancelled, CheckKeyStates will be equal to 5. ; Which is fine, since that's what it'd start at anyway. If CheckKeyStates % 2 == 0 set CheckKeyStates to 5 EndIf ; Auto Keystate Handler, auto-confirms the prompt without any keys needing to be pressed/held. Used when the quantity prompt was auto-confirmed If CheckKeyStates == 1 ; Just pass through, no checks required ; Cautious Keystate Handler, requires the player to press the key instead of allowing it to be held down ; Mainly used when DefaultAction != 0, and the hotkey is held down ElseIf CheckKeyStates == 3 set bStackPressed to OnKeyDown RightStackKey || OnKeyDown LeftStackKey set bSinglePressed to OnKeyDown RightSingleKey || OnKeyDown LeftSingleKey ; Normal Keystate Handler, does the work when the Quantity prompt was NOT auto-confirmed. ; Either the prompt didn't appear (to transact a single item), or the prompt was manually confirmed Else ; Check keystates. Doing it all at once and stashing the results for a frame makes the code cleaner. ; It also improves performance slightly by preventing multiple redundant function calls ; This is redundant, but necessary. This makes OnKeyDown report as expected if CheckKeyStates changes. set bStackPressed to OnKeyDown RightStackKey || OnKeyDown LeftStackKey set bSinglePressed to OnKeyDown RightSingleKey || OnKeyDown LeftSingleKey set bStackPressed to IsKeyPressed2 RightStackKey || IsKeyPressed2 LeftStackKey set bSinglePressed to IsKeyPressed2 RightSingleKey || IsKeyPressed2 LeftSingleKey ; This block acts to control the various default actions If bStackPressed && bSinglePressed && DefaultAction ; If a DefaultAction is in use, and both keys are pressed: Use standard behavior set CheckKeyStates to 3 Return ElseIf bStackPressed && DefaultAction == 1 ; If the SINGLE DefaultAction is in use, and the STACK keys are pressed: STACK keys override DefaultAction ElseIf bSinglePressed && DefaultAction == 1 ; If the SINGLE DefaultAction is in use, and the SINGLE keys are pressed: Use standard behavior set CheckKeyStates to 3 Return ElseIf bStackPressed && DefaultAction == 2 ; If the STACK DefaultAction is in use, and the STACK keys are pressed: Use standard behavior set CheckKeyStates to 3 Return ElseIf bSinglePressed && DefaultAction == 2 ; If the STACK DefaultAction is in use, and the SINGLE keys are pressed: SINGLE keys override DefaultAction ElseIf DefaultAction == 1 ; If the STACK DefaultAction is in use, and NO keys are pressed: Emulate SINGLE keys set bSinglePressed to 1 ElseIf DefaultAction == 2 ; If the STACK DefaultAction is in use, and NO keys are pressed: Emulate STACK keys set bStackPressed to 1 EndIf EndIf If ( bSinglePressed || bStackPressed ) == 0 Return EndIf ; It isn't possible to directly tell if this is the confirmation screen, hence all the checks. ; I've tried to make it work with non-English setups by using the GameSettings, but haven't tested it. ; If there are any issues, please notify me. ; See if the current message menu was game generated, and a barter screen is active If GetActiveMenuObject 1001 == 0 ; If so, make sure there are only two buttons If GetMenuHasTrait "background\button_3\visible" 1001 == 0 MessageBoxEX "Error: TQP couldn't read a menu element!%r%rbackground\button_3\visible%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf If ( GetMenuFloatValue "background\button_3\visible" 1001 ) == 1 If GetMenuHasTrait "background\button_1\string" 1001 == 0 MessageBoxEX "Error: TQP couldn't read a menu element!%r%rbackground\button_1\string%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf set sCheck1 to GetStringGameSetting sYes set sCheck2 to GetMenuStringValue "background\button_1\string" 1001 ; Now see if the two buttons are "Yes" and "No". If ( sv_Count "%z" sCheck1 sCheck2 ) == 1 If GetMenuHasTrait "background\button_2\string" 1001 == 0 MessageBoxEX "Error: TQP couldn't read a menu element!%r%rbackground\button_2\string%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf set sCheck1 to GetStringGameSetting sNo set sCheck2 to GetMenuStringValue "background\button_2\string" 1001 If ( sv_Count "%z" sCheck1 sCheck2 ) == 1 ; At this point, it is known that the message menu was game generated while a barter screen is open, and that there are two buttons "Yes, and "No" If GetMenuHasTrait "background\message_text\string" 1001 set sCheck2 to GetMenuStringValue "background\message_text\string" 1001 ElseIf GetMenuHasTrait "background\msg_text_rect\message_text\string" 1001 ; Compatibility for DarN's UI v1.3.2 set sCheck2 to GetMenuStringValue "background\msg_text_rect\message_text\string" 1001 Else MessageBoxEX "Error: TQP couldn't read either menu element!%r%rbackground\message_text\string%rbackground\msg_text_rect\message_text\string%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf If cMenu == 1 set sCheck1 to GetStringGameSetting sBuy ElseIf cMenu == 2 set sCheck1 to GetStringGameSetting sSell Else set sCheck1 to GetStringGameSetting sConfirmBuySpell EndIf ; See if the menu text starts with either of these three phrases, "Buy" or "Sell" or "Are you sure you want to buy" If ( sv_Find "%z" sCheck1 sCheck2 ) == 0 set sCheck1 to GetStringGameSetting sFor ; Lastly, see if the menu text contains "for" and "gold". If sv_Count "%z" sCheck1 sCheck2 set sCheck1 to GetStringGameSetting sGold If sv_Count "%z" sCheck1 sCheck2 ; Now, assume that this actually is the confirm buy/sell screen ClickMenuButton "background\button_1" 1001 EndIf EndIf ElseIf bAutoGiveAway set sCheck1 to GetStringGameSetting sGiveAway If ( sv_Find "%z" sCheck1 sCheck2 ) == 0 ; Now, assume that this actually is the confirm Give Away screen ClickMenuButton "background\button_1" 1001 EndIf EndIf EndIf EndIf EndIf set sCheck1 to sv_Destruct set sCheck2 to sv_Destruct EndIf ; This prevents this check from running more than once per confirmation screen. set CheckKeyStates to 0EndBegin MenuMode 1016 ;quantity prompt ; cMenu serves as a temporary variable before it is set. ; cMenu == 1, Inventory is open, use InvXXX hotkeys, and there won't be a confirm screen ; cMenu == 2, Container is open, use XXX hotkeys, and there won't be a confirm screen ; cMenu == 4, Barter is open, use XXX hotkeys, and there will be a confirm screen to bypass ; Any even number (or zero) will trigger the XXX hotkeys. Any odd number will trigger the InvXXX hotkeys. set cMenu to GetMenuFloatValue "user8" 1008 If cMenu == 0 ; Barter/Container NOT visible! See if Inventory is open. If GetMenuHasTrait "user3" 1004 == 0 MessageBoxEX "Error: TQP couldn't read a menu element!%r%rHUDMain%ruser3%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf set cMenu to GetMenuFloatValue "user3" 1004 If cMenu ; Inventory Closed! set CheckKeyStates to 0 Return Else If GetMenuHasTrait "user4" 1004 == 0 MessageBoxEX "Error: TQP couldn't read a menu element!%r%rHUDMain%ruser4%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf set cMenu to GetMenuFloatValue "user4" 1004 If cMenu == 2 ; Inventory Open! set cMenu to 1 Else ; Inventory Closed! set CheckKeyStates to 0 Return EndIf EndIf ElseIf cMenu == 2 ; Container Visible! set cMenu to 2 Else ; cMenu == 3 If GetMenuHasTrait "user9" 1008 == 0 MessageBoxEX "Error: TQP couldn't read a menu element!%r%rBarter\Container%ruser9%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf set cMenu to GetMenuFloatValue "user9" 1008 If cMenu == 2 ; Barter Visible! set cMenu to 4 EndIf EndIf ; CheckKeyStates == 0 on the first pass, unless it is being auto-confirmed by the quantity prompt ; It is otherwise set while the prompt is open, and reset to 0 when done. ; If the prompt is cancelled, CheckKeyStates will be equal to 5. ; Which is fine, since that's what it'd start at anyway. If CheckKeyStates == 0 || CheckKeyStates % 2 == 1 set CheckKeyStates to 6 EndIf ; Auto Keystate Handler, auto-confirms the prompt without any keys needing to be pressed/held. Used when the quantity prompt was auto-confirmed If CheckKeyStates == 2 ; Currently not used ; Cautious Keystate Handler, requires the player to press the key instead of allowing it to be held down ; Mainly used when DefaultAction != 0, and the hotkey is held down ElseIf CheckKeyStates == 4 If cMenu % 2 set bStackPressed to OnKeyDown InvRightStackKey || OnKeyDown InvLeftStackKey set bSinglePressed to OnKeyDown InvRightSingleKey || OnKeyDown InvLeftSingleKey Else set bStackPressed to OnKeyDown RightStackKey || OnKeyDown LeftStackKey set bSinglePressed to OnKeyDown RightSingleKey || OnKeyDown LeftSingleKey EndIf Else ; Check keystates. Doing it all at once and stashing the results for a frame makes the code cleaner. ; It also improves performance slightly by preventing multiple redundant function calls ; This is redundant, but necessary. This makes OnKeyDown report as expected if CheckKeyStates changes. If cMenu % 2 set bStackPressed to OnKeyDown InvLeftStackKey || OnKeyDown InvRightStackKey set bSinglePressed to OnKeyDown InvLeftSingleKey || OnKeyDown InvRightSingleKey set bStackPressed to IsKeyPressed2 InvLeftStackKey || IsKeyPressed2 InvRightStackKey set bSinglePressed to IsKeyPressed2 InvLeftSingleKey || IsKeyPressed2 InvRightSingleKey Else set bStackPressed to OnKeyDown RightStackKey || OnKeyDown LeftStackKey set bSinglePressed to OnKeyDown RightSingleKey || OnKeyDown LeftSingleKey set bStackPressed to IsKeyPressed2 RightStackKey || IsKeyPressed2 LeftStackKey set bSinglePressed to IsKeyPressed2 RightSingleKey || IsKeyPressed2 LeftSingleKey EndIf ; This block acts to control the various default actions If bStackPressed && bSinglePressed && DefaultAction ; If a DefaultAction is in use, and both keys are pressed: Use standard behavior set CheckKeyStates to 4 Return ElseIf bStackPressed && DefaultAction == 1 ; If the SINGLE DefaultAction is in use, and the STACK keys are pressed: STACK keys override DefaultAction ElseIf bSinglePressed && DefaultAction == 1 ; If the SINGLE DefaultAction is in use, and the SINGLE keys are pressed: Use standard behavior set CheckKeyStates to 4 Return ElseIf bStackPressed && DefaultAction == 2 ; If the STACK DefaultAction is in use, and the STACK keys are pressed: Use standard behavior set CheckKeyStates to 4 Return ElseIf bSinglePressed && DefaultAction == 2 ; If the STACK DefaultAction is in use, and the SINGLE keys are pressed: SINGLE keys override DefaultAction ElseIf DefaultAction == 1 ; If the STACK DefaultAction is in use, and NO keys are pressed: Emulate SINGLE keys set bSinglePressed to 1 ElseIf DefaultAction == 2 ; If the STACK DefaultAction is in use, and NO keys are pressed: Emulate STACK keys set bStackPressed to 1 EndIf EndIf ; If NO keys are pressed (or emulated): Wait for input If ( bSinglePressed || bStackPressed ) == 0 Return EndIf ; If the SINGLE hotkeys ARE pressed: Confirm ONE item. If bSinglePressed If GetMenuHasTrait "quantity_background\quantity_scroll\user7" 1016 == 0 MessageBoxEX "Error: TQP couldn't write to a menu element!%r%rquantity_background\quantity_scroll\user7%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf SetMenuFloatValue "quantity_background\quantity_scroll\user7" 1016 1 ; If the STACK hotkeys ARE pressed: Confirm ALL items. ElseIf bStackPressed ; The player may have changed the amount on his own, so the max value DOES have to be read and used. If GetMenuHasTrait "quantity_background\quantity_scroll\user2" 1016 == 0 MessageBoxEX "Error: TQP couldn't read a menu element!%r%rquantity_background\quantity_scroll\user2%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf set promptAmount to GetMenuFloatValue "quantity_background\quantity_scroll\user2" 1016 ;Max If GetMenuHasTrait "quantity_background\quantity_scroll\user7" 1016 == 0 MessageBoxEX "Error: TQP couldn't write to a menu element!%r%rquantity_background\quantity_scroll\user7%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf SetMenuFloatValue "quantity_background\quantity_scroll\user7" 1016 promptAmount EndIf ; If this was from the barter screen, then auto-confirm the upcoming confirm screen ; Otherwise, don't auto-confirm anything that happens to appear. If cMenu == 4 set CheckKeyStates to 1 Else set CheckKeyStates to 0 EndIf ; One of the hotkeys were pressed, so auto-confirm the prompt. If GetMenuHasTrait "quantity_background\quantity_button_okay\id" 1016 == 0 MessageBoxEX "Error: TQP couldn't find a menu element!%r%rquantity_background\quantity_button_okay%r%rPlease report this error, along with any UI mods in use| Okay " set CheckKeyStates to 0 Return EndIf ClickMenuButton "quantity_background\quantity_button_okay" 1016 ReturnEnd