How to track a series of non linear events in a script

Post » Sun Jun 24, 2012 7:20 am

I find myself again trying to figure out how to do something with Papyrus that I could easily do the old way, lol. I have 5 recruits located in 5 different locations that the player has to find and ask them if they want to work as a guard in Helgen. I could set it up strictly linear, and let each successful recruit update the quest and point to the next candidate. But I would really like to allow the player to recruit them in any order they wish, and after recruiting each one have an update in the quest journal that says you only have x number of recruits left to find or whatever.

I don't know if this is possible, but could I just put a script fragment in each of my recruits dialog where they agree to join my guards that does this:

“if my main quest is at stage 100, then set it to 101, if it's at 101, set it to 102, if it's at 102 set it to 103”... and all the way to stage 105 which would complete the recruiting quest and tell the player to return to my main quest giver? If so, how do I script it.

Or do I need to set up a separate quest to track the recruits? I'm lost with how to script this. In Fallout, I would just set a variable + 1 each time and when it hit the correct number it would update everything.
User avatar
Cheville Thompson
 
Posts: 3404
Joined: Sun Mar 25, 2007 2:33 pm

Post » Sun Jun 24, 2012 6:40 pm

they each need to be filled in an alias
you can point your objective to all 5 alias targets so that the diamond pointer is on all of them.

for each dialogue (or even if they all share the same dialogue topic), a successful recruit will count down a global variable by a value of 1. you must use a global and not a quest integer. you must then associate this global with your quest by going to the Quest Data Tab and under the window called Text Display Globals, add your global variable that counts how many guards you have left.

in your objective text you would display something like this:

Guards left ( / 5)

(substitute "globalname" with the editor id of the one you added to the quest)


In your dialogue topic info, you must include this in your papyrus fragment after the dialogue for a successful recruit is hired.

YourGlobalVariable.Value -= 1; do stuff that sends them to helgenUpdateCurrentInstanceGlobal(YourGlobalVariable)SetObjectiveDisplayed(#, True, True)

obviously substituting the # with your objective index number and YourGlobal with the name of your actual global (declared as a property in the fragment)


additionally you will need a condition in there so that when 5/5 is met it closes the objective displayed

If (YourGlobalVariable.Value =http://forums.bethsoft.com/topic/1386702-how-to-track-a-series-of-non-linear-events-in-a-script/= 5)    SetObjectiveCompleted(#)EndIf


this is kind of a lot to be putting into a fragment especially if you have more than 1 topic info that uses it, so it would be best to put this into a quest script function and call it remotely

GetOwningQuest().MyFunction()
User avatar
Vickey Martinez
 
Posts: 3455
Joined: Thu Apr 19, 2007 5:58 am

Post » Sun Jun 24, 2012 5:09 am

Thanks AD, after a good night of sleep I'm ready to get started building this. So far, I've got my NPC guards created and placed where they need to go. In my main quest I've added alias for each of them, they're initially disabled, and they enable off of a SetStage from my main quest giver's dialog like they should. They enable perfectly and all have pointers in my journal.

I have all my dialog branches, topics and infos all set and the conditions are working properly as well. So, I think I'm ready to start scripting this puppy, lol.

1 - I don't know if this is what I should have done, but in my main quest script I created a GlobalVariable named "BalokGuardCount". When I edit it it has a "Pick Object" option that's set to none right now. What object does this need to be set to or did I not need this or did I do it wrong?

2 - In order for each quest pointer to go away after recruiting the guard it's pointing to, wouldn't I need to set each recruit on their own objective as opposed to having all of the pointers set to one objective? I could just set all of the individual objectives to be displayed with my dialog fragment from my main guy and complete each one with my recruits dialog when they agree to join..

I know I'll have more questions, but I'd like to take it a bit at a time.
User avatar
Stephanie Nieves
 
Posts: 3407
Joined: Mon Apr 02, 2007 10:52 pm

Post » Sun Jun 24, 2012 2:34 pm

Lol, are you making a "re-build Helgen" mod? I was gonna do that, good to know I don't need to. Keep me focused on Torment.
User avatar
Fam Mughal
 
Posts: 3468
Joined: Sat May 26, 2007 3:18 am

Post » Sun Jun 24, 2012 6:24 pm

1. since a global variable is actually an object, you will need to point it to the global variable you created from the object window (if you named it the same as the editor ID, you should be able to auto-fill it)

2. yes, that is true, set 5 separate objectives each pointing to a different guard. if you want only a single objective to be displayed to the player (i.e. "recruit guard 0/5") and not have the same objective show 5 times in the journal, you may need a 6th objective that only shows the text, and leave the text for all the guards' objectives blank (you may also need to toggle a boolean on the objectivedisplayed function so that it doesnt show a blank space in the journal for each one).

when you successfully recruit one of the guards, setobjectivecompleted on that guards pointer, and setobjectivedisplayed on the main text objective along with the updateinstanceglobal right before so it updates the global count in real time. once it hits 5/5 you can setobjectivecompleted on the text objective so it goes away in the quest journal
User avatar
kitten maciver
 
Posts: 3472
Joined: Fri Jun 30, 2006 2:36 pm

Post » Sun Jun 24, 2012 7:53 am

1. since a global variable is actually an object, you will need to point it to the global variable you created from the object window (if you named it the same as the editor ID, you should be able to auto-fill it)

Ah, I see that now. I've never done this before so I didn't know they were actually an object, lol. So, I got that created as variable type "short", value = http://forums.bethsoft.com/topic/1386702-how-to-track-a-series-of-non-linear-events-in-a-script/0, and constant is unchecked. I'll try the next stuff now.
User avatar
Claudz
 
Posts: 3484
Joined: Thu Sep 07, 2006 5:33 am

Post » Sun Jun 24, 2012 3:02 am

OK, so I tried this in my dialog info:

getOwningQuest().setObjectiveCompleted(73)GetOwningQuest().SetStage(73)BalokGuardCount.Value -= 1UpdateCurrentInstanceGlobal(BalokGuardCount)

and I'm getting this error: Compiling "Balo_TIF__01019841"...
c:\steam\steamapps\common\skyrim\Data\Scripts\Source\temp\Balo_TIF__01019841.psc(12,0): UpdateCurrentInstanceGlobal is not a function or does not exist
No output generated for Balo_TIF__01019841, compilation failed.

what did I do wrong?

Also, after working with this a little, I think simply having 5 objectives displayed is fine as each are in different locations. it will be something like this:

1) Check for recruits in the Bannered Mare in Whiterun.
2) Check for recruits in the Winking Skeever in Solitude.
3) Check for recruits in Candlehearth Hall in Windhelm.
4) Check for recruits in the Windpeak Inn in Dawnstar.
5) Check for recruits in the Bee and Barb in Riften.

I don't necessarily need an overall objective showing where the count is (like recruit "x" more guards or whatever), and I think that will make things a little simpler for me. So, I think all I really need to know how to do is how and where to put the actual script that counts down and sets the objective to display that tells you to return to the quest giver after completing all 5 of the recruiting objectives. Could I do it in a stage or something, or does it need to go in my main quest script somewhere?
User avatar
Markie Mark
 
Posts: 3420
Joined: Tue Dec 04, 2007 7:24 am


Return to V - Skyrim