Jump to content

[LE] Script to Replace an Inventory Item With Another?


McTAL

Recommended Posts

I considered a single script but given that not all functions / events are called on items when in a container / inventory, I prefer to move as much as possible off of the individual items. I'd rather have something that does work than beat myself over the head trying to figure out why something does not work. If someone wants to test the single script and determine that it actually works and share the way to do it, that would probably be for the best.

Link to comment
Share on other sites

Ishara maybe next is working, I didn't test it in game. In fact quest is required, this script should be adjusted for extending as ReferenceAlias.

 

LinenObjectScript

 

Scriptname LinenObjectScript extends ObjectReference
; https://forums.nexusmods.com/index.php?/topic/7267376-script-to-replace-an-inventory-item-with-another/
; sample script by IsharaMeradin, suggestion for one script by foamyesque

; huggibee wrote: "looking for .. help with creating a script that would remove a miscobject from an inventory
;                  after set amount of time and replace it with another miscobject."

; *** Note: This script is for both linen, washed and unwashed! ***
;----------------------------------------------------------------------
;; if self is the clean Linen
;  MiscObject PROPERTY otherLinen auto    ; fill with unwashed linen here

;; if self is the dirty Linen
;  MiscObject PROPERTY otherLinen auto    ; fill with washed linen here
;----------------------------------------------------------------------

  MiscObject PROPERTY otherLinen auto     ; fill with the baseobject like samples above

  Float f = 8.0        ; time of ingame waiting (8 hours)
  Actor myOwner        ; make owner of this linen persistent


; -- EVENTs -- 3 + 2 = 5

EVENT OnCellLoad()
    Debug.Trace(" OnCellLoad() - has been reached.. " +self)        ; info only
ENDEVENT

EVENT OnEquipped(Actor akActor)
    Debug.Trace(" OnEquipped() - has been reached.. " +self)        ; info only
ENDEVENT

EVENT OnUnEquipped(Actor akActor)
    Debug.Trace(" OnUnEquipped() - has been reached.. " +self)      ; info only
ENDEVENT


EVENT OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
    UnRegisterForUpdateGameTime()             ; unregister first

IF !(akNewContainer as Actor)
    myOwner = None                            ; clear owner, if any
    RETURN    ; - STOP - removed to the void /or/ dropped to the ground /or/ put into a container
ENDIF
;---------------------
; we put into an actors inventory
    myOwner = akNewContainer as Actor
    RegisterForSingleUpdateGameTime(f)        ; start waiting
;;; Utility.WaitGameTime(f)
;;; myF_SwitchLinen()
ENDEVENT


EVENT OnUpdateGameTime()
    myF_SwitchLinen()
ENDEVENT


; -- FUNCTION --

;-------------------------
FUNCTION myF_SwitchLinen()
;-------------------------
IF ( !myOwner )
    RETURN    ; - STOP -    mod uninstalled /or/ stored actor is invalid
ENDIF
;---------------------
    myOwner.RemoveItem(self as Form, 1)   ; https://www.creationkit.com/index.php?title=RemoveItem_-_ObjectReference
    myOwner.AddItem(otherLinen as Form, 1)

; maybe next two lines are useless !? 
    self.DisableNoWait()        ; disable the removed linen
    self.Delete()               ; and remove it from the game
ENDFUNCTION

 

 

 

Happy new Year to all. Freedom all over the world.

Edited by ReDragon2013
Link to comment
Share on other sites

Hello all -- thanks so much for all your help! thus far I've been trying for the life of me these past few days in my free time to get Ishara's lovely script to work, but I just can't. It compiles just fine, and the properties line up. I apply the script to both the clean and dirty linens, and management quest is set to run at the start of the game -- but no dice. I'm not quite sure what it is I'm doing wrong? Any suggestions?

Link to comment
Share on other sites

It may very well be that the OnUpdate event won't run because the object is within the player inventory. I cannot say for certain as I avoid placing scripts directly on objects that will be in the player's inventory whenever possible.

 

Another possible script route would be to create a player alias on the management quest and use a single script there. Instead of OnContainerChanged, the event would be OnItemAdded. An Inventory Event Filter would be a good idea too. Something like:

 

 

 

ScriptName LinenSwapScriptPlayerAlias Extends ReferenceAlias

MiscObject Property CL Auto ; clean linens
MiscObject Property DL Auto ; dirty linens
Bool isDirty = false
Actor PlayerRef

Event OnInit()
  AddInventoryEventFilter(CL)               ; add filter for clean item
  AddInventoryEventFilter(DL)               ; add filter for dirty item
  PlayerRef = Self.GetReference() as Actor  ; cast the object reference that this alias points to as an actor and store it.
                                            ; if this give compile issues, just change to Game.GetPlayer()
  RegisterForSingleUpdateGameTime(8)        ; register for an update in 8 game hours
    ; place a copy of starting linen item in the player alias inventory section
    ; thus when quest is started, the player automatically gets the first item and thus we register for the update here
