Jump to content

Help with container changed please.


Recommended Posts

Hi all.

So players picks up item from the world, a sound is played, a messagebox pops up once (so in future when player picks up the same item anywhere else he/she doesn't get reminded what it is and what it can be used for), player has item in inventory, The End.

I know it is a OnContainerChanged script just need an example like I said above so I can script it.

Thanking yous!

Link to comment
Share on other sites

Place it locally to the item that will be picked up.

 

 

Sound Property MySoundFX  Auto
{Sound FX to play when this item is picked up}
 
Message PROPERTY MyMessage auto
{Message to show when this item is picked up}
 
bool property DoOnce = false auto
{Checked this -TRUE - to fire only once then goes to a state that does nothing, default FALSE}
 
int instanceID ;used to store sound ref
 
 
auto state waiting
Event OnContainerChanged(ObjectReference newContainer, ObjectReference oldContainer)
         if (newContainer == Game.GetPlayer())
             instanceIDA =  MySoundFX. Play(Game.GetPlayer())
             Utility.wait(2.0)             
             MyMessage.Show()
    endif
          if ( DoOnce )
              DoOnce = TRUE
              GoToState("Done")
     endif
EndEvent
endstate

Link to comment
Share on other sites

Problem with having this locally on the item, it will still run on all new instances of the object. antstubell indicated that they only wanted it to happen once no matter how many new instances are picked up. For this it needs to be on a player alias script using OnItemAdded instead of OnContainerChanged.

 

Example adapting code from maxarturo:

 

 

Scriptname SomeScript Extends ReferenceAlias
 
MiscObject Property MyObject Auto ; <-- change type of property depending upon object type MiscObject is merely used for the example
 
Sound Property MySoundFX  Auto
{Sound FX to play when this item is picked up} 

Message PROPERTY MyMessage auto
{Message to show when this item is picked up} 

bool property DoOnce = false auto
{Checked this -TRUE - to fire only once then goes to a state that does nothing, default FALSE} 

int instanceID ;used to store sound ref
 
Event OnInit()
  AddInventoryEventFilter(MyObject) ; <-- create an event filter so that it only runs when the target object is handled
EndEvent
 
Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
  If akBaseItem as MiscObject == MyObject ; <-- double check to ensure that the picked up item is the one we want to work with.
    If DoOnce == false
      DoOnce = true
      instanceIDA =  MySoundFX. Play(Game.GetPlayer())
      Utility.wait(2.0)
      MyMessage.Show()
    EndIf
  EndIf
EndEvent

 

 

Can take it even further and utilize states as well tho it isn't really necessary. The filter eliminates other objects from triggering and the bool check prevents future instances from displaying the message or playing the sound.

Link to comment
Share on other sites

Problem with having this locally on the item, it will still run on all new instances of the object. antstubell indicated that they only wanted it to happen once no matter how many new instances are picked up. For this it needs to be on a player alias script using OnItemAdded instead of OnContainerChanged.

 

Example adapting code from maxarturo:

 

 

Scriptname SomeScript Extends ReferenceAlias
 
MiscObject Property MyObject Auto ; <-- change type of property depending upon object type MiscObject is merely used for the example
 
Sound Property MySoundFX  Auto
{Sound FX to play when this item is picked up} 

Message PROPERTY MyMessage auto
{Message to show when this item is picked up} 

bool property DoOnce = false auto
{Checked this -TRUE - to fire only once then goes to a state that does nothing, default FALSE} 

int instanceID ;used to store sound ref
 
Event OnInit()
  AddInventoryEventFilter(MyObject) ; <-- create an event filter so that it only runs when the target object is handled
EndEvent
 
Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
  If akBaseItem as MiscObject == MyObject ; <-- double check to ensure that the picked up item is the one we want to work with.
    If DoOnce == false
      DoOnce = true
      instanceIDA =  MySoundFX. Play(Game.GetPlayer())
      Utility.wait(2.0)
      MyMessage.Show()
    EndIf
  EndIf
EndEvent

 

 

Can take it even further and utilize states as well tho it isn't really necessary. The filter eliminates other objects from triggering and the bool check prevents future instances from displaying the message or playing the sound.

Yeap, this also works.
But i made the script to be placed in only one object, the first object that the player encounters and picks up, "if there is a line up on how the player meets the items", if there isn't an objects meet line up and the encounter is random, then IsharaMeradin script is the way to go.
* By "locally" i mean to the object's Reference menu.
Edited by maxarturo
Link to comment
Share on other sites

If the object is already loaded in the save file, a newly added script will not be recognized. Make sure you are testing on a new game or a the very least a save that has not seen the object in question loaded. Beyond that, make sure you are using the correct variation of the script. maxarturo's is intended for the object (best to be put on the pre-placed instance since putting it on the base would cause the issue I indicated). Mine was for a player alias (which is best for use with non-custom objects) and would not work when placed on the object itself (base or instance).

Link to comment
Share on other sites

Putting maxarturo's script on the base object causes the script to always fire, whether DoOnce is checked as TRUE. So as you said if I put it directly onto the object, in the render window, (please define 'locally'), you say it will fire once. This is the best scenario but let me explain the object and its use and availability. Object is a piece of flint to start fires. Player will be prompted very early in the mod that flint is required to start a fire. Upon inspection of the area, player will come across a piece of flint. With all other necessary materials found a fire can be lit. But... we know how players work, the player can not bother to even attempt to light a fire, search for a key, unlock the door and go off exploring. At some point later the player will realise what is required to light a fire and presuming the player skipped all the 'light a fire' scenario - more pieces of flint need to made discoverable. So script needs to fire ONCE on the base object, so wherever an instance of it is found in the world, player gets the message and knows what to do with it ONCE.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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