New Papyrus Thread: Code not executing.

Post » Wed Jun 20, 2012 4:53 pm

Ok, so trying to work with states now. Have a question. If I put an OnInit() event in a state, will the Event trigger whenever that state becomes the active state?

Edit: Answered the question by trying it. Nope.

Also found the events related to states. Including OnBeginState() and OnEndState()
User avatar
Chloe Yarnall
 
Posts: 3461
Joined: Sun Oct 08, 2006 3:26 am

Post » Wed Jun 20, 2012 9:32 am

Ok, so trying to work with states now. Have a question. If I put an OnInit() event in a state, will the Event trigger whenever that state becomes the active state?

Edit: Answered the question by trying it. Nope.

Also found the events related to states. Including OnBeginState() and OnEndState()

States control what functions and events are used...if you have an OnInit() event in a state, it will replace the OnInit() event in all other states, including the empty state.
User avatar
Lynette Wilson
 
Posts: 3424
Joined: Fri Jul 14, 2006 4:20 pm

Post » Wed Jun 20, 2012 2:58 pm

States control what functions and events are used...if you have an OnInit() event in a state, it will replace the OnInit() event in all other states, including the empty state.
OnInit is an exception to that rule, it is not allowed to be declared within an state other than the default (called empty for some reason) state.
User avatar
Albert Wesker
 
Posts: 3499
Joined: Fri May 11, 2007 11:17 pm

Post » Wed Jun 20, 2012 8:35 am

Can't set my global variable for some reason. I created a global variable named MOD1QCombatPhase, I've assigned it as a property and everything, for some reason though I can't change it through code or the console (which the wiki says I should be able to do). I am using MOD1QCombatPhase.Setvalue(1)


EDIT: Also, just FYI, the Global's "Constant" checkbox is NOT checked.
User avatar
Baylea Isaacs
 
Posts: 3436
Joined: Mon Dec 25, 2006 11:58 am

Post » Wed Jun 20, 2012 1:09 pm

So according to GetGlobalValue, my global is actually setting to the right value, but there is some kind of fault in this code right here:

state activestateEvent OnBeginState()  debug.notification("entered active state");  registerforsingleupdate(5);endeventevent onupdate()  if (combatphase.getvalue() == 0)   ;Do Nothing: Combat Has Not Started   debug.notification ("In activestate. Phase =" + combatphase.getvalue())   gotostate ("activestate")  elseif (combatphase.getvalue() == 1)   gotostate ("combatstate");  elseif (combatphase.getvalue() == 2)   gotostate ("flyingstate1");  elseif (combatphase.getvalue() == 3)   gotostate ("flyingstate2");  else   gotostate ("activestate")  endifendeventendstate

Any ideas?

EDIT: combatphase is a globalvariable property linked to my global. (Yes the property is filled.)

Also, the debug.notification ("In activestate. Phase =" + combatphase.getvalue()) is returning a value of 0, even though GetGlobalValue (in the console says that the value was properly set to 1) this tells me that combatphase.getvalue() isn't properly retrieving the value of combatphase(or MOD1QCombatPhase)
User avatar
yermom
 
Posts: 3323
Joined: Mon Oct 15, 2007 12:56 pm

Post » Wed Jun 20, 2012 1:33 am

Well you're already in ActiveState if you're using this OnUpdate(), so Setstate("Activestate") is redundant...Just put a RegisterForSingleUpdate in there instead.

(OnBeginState does NOT fire if you're already in that state!)
User avatar
cassy
 
Posts: 3368
Joined: Mon Mar 05, 2007 12:57 am

Post » Wed Jun 20, 2012 4:08 am

Well you're already in ActiveState if you're using this OnUpdate(), so Setstate("Activestate") is redundant...Just put a RegisterForSingleUpdate in there instead.

(OnBeginState does NOT fire if you're already in that state!)

I'm well aware Redwood... I wanted it to fire again, or I would have written it differently.
User avatar
Anne marie
 
Posts: 3454
Joined: Tue Jul 11, 2006 1:05 pm

Post » Wed Jun 20, 2012 12:35 pm

I'm well aware Redwood... I wanted it to fire again, or I would have written it differently.

Um...if you knew it wouldn't fire again by going back to that state, then why did you write it so you went back to that state? Your statement is self-contradictory. The only way to get it to fire again would be to leave the state and then return.
User avatar
Latino HeaT
 
Posts: 3402
Joined: Thu Nov 08, 2007 6:21 pm

Post » Wed Jun 20, 2012 10:19 am

Um...if you knew it wouldn't fire again by going back to that state, then why did you write it so you went back to that state? Your statement is self-contradictory. The only way to get it to fire again would be to leave the state and then return.

No... if you use gotostate("activestate") it starts the state over from the beginning. Thus calling the OnBeginState() event. I wanted this. I wanted to see my debug message again.

EDIT: What you're saying is that it is redundant and that if you call gotostate("activestate") while in active state, the begin state even will not fire. this is incorrect. I have seen it fire at least 100 times. With my own eyes.
User avatar
Lou
 
Posts: 3518
Joined: Wed Aug 23, 2006 6:56 pm

Post » Wed Jun 20, 2012 1:24 am

Well then the wiki is wrong...but you can still just call RegisterForSingleUpdate directly...
User avatar
sophie
 
Posts: 3482
Joined: Fri Apr 20, 2007 7:31 pm

Post » Wed Jun 20, 2012 6:07 am

Well then the wiki is wrong...but you can still just call RegisterForSingleUpdate directly...

I know. Just FYI, I'm not trying to sound attacking or condescending in any way. But also, I can find nothing on the state wiki page to support what you are saying.
User avatar
Petr Jordy Zugar
 
Posts: 3497
Joined: Tue Jul 03, 2007 10:10 pm

Post » Wed Jun 20, 2012 8:08 am

Also, just so you guys can see: I have updated my code.


Spoiler
Scriptname MOD1AazCombatScript extends Actor  Quest Property MOD1QPart1 AutoGlobalVariable Property combatphase  Auto  ;Event OnLoad();	Registerforupdate(120);EndEventEvent OnInit()endeventauto state waitingstate		Event OnInit()		registerforupdate(5);Polling	endevent	Event OnUpdate()		if (MOD1QPart1.GetStage() == 29)			unregisterforupdate();			debug.notification("exiting waiting state");			gotostate ("activestate")		else			debug.notification("in waiting state" + MOD1QPart1.GetStage())		endif	endeventendstatestate activestate	Event OnBeginState()		debug.notification("entered active state");		registerforsingleupdate(5);	endevent	event onupdate()		if (combatphase.getvalue() == 1)			gotostate ("combatstate");		elseif (combatphase.getvalue() == 2)			gotostate ("flyingstate1");		elseif (combatphase.getvalue() == 3)			gotostate ("flyingstate2");		else			gotostate ("activestate")			debug.notification ("In activestate. Phase =" + combatphase.getvalue())		endif	endeventendstatestate combatstate	Event OnBeginState()		setallowflying(false);		startcombat(game.getplayer());		registerforsingleupdate(10);	endevent	event onupdate()		gotostate ("activestate")	endeventendstatestate flyingstate1	event onbeginstate()		setallowflying(true)		stopcombat()	endeventendstatestate flyingstate2	event onbeginstate()		setallowflying(true)		stopcombat()	endeventendstate

Still having a problem. For some reason combatphase.getvalue() isn't returning the true value of the global variable. No clue why.
User avatar
Shiarra Curtis
 
Posts: 3393
Joined: Thu Jan 04, 2007 3:22 pm

Post » Wed Jun 20, 2012 1:53 am

As far as papyrus is concerned a GlobalVariable is always a float. Therefore proper checks would be against another float; or alternatively (and worse, because of the added run-time cost of calling a papyrus function wrapper) using GetValueInt.

Also since papyrus is multi-threaded, meaning your script can stop and continue at any point in time. And therefore the value of the global can change in-between stopping and continuing. So, you should only call GetValue(Int) once and assign it to a local variable.
Maybe make it in integer local, because it needs to be casted only once, this way.
For the same reason use a local to store the current quest stage.

Ohh, I see you have an OnInit event inside an state... that's not allowed -- the script won't compile.

This compiles, and I removed the redundant second flying state.
Spoiler
scriptname MOD1AazCombatScript extends ActorQuest property MOD1QPart1 autoGlobalVariable property CombatPhase autoevent OnInit()	RegisterForUpdate(5.0)endeventauto state Waiting	event OnUpdate()		int currentStage = MOD1QPart1.GetCurrentStageID()		if (currentStage == 29)			UnregisterForUpdate()			GoToState("Active")			Debug.Notification("exiting waiting state")		else			Debug.Notification("in waiting state" + currentStage)		endif	endeventendstatestate Active	event OnBeginState()		Debug.Notification("entered active state")		RegisterForSingleUpdate(5.0)	endevent	event OnUpdate()		int phase = CombatPhase.GetValue() as int		if (phase == 1)			GoToState("Combat")		elseif (phase == 2 || phase == 3)			GoToState("Flying")		else			GoToState("Active")			Debug.Notification("In active. Phase =" + phase)		endif	endeventendstatestate Combat	event OnBeginState()		SetAllowFlying(false)		StartCombat(Game.GetPlayer())		RegisterForSingleUpdate(10.0)	endevent	event OnUpdate()		GoToState("Active")	endeventendstatestate Flying	event OnBeginState()		SetAllowFlying(true)		StopCombat()	endeventendstate
User avatar
Blackdrak
 
Posts: 3451
Joined: Thu May 17, 2007 11:40 pm

Post » Wed Jun 20, 2012 8:50 am

As far as papyrus is concerned a GlobalVariable is always a float. Therefore proper checks would be against another float; or alternatively (and worse, because of the added run-time cost of calling a papyrus function wrapper) using GetValueInt.

Also since papyrus is multi-threaded, meaning your script can stop and continue at any point in time. And therefore the value of the global can change in-between stopping and continuing. So, you should only call GetValue(Int) once and assign it to a local variable.
Maybe make it in integer local, because it needs to be casted only once, this way.
For the same reason use a local to store the current quest stage.

Ohh, I see you have an OnInit event inside an state... that's not allowed -- the script won't compile.

This compiles, and I removed the redundant second flying state.
Spoiler
scriptname MOD1AazCombatScript extends ActorQuest property MOD1QPart1 autoGlobalVariable property CombatPhase autoevent OnInit()	RegisterForUpdate(5.0)endeventauto state Waiting	event OnUpdate()		int currentStage = MOD1QPart1.GetCurrentStageID()		if (currentStage == 29)			UnregisterForUpdate()			GoToState("Active")			Debug.Notification("exiting waiting state")		else			Debug.Notification("in waiting state" + currentStage)		endif	endeventendstatestate Active	event OnBeginState()		Debug.Notification("entered active state")		RegisterForSingleUpdate(5.0)	endevent	event OnUpdate()		int phase = CombatPhase.GetValue() as int		if (phase == 1)			GoToState("Combat")		elseif (phase == 2 || phase == 3)			GoToState("Flying")		else			GoToState("Active")			Debug.Notification("In active. Phase =" + phase)		endif	endeventendstatestate Combat	event OnBeginState()		SetAllowFlying(false)		StartCombat(Game.GetPlayer())		RegisterForSingleUpdate(10.0)	endevent	event OnUpdate()		GoToState("Active")	endeventendstatestate Flying	event OnBeginState()		SetAllowFlying(true)		StopCombat()	endeventendstate

I appreciate the response and your help, but:

#1 Why does mine compile properly as it it written if OnInt() is Invalid for a state?
#2 The second flying state isn't entirely redundant. It appears redundant because I havn't finished the code yet. There will be different code blocks underneath each flying state.

Thanks, I'll get back to you. This will probably help a lot. I'll have to test it first though.


EDIT: Also, does the "as int" in "int phase = CombatPhase.GetValue() as int" tell it to cast combatphase as an int? I believe that it does, just thought I'd confirm.
User avatar
Steve Smith
 
Posts: 3540
Joined: Sat Jun 30, 2007 10:47 am

Post » Wed Jun 20, 2012 6:45 am

#1 Why does mine compile properly as it it written if OnInt() is Invalid for a state?
Because you have two separate OnInit declarations inside your script, and only one will ever execute; the empty one.
At least I think so, I'm gonna test this and get back to you. I know, see later post.
User avatar
Thomas LEON
 
Posts: 3420
Joined: Mon Nov 26, 2007 8:01 am

Post » Wed Jun 20, 2012 3:28 pm

Unfortunately the result did not change. still getting an output of zero with this edited code:

Sorry CK is bugging on me ATM. Will post the code in a min.
User avatar
lilmissparty
 
Posts: 3469
Joined: Sun Jul 23, 2006 7:51 pm

Post » Wed Jun 20, 2012 5:21 pm

Like I thought, it's a bug. You can only have on OnInit event block. The compiler allows multiple declarations as long as they are withing separate states, but only the default one, declared in the empty state, will get executed.

Here's my test script
Spoiler
scriptname XsTest extends Quest;////////////////////////////////////////////////////////////////////////////// Events/////////////////////////////////////////////////////////////////////////////;event OnInit()	Notify("OnInit", "Register Update")	RegisterForSingleUpdate(2.0)endeventevent OnReset()	Notify("OnReset", "Nothing")endeventevent OnUpdate()	Notify("OnUpdate", "GoToState(Other)")	GoToState("Other")endevent;////////////////////////////////////////////////////////////////////////////// States/////////////////////////////////////////////////////////////////////////////;state Other	event OnBeginState()		Notify("OnBeginState", "Register Update")		RegisterForSingleUpdate(2.0)	endevent	event OnEndState()		Notify("OnEndState", "Nothing")	endevent	event OnInit()		Notify("OnInit", "Register Update")		RegisterForSingleUpdate(2.0)	endevent	event OnUpdate()		Notify("OnUpdate", "Reset")		Reset()	endevent	event OnReset()		Notify("OnReset", "Nothing")	endeventendstate;////////////////////////////////////////////////////////////////////////////// Functions/////////////////////////////////////////////////////////////////////////////;function Notify(string source, string doing)	string m = "[XsT1]  " + source + " @ [" + GetState() + "] : " + doing	Debug.Notification(m)	Debug.Trace(m)endfunction
Here's the output:
Spoiler
[03/22/2012 - 04:09:27PM] [XsT1]  OnInit @ [] : Register Update[03/22/2012 - 04:09:29PM] [XsT1]  OnUpdate @ [] : GoToState(Other)[03/22/2012 - 04:09:29PM] [XsT1]  onBeginState @ [OTHER] : Register Update[03/22/2012 - 04:09:31PM] [XsT1]  OnUpdate @ [OTHER] : Resetafter a manual startquest via console[03/22/2012 - 04:10:18PM] [XsT1]  OnInit @ [] : Register Update[03/22/2012 - 04:10:21PM] [XsT1]  OnUpdate @ [] : GoToState(Other)[03/22/2012 - 04:10:21PM] [XsT1]  onBeginState @ [OTHER] : Register Update[03/22/2012 - 04:10:23PM] [XsT1]  OnUpdate @ [OTHER] : Reset

Yes, the as int is a cast to integer.
User avatar
Hannah Barnard
 
Posts: 3421
Joined: Fri Feb 09, 2007 9:42 am

Post » Wed Jun 20, 2012 3:44 pm

Did you run a test with 'Auto state Other' ? So Other was the default state.
User avatar
Heather Kush
 
Posts: 3456
Joined: Tue Jun 05, 2007 10:05 pm

Post » Wed Jun 20, 2012 2:32 am

Hmm, I did now. I also rearranged the code to behave the same (OnUpdate).
Spoiler
; after gameload even though its not an auto-start quest and GetQR returns 0[03/22/2012 - 05:36:00PM] [XsT1]  OnInit @ [OTHER] : Register Update[03/22/2012 - 05:36:02PM] [XsT1]  OnUpdate @ [OTHER] : GoToState()[03/22/2012 - 05:36:02PM] [XsT1]  onEndState @ [OTHER] : Nothing; after manual starquest[03/22/2012 - 05:36:21PM] [XsT1]  OnInit @ [OTHER] : Register Update[03/22/2012 - 05:36:25PM] [XsT1]  OnUpdate @ [OTHER] : GoToState()[03/22/2012 - 05:36:25PM] [XsT1]  onEndState @ [OTHER] : Nothing
Well, that's interesting. Still, multiple OnInit are allowed, but they don't provide any value.
Only a single OnInit event can be executed, so it makes no sense not to place it in the default, implicit state they call empty.
User avatar
Liv Staff
 
Posts: 3473
Joined: Wed Oct 25, 2006 10:51 pm

Post » Wed Jun 20, 2012 12:33 pm

Umm, yeah that's strange, but that test doesn't actually show which OnInit() ran as the args are the same.
It could have been the empty state OnInit() code.

Whatever though, I agree with your conclusion :)
User avatar
scorpion972
 
Posts: 3515
Joined: Fri Mar 16, 2007 11:20 am

Post » Wed Jun 20, 2012 7:55 am

Sure it does, the one from the Other state in the last test, and the default empty state in the first test.
User avatar
Abi Emily
 
Posts: 3435
Joined: Wed Aug 09, 2006 7:59 am

Post » Wed Jun 20, 2012 3:04 pm

The reason, of course, is that when OnInit fires, it hasn't run any code yet, so it will be in it's Auto state, which is either the user defined Auto state, or the "empty" state (the initial code of the script, anything outside any "State" blocks, is implicity in a namesless State block (Which is why "GoToState("")" will send you back to the empty state)
User avatar
Harry Hearing
 
Posts: 3366
Joined: Sun Jul 22, 2007 6:19 am

Post » Wed Jun 20, 2012 9:02 am

Sure it does, the one from the Other state in the last test, and the default empty state in the first test.

I appreciate you. Thanks for doing the test. You seem to know papyrus pretty well now.

Unfortunately, creating an internal variable (a regular int) didn't change my results. still getting 0 as the output, and GetGlobalValue still says the the value is indeed 1.
User avatar
Justin Bywater
 
Posts: 3264
Joined: Tue Sep 11, 2007 10:44 pm

Post » Wed Jun 20, 2012 4:19 am

Spoiler
Scriptname MOD1AazCombatScript extends Actor  Quest Property MOD1QPart1 AutoGlobalVariable Property combatphase  Auto  ;Event OnLoad();	Registerforupdate(120);EndEventEvent OnInit()endeventauto state waitingstate		Event OnInit()		registerforupdate(5);Polling	endevent	Event OnUpdate()		if (MOD1QPart1.GetStage() == 29)			unregisterforupdate();			debug.notification("exiting waiting state");			gotostate ("activestate")		else			debug.notification("in waiting state" + MOD1QPart1.GetStage())		endif	endeventendstatestate activestate	Event OnBeginState()		debug.notification("entered active state");		registerforsingleupdate(5);	endevent	event onupdate()	int phase = combatphase.getvalue() as int;		if (phase == 1)			gotostate ("combatstate");		elseif (phase == 2)			gotostate ("flyingstate1");		elseif (phase == 3)			gotostate ("flyingstate2");		else			gotostate ("activestate");			debug.notification ("In activestate. Phase =" + phase);		endif	endeventendstatestate combatstate	Event OnBeginState()		setallowflying(false);		startcombat(game.getplayer());		registerforsingleupdate(10);	endevent	event onupdate()		gotostate ("activestate")	endeventendstatestate flyingstate1	event onbeginstate()		setallowflying(true)		stopcombat()	endeventendstatestate flyingstate2	event onbeginstate()		setallowflying(true)		stopcombat()	endeventendstate


The posted code that I mentioned above.
User avatar
DeeD
 
Posts: 3439
Joined: Sat Jul 14, 2007 6:50 pm

Post » Wed Jun 20, 2012 3:03 am

Just Posting to say. Still having the problem with "Global".GetValue() not returning the proper value. Still looking for help if anyone is willing to provide.
User avatar
Laura Ellaby
 
Posts: 3355
Joined: Sun Jul 02, 2006 9:59 am

PreviousNext

Return to V - Skyrim