EndEvent

Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
  If akBaseItem as MiscObject == CL     ; is the added item clean linens
    PlayerRef.RemoveItem(DL)            ; remove the dirty item
    isDirty = false                     ; indicate that the current item is clean
    RegisterForSingleUpdateGameTime(8)  ; register for an update in 8 game hours
  ElseIf akBaseItem as MiscObject == DL ; is the added item dirty linens
    PlayerRef.RemoveItem(CL)            ; remove the clean item
    isDirty = true                      ; indicate that current linen are dirty
    RegisterForSingleUpdateGameTime(8)  ; register for an update in 8 game hours
  EndIf
EndEvent

Event OnUpdateGameTime()              ; timer is up
  If isDirty == false                 ; are current linens clean
    PlayerRef.AddItem(DL)             ; add the dirty linen
  ElseIf isDirty == true              ; are current linens dirty
    PlayerRef.AddItem(CL)             ; add the clean linen
  EndIf
  RegisterForSingleUpdateGameTime(8)  ; register for an update in 8 game hours
EndEvent

 

 

Downside that I foresee is that the player will still be able to manually remove the item from inventory. This may or may not be desired. If it is not, you may wish to create aliases of both objects and change the property type for the two objects from MiscObject to ReferenceAlias and point to the specific aliases added to your quest. Thus as quest aliases you can flag the check box to indicate that they are quest objects that cannot be manually moved from inventory.

Link to comment
Share on other sites

Thank you very much for your help and timely reply! I well get right on to working in this script right away --- but with this new script, it is no longer applied to npc inventories anymore, correct?

Link to comment
Share on other sites

Thank you very much for your help and timely reply! I well get right on to working in this script right away --- but with this new script, it is no longer applied to npc inventories anymore, correct?

 

That would be correct. However, you could create an alias for each unique NPC and do the same thing. Highly doubt you'd need to be that concerned about randomly spawned bandits and such. But that would also leave your mod not working with mod added NPCs. And it may be a bit weird to encounter some NPCs with your system and some without.

Link to comment
Share on other sites

All things considered I myself would approach this by adding the script to the clean cotton.

With a one time timer triggered when added to inventory (or equipped) that simply adds the dirty cotton then remove itself.

That approach would solve 90% of any problems not considered.

 

Jucoking script is very close to how I would do it. (btw, that is more phytocode than actual code but his concept is sound).

Edited by NexusComa
Link to comment
Share on other sites

 

Thank you very much for your help and timely reply! I well get right on to working in this script right away --- but with this new script, it is no longer applied to npc inventories anymore, correct?

 

That would be correct. However, you could create an alias for each unique NPC and do the same thing. Highly doubt you'd need to be that concerned about randomly spawned bandits and such. But that would also leave your mod not working with mod added NPCs. And it may be a bit weird to encounter some NPCs with your system and some without.

 

 

I wonder about adding magic effects? You could run your timer through the effect's duration. Failing that you could avoid needing to specify an alias for each unique NPC if you had some sort of registration call-in to a generic pool of aliases and just fill the first available.

(Also, with the OnUpdate approaches, they should probably be done with OnUpdateGameTime() instead, to account for things like fast travel, sleep, and waiting)

Link to comment
Share on other sites

 

 

Thank you very much for your help and timely reply! I well get right on to working in this script right away --- but with this new script, it is no longer applied to npc inventories anymore, correct?

 

That would be correct. However, you could create an alias for each unique NPC and do the same thing. Highly doubt you'd need to be that concerned about randomly spawned bandits and such. But that would also leave your mod not working with mod added NPCs. And it may be a bit weird to encounter some NPCs with your system and some without.

 

 

I wonder about adding magic effects? You could run your timer through the effect's duration. Failing that you could avoid needing to specify an alias for each unique NPC if you had some sort of registration call-in to a generic pool of aliases and just fill the first available.

(Also, with the OnUpdate approaches, they should probably be done with OnUpdateGameTime() instead, to account for things like fast travel, sleep, and waiting)

 

I suppose it might be possible. Not sure.

 

In theory, one could track all NPCs that get the item(s) added via a formlist and use a single global game timer. The formlist could be cycled through and have all NPCs swap their items at the same time. But the processing time would increase as more NPCs are added to the list. Checks would be needed to bypass any that may have been killed etc etc...

 

Nonetheless, it can sometimes be a good thing to have one setup dedicated to the player and a different dedicated to NPCs. After all, the player many times needs additional or different conditions than the NPCs would require.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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