YouDoNotKnowMyName Posted June 1, 2021 Share Posted June 1, 2021 Good evening everybody! A while ago I asked about using quests (quest stages) as a state machine.Somebody told me that that isn't really possible because you can't decrement quest stages. So I got told to use global variables instead.Alright, but that brings up a very big question: For quest stages, there is a nice "event" that lets you do something when a certain quest stage is reached (OnStageSet).But there is no such thing for global variables. So how would I "do something" (in a scirpt) when a global variable reaches a certian value?Something like "OnStageSet" but for global variables. If there is no such thing, how else should something like this be done?And don't tell me that you can't implement a state machine in a game in the 21st century, because that would just be sad ... Link to comment Share on other sites More sharing options...
DocClox Posted June 1, 2021 Share Posted June 1, 2021 Don't use a global variable. Use a property on a quest. Make it a full property with getter and setter functions, so these are the only way the state variable can be altered. Then, on the setter property, raise a CustomEvent whenever someone changes the value. Anyone who needs to know can register for the event. Link to comment Share on other sites More sharing options...
YouDoNotKnowMyName Posted June 1, 2021 Author Share Posted June 1, 2021 Don't use a global variable. Use a property on a quest. Make it a full property with getter and setter functions, so these are the only way the state variable can be altered.I am sorry for the "n00b" question, but how do I do that?I haven't really been doing much with "functions" in scripts ... Link to comment Share on other sites More sharing options...
DieFeM Posted June 2, 2021 Share Posted June 2, 2021 Don't use a global variable. Use a property on a quest. Make it a full property with getter and setter functions, so these are the only way the state variable can be altered. Then, on the setter property, raise a CustomEvent whenever someone changes the value. Anyone who needs to know can register for the event. +1 Great idea. Link to comment Share on other sites More sharing options...
DocClox Posted June 2, 2021 Share Posted June 2, 2021 (edited) Don't use a global variable. Use a property on a quest. Make it a full property with getter and setter functions, so these are the only way the state variable can be altered.I am sorry for the "n00b" question, but how do I do that?I haven't really been doing much with "functions" in scripts ... Like this: scriptname statemachine extends quest int START_STATE = 0 const int STEADY_STATE = 1 const int END_STATE = 2 const CustomEvent State_Changed int state_variable = START_STATE property StateVariable function get() return state_variable endfunction function set(int value) ; ; transition checking ; if value == END_STATE if state_variable != STEADY_STATE return ; in any other language we'd raise an exception endif ; as it is, there's no way to communcate the error elsif value = STEADY_STATE if state_variable != START_STATE return endif else return ; can't transition to start state, so anything else is an error endif ; ; set the state ; int old_state = state_variable state_variable = value ; ; raise the event ; var[] args = new var[2] args[0] = state_variable args[1] = state_variable SendCustomEvent("State_Changed", args) endfunction endproperty That's for a simple 3-state machine, where START_STATE can only transition to STEADY_STATE and STEADY_STATE can only go to END_STATE. You'll want something more sophisticated, and probably end up putting the state checking in one or more separate functions. The property thing is the way all properties work "under the hood". Saying int property foo autois just shorthand for int _foo int property foo int function get() return _foo endfunction function set(int value) _foo = value endfunction endproperty ... but you can use the long form to add extra processing to getting and or setting the value. Edited June 2, 2021 by DocClox Link to comment Share on other sites More sharing options...
YouDoNotKnowMyName Posted June 19, 2021 Author Share Posted June 19, 2021 Ok, let's say I have a script that has the state machine in it.And I I have an object that I want to enable if the state machine reaches a certain state.I want to do that with a script attached to the "object that should be enabled". How would I do that?There doesn't seem to be an "OnStateSet" event ... Link to comment Share on other sites More sharing options...
dylbill Posted June 19, 2021 Share Posted June 19, 2021 What specifically are you trying to do? You can send and receive custom events with Papyrus: https://www.creationkit.com/fallout4/index.php?title=Custom_Papyrus_Events Link to comment Share on other sites More sharing options...
dylbill Posted June 19, 2021 Share Posted June 19, 2021 I just thought of another option, if you're interested. To actually use States in the StateMachine script with RegisterForRemoteEvent OnBeginState in other scripts. So your StateMachine script on the quest would look like this: Scriptname statemachine extends Quest Event OnInit() Utility.Wait(1) GoToState("StateA") EndEvent State StateA EndState State StateB EndStateThen in your object reference script you can do this: statemachine Property ScriptRef Auto Event OnInit() RegisterForRemoteEvent(ScriptRef, "OnBeginState") EndEvent Event ScriptObject.OnBeginState(ScriptObject akSender, string asOldState) String CurrentState = akSender.GetState() If CurrentState == "StateA" ;do something elseif CurrentState == "StateB" ;do something else Endif EndEventto change states, in another script you can do this: statemachine Property ScriptRef Auto Event SomeEvent() ScriptRef.GoToState("StateA") EndEvent Link to comment Share on other sites More sharing options...
YouDoNotKnowMyName Posted June 19, 2021 Author Share Posted June 19, 2021 Thank you soooo much!That "OnBeginState" event was exactly what I needed! Link to comment Share on other sites More sharing options...
dylbill Posted June 19, 2021 Share Posted June 19, 2021 No problem. Happy modding! Link to comment Share on other sites More sharing options...
Recommended Posts