Editing A beginner's guide, lesson 5 - Anatomy of a quest, part 2
Jump to navigation
Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
'''TES IV: Oblivion Modding for Beginners''' | |||
'''B. Scripts, Quests and NPC's''' | |||
'''Lesson Five: Anatomy of a Quest. Part Two''' | |||
'''Preamble''' | |||
This is the fifth in a proposed series of ''Tutorial Lessons'' | This is the fifth in a proposed series of ''Tutorial Lessons'' | ||
Line 13: | Line 17: | ||
they may find something of interest here. | they may find something of interest here. | ||
'''Files''' | |||
I have uploaded some files which we will use to accompany the next few | I have uploaded some files which we will use to accompany the next few | ||
Line 19: | Line 23: | ||
They include: | They include: | ||
'''[http://www.tessource.net/files/cache/4865.html Download the following three files from here (external link)]''' | |||
A. BGModTut4.esp: | A. BGModTut4.esp: | ||
Line 36: | Line 42: | ||
C. A RTF document containing the text for the first 5 lessons (as requested). | C. A RTF document containing the text for the first 5 lessons (as requested). | ||
=='''Introduction'''== | =='''Introduction'''== | ||
Line 43: | Line 47: | ||
This is a continuation of our dissection of a quest. We are about to | This is a continuation of our dissection of a quest. We are about to | ||
get a bit technical, and I am going to recommend a nice little utility | get a bit technical, and I am going to recommend a nice little utility | ||
called " | called "the script dumper". If you drag an '''esp''' or '''esm''' over the | ||
executable file, it creates a folder containing the named scripts for | executable file, it creates a folder containing the named scripts for | ||
that '''esp''' or '''esm'''. The scripts are produced in HTML form. And this is | that '''esp''' or '''esm'''. The scripts are produced in HTML form. And this is | ||
Line 69: | Line 73: | ||
'''player.additem BenirusManorKey 1''' | '''player.additem BenirusManorKey 1''' | ||
''(This adds the key object BenirusManorKey to the player's inventory. The number 1 denote how many keys are added. Additem is a commonly used function. Note the period between player and additem, and no space between '''add''' and '''item'''. The target reference must be a container, which includes player)''. | ''(This adds the key object BenirusManorKey to the player's inventory. | ||
The number 1 denote how many keys are added. Additem is a commonly | |||
used function. Note the period between player and additem, and no | |||
space between '''add''' and '''item'''. The target reference must be a | |||
container, which includes player)''. | |||
'''player.additem MS02BenirusDeed 1''' | '''player.additem MS02BenirusDeed 1''' | ||
''(This adds 1 copy of a book item called MS02BenirusDeed. Note this purely cosmetic. The deed does not actually transfer ownership; it is just a bit of window dressing)''. | ''(This adds 1 copy of a book item called MS02BenirusDeed. Note this | ||
purely cosmetic. The deed does not actually transfer ownership; it is | |||
just a bit of window dressing)''. | |||
'''player.removeitem gold001 5000''' | '''player.removeitem gold001 5000''' | ||
''(Removes 5000 gold from the player. This can cause problems if the player has not got the money in his inventory. Take care to set conditional checks before you remove money or items as you can get minus values still appearing in an inventory.)'' | ''(Removes 5000 gold from the player. This can cause problems if the | ||
player has not got the money in his inventory. Take care to set | |||
conditional checks before you remove money or items as you can get | |||
minus values still appearing in an inventory.)'' | |||
'''setstage MS02 30''' | '''setstage MS02 30''' | ||
Line 87: | Line 100: | ||
'''set MS02.fQuestDelayTime to 1''' | '''set MS02.fQuestDelayTime to 1''' | ||
''(This is a useful bit of code. The FQuestDelayTime float variable is a kind of a hybrid global variable. It has to be declared but the system knows what you mean by it. It is used to set the time between quest scripts running. This is a default 5 seconds. This line changes that to '''1 second''' for this '''script'''.)'' | ''(This is a useful bit of code. The FQuestDelayTime float variable is | ||
a kind of a hybrid global variable. It has to be declared but the | |||
system knows what you mean by it. It is used to set the time between | |||
quest scripts running. This is a default 5 seconds. This line changes | |||
that to '''1 second''' for this '''script'''.)'' | |||
'''VelwynBenirusRef.moddisposition player 30''' | '''VelwynBenirusRef.moddisposition player 30''' | ||
''(This is not a reference script so we need to say VelwynBenirusRef, so the game knows who we are talking about. The function is a part of a family of functions of the form '''mod''' something. In this case in modifies the disposition of the player by adding 30 to it.)'' | ''(This is not a reference script so we need to say VelwynBenirusRef, | ||
so the game knows who we are talking about. The function is a part of | |||
a family of functions of the form '''mod''' something. In this | |||
case in modifies the disposition of the player by adding 30 to it.)'' | |||
'''MS02PlayerDoor.SetOwnership''' | '''MS02PlayerDoor.SetOwnership''' | ||
'' | (''This is a function of the '''set''' something family. It | ||
'''player'''. | sets the ownership of the door. By default if '''no target | ||
reference''' is given, the target is assumed to be the | |||
'''player'''). | |||
'''MS02PlayerDoor02.SetOwnership''' | '''MS02PlayerDoor02.SetOwnership''' | ||
Line 104: | Line 126: | ||
'''SetCellOwnership AnvilBenirusManorHaunted''' | '''SetCellOwnership AnvilBenirusManorHaunted''' | ||
''(Slightly different format because it '''sets''' a whole cell ownership, not an object, no target=player)'' | ''(Slightly different format because it '''sets''' a whole | ||
cell ownership, not an object, no target=player)'' | |||
Then the quest Script blocks where finally able to run | Then the quest Script blocks where finally able to run | ||
Line 128: | Line 151: | ||
'''float fQuestDelayTime''' | '''float fQuestDelayTime''' | ||
''(Declares not only the variable for the quest script but for all | ''(Declares not only the variable for the quest script but for all | ||
the results and dialogue scripts)'' | |||
'''begin menumode''' | '''begin menumode''' | ||
''(This begins the script only when the player is using one of the | ''(This begins the script only when the player is using one of the | ||
menus. F2 or sleeping for example)'' | |||
''';This part of the script enables ghost attacks if player sleeps''' | ''';This part of the script enables ghost attacks if player sleeps''' | ||
Line 145: | Line 168: | ||
'''if ( IsPCSleeping == 1 && player.getincell AnvilBenirusManorHaunted == 1 )''' | '''if ( IsPCSleeping == 1 && player.getincell AnvilBenirusManorHaunted == 1 )''' | ||
''(A set of '''nested if''' conditions. '''IF''' statements are the bread and butter of scripting. | ''(A set of '''nested if''' conditions. '''IF''' statements are the bread and butter of scripting. As such I will save a special place for them in the next tutorial. Just for now note double '''==''' for '''equal to''')'' | ||
'''MS02GhostTest1Ref.Enable''' | '''MS02GhostTest1Ref.Enable''' | ||
Line 158: | Line 179: | ||
'''set GhostGen to 1''' | '''set GhostGen to 1''' | ||
'' | '' It is included in the '''if statement''' as being '''true''' if it is = 0.'' | ||
''This line set the value to 1.'' | ''This line set the value to 1.'' | ||
''(Note for Basic programmers: it uses "TO", not "=" to do this, ie "set X to 1", not "set X=1 )'' | ''(Note for Basic programmers: it uses "TO", not "=" to do this, ie "set X to 1", not "set X=1 )'' | ||
''From now on this '''IF block''' will be '''false''' unless we reset GhostGen back to zero.'' | ''From now on this '''IF block''' will be '''false''' unless we reset GhostGen back to zero.'' | ||
''Do once checksums are another Bread and Butter tool in scripting.'' | ''Do once checksums are another Bread and Butter tool in scripting.'' | ||
''Hence the large number of Doonce variable declared at the top of the script | ''Hence the large number of Doonce variable declared at the top of the script'') | ||
'''endif''' | '''endif''' | ||
'''Endif''' | '''Endif''' | ||
'' | (''Closes the IF statement'') | ||
'''end''' | '''end''' | ||
Line 173: | Line 194: | ||
'''begin gamemode''' | '''begin gamemode''' | ||
'' | (''begins this block whenever the game is in normal game mode. Note | ||
the game has been trying this from the very start of the game, not | |||
just since the above block ran'') | |||
'';This triggers new journal when first arriving at manor'' | |||
''(developers comments)'' | ''(developers comments)'' | ||
'''if ( GetStage MS02 == 30 )''' | '''if ( GetStage MS02 == 30 )''' | ||
'''if ( Player.GetDistance MS02BenirusManorWaitFollow <= 500 )''' | '''if ( Player.GetDistance MS02BenirusManorWaitFollow <= 500 )''' | ||
'' | (''This uses one of the '''Get'''something family of functions to find the distance of the player from an x-marker in the Benirus Manor Cell. Look in the cells object list. '''Get''' type functions are information retrieval functions'') | ||
'''setstage MS02 35''' | '''setstage MS02 35''' | ||
'' | (''Set the stage to 35'') | ||
'''endif''' | '''endif''' | ||
'''endif''' | '''endif''' | ||
Line 202: | Line 221: | ||
'''begin onDeath''' | '''begin onDeath''' | ||
''(Begins when the Actor (ghost) dies. Because this is a reference script attached to the ghost | ''(Begins when the Actor (ghost) dies. Because this is a reference script attached to the ghost it assumes we mean when the ghost dies, and we don't have to give a reference)'' | ||
''';This part of the script enables the inital Ghost Generation & Sets Journal 40''' | ''';This part of the script enables the inital Ghost Generation & Sets Journal 40''' | ||
'''set MS02.GhostJournal to MS02.GhostJournal + 1''' | '''set MS02.GhostJournal to MS02.GhostJournal + 1''' | ||
''(This is a counter that adds to the variable mentioned in the quest script. | ''(This is a counter that adds to the variable mentioned in the quest script. By referencing using "MS02." we can add to it.)'' | ||
'''if ( MS02.GhostJournal == 3) && ( GetStage MS02 <=35 )''' | '''if ( MS02.GhostJournal == 3) && ( GetStage MS02 <=35 )''' | ||
Line 217: | Line 234: | ||
'''VelwynBenirusRef.EvaluatePackage''' | '''VelwynBenirusRef.EvaluatePackage''' | ||
''(This is another really useful bit of script. It is a forced | ''(This is another really useful bit of script. It is a forced | ||
Evaluation of the AI Package that an NPC is using. It is used when we | |||
change a key game condition that affects packages and want it to have | |||
an immediate effect. Normally Actor evaluate its AI once an hour. | |||
When evaluating it choses the first valid AI package in its list'') | |||
'''VelwynBenirusRef.MoveTo MS02VelwynArrivalMarker''' | '''VelwynBenirusRef.MoveTo MS02VelwynArrivalMarker''' | ||
''(This is a Teleport instruction. It instantly moves the Actor | |||
Velwyn Benirus to a marker in the Imperial City, The King and Queen Tavern)'' | |||
'''endif''' | '''endif''' | ||
'''end''' | '''end''' | ||
Line 235: | Line 252: | ||
Stage 40 updates the journal | Stage 40 updates the journal | ||
''Benirus Manor is haunted! I was awakened by ghosts that attacked me as I slept. As I awoke, I thought I heard a crash from downstairs. I should search the house and investigate.'' | ''Benirus Manor is haunted! I was awakened by ghosts that attacked me | ||
as I slept. As I awoke, I thought I heard a crash from downstairs. I | |||
should search the house and investigate.'' | |||
And runs this script | And runs this script | ||
Line 251: | Line 270: | ||
set MS02.fQuestDelayTime to 0 | set MS02.fQuestDelayTime to 0 | ||
This '''enables''' a lot of objects in the house which were previously '''disabled. ''' | |||
Look for the references in the render window. | |||
It also animates the Skeleton hand. | |||
Among the objects enabled is '''Longren's Diary'''. | |||
When the player picks this up in the game it activates this ''script attached to the diary''. | |||
'''Scriptname MS02LorgrenDiaryScrapScript''' | '''Scriptname MS02LorgrenDiaryScrapScript''' | ||
Line 262: | Line 281: | ||
'''if ( GetStage MS02 >=40 ) && ( IsActionRef Player == 1 )''' | '''if ( GetStage MS02 >=40 ) && ( IsActionRef Player == 1 )''' | ||
''(IsActionRef Player is another really useful script function that makes sure | ''(IsActionRef Player is another really useful script function that makes sure it is the player who has activated a scripted object not a NPC)'' | ||
'''Activate''' | '''Activate''' | ||
''(Opens the diary so you can read it)'' | ''(Opens the diary so you can read it)'' | ||
Line 276: | Line 294: | ||
We get another journal update. | We get another journal update. | ||
''I've found a skeletal hand next to a page from a diary. The diary makes mention of a secret room in the house that only a true-blooded Benirus can open. I am going to need to talk to Velwyn about this. I may have to ask around town to find out where he's gone.'' | ''I've found a skeletal hand next to a page from a diary. The diary | ||
makes mention of a secret room in the house that only a true-blooded | |||
Benirus can open. I am going to need to talk to Velwyn about this. I | |||
may have to ask around town to find out where he's gone.'' | |||
And the results script runs | And the results script runs | ||
Line 290: | Line 311: | ||
'''MS02BenirusGhostGRef.Enable''' | '''MS02BenirusGhostGRef.Enable''' | ||
This Enable a whole bunch of ghost creatures | |||
Each has this script attached to them. | |||
'''Scriptname MS02BenirusGhosts''' | '''Scriptname MS02BenirusGhosts''' | ||
Line 302: | Line 323: | ||
'''Return''' | '''Return''' | ||
''(This ends the processing of the '''entire script''' for 1 frame. | ''(This ends the processing of the '''entire script''' for 1 frame. It will try again next frame, but all the lines below this one are not processed following the '''return''' command)'' | ||
'''endif''' | '''endif''' | ||
Line 311: | Line 330: | ||
'''set GhostKill to 1''' | '''set GhostKill to 1''' | ||
'''Endif''' | '''Endif''' | ||
''(This '''if block''' is used to get rid of the ghost near the end of the quest. | ''(This '''if block''' is used to get rid of the ghost near the end of the quest. It also sets ghostKill ==1 so that the return statement kicks in and prevent this script from running every frame)'' | ||
'''if ( GetDisabled == 0 ) && ( GetDead == 1 )''' | '''if ( GetDisabled == 0 ) && ( GetDead == 1 )''' | ||
Line 320: | Line 337: | ||
'''endif''' | '''endif''' | ||
'''endif''' | '''endif''' | ||
'' | (''This block checks that the ghosts have been enabled (not disabled , and that you have killed a ghost and you are in the manor. It then resurrects the ghost. This means they will keep coming back'') | ||
'''end''' | '''end''' | ||
Line 332: | Line 347: | ||
due to the new quest stage bump. | due to the new quest stage bump. | ||
The first directs you to the ''' | The first directs you to the '''Kings Arms.''' The second, if you are | ||
in the ''' | in the '''Kings Arms''', directs you to '''the Imperial City'''. This | ||
second dialogue also sets the stage to 50 in its results script. | second dialogue also sets the stage to 50 in its results script. | ||
Line 340: | Line 355: | ||
Another Journal Update | Another Journal Update | ||
''I've discovered that Velwyn has left town and made his way to the Imperial City. If I am to find out why Benirus Manor is haunted, I need to find him there.'' | ''I've discovered that Velwyn has left town and made his way to the | ||
Imperial City. If I am to find out why Benirus Manor is haunted, I | |||
need to find him there.'' | |||
And a target update setting it to Velwyn Benirus. | And a target update setting it to Velwyn Benirus. | ||
Line 362: | Line 379: | ||
The Journal gets updated | The Journal gets updated | ||
''I've been told that Velwyn stays in the King and Queen Tavern here in the Imperial City. I should go there to find him.'' | ''I've been told that Velwyn stays in the King and Queen Tavern here | ||
in the Imperial City. I should go there to find him.'' | |||
Talking to Velwyn updates the stage to 70 via a dialogue result. The | Talking to Velwyn updates the stage to 70 via a dialogue result. The | ||
Line 370: | Line 388: | ||
=='''Stage 70'''== | =='''Stage 70'''== | ||
''I've found Velwyn at The King and Queen Tavern in the Imperial City. I should speak to him further about the manor and the strange goings on within.'' | ''I've found Velwyn at The King and Queen Tavern in the Imperial | ||
City. I should speak to him further about the manor and the strange | |||
goings on within.'' | |||
To progress to the next stage you have to navigate through a dialogue | To progress to the next stage you have to navigate through a dialogue | ||
Line 387: | Line 407: | ||
Journal updates again | Journal updates again | ||
''After questioning Velwyn, I've learned that his grandfather dabbled in necromancy and was killed when the townspeople of Anvil found out. Strangely, the body was never recovered. Since then, the house has been cursed. I need to convince Velwyn to come back with me to Anvil and lift the curse.'' | ''After questioning Velwyn, I've learned that his grandfather dabbled | ||
in necromancy and was killed when the townspeople of Anvil found | |||
out. Strangely, the body was never recovered. Since then, the house | |||
has been cursed. I need to convince Velwyn to come back with me to | |||
Anvil and lift the curse.'' | |||
If you don't have the diary, Velwyn cuts you short. This is again | If you don't have the diary, Velwyn cuts you short. This is again | ||
Line 398: | Line 422: | ||
The journal updates | The journal updates | ||
''Velwyn agreed to meet me back in Anvil at the Count's Arms. I should return there as soon as possible.'' | ''Velwyn agreed to meet me back in Anvil at the Count's Arms. I should | ||
return there as soon as possible.'' | |||
The stage result script also gives you another disposition bump by 20. | The stage result script also gives you another disposition bump by 20. | ||
Line 410: | Line 435: | ||
will look at characters in the next lesson. | will look at characters in the next lesson. | ||
'''Before we look at the script you may wish to look at the | '''Before we look at the script you may wish to look at the appendix | ||
to this lesson which looks at NPC Behaviour and AI packages. I have | |||
separated it out as it is quite a detailed look at this complex | |||
area. Read it and return here.''' | |||
Back to the Script. Select the • • • next to Script | Back to the Script. Select the • • • next to Script | ||
Line 494: | Line 522: | ||
'''end''' | '''end''' | ||
This block is the first to become active (have its IF conditions met) | This block is the first to become active (have its IF conditions met) | ||
'''if ( GetStage MS02 >=80 ) && ( MenuMode == 0 ) && ( Doonce == 0 ) && ( Player.GetInCell ICElvenGardensTheKingandQueenTavern == 0 )''' | '''if ( GetStage MS02 >=80 ) && ( MenuMode == 0 ) && ( Doonce == 0 ) && ( Player.GetInCell ICElvenGardensTheKingandQueenTavern == 0 )''' | ||
Line 501: | Line 529: | ||
'''Set Doonce to 1''' | '''Set Doonce to 1''' | ||
'' | (''This forces Velwyn back to Anvil as soon as the PC has left the | ||
tavern. The GetInCell check, prevents him just disappearing in front | |||
of the PC. Finally, it forces him to adopt his "back in Anvil" AI | |||
packages. Without this he would simply start walking back to the | |||
Imperial City for lunch'') | |||
'''Endif''' | '''Endif''' | ||
Line 521: | Line 549: | ||
set MS02.BenirusEscort to 1 | set MS02.BenirusEscort to 1 | ||
VelwynBenirusRef.EvaluatePackage | VelwynBenirusRef.EvaluatePackage | ||
'' | (''this sets Velwyn into an Escort package'') | ||
=='''Stage 85'''== | =='''Stage 85'''== | ||
Line 541: | Line 569: | ||
''(bumps the stage)'' | ''(bumps the stage)'' | ||
'''VelwynBenirusRef.StartConversation player, Greeting''' | '''VelwynBenirusRef.StartConversation player, Greeting''' | ||
''(Forces a conversation. The actual greeting depends on whether you are inside | ''(Forces a conversation. The actual greeting depends on whether you are inside or outside the house at the time)'' | ||
'''set BenirusGreet to 1''' | '''set BenirusGreet to 1''' | ||
''(do once checksum)'' | ''(do once checksum)'' | ||
'''set MS02.BenirusFollow to 1''' | '''set MS02.BenirusFollow to 1''' | ||
''(sets a variable to make the next package up the list valid. | ''(sets a variable to make the next package up the list valid. See Velywn's AI packages)'' | ||
'''VelwynBenirusRef.EvaluatePackage''' | '''VelwynBenirusRef.EvaluatePackage''' | ||
''(forces a package change)'' | ''(forces a package change)'' | ||
Line 556: | Line 582: | ||
=='''Stage 87'''== | =='''Stage 87'''== | ||
''Velwyn and I have arrived in Benirus Manor. I must proceed cautiously to the secret room's entrance and prevent any harm from befalling us if the curse is to ever be lifted from this place.'' | ''Velwyn and I have arrived in Benirus Manor. I must proceed cautiously | ||
to the secret room's entrance and prevent any harm from befalling us | |||
if the curse is to ever be lifted from this place.'' | |||
The next AI package, called '''MS02VelwynManorFollow''', will see him | The next AI package, called '''MS02VelwynManorFollow''', will see him | ||
Line 605: | Line 633: | ||
'''set MS02.DoorCheck to 1''' | '''set MS02.DoorCheck to 1''' | ||
'''VelwynBenirusRef.EvaluatePackage''' | '''VelwynBenirusRef.EvaluatePackage''' | ||
''(Forces next package, to simulate door opening activity | ''(Forces next package, to simulate door opening activity'') | ||
'''end''' | '''end''' | ||
Line 611: | Line 639: | ||
'''set MS02.Runaway to 1''' | '''set MS02.Runaway to 1''' | ||
'''VelwynBenirusRef.EvaluatePackage''' | '''VelwynBenirusRef.EvaluatePackage''' | ||
''(Sets Velwyn's behaviour so he will run away. | ''(Sets Velwyn's behaviour so he will run away. Controls any dialogue you try to have with him)'' | ||
'''setstage MS02 90''' | '''setstage MS02 90''' | ||
''(Bumps the stage)'' | ''(Bumps the stage)'' | ||
'''BenirusDoorRef.Activate VelwynBenirusRef''' | '''BenirusDoorRef.Activate VelwynBenirusRef''' | ||
''(This actually opens the door. All the rest of the bits above have been fluff | ''(This actually opens the door. All the rest of the bits above have been fluff and filler aimed at making Velwyn simulate opening the door. This is the only command needed to ACTUALLY open the door)'' | ||
'''set Doonce2 to 1''' | '''set Doonce2 to 1''' | ||
'''end''' | '''end''' | ||
Line 624: | Line 649: | ||
=='''Stage 90'''== | =='''Stage 90'''== | ||
''Velwyn successfully opened the door to the secret room, which has stopped the ghosts from attacking. He then ran off, leaving me to clean up the mess. It's up to me, and me alone, to investigate what's beyond the mysterious portal.'' | ''Velwyn successfully opened the door to the secret room, which has | ||
stopped the ghosts from attacking. He then ran off, leaving me to | |||
clean up the mess. It's up to me, and me alone, to investigate what's | |||
beyond the mysterious portal.'' | |||
The door has its very own script attached to it. Of course it has. | The door has its very own script attached to it. Of course it has. | ||
Line 661: | Line 689: | ||
''(sets the variables)'' | ''(sets the variables)'' | ||
'''[[Begin]] [[OnActivate]]''' | '''[[<u>Begin</u>]] [[<u>OnActivate</u>]]''' | ||
''(starts when the altar is activated)'' | ''(starts when the altar is activated)'' | ||
Line 686: | Line 714: | ||
'''[[Set]] Timer to MS02LorgrenAltarRef.[[Say]] LorgrenSpeech 1 LorgrenBenirusNPC 1''' | '''[[Set]] Timer to MS02LorgrenAltarRef.[[Say]] LorgrenSpeech 1 LorgrenBenirusNPC 1''' | ||
'' | (''This is a very complex bit of script but is also very elegant. '' | ||
''It sets the value of the variable '''Timer''' and at the same activates a conversation info | ''It sets the value of the variable '''Timer''' and at the same activates a conversation info called LorgrenSpeech.'' | ||
''Look this up in the '''topic tab''' for the quest.'' | ''Look this up in the '''topic tab''' for the quest.'' | ||
''The '''1''' forces the subtitles to be displayed.'' | ''The '''1''' forces the subtitles to be displayed.'' | ||
''When the LongrenSpeech starts it plays the first part of a long speech because | ''When the LongrenSpeech starts it plays the first part of a long speech because LongrenBlab is set at 1 and this is one of the '''responses conditions'''.'' | ||
'''''Now here is the really cool bit.''''' | |||
''Now here is the really cool bit.'' | ''Whenever you use the '''Say''' function to force a speech, the Say function returns a '''numerical value''' equivalent to the '''length''' of the mp3 file that '''still has to play'''.'' | ||
''Whenever you use the '''Say''' function to force a speech, the Say function returns | ''So by setting the Variable called Timer to '''MS02LorgrenAltarRef.[[Say]] LorgrenSpeech 1 LorgrenBenirusNPC 1''', you set the timer value to the length of time this response still left to play. As long as this is a positive number the script will not pass its if statement.'' | ||
''Eventually the MP3 file stops and the value ''drops to zero. | |||
''So by setting the Variable called | ''The IF condition passes and the script moves on to the next bit of the speech'') | ||
''Eventually the MP3 file stops and the value drops to zero. | |||
''The IF condition passes and the script moves on to the next bit of the speech | |||
'''[[Set]] LorgrenBlab to 2''' | '''[[<u>Set</u>]] LorgrenBlab to 2''' | ||
'''elseif ( LorgrenBlab == 2 )''' | '''elseif ( LorgrenBlab == 2 )''' | ||
'''[[Set]] Timer to MS02LorgrenAltarRef.[[Say]] LorgrenSpeech 1 LorgrenBenirusNPC 1''' | '''[[<u>Set</u>]] Timer to MS02LorgrenAltarRef.[[<u>Say</u>]] LorgrenSpeech 1 LorgrenBenirusNPC 1''' | ||
''(repeats for each bit of the speech)'' | ''(repeats for each bit of the speech)'' | ||
'''[[Set]] LorgrenBlab to 3''' | '''[[<u>Set</u>]] LorgrenBlab to 3''' | ||
'''elseif ( LorgrenBlab == 3 )''' | '''elseif ( LorgrenBlab == 3 )''' | ||
'''[[Set]] Timer to MS02LorgrenAltarRef.[[Say]] LorgrenSpeech 1 LorgrenBenirusNPC 1''' | '''[[<u>Set</u>]] Timer to MS02LorgrenAltarRef.[[<u>Say</u>]] LorgrenSpeech 1 LorgrenBenirusNPC 1''' | ||
'''[[Set]] LorgrenBlab to 4''' | '''[[<u>Set</u>]] LorgrenBlab to 4''' | ||
'''elseif ( LorgrenBlab == 4 )''' | '''elseif ( LorgrenBlab == 4 )''' | ||
'''[[Set]] Timer to MS02LorgrenAltarRef.[[Say]] LorgrenSpeech 1 LorgrenBenirusNPC 1''' | '''[[<u>Set</u>]] Timer to MS02LorgrenAltarRef.[[<u>Say</u>]] LorgrenSpeech 1 LorgrenBenirusNPC 1''' | ||
'''[[Set]] LorgrenBlab to 5''' | '''[[<u>Set</u>]] LorgrenBlab to 5''' | ||
'''elseif ( LorgrenBlab == 5 )''' | '''elseif ( LorgrenBlab == 5 )''' | ||
''(ends the speech run)'' | ''(ends the speech run)'' | ||
'''[[SetStage]] MS02 100''' | '''[[<u>SetStage</u>]] MS02 100''' | ||
''(bumps the stage)'' | ''(bumps the stage)'' | ||
'''endif''' | '''endif''' | ||
Line 726: | Line 748: | ||
=='''Stage 100'''== | =='''Stage 100'''== | ||
''After touching the altar, I heard the voice of Lorgren Benirus. He said he wished to atone for his past and make peace with the Nines. All he wished was to be whole again. This must be the way to lift the curse from Benirus Manor. I should touch his skeleton while I carry the bony hand and put an end to this madness.'' | ''After touching the altar, I heard the voice of Lorgren Benirus. He | ||
said he wished to atone for his past and make peace with the | |||
Nines. All he wished was to be whole again. This must be the way to | |||
lift the curse from Benirus Manor. I should touch his skeleton while I | |||
carry the bony hand and put an end to this madness.'' | |||
Again we are in a Quest hold until we want to activate the skeleton. | Again we are in a Quest hold until we want to activate the skeleton. | ||
Line 778: | Line 804: | ||
'''MS02LichMarker.[[PME]] MYTH''' | '''MS02LichMarker.[[PME]] MYTH''' | ||
''(PME is shorthand for '''Preload Magical Effects'''. | ''(PME is shorthand for '''Preload Magical Effects'''. This is used for non-magical references which will display a magical effect, in this case an x-marker. It speeds up the processing to avoid any momentary delay in this effect.)'' | ||
'''MS02LorgrenLichRef.[[PlaySound]] AMBBenirusLich''' | '''MS02LorgrenLichRef.[[PlaySound]] AMBBenirusLich''' | ||
''(Plays a sound file. The game carries on as the file plays so you remain in control | ''(Plays a sound file. The game carries on as the file plays so you remain in control of your player)'' | ||
'''[[PlayGroup]] forward ,0''' | '''[[PlayGroup]] forward ,0''' | ||
''(Animates the Lich)'' | ''(Animates the Lich)'' | ||
Line 802: | Line 824: | ||
The Lich has of course got some more script attached. | The Lich has of course got some more script attached. | ||
'''[[Scriptname]] MS02LorgrenScript''' | '''[[<u>Scriptname</u>]] MS02LorgrenScript''' | ||
''' | '''<u>Begin</u> [[<u>OnDeath</u>]]''' | ||
''' | '''<u>SetStage</u> MS02 110''' | ||
''(this is the simplest script of them all. Creature Dead, bump Stage)'' | ''(this is the simplest script of them all. Creature Dead, bump Stage)'' | ||
'''[[End]]''' | '''[[<u>End</u>]]''' | ||
=='''Stage 110'''== | =='''Stage 110'''== | ||
''Completing the skeleton was a ruse and Lorgren rose from the dead! I had no choice but to destroy him. With his destruction, the curse of Benirus Manor was lifted. I should return to The Count's Arms and speak to Velwyn.'' | ''Completing the skeleton was a ruse and Lorgren rose from the dead! I | ||
had no choice but to destroy him. With his destruction, the curse of | |||
Benirus Manor was lifted. I should return to The Count's Arms and | |||
speak to Velwyn.'' | |||
And runs the following results script | And runs the following results script | ||
Line 817: | Line 843: | ||
'''BenirusManorHauntedRef.Disable''' | '''BenirusManorHauntedRef.Disable''' | ||
'''BenirusManorRef.Enable''' | '''BenirusManorRef.Enable''' | ||
''(In the cell containing the house interior are two overlapping interior sets, | ''( In the cell containing the house interior are two overlapping interior sets, this switches which one is active or enabled. When you go back upstairs you will find the place better decorated and a lot nicer to live in)'' | ||
'''BenirusManorExteriorHauntedRef.Disable''' | '''BenirusManorExteriorHauntedRef.Disable''' | ||
'''BenirusManorExteriorRef.Enable''' | '''BenirusManorExteriorRef.Enable''' | ||
''(Does the same switch with the exterior cells.)'' | ''( Does the same switch with the exterior cells.)'' | ||
'''RFDpot01broke01Ref.Disable''' | '''RFDpot01broke01Ref.Disable''' | ||
'''MS02HandLightRef.Disable''' | '''MS02HandLightRef.Disable''' | ||
Line 835: | Line 859: | ||
All we have to do is go see Velwyn in the Kings Arms. | All we have to do is go see Velwyn in the Kings Arms. | ||
When we do this Velwyn will issue a brief statement, close the dialogue and set the stage to 120 | When we do this Velwyn will issue a brief statement, close the dialogue and set the stage to 120 | ||
=='''Stage 120'''== | =='''Stage 120'''== | ||
''I have met Velwyn back at The Count's Arms. He congratulated me and then told me he would be off again to live in the Imperial City. Now I can truly call Benirus Manor my home.'' | ''I have met Velwyn back at The Count's Arms. He congratulated me and | ||
then told me he would be off again to live in the Imperial City. Now I | |||
can truly call Benirus Manor my home.'' | |||
Stage 120 is the final stage in the quest. | Stage 120 is the final stage in the quest. | ||
Line 857: | Line 883: | ||
''(Setting someone's faction value to -1 removes them from the faction)'' | ''(Setting someone's faction value to -1 removes them from the faction)'' | ||
'''VelwynBenirusRef.SetFactionRank ICFaction 0''' | '''VelwynBenirusRef.SetFactionRank ICFaction 0''' | ||
''(setting someone's faction value adds that faction to the actors list. | ''(setting someone's faction value adds that faction to the actors list. If the faction is marked as hide from PC, it will not show up. Only really relevant if the PC joins a faction and you want to decide if the faction will show up on the player's menus)'' | ||
'''SetQuestObject BenirusManorKey 0''' | '''SetQuestObject BenirusManorKey 0''' | ||
''(Removes the Quest Object status from the key so you can put it down)'' | ''(Removes the Quest Object status from the key so you can put it down)'' | ||
Line 885: | Line 908: | ||
'''HOMEWORK:''' | '''HOMEWORK:''' | ||
While you wait for '''Lesson Six''', why not try a couple of things? | |||
1. Choose a quest and see if you can reconstruct its path from rumour to completion. | 1. Choose a quest and see if you can reconstruct its path from rumour to completion. |