Jump to content

"For all items in inventory" cycle OBSE script help


MaxKot

Recommended Posts

I need to detect all keys in players inventory, so I made the code below. But it detects no keys. It looks like CurItemRef is wrong because GetWeight function return 0 for all items in inventory and GetBaseObject crashes the script.

 

long PlayerItemsNum
long CurItemNum
ref CurItemRef

Begin MenuMode 1002		
   Set Self to GetSelf

   Set PlayerItemsNum to Player.GetNumItems    ; for all items in players 
   Set CurItemNum to 0                         ;     invetory do {
   SaveIP 1                                    ;
   if (CurItemNum < PlayerItemsNum)            ;

       Set CurItemRef to Player.GetInventoryObject CurItemNum
       If CurItemRef.IsKey == 1
           Message "Debug: Item number %g is a key" CurItemNum
       Endif
																		
   Set CurItemNum to CurItemNum + 1
   RestoreIP 1                                 ; } for all items in players
   Endif                                       ;     invetory
End

Link to comment
Share on other sites

Getself doesn't work on inventory items. Ignore OBSE, just make a quest script using player.getitemcount xxxx 1 to detect if the player has the keys. Then doing whatever it is you want done. OBSE is only useful for highly complicated scripting projects which aren't possible without using one of the funtions, people who aren't totally familiar with scripting shouldn't use it. This is nothing against you, it is just my feeling that people tend to get caught up in using OBSE functions and ignoring standard methods which usually end up working better, if at all.
Link to comment
Share on other sites

Vagrant0 said it, the GetSelf function won't work. I used it on an item that couldn't be picked up. It worked, but would give me an error message every time I booted the CS. And it'll screw up when I forced the player to pick it up.

 

So since GetSelf and GetItemVount won't work, we'll have to find another way. But for that we should probably know more about these actions the keys will be used for.

Link to comment
Share on other sites

I need to get reference on every key in inventory to make some actions with them.

Then it cannot be done in any way, shape, or form, not with OBSE, not without OBSE, not even with direct hex editing of the game while it's running. Inventory items cannot be directly referenced since they don't have any sort of reference ID until they are dropped in world, and then that ID is no longer valid when they get picked up. They can be indirectly referenced if you know the specific form ID for the base object, but with that you're essentially limited to usage within conditions or adding/removing that item type. I mentioned checking what keys are in the players inventory since all the keys exist as seperate entities and are defined individually within the CS, so essentially you already have the ID of all the keys on hand, just need to check if the player has them.

 

If you could care to explain what you are trying to accomplish, there may be other ways of doing it which are actually possible.

Link to comment
Share on other sites

I like KeyChain mod ( http://tessource.net/files/file.php?id=3409 ). But it cant hide keys from mods, it has inventory delay problem in Automatic mode and it replaces localized names of keys with english ones.

So I want to make a mod with same functionality but without these problems.

P.S. GetSelf function is not necessary. It will be used to prevent Keychain from removing itself from inventory. But it can be replaced with a base object check.

Link to comment
Share on other sites

I like KeyChain mod ( http://tessource.net/files/file.php?id=3409 ). But it cant hide keys from mods, it has inventory delay problem in Automatic mode and it replaces localized names of keys with english ones.

So I want to make a mod with same functionality but without these problems.

P.S. GetSelf function is not necessary. It will be used to prevent Keychain from removing itself from inventory. But it can be replaced with a base object check.

You really can't, atleast not in any way I can think of. The key names are tied to the language because they have been changed in some way (probably adding a needed script to those keys, or replacing them with modded versions). The reason why there's a delay is because there are scripts running to determine what keys the player has against what keys they need to open a certain door... since this is the only way to do this, you cannot get rid of the delay.

Link to comment
Share on other sites

I understood my error in the script, remade it with use of Object IDs instead of trying to get references and my mod appears to work as it should now.

 

But I'm unsure if this code is safe. Will use of AddItem function for every key every time you enter inventory will cause some kind of Shivering Isles "Form ID Reference Bug" and break your game?

 

scn MKKeychainScript

; /* ============================================================================= */
; /* ================================= Variables ================================= */
; /* ============================================================================= */

short GameOnce			; Variable to make GameMode script run once on inventory exit
short MenuOnce			; Variable to make MenuMode script run once on inventory enter

short ClickCount		; Counts clicks on Keychain in inventory

long PlayerItemsNum		; Total number of items in players inventory
long CurItemNum			; Number of currently processing item
ref CurItemObjID		; Reference on currently processind item
long CurItemCount

; /* ============================================================================== */
; /* ==================================== Code ==================================== */
; /* ============================================================================== */

; /*______________________________________________________________________________ */
Begin GameMode

if (GameOnce == 0)
	MKKeychainContainerRef.RemoveAllItems Player
	Set MenuOnce to 1
	Set GameOnce to 1
Endif

End

; /*______________________________________________________________________________ */
Begin MenuMode 1002

if (MenuOnce == 1)

	Set ClickCount to 0

	if (MKInChain == 1)

		Message " "
		Message " "
		Set PlayerItemsNum to Player.GetNumItems	; for all items in players
		Set CurItemNum to 0				;	invetory do {
		SaveIP 1					;
		if (CurItemNum < PlayerItemsNum)		;

			Set CurItemObjID to Player.GetInventoryObject CurItemNum
			If (IsKey CurItemObjID) && (CurItemObjID != MKKeychain)
				;;Message "Debug: Item number %g = is a key and not keychain." CurItemNum
				Set CurItemCount to player.GetItemCount CurItemObjID
				Player.RemoveItem CurItemObjID CurItemCount
				MKKeychainContainerRef.AddItem CurItemObjID CuritemCount
			Endif

		Set CurItemNum to CurItemNum + 1
		RestoreIP 1					; } for all items in players
		Endif						;	invetory
	EndIf

	Set MenuOnce to 0
	Set GameOnce to 0

Endif

End

; /*______________________________________________________________________________ */
Begin OnEquip

Set ClickCount to ClickCount + 1

if ClickCount > 1

	if (MKInChain == 1)
		Set MKInChain to 0  ; Should add return keys to inventory code here
	Else
		Set MKInChain to 1  ; Should add hide keys code here
	Endif
	Set ClickCount to 0

Endif

End

; /*______________________________________________________________________________ */
Begin OnDrop
MKKeychainContainerRef.RemoveAllItems Player
Set MKInChain to 0
End

; /*______________________________________________________________________________ */
Begin OnSell
MKKeychainContainerRef.RemoveAllItems Player
Set MKInChain to 0
End

Link to comment
Share on other sites

I understood my error in the script, remade it with use of Object IDs instead of trying to get references and my mod appears to work as it should now.

 

But I'm unsure if this code is safe. Will use of AddItem function for every key every time you enter inventory will cause some kind of Shivering Isles "Form ID Reference Bug" and break your game?

 

scn MKKeychainScript

; /* ============================================================================= */
; /* ================================= Variables ================================= */
; /* ============================================================================= */

short GameOnce			; Variable to make GameMode script run once on inventory exit
short MenuOnce			; Variable to make MenuMode script run once on inventory enter

short ClickCount		; Counts clicks on Keychain in inventory

long PlayerItemsNum		; Total number of items in players inventory
long CurItemNum			; Number of currently processing item
ref CurItemObjID		; Reference on currently processind item
long CurItemCount

; /* ============================================================================== */
; /* ==================================== Code ==================================== */
; /* ============================================================================== */

; /*______________________________________________________________________________ */
Begin GameMode

if (GameOnce == 0)
	MKKeychainContainerRef.RemoveAllItems Player
	Set MenuOnce to 1
	Set GameOnce to 1
Endif

End

; /*______________________________________________________________________________ */
Begin MenuMode 1002

if (MenuOnce == 1)

	Set ClickCount to 0

	if (MKInChain == 1)

		Message " "
		Message " "
		Set PlayerItemsNum to Player.GetNumItems	; for all items in players
		Set CurItemNum to 0				;	invetory do {
		SaveIP 1					;
		if (CurItemNum < PlayerItemsNum)		;

			Set CurItemObjID to Player.GetInventoryObject CurItemNum
			If (IsKey CurItemObjID) && (CurItemObjID != MKKeychain)
				;;Message "Debug: Item number %g = is a key and not keychain." CurItemNum
				Set CurItemCount to player.GetItemCount CurItemObjID
				Player.RemoveItem CurItemObjID CurItemCount
				MKKeychainContainerRef.AddItem CurItemObjID CuritemCount
			Endif

		Set CurItemNum to CurItemNum + 1
		RestoreIP 1					; } for all items in players
		Endif						;	invetory
	EndIf

	Set MenuOnce to 0
	Set GameOnce to 0

Endif

End

; /*______________________________________________________________________________ */
Begin OnEquip

Set ClickCount to ClickCount + 1

if ClickCount > 1

	if (MKInChain == 1)
		Set MKInChain to 0  ; Should add return keys to inventory code here
	Else
		Set MKInChain to 1  ; Should add hide keys code here
	Endif
	Set ClickCount to 0

Endif

End

; /*______________________________________________________________________________ */
Begin OnDrop
MKKeychainContainerRef.RemoveAllItems Player
Set MKInChain to 0
End

; /*______________________________________________________________________________ */
Begin OnSell
MKKeychainContainerRef.RemoveAllItems Player
Set MKInChain to 0
End

Possible, it would probably also cause massive message spam since each time keys were added there would be a message saying what key was added. Also, I thought the idea was to get around having keys cluttering up the inventory.

Link to comment
Share on other sites

Message spam is avoided with two Message " ". And should prevent keys from cluttering up the inventory. It should remove keys when you enter the inventory and bring them back when you leave. So you can't see pile of keys but you can open doors, chests etc.
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

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