MaxKot Posted July 26, 2007 Share Posted July 26, 2007 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 More sharing options...
Vagrant0 Posted July 26, 2007 Share Posted July 26, 2007 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 More sharing options...
MaxKot Posted July 27, 2007 Author Share Posted July 27, 2007 Thank you for advice, but I don't need to count keys. I need to get reference on every key in inventory to make some actions with them. It is not for detecting a certain key. Link to comment Share on other sites More sharing options...
Povuholo Posted July 27, 2007 Share Posted July 27, 2007 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 More sharing options...
Vagrant0 Posted July 27, 2007 Share Posted July 27, 2007 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 More sharing options...
MaxKot Posted July 27, 2007 Author Share Posted July 27, 2007 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 More sharing options...
Vagrant0 Posted July 27, 2007 Share Posted July 27, 2007 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 More sharing options...
MaxKot Posted July 27, 2007 Author Share Posted July 27, 2007 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 More sharing options...
Vagrant0 Posted July 27, 2007 Share Posted July 27, 2007 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 EndPossible, 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 More sharing options...
MaxKot Posted July 28, 2007 Author Share Posted July 28, 2007 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 More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.