Guest Messenjah Posted September 9, 2011 Share Posted September 9, 2011 Begin OnActivate showmessage FFWeaponCloset if getbuttonpressed == 0 player.removealltypeditems FFWeaponClosetREF 1 0 40 elseif getbuttonpressed == 1 FFWeaponClosetREF.activate endif end So, the idea is that I want to create a script that uses an object as an activator. When you activate it, it will pop up a menu that allows you to sort all of your weapons into a container or to simply open the container to sort them yourself. Button 0 is assigned to sort the items into the container. 1 is to allow the player to retain ownership of the moved items. 0, tells the script not to pop up a message saying that the items are being moved (this could actually be better as a 1 in this case actually), 40 is a type code for weapons so it knows only to move weapons from the players inventory. Basically, the script doesn't work, anyone know what I am missing? Link to comment Share on other sites More sharing options...
rickerhk Posted September 10, 2011 Share Posted September 10, 2011 Here's my weapon sorting script. I prefer to use the On Activate block to set things up, and do all the message menus in the GameMode block. scn RHKWendyWeaponSortNScript short iAwaitingInput short iButtonPressed short iMessageToShow short iMessageShown short iActivated BEGIN ONActivate set iAwaitingInput to 0 set iButtonPressed to 0 set iMessageToShow to 1 set iMessageShown to 0 if (IsActionRef Player == 1) set iActivated to 1 else Activate endif END BEGIN GameMode if (iActivated) else return endif if (iMessageShown) else if (iMessageToShow == 1) ShowMessage RHKWendyWeaponLockerSortMSG set iMessageShown to 1 set iAwaitingInput to 1 endif endif if (iAwaitingInput) set iButtonPressed to GetButtonPressed if (iButtonPressed > -1) set iAwaitingInput to 0 if (iMessageShown == 1) ;Sort player if (iButtonPressed == 0) set iActivated to 0 Player.RemoveAllTypedItems RHKWendyLockerWeaponREF 0 1 40 RHKWendyWeaponExplosiveExclude ;Sort weapons except explosives Player.RemoveAllTypedItems RHKWendyAmmoBoxEXREF 0 1 40 ;Explosives here ShowMessage RHKWendyWeaponsWereSorted ;not a message box elseif (iButtonPressed == 1) ;Sort Wendy set iActivated to 0 if ((RHKNvseFlag) && (RHKWendyMN.iWeaponsMode == 2) && (RHKWendyWPE.iWeaponFormListReady)) RHKWendyREF.RemoveAllTypedItems RHKFootlockerWeapTemp1REF 0 1 40 RHKWendyWPEWeaponList RHKFootlockerWeapTemp1REF.RemoveAllTypedItems RHKWendyLockerWeaponREF 0 1 40 RHKWendyWeaponExplosiveExclude RHKFootlockerWeapTemp1REF.RemoveAllTypedItems RHKWendyAmmoBoxEXREF 0 1 40 else RHKWendyREF.RemoveAllTypedItems RHKWendyLockerWeaponREF 0 1 40 RHKWendyWeaponExplosiveExclude RHKWendyREF.RemoveAllTypedItems RHKWendyAmmoBoxEXREF 0 1 40 RHKWendyWeaponList endif RHKWendyBackPackREF.RemoveAllTypedItems RHKWendyLockerWeaponREF 0 1 40 RHKWendyWeaponExplosiveExclude RHKWendyBackPackREF.RemoveAllTypedItems RHKWendyAmmoBoxEXREF 0 1 40 ShowMessage RHKWendyWeaponsWereSorted ;not a message box elseif (iButtonPressed == 2) ;Just open it set iActivated to 0 Activate Player endif endif endif endif END Link to comment Share on other sites More sharing options...
Tefnacht Posted September 10, 2011 Share Posted September 10, 2011 (edited) Hi. Using GetButtonPressed in the same OnActivate block as the ShowMessage command will not work. It will only run once and always return -1 in this case because the player did not actually have time to make a choice yet. You need to move the part of the script that reacts to the message box into a MenuMode or GameMode block. I found it most efficient to use MenuMode 1001 (message box menu mode) to do this. GetButtonPressed will return the players chosen button only ONCE! Successive calls to the function will only yield -1 again. You have to store the result into a local variable and then perform your checks on that. ScriptName MyWeaponSorterScript Short active ;set to 1 while this script waits for the player choice Short key ;result of GetButtonPressed Begin OnActivate If GetActionRef == Player ;if activated by the player (not a NPC) Set active To 1 ;we now react to the player choice ShowMessage FFWeaponCloset ;show the dialog box EndIf End Begin MenuMode 1001 ;during dialog box menu mode If active == 0 ;if this script is not responsible for opening the dialog box Return ;abort EndIf Set key To GetButtonPressed ;read what key was pressed If key >= 0 ;if a key was actually pressed If key == 0 ;if it was the first key Player.RemoveAllTypedItems FFWeaponClosetREF 1 0 40 ;sort weapons ElseIf key == 1 ;otherwise if it was the second key FFWeaponClosetREF.Activate Player ;open the container EndIf Set active To 0 ;done, we reacted to the dialog box EndIf EndHave fun. Edit: RickerHK's script is a good one too, of course. Reacting to the menu choice during game mode also has its merits. For example: Some actions require ongoing execution of the script. The MenuMode 1001 is only executed for a few frames after the player made his choice. If your script needs more frames to do its magic, you will have to use a GameMode block like he does. Edited September 10, 2011 by Tefnacht Link to comment Share on other sites More sharing options...
Guest Messenjah Posted September 10, 2011 Share Posted September 10, 2011 BEGIN ONActivate set iAwaitingInput to 0 set iButtonPressed to 0 set iMessageToShow to 1 set iMessageShown to 0 if (IsActionRef Player == 1) set iActivated to 1 else Activate endif This makes sense, you are setting up the defaults that you want it to be set to upon activation so that the script can be run properly. BEGIN GameMode if (iActivated) else return endif So, are you saying, to only Begin GameMode if iActivated is running? if (iMessageShown) else if (iMessageToShow == 1) ShowMessage RHKWendyWeaponLockerSortMSG set iMessageShown to 1 set iAwaitingInput to 1 endif endif So, what are we accomplishing by having a condition that doesn't appear to do anything that has an else that leads to a condition that runs the message? Just not sure what I'm reading here. Link to comment Share on other sites More sharing options...
rickerhk Posted September 10, 2011 Share Posted September 10, 2011 BEGIN GameMode if (iActivated) else return endif So, are you saying, to only Begin GameMode if iActivated is running?Since a Gamemode block runs every frame on an object in the currently loaded cell, the 'return' makes sure nothing after it will run unless the activate block is triggered by the player. So, what are we accomplishing by having a condition that doesn't appear to do anything that has an else that leads to a condition that runs the message? Just not sure what I'm reading here. Once the gamemode code is enabled, each section of the code is 'guarded' by a variable so it only runs once, then disables itself. I can re-enable it later when processing buttons. iMessageShown is one of these 'guard' variables. The way the if/else is written is an optimized shorthand which actually executes faster instead of this: if (iMessageShown == 0) if (iMessageShown == 0) is the same as if (iMessageShown) ;if non zero ;Do nothing. skip the whole block else ;Do someting So it's the same as this: if (iMessageShown == 0) if (iMessageToShow == 1) ShowMessage RHKWendyWeaponLockerSortMSG set iMessageShown to 1 ;Guard this section set iAwaitingInput to 1 ;Enable the next section endif endif I use this structure for every message box script I do, no matter how simple or complex, so some of this may look like overkill, but by guarding things this way I can ensure there is no interaction with other sections of the script that run after the menu parts are done. Link to comment Share on other sites More sharing options...
Recommended Posts