Bendu and S M Nodes

From the CreationKit Wiki
Jump to navigation Jump to search

Or, a Brief Walkthrough Hooking the Bendu Quest onto the Story Manager.


DialogueInGame.png


Introduction[edit | edit source]

This is a walkthrough of the procedures in starting the Bendu Olo Quest through the Script Event node.


Requirements:

  • Completion of the "Intermediate Quest Design" series with particular focus on the [Story Manager].
  • A working copy of the Bendu Quest that will either activate by the Startquest command through console or with "Start Game enabled" checked off.


Completion of the "Scripting with Papyrus" series is also strongly recommended.


Protip.jpg Seasoned stagers can bypass the above and transpose just the methods to their own works.

The Nodes[edit | edit source]

  • Load up the quest and navigate to the Keyword entry under the Miscellaneous category in the Object Browser. Right click somewhere in the RH pane, New, and type the name of a keyword, in this case: GSQ01Keyword.


  • From the Character category in the Object Browser choose SM Event Node and double click on Script Event. Right click and create a new Branch node. It will be checked as stacked by default. The new node will appear below all other entries. I gave it a name of GSQ01BranchStart.


Protip.jpg We choose to work with the Script event as opposed to the other events on offer as it is much more versatile, and less buggy.


  • Right click on GSQ01BranchStart and select New Quest Node. Give this a name of something like GSQ01Start. The GSQ part will at some stage appear as lower case for some reason. I checked Num quests to run and left it at 1. Ensure the Stacked Bullet is checked and, at the base of the page locate the Shared checkbox and click it. On lower resolutions accessing the bottom requires some sorcery.


  • Right click on the GSQ01Start Node Conditions area and implement a new condition with function GetEventData. The function parameters will be from top-down: GetIsId, Keyword, and GSQ01Keyword. Click Ok out.


  • Right click on the GSQ01Start Node and select Add Quests. Choose GSQ01 from the list. Then select the newly created quest node, right click it, and choose Edit Quest.


This will bring up the quest tab, which serves as quite a useful shortcut to it, actually


Achtung.png It's important to remove an attached quest before deleting a node.


  • Select the Quest Data tab and from the event drop-down list choose Script Event. Notice that the Start Game Enabled box is now greyed out. Now Ok out of all windows back to the main CK window and save.


Now that the Node has been set up with the minimum amount of information required to activate the quest, let's work on our Script Event.

The Quest Script[edit | edit source]

  • Open up the Scripts tab and select QF_GSQ01_01000D62. Click the Properties button to add two new properties:
   GSQ01KeywordLocal of type Keyword filled with the GSQ01Keyword object.
   MixWaterMill of type Location filled with the MixWaterMillLocation object


  • Edit the script source and add this code below all existing code:


    Function GSQ01Story()
    if (!GetStageDone(0))
    GSQ01KeywordLocal.SendStoryEvent(akLoc = MixWaterMill, akRef1 =None, akRef2 = None, aiValue1 = 0, aiValue2 = 0);
    endif
    endFunction


Protip.jpg Even though the quest may be stopped and/or in a disabled state, the mod is still active,

and the SendStoryEvent will transmit the data from the trigger zone to the node stack via the quest script.


InDepth.jpg All of the parameters excepting akLoc are unused here and can be removed,

so GSQ01KeywordLocal.SendStoryEvent(akLoc = MixWaterMill) would work fine.

Including them here shows the potential capabilities of this function in more complex quest trigger scenarios.


  • Save it and exit: let's review we have done so far. See notes regarding the extra entry in the conditions.


S M Node.jpg

The Trigger[edit | edit source]

Now we turn our attention to selecting the quest trigger or activator in the MixWaterMillLocation. The activating object doesn't have to be there, indeed it could be anywhere in Tamriel, but in the spirit of the previous tutorials let's stay in the Mixwater lumber mill locale.

We would also prefer to use something inside the workers house like a chest, barrel, bed, or even Bendu himself. But as Bendu is a base object, and exists outside the quest when the mod is activated, it'll be Keith Szarabajkas's voice on the infos, making an early visit an immersion breaker. (Not to mention what happens post quest completion)

So let's look at something in the exterior. Candidates like chopping blocks, the lever on the lumber mill or any object in Gilfre's home are great. A one-off "Bendu sweetroll" found on the crate outside Gifre's home would be ideal, but we'll use something rather obvious here, Bendu's door.


InDepth.jpg One drawback of opting for "well used" objects like doors as activators, is that Papyrus will log those events more often.

Also, the quest is being started unnecessarily every time we use the door during the quest.

To limit Papyrus logging, conditions on Quest Stages can be employed on the Quest Node. See Notes Below.


  • Locate and edit the FarmhouseDoor01 object on the exterior of the MixwaterMill Workers House. Click the scripts tab and Add a new script. Call it StartingGSQ01Quest.


  • Add a new property to it:
   GetGSQ01of type Quest filled with the GSQ01 object.


  • Edit the script source of StartingGSQ01Quest and add this code below the property:


    EVENT onActivate (objectReference akActionRef)	
    Send_Story()
    EndEvent

    Function Send_Story()
    QF_GSQ01_01000D62 tempGSQ01 = GetGSQ01 as QF_GSQ01_01000D62
    tempGSQ01.GSQ01Story()
    tempGSQ01=None
    EndFunction


InDepth.jpg The long line of code beginning with QF_GSQ01_01000D62 looks scary.

Here we replace the (empty) reference of tempGSQ01 with the reference we got from GetGSQ01, a reference which is, in fact, directed toward our quest object, GSQ01.

Consider QF_GSQ01_01000D62 as a "type". It's type is that of script.


If the line in Send_Story() were just

QF_GSQ01_01000D62 tempGSQ01 = GetGSQ01

That would be the same as:

QF_GSQ01_01000D62 tempGSQ01 = GetGSQ01 as Quest

The "as" operator is called a cast and the following statement looks for something in GSQ01 to "match" the script object QF_GSQ01_01000D62:

QF_GSQ01_01000D62 tempGSQ01 = GetGSQ01

Unfortunately Quest doesn't match and it won't compile because there is no implicit casting of GetGSQ01 to QF_GSQ01_01000D62


We expect the variable tempGSQ01 to be used just once, so it's good practice to clear any persistent reference to the local GetGSQ01 by "nulling" tempGSQ01 after GSQ01Story is called.


Protip.jpg For more detailed info on casting refer here.

For a better picture of how script objects are organized in the CK, check this out.


  • Save the script. Our task is done and the modifications are ready for Bendu.

Notes[edit | edit source]

  • We could, of course have put all the scripts in the StartingGSQ01Quest script instead of the quest script.
The upside of our decision not to is that the properties and functions are available for re-use globally.
The downside is that for some reason the nice message in the Papyrus Log:
   [Date - Time] [StartingGSQ01Quest < (0001656B)>]: send_story Called - starting quest [Keyword <GSQ01Keyword (2E00A9D9)>]
only appears when the SendStory Event is generated from the trigger object.


  • Given a [problem] experienced with conditions, the if condition in Function GSQ01Story() can be replaced by adding:
   GetStageDone {MyQuest 0} == 0

to the Quest Node for GSQ01 in S M Event Nodes for very much the same effect.