Jump to content

Need help with scripted containers... (sorting script)


Guest Messenjah

Recommended Posts

Guest Messenjah

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

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

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
End

Have 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 by Tefnacht
Link to comment
Share on other sites

Guest Messenjah

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

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...