New Papyrus Thread: Code not executing.

Post » Wed Jun 20, 2012 7:24 am

So yea... I finally have another thread with questions that somebody may actually be able to answer.

So here's the code:
Spoiler

Dragon Combat Script (Script which exists on the Dragon's Base Actor)
Scriptname MOD1AazCombatScript extends Actor  Quest Property MOD1QPart1 AutoEvent OnLoad()    Registerforupdate(120)EndEventEvent OnUpdate()    Debug.Notification("OnUpdate")    If (MOD1QPart1.GetStage() == 32)        self.SetAllowFlying(True)        debug.Notification( "SetAllowFlying Should Be True")        self.StopCombat()        MOD1QPart1.SetStage(33)    ElseIf (MOD1QPart1.GetStage() == 33)        MOD1QPart1.SetStage(34)        Debug.Notification("Stage Should Be = 34")    ElseIf(MOD1QPart1.GetStage() == 34)        MOD1QPart1.SetStage(32)        self.SetAllowFlying(False)        self.StartCombat(game.GetPlayer())    Else        Debug.Notification("Else Condition")    EndIf        self.EvaluatePackage()EndEventEvent OnCombatStateChanged(Actor akTarget, Int aeCombatState)    If (aeCombatState == 1 && MOD1QPart1.GetStage() != 32)            self.StopCombat()            self.EvaluatePackage()    EndIfEndEvent


And HERE

is the problem:

The Dragon is originally set (by some code which executes at the final dialogue of a scene) to have SetAllowFlying(False) and to be attacking the player. It is at this point that the quest stage is also set to 32. After the first 120 seconds (when the OnUpdate Runs) the dragon's SetAllowFlying is set to true, the dragon leaves combat, and successfully reevaluates his package stack. (This causes the dragon to run his package, which has a condition of GetStage (This Same Quest) == 33). The problem is, after another 120 seconds, I get the "OnUpdate," and "Stage Should Be = 34" notifications, but the stage never actually sets to 34. So, the MOD1QPart1.SetStage(34) doesn't appear to be setting, anyone have any ideas?
User avatar
Ladymorphine
 
Posts: 3441
Joined: Wed Nov 08, 2006 2:22 pm

Post » Wed Jun 20, 2012 4:23 pm

Is it possible there is something somewhere else that is setting the stage to something other than 34? Is there a code fragment in stage 32 that might be interfering? Move any SetStage() commands to the END of their code blocks and see if that has any effect.

Does the quest have "Allow Repeated stages" checked?
User avatar
Harry Hearing
 
Posts: 3366
Joined: Sun Jul 22, 2007 6:19 am

Post » Wed Jun 20, 2012 6:24 am

*Facepalm*... Don't ask...; found it. I feel like an idiot. AGAIN.
User avatar
Ebony Lawson
 
Posts: 3504
Joined: Fri Feb 16, 2007 11:00 am

Post » Wed Jun 20, 2012 5:13 am

Okay, so different, but similar problem. It's with nearly the same script as originally posted. Now the stage won't set back to 32 for some reason. Is there a reason that I can't set the quest stage backward? From 34 to 32?
User avatar
nath
 
Posts: 3463
Joined: Mon Jan 22, 2007 5:34 am

Post » Wed Jun 20, 2012 4:47 am

In Oblivion, setting a stage backwards would not do anything. At most, it would run the code for that quest stage if "Allow repeated quest stages" was checked. But then again, Oblivion didn't allow you to reset quests either.
User avatar
Arrogant SId
 
Posts: 3366
Joined: Sat May 19, 2007 11:39 am

Post » Wed Jun 20, 2012 1:30 am

Well Crap...

I need to rewrite my entire code then. I was planning on using quest stages as sort-of Phase variables for a boss encounter. since I can't go back quest stages, this won't work, what do I do about this?
User avatar
Matt Bigelow
 
Posts: 3350
Joined: Sun Sep 30, 2007 6:36 pm

Post » Wed Jun 20, 2012 12:16 pm

Quests are repeatable.
Quest stages are not.

If you want a particular stage to be a sort of back and forward junction ... rather than a rewrite, could you seperate that stage into a separate (repeatable) sub quest?

(just a thought)
User avatar
BRAD MONTGOMERY
 
Posts: 3354
Joined: Mon Nov 19, 2007 10:43 pm

Post » Wed Jun 20, 2012 5:57 am

Quests are repeatable.
Quest stages are not.

If you want a particular stage to be a sort of back and forward junction ... rather than a rewrite, could you separate that stage into a separate (repeatable) sub quest?

(just a thought)

It would probably be more beneficial for my knowledge of Papyrus if someone could tell me another way to do this. Is there something else I can as a sort of global variable, I basically just need an int or float to hold the stage, and I need it accessible by multiple actor scripts.
User avatar
ladyflames
 
Posts: 3355
Joined: Sat Nov 25, 2006 9:45 am

Post » Wed Jun 20, 2012 12:18 pm

Quests are repeatable.
Quest stages are not.

If you want a particular stage to be a sort of back and forward junction ... rather than a rewrite, could you seperate that stage into a separate (repeatable) sub quest?

(just a thought)

^^ Wrong.

Look on the first page of the quest data. You will see a checkbox that says "Allow repeated stages" - turn that on, and you can repeat stages as often as you like.
User avatar
Yvonne
 
Posts: 3577
Joined: Sat Sep 23, 2006 3:05 am

Post » Wed Jun 20, 2012 4:18 am

^^ Wrong.

Look on the first page of the quest data. You will see a checkbox that says "Allow repeated stages" - turn that on, and you can repeat stages as often as you like.

Well then, what's wrong? Because "Allow Repeated Stages"is on.
User avatar
Quick Draw III
 
Posts: 3372
Joined: Sat Oct 20, 2007 6:27 am

Post » Wed Jun 20, 2012 4:52 pm

Allow Repeated Stages: If this box is checked, a journal entry will be displayed (and quest stage results run) every time http://www.creationkit.com/SetCurrentStageID_-_Quest is called for a particular stage number. Otherwise, http://www.creationkit.com/SetCurrentStageID_-_Quest has no effect after it is called the first time for any stage on a running quest.

I'm not entirely sure I understand that (it's from the wiki: http://www.creationkit.com/Quest_Data_Tab) - I think it means that you can keep repeating that stage, providing you do not go beyond that stage

As far as I understood, once you have SetStage to a higher Stage, you cannot SetStage back to a lower stage ... but yeah, I might be wrong (I often am)
User avatar
Lynette Wilson
 
Posts: 3424
Joined: Fri Jul 14, 2006 4:20 pm

Post » Wed Jun 20, 2012 4:30 am

I'm not entirely sure I understand that (it's from the wiki: http://www.creationkit.com/Quest_Data_Tab) - I think it means that you can keep repeating that stage, providing you do not go beyond that stage

As far as I understood, once you have SetStage to a higher Stage, you cannot SetStage back to a lower stage ... but yeah, I might be wrong (I often am)

You're obviously right. The Engine won't allow me to go backwards. Plus it says right there in the wiki: "Otherwise, http://www.creationkit.com/SetCurrentStageID_-_Quest has no effect after it is called the first time for any stage on a running quest." This was invalid, however, my point still stands, the quote mentioned that it only affects what the player sees when "SetStage" is called for a stage, it still does not allow one to entirely repeat a stage. Now I just need to figure out how to get around it.

So I need to figure out how to create some kind of global-variable-esque thing.
User avatar
Gemma Woods Illustration
 
Posts: 3356
Joined: Sun Jun 18, 2006 8:48 pm

Post » Wed Jun 20, 2012 9:44 am

I did what I think you're trying to do by using an "invisible" sub-quest (rather than a variable)

When I did a similar thing I took out the stage that needed to be repeated - if the PC got something wrong - and made it a repeatable, seperate Quest with no Journal Entries; so the player was unaware that anything had happened, and the main quest the PC was on did not update
  • At the appropriate point in the main quest I had that SetStage to the repeatable, "hidden" Quest
  • In the repeatable Quest I did the if scripts to check that the PC had done things correctly.
  • If not correct, I restarted the hidden sub-quest
  • If correct, I set the invisible quest to complete and SetStaged the main, visible quest to the appropriate higher stage.
(I don't know if you can make that work for you, because I'm not sure exactly what your quest is doing)
User avatar
Peter P Canning
 
Posts: 3531
Joined: Tue May 22, 2007 2:44 am

Post » Wed Jun 20, 2012 2:37 am

I did what I think you're trying to do by using an "invisible" sub-quest (rather than a variable)

When I did a similar thing I took out the stage that needed to be repeated - if the PC got something wrong - and made it a repeatable, seperate Quest with no Journal Entries; so the player was unaware that anything had happened, and the main quest the PC was on did not update
  • At the appropriate point in the main quest I had that SetStage to the repeatable, "hidden" Quest
  • In the repeatable Quest I did the if scripts to check that the PC had done things correctly.
  • If not correct, I restarted the hidden sub-quest
  • If correct, I set the invisible quest to complete and SetStaged the main, visible quest to the appropriate higher stage.
(I don't know if you can make that work for you, because I'm not sure exactly what your quest is doing)

I may be able to. I'd much prefer trying to find some other way to do this via properties and variables, but if I can't find out anything else I will probably try it. Thanks for the idea anyway. It's currently back-up plan #1.


EDIT: Anyway, going to bed. Hoping someone will give me some more ideas by time I get back on tomorrow.
User avatar
x_JeNnY_x
 
Posts: 3493
Joined: Wed Jul 05, 2006 3:52 pm

Post » Wed Jun 20, 2012 1:19 pm

I'm not entirely sure I understand that (it's from the wiki: http://www.creationkit.com/Quest_Data_Tab) - I think it means that you can keep repeating that stage, providing you do not go beyond that stage As far as I understood, once you have SetStage to a higher Stage, you cannot SetStage back to a lower stage ... but yeah, I might be wrong (I often am)

In FNV you could set any stage when using that flag, and the text on the GECK wiki for that entry is http://geck.gamesas.com/index.php/Quest_Data_Tab. So I don't think you can interpret it that way.
Library mods were made for Oblivion that relied on that feature. I'd be surprised if it no longer worked the same.

@Gargion. are you using a clean save?
You could also check the return value of SetStage(), just to make sure it is actually the SetStage failing.
User avatar
Maddy Paul
 
Posts: 3430
Joined: Wed Feb 14, 2007 4:20 pm

Post » Wed Jun 20, 2012 10:56 am

FYI, you can omit all of the 'Self' instances and just call the functions implicitly.
User avatar
Sara Johanna Scenariste
 
Posts: 3381
Joined: Tue Mar 13, 2007 8:24 pm

Post » Wed Jun 20, 2012 9:33 am

FYI, you can omit all of the 'Self' instances and just call the functions implicitly.
Are you saying that I simply don't need to declare "Self.****"
User avatar
Elea Rossi
 
Posts: 3554
Joined: Tue Mar 27, 2007 1:39 am

Post » Wed Jun 20, 2012 3:39 pm

Are you saying that I simply don't need to declare "Self.****"

Correct. You only need to use self if you need to pass yourself to a function. For example:

Game.GetPlayer().GetDistance(Self)

and

GetDistance(Game.GetPlayer())

will return the same result. In the first case, you're passing yourself as a parameter, and in the second you're passing the player, but implicitly calling it on "self"
User avatar
liz barnes
 
Posts: 3387
Joined: Tue Oct 31, 2006 4:10 am

Post » Wed Jun 20, 2012 3:19 am

I may be able to. I'd much prefer trying to find some other way to do this via properties and variables, but if I can't find out anything else I will probably try it. Thanks for the idea anyway. It's currently back-up plan #1.
Use http://www.creationkit.com/States_(Papyrus), they are efficient and elegant and probably what you

Anyway, based on the script you posted, look at it, could help you debug in the future.
I use lowercase keywords, because I hate that papyrus is case-insensitive and pretty much every other language does it this way.
Spoiler
scriptname MOD1AazCombatScript extends ActorQuest property MOD1QPart1 autoevent OnLoad() ; shouldn't this be done with a trigger instead?RegisterForSingleUpdate(120.0) ; RegisterForUpdate is almost always the wrong function to callendeventevent OnUpdate()bool failedSettingStage = falseint currentStage = MOD1QPart1.GetCurrentStageID()if (currentStage == 32)SetAllowFlying(true)StopCombat()failedSettingStage = !MOD1QPart1.SetCurrentStageID(33)elseif (currentStage == 33)MOD1QPart1.SetCurrentStageID(34)elseif (currentStage == 34)SetAllowFlying(false)StartCombat(Game.GetPlayer())failedSettingStage = !MOD1QPart1.SetCurrentStageID(32) ; invalid but you already know that, also; I put this call last since the function is latent -- might or might not be what you wantendifif (failedSettingStage)Debug.Notification("ERROR: Failed to set quest stage")Debug.TraceStack("Failed to set quest stage", 2)endifEvaluatePackage()endeventevent OnCombatStateChanged(Actor target, int combatState)if (combatState == 1 && MOD1QPart1.GetCurrentStageID() != 32)StopCombat()EvaluatePackage()endifendevent

Are you saying that I simply don't need to declare "Self.****"
self.something is not a declaration, its an expression and probably an invocation too.
User avatar
Tha King o Geekz
 
Posts: 3556
Joined: Mon May 07, 2007 9:14 pm

Post » Wed Jun 20, 2012 1:19 am

Xetrill. So, a couple of things:

#1 Does "registerforsingleupdate()" only call OnUpdate once? If so, I don't want it.
#2 I like using case-insensitivity to my advantage. I make all of my Exterior If statements with the first letters capitalized to help distinguish nesting.
#3. States are cool and all, I've never really used them. I know in essence what they do, but I'm not entirely sure how it would help me here. I need something that I can use in place of quest stages, because as I said earlier, I need to be able to access this variable from several different actor scripts.
User avatar
Georgine Lee
 
Posts: 3353
Joined: Wed Oct 04, 2006 11:50 am

Post » Wed Jun 20, 2012 3:20 am

#1 Does "registerforsingleupdate()" only call OnUpdate once? If so, I don't want it.
Even so, RegiserForUpdate has side effects which make it troublesome, although usually only if used with a small interval. Then again there is nothing stopping you from calling it again, to re-register the next update.

Generally, wouldn't it be easier and clearer if you did everything that is done in OnUpdate instead in the quest with fragment scripts? Or is this supposed to be a 6 minute battle in which the player can't slay the beast?

#2 I like using case-insensitivity to my advantage. I make all of my Exterior If statements with the first letters capitalized to help distinguish nesting.
Proper indentation already accomplishes that.

#3. States are cool and all, I've never really used them. I know in essence what they do, but I'm not entirely sure how it would help me here. I need something that I can use in place of quest stages, because as I said earlier, I need to be able to access this variable from several different actor scripts.
States, can guard code, they can switch behavior by actually switching the code that gets executed based on state. And they are entirely programmable.
User avatar
Emzy Baby!
 
Posts: 3416
Joined: Wed Oct 18, 2006 5:02 pm

Post » Wed Jun 20, 2012 3:54 am

#1 Does "registerforsingleupdate()" only call OnUpdate once? If so, I don't want it.
Even so, RegiserForUpdate has side effects which make it troublesome, although usually only if used with a small interval. Then again there is nothing stopping you from calling it again, to re-register the next update.

Generally, wouldn't it be easier and clearer if you did everything that is done in OnUpdate instead in the quest with fragment scripts? Or is this supposed to be a 6 minute battle in which the player can't slay the beast?

#2 I like using case-insensitivity to my advantage. I make all of my Exterior If statements with the first letters capitalized to help distinguish nesting.
Proper indentation already accomplishes that.

#3. States are cool and all, I've never really used them. I know in essence what they do, but I'm not entirely sure how it would help me here. I need something that I can use in place of quest stages, because as I said earlier, I need to be able to access this variable from several different actor scripts.
States, can guard code, they can switch behavior by actually switching the code that gets executed based on state. And they are entirely programmable.

The Quest Stages are supposed to loop. Yes I will probably do states, but this doesn't solve the problem. The problem is that since SetStage() cannot go back quest stages, I cannot use quest stages as a global variable to tell my actors which phase of the encounter they should be in. The purpose is not to have a 6 minute battle, but a battle that cycles through three stages every 2 minutes. Since it looks like you're more of a code guy--which is a very good thing, as I only dabble in code when I need to--how can I accomplish this with papyrus? I need a single variable, such as and int or float, that can track my phase and be read by multiple actor scripts. How could I accomplish this?

Edit:

I keep nagging on the global variable issue because, even if I put in states, I need to make code that sets the states of all of my actors BASED on an int or a float which gives the current phase of the encounter.

EDIT EDIT: Also, regardless, this creates another problem. I have not seen a way (scenes Excluded) to force an actor to run a particular package. Currently my encounter utilizes packages with Quest GetStage conditions. If I an bit using quest stages, this may possibly be another problem. Would the GetScriptVariable condition allow me to check this variable in a similar fashion?
User avatar
Jodie Bardgett
 
Posts: 3491
Joined: Sat Jul 29, 2006 9:38 pm

Post » Wed Jun 20, 2012 2:39 pm

To use a global variable in the way you describe, just replace all your SetStage and GetStage functions with SetValueInt and GetValueInt.

For example, change this:

Quest property MyQuest autoMyQuest.SetStage(10)int stage = MyQuest.GetStage()

to

GlobalVariable property MyGlobal autoMyGlobal.SetValueInt(10)int stage = MyGlobal.GetValueInt()
User avatar
Dark Mogul
 
Posts: 3438
Joined: Tue Feb 20, 2007 11:51 am

Post » Wed Jun 20, 2012 4:20 pm

Take a look at this, should explain what I meant.
Spoiler
scriptname XsCyclingBattleScript extends Actor;///////////////////////////////////////////////////////////////////////////// / Properties /////////////////////////////////////////////////////////////////////////////;float property CycleInterval = 120.0 autoreadonly hidden;///////////////////////////////////////////////////////////////////////////// / States /////////////////////////////////////////////////////////////////////////////;auto state Cycle1	event OnUpdate()		GoToState("Cycle2")		; more code		RegisterForSingleUpdate(CycleInterval)	endeventendstatestate Cycle2	event OnUpdate()		GoToState("Cycle3")		; more code		RegisterForSingleUpdate(CycleInterval)	endeventendstatestate Cycle3	event OnUpdate()		GoToState("Cycle1")		; more code		RegisterForSingleUpdate(CycleInterval)	endeventendstate
User avatar
luis ortiz
 
Posts: 3355
Joined: Sun Oct 07, 2007 8:21 pm

Post » Wed Jun 20, 2012 7:57 am

Take a look at this, should explain what I meant.
Spoiler
scriptname XsCyclingBattleScript extends Actor;////////////////////////////////////////////////////////////////////////////// Properties/////////////////////////////////////////////////////////////////////////////;float property CycleInterval = 120.0 autoreadonly hidden;////////////////////////////////////////////////////////////////////////////// States/////////////////////////////////////////////////////////////////////////////;auto state Cycle1	event OnUpdate()		GoToState("Cycle2")		; more code		RegisterForSingleUpdate(CycleInterval)	endeventendstatestate Cycle2	event OnUpdate()		GoToState("Cycle3")		; more code		RegisterForSingleUpdate(CycleInterval)	endeventendstatestate Cycle3	event OnUpdate()		GoToState("Cycle1")		; more code		RegisterForSingleUpdate(CycleInterval)	endeventendstate

I see what you're doing here. It's nice. Thanks.

However, I needed RandomNoob's input. Because I have multiple actors who must respond the the phase (or cycle in your script.)
User avatar
Marcia Renton
 
Posts: 3563
Joined: Fri Jan 26, 2007 5:15 am

Next

Return to V - Skyrim