dizietemblesssma Posted October 16, 2020 Share Posted October 16, 2020 Dumb question from an onlooker, but isn't GoToState("AllDone") supposed to be _after_ the script does stuff? diziet Link to comment Share on other sites More sharing options...
IsharaMeradin Posted October 17, 2020 Share Posted October 17, 2020 Dumb question from an onlooker, but isn't GoToState("AllDone") supposed to be _after_ the script does stuff? dizietNo. The processing thread has to complete that block before it can be released. Despite the script being told to go to a state that does not allow anything to happen when the event gets triggered, the current processing of that code block still gets executed. The state merely prevents any additional event triggers from processing the code. Link to comment Share on other sites More sharing options...
maxarturo Posted October 17, 2020 Share Posted October 17, 2020 (edited) Hi antstubell Sorry for my late response, but i've been so busy with work. Although i have done this, i do admitte that i've never use this logic with 'Light' objects. This needs some testing, but i think using "GetBaseObject()' as dylbill did is the key. @ dizietemblesssma As IsharaMeradin already explain, the "OnTrigger" event will fire multiple times once the object is inside, in contrast with the "OnTriggerEnter/Leave" which will fire only one. In my humble opinion "States" are the most powerful tool that papyrus has, they can serve as 'fail safes' when they are called in an 'empty state' to prevent a reactivation from firing, this is the most common use of states. But aside from that, they have sooooo Many Applications !, you can even make the same script run another function while the initial script function is "Paused", or have different versions of the script inside the same script. And many, many more.... The tricky part with 'States' is that they need a carefully pre constructed script idea before actually writing it, the more complicated the use of 'States' becomes, the easiest is to lose track of 'what does what' and what 'State' is f***** up your whole script, since only one wrong 'State' call will result in chaos. Plus, the biggest drawback with states is that mistakes been made will not trigger a "Compiler Error", and this is a big trap, because your script could be fully functional, but is not working because you have a "TYPO" on a state !!!, or a wrong state call. Have all a nice weekend. Edited October 17, 2020 by maxarturo Link to comment Share on other sites More sharing options...
antstubell Posted October 17, 2020 Author Share Posted October 17, 2020 (edited) Can one of you guys define a STATE and it's purposes/usage in papyrus scripting? @dylbillScript compiles and works but repeatedly fires. Edited October 17, 2020 by antstubell Link to comment Share on other sites More sharing options...
IsharaMeradin Posted October 17, 2020 Share Posted October 17, 2020 Most state usage is done to block something from happening again. A bool or some other variable could be used to block the inside code from running, but the event would still be triggered and take up some processing time to determine that it isn't supposed to do anything. A state containing the same event but without any code shortens the processing time considerably. Consider the following example: Event OnActivate(ObjectReference akActivator) Debug.Notification("You pressed a button!) EndEvent This will run every time the object is activated Event OnActivate(ObjectReference akActivator) GoToState("DoNothing") Debug.Notification("You pressed a button!) EndEvent State DoNothing Event OnActivate(ObjectReference akActivator) EndEvent EndState This will display the text on the first activation and then never display it again. Other times states are used to do something different for the same event. A typical situation is one where interaction with an object triggers a bunch of behind the scenes work (perhaps scanning player inventory for items to put on display). Switching states prior to starting the scan lets the author display a busy message to the player should they try to use the object again prior to completing the initial scan. Link to comment Share on other sites More sharing options...
antstubell Posted October 17, 2020 Author Share Posted October 17, 2020 (edited) What's the difference when a state ("IsInBrackets") like that and not.What are the states doing in this short script and why do they have different names - busy, done, waiting? auto state waitingEvent OnTriggerEnter(ObjectReference akActionRef)if akActionRef == PlayerRefGotoState("Busy")xMarkerSpell.placeAtMe(MyMagFX)xMarkerSpell.placeAtMe(MyFX)xMarkerSpell.placeAtMe(myFXShader)Utility.Wait(Delay)EnObj1.Enable()MySND.Play(SNDHere)GoToState("Done")EndIfENDEVENTENDSTATE Edited October 17, 2020 by antstubell Link to comment Share on other sites More sharing options...
dylbill Posted October 17, 2020 Share Posted October 17, 2020 In short, if you have two or more states in your script, the only events that will run are the events in the state that the script is currently in. So if you did this: auto state waiting ;the state the script is in when first initialized Event OnTriggerEnter(ObjectReference akActionRef) if akActionRef == PlayerRef GotoState("Busy") xMarkerSpell.placeAtMe(MyMagFX) xMarkerSpell.placeAtMe(MyFX) xMarkerSpell.placeAtMe(myFXShader) Utility.Wait(Delay) EnObj1.Enable() MySND.Play(SNDHere) GoToState("Done") EndIf EndEvent EndState State Busy Event OnTriggerEnter(ObjectReference akActionRef) Debug.Notification("Busy") EndEvent EndState State Done EndStateThe script starts in the waiting state. When the player enters the trigger box, it goes to the busy state while processing the rest of the code. If something enters the trigger box while it's still processing, you'll get the "Busy" notification and the code in the Waiting state won't run again. Once it's done processing and goes to the Done state, then the events and code won't run at all anymore. Link to comment Share on other sites More sharing options...
IsharaMeradin Posted October 17, 2020 Share Posted October 17, 2020 What's the difference when a state ("IsInBrackets") like that and not. The default state for a script is called the empty state. Every function or event not inside a specified state is considered to be inside the empty state. Calling GoToState("") tells the script to go to the empty state. Properties are always defined in the empty state even if used inside of other states. Declaring a state is as simple as the following:State NameOfStateEndState NameOfState will be recognized by papyrus automatically as the state's name string and will go to that state when GoToState("NameOfState") is used. This page may give you some further insight into states: https://www.creationkit.com/index.php?title=States_(Papyrus) Link to comment Share on other sites More sharing options...
antstubell Posted October 18, 2020 Author Share Posted October 18, 2020 (edited) I think I'm getting it. A state prevents other stuff from happening while a script is processing code. If I changed the last state GoToState ("Done") in the above script to GoToState ("Waiting") would this then set up the trigger box to be fired again? BTW the script that was posted by dylbill repeatedly fires. The debug message reappears on screen all the time. Could I just Self.Disable() or Self.Delete() the script/trigger box to stop this? EDIT: And the oil trap doesn't self activate. Edited October 18, 2020 by antstubell Link to comment Share on other sites More sharing options...
dylbill Posted October 18, 2020 Share Posted October 18, 2020 Yes, that would set up the trigger box to be fired again. Looking at some vanilla scripts, it looks like you have to put the events with nothing in them to block them. Also I looked at the TrapOilPool vanilla script, and there's no OnActivate event, so instead in the script try this: Light Property MyTorch Auto ObjectReference Property MyOilPool Auto Bool Check = False EVENT OnTrigger(ObjectReference akActionRef) If Check == False Form Base = akActionRef.GetBaseObject() If Base as Light If Base == MyTorch Check = True GoToState("AllDone") TrapOilPool OilPoolScript = MyOilPool as TrapOilPool OilPoolScript.gasExplode(Self) debug.notification("Whoosh!") ; Or whatever else you intend on doing to start the fire Endif EndIf Endif ENDEVENT STATE AllDone Event OnTrigger(ObjectReference akActionRef) Endevent ENDSTATEI also put a bool in to be doubly sure it only fires once. Link to comment Share on other sites More sharing options...
Recommended Posts