Jump to content

Recommended Posts

Hi there,

 

I am a relatively new modder and have only a light understanding of papyrus (I kinda make it work) and could use some help figuring out how to properly make one quest dependant on another. The short version is that I am making a mod that uses a MainQuest (MQ) to kind of track 3 separate SubQuests (SQ) that the player can start in any order but only if the MQ is active. Now I have sorted my SQ by number (i.e.: SQ01; SQ02 and SQ03).

 

SQ02 I want to start when the player starts the RiftenFreeForm Quest 10 (Stoking the Fire -> Riften blacksmith fire salt quest) and I don't really know how to do that.

A similar situation arises with SQ03, which I want to start once SQ01 & 02 have been started (which I think I have figured out how to do that) and then track the progress of the Dawnguard DLC quest "Lost to the Ages -> Aetherium forge quest).

 

So my question is, what would be the best and "lightest/least-intrusive" way to implement my mod quest dependencies on vanilla quests?

 

Any and all help is highly appreciated. Have a good one.

Edited by secretsniper01
Link to comment
Share on other sites

The short...it's going to take a bunch of ugly hacks to do what you want.

Without modifying the vanilla quests there's really only one way I know of to pull this off. The best solution I have is checking periodically to see if your trigger quest stages are passed/completed. Though that brings its own list of drawbacks, primarily you have a script running a check every so often for things that realistically may never happen. Depending how the player plays.

 

The "best" way to do that would be using a one time timer on a quest script to activate and then see if the stage you want is fired. If not, register the timer again to check later. This prevents the script from endlessly looping with Waits which can cause other problems.

So on your main quest, have the startup stage (or some other trigger) start the timer.
So the check for your SQ02 would be FreeformRiften10.GetStage() >= 20. 20 is the stage that is set when the player is tasked to find fire salts. If you're trying to get an immediate trigger of your SQ02 the only way is to modify the vanilla quest script stage to start up yours.
The others would use similar checks for stages and then react accordingly.

For your timer you'll want RegisterForSingleUpdate and the callback is OnUpdate

 

Edit: Just thought of another way. I've not actually tried this so the exact method may be slightly off, and I'm not sure how I feel about using this method but I'll document it anyway. You could use a spell that works like an ability. It's placed on the player via a start enabled quest. The spell then has 3 (or more) conditioned magic effects. Each one having the conditions of your quest start logic. Then when that condition is valid that effect is applied. The effect then has an archtype of script and when it's applied runs the script. The script has an event for the OnEffectStart which then fires up your side quest. Adding a n-th effect with conditions for all of your side quests have started then causing a dispell would be suggested but optional. This may not be a good solution if you plan to add additional quests later as the list of triggers may grow quite large.

Edited by BigAndFlabby
Link to comment
Share on other sites

Damn, I was hoping that there is an easy solution to my problem.

Ok so, a different but related question then: How bad would it be to simply add a script fragment to the vanilla quests? Because that would be the easiest way for me now, but of course that could perhaps lead to some issues in the future. Would there be a way to make this version as compatible as possible with other mods? I mean technically I wouldn't be removing anything from the vanilla files, just adding a small fragment but in reality, I know this might still cause problems.

Even though I am mainly making the mod for myself, I was thinking of releasing it to the public so I want to try to make it "simple"/non-intrusive/compatible as possible. Would the above fall into that category or is it an absolute no-go?

 

The problem I see with the RegisterSingleUpdate Form is that if I start it, say, at MQ stage 10 (start-up stage) on what "update" would it fire (using the OnUpdate callback)?

 

Wouldn't this script be better suited and make it only check ... I don't know, every 10 - 15 minutes? I did read that the regular RegisterForUpdate Form can cause problems on mod uninstallations.

 

 

Function SomeFunction()
    RegisterForUpdate(5.0) ; Before we can use OnUpdate() we must register.
EndFunction
 
Event OnUpdate() ; This event occurs every five seconds        
    If myQuest.GetStage() == 10
        UnregisterForUpdate() ; when we're done with it, make sure to unregister
        Debug.Trace("Got what we needed, so stop polling!")
    EndIf
EndEvent

 

 

 

And although it is great to know that using a spell effect on the player could also work, I am not sure if I want to have the "inner workings" showing in-game.

 

In any case, I want to thank you for your help, Big :)

Edited by secretsniper01
Link to comment
Share on other sites

Damn, I was hoping that there is an easy solution to my problem.

 

Ok so, a different but related question then: How bad would it be to simply add a script fragment to the vanilla quests? Because that would be the easiest way for me now, but of course that could perhaps lead to some issues in the future. Would there be a way to make this version as compatible as possible with other mods? I mean technically I wouldn't be removing anything from the vanilla files, just adding a small fragment but in reality, I know this might still cause problems.

Even though I am mainly making the mod for myself, I was thinking of releasing it to the public so I want to try to make it "simple"/non-intrusive/compatible as possible. Would the above fall into that category or is it an absolute no-go?

 

The problem I see with the RegisterSingleUpdate Form is that if I start it, say, at MQ stage 10 (start-up stage) on what "update" would it fire (using the OnUpdate callback)?

 

Wouldn't this script be better suited and make it only check ... I don't know, every 10 - 15 minutes? I did read that the regular RegisterForUpdate Form can cause problems on mod uninstallations.

 

 

Function SomeFunction()
    RegisterForUpdate(5.0) ; Before we can use OnUpdate() we must register.
EndFunction
 
Event OnUpdate() ; This event occurs every five seconds        
    If myQuest.GetStage() == 10
        UnregisterForUpdate() ; when we're done with it, make sure to unregister
        Debug.Trace("Got what we needed, so stop polling!")
    EndIf
EndEvent

 

 

 

And although it is great to know that using a spell effect on the player could also work, I am not sure if I want to have the "inner workings" showing in-game.

 

In any case, I want to thank you for your help, Big :smile:

 

I'm going to start with my normal rant about how mods (especially those with scripts) should never be removed mid game (after being baked in a save). So many things can go wrong. Even if you do your best to stop quests, timers, etc. Skyrim is especially bad at trying to cleanup removed things and something *will* break. /endrant

 

I would avoid at all costs modifying vanilla scripts. Adding a stage to the quest has its own issues.

 

It sounds like you don't need your quests to start up exactly after certain stages, which maybe that was my fault misunderstanding. So that opens up a few other alternatives.

  • *Maybe the best choice* You could use the built in story manager and hook in on location changes. This has pros and cons as well. The pro is there's no constant running timer. A con is that the player will have to cross a "location" border. So if they're roaming around in the wilderness with no location it could take time. But it sounds like the criteria you want to use for your starts will require them to be in location tagged areas. This will also require a new quest that is event started to do the work you want. If the mod isn't distributed and no saves have seen it, you can just change the side quest Event types to be Change Location event. You could condition the start criteria to be the prerequisite stages of the vanilla quests. So you can have something like, when the location is changed, check if the other vanilla quest is started/at stage n, then start SQnn or whatever. To see how this is done check out Object Window > Character > SM Event Node > Change Location Event. Make sure if you use this that when you add a node you check the box that says "Shares Event" otherwise you *will* break things.
  • Your timer can be expanded like you said to a longer delay. I would probably go up to maybe 1 or 2 minutes. 10-15 seems really far out there.
  • You can set up trigger boxes in major areas, like city entrances. Not the most accurate but it may get the job done in an acceptable fashion. You can use either the OnTriggerEnter or OnCellAttach then do your if checks within. This alleviates the need for a constantly running timer. But will require the player go back to the area where the trigger box is.
Link to comment
Share on other sites

  • 2 years later...

Just wanted to chime in here about RegisterForUpdate() According to the CK Wiki, this function's arguments are run in real-time seconds. Example below

 

; Run Register For Update every 1 hour in real time

RegisterForUpdate(3600.00)

 

Source: https://www.creationkit.com/index.php?title=RegisterForUpdate_(Papyrus)

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...