Difference between revisions of "A beginner's guide, lesson 7 - Using Scripts in Quests"

imported>Qazaaq
(ready to by wikified)
 
imported>Pyrocow2
(→‎Imperial City Phase Two: Editing dialogue and script)
 
(57 intermediate revisions by 9 users not shown)
Line 1: Line 1:
[quote name='dtom' date='Jul 24 2006, 06:49 PM' post='7398680']
{{Update}}
[url=http://www.elderscrolls.com/forums/index.php?showtopic=517001]Index Page[/url]
{{ABGContents}}


[b]TES IV: Oblivion Modding for Beginners
==Preamble==
 
B. Scripts, Quests and NPC’s
Lesson Seven: Using Scripts in Quests[/b]
 
[b]Preamble[/b]


This is the Seventh in a proposed series of Tutorial Lessons aimed at teaching how to mod TES IV: Oblivion aimed at beginners. It will build up into a Complete Modding Course. Don't worry there are no exams, though there is some homework.
This is the Seventh in a proposed series of Tutorial Lessons aimed at teaching how to mod TES IV: Oblivion aimed at beginners. It will build up into a Complete Modding Course. Don't worry there are no exams, though there is some homework.


[b]Files[/b]
===Files===


I have uploaded some files which we will use to accompany the next few tutorials.  
I have uploaded some files which we will use to accompany the next few tutorials.  
It contains
It contains


[i]A. BGModTutBase.esp:
A. BGModTutBase.esp  
This contains a building, a farmhouse, and a dungeon that we will use as sets in lessons 6, 7 and 8. This file is referred to in the text as the BASE files
This contains a building, a farmhouse, and a dungeon that we will use as sets in lessons 6, 7 and 8. This file is referred to in the text as the BASE files


B BGModTutPlayTest.esp
B. BGModTutPlayTest.esp
This is the interim quest mod illustrating the stage you should have reached prior to polishing the mod. This is referred to in the text as the PLAYTEST files
This is the interim quest mod illustrating the stage you should have reached prior to polishing the mod. This is referred to in the text as the PLAYTEST files


B. BGModAnvilCheat.esp:  
C. BGModAnvilCheat.esp:  
This is a small optional cheat mod to give users 5000 septims to allow them to follow this tutorial if they have not completed the quest. (See Introduction to lesson 4)
This is a small optional cheat mod to give users 5000 septims to allow them to follow this tutorial if they have not completed the quest. (See Introduction to lesson 4)


C. A RTF document containing the text for the first 7 lessons (as requested).
D. A RTF document containing the text for the first 7 lessons (as requested).''
[/i]


[b]Introduction[/b]
'''Download the files [http://www.tesnexus.com/downloads/file.php?id=4865 here.]'''


We have already begun  building a quest. This lesson continues directly where lesson Six left off. We have set up a cottage which the PC will need to investigate to gain clues to identify who has stolen the deed and key. We have learned how to add dialogue using Topic/Response combinations and conditional statements to limit who gets to say the dialogue.  
==Introduction==
 
We have already begun  building a quest. This lesson continues directly where [[A beginner's guide, lesson 6 - Quest Dialogue|Lesson 6]] left off. We have set up a cottage which the PC will need to investigate to gain clues to identify who has stolen the deed and key. We have learned how to add dialogue using Topic/Response combinations and conditional statements to limit who gets to say the dialogue.  


We have seen how to use a limited amount of scripting to progress our quest. While there is loads more dialogue to include in this part of the quest, we will focus far more on the use of scripting.  
We have seen how to use a limited amount of scripting to progress our quest. While there is loads more dialogue to include in this part of the quest, we will focus far more on the use of scripting.  


[b]At the Cottage[/b]
==Cottage Phase==
===Entering the cottage===
We cannot rely on dialogue to progress our quest because the courier is dead.


We cannot rely on any information from NPC’s to progress our quest because the courier is dead.
The next stage bump is done via another addition to the main quest script which will check if the player is inside the cottage or not. We can use the [[GetInCell]] function to do this. If you examine the wiki page, you will see that the usage for that function is:
''[ActorID].''GetInCell CellName
The square brackets indicate that providing an ActorID is optional. In this case, the actor ID will be Player. If you're using the base file provided at the beginning of the tutorial, the cell name will be ''BGModCourierCottage''. If not, it will be whatever you called the cottage cell.


We will first of all use the xmarkerheading object we placed in lesson 6 to identify when the PC gets close enough to trigger a stage bump. By placing the marker inside the cottage, you force the player to be in the cell before this gets triggered.  
When the character enters the cell we want to move to stage 40. We can use the stage to limit when the active part of the script runs. We first need to add stage 40 in the stage tab. Then add this piece of script to the ''GameMode'' block in ''BGM001QuestScript''.


The next stage bump is done via another addition to the quest script. The quest script is used to add small conditional snippets that do useful jobs; In this case we are going to use GetDistance. This in common with all GET functions returns a numerical value. Some Get functions return values which are either 1 (Yes) or 0 (No). For example GetInFaction will return a 1 or 0 depending on whether the reference is in a particular faction or not.
<pre>
If (GetStage BGM001 == 30)
  If (Player.GetInCell BGModCourierCottage == 1)
    SetStage BGM001 40
  EndIf
EndIf
</pre>


The GetDistance function returns a numerical value which indicates how far away a reference is from a specified point. (Distance is measure in UNITS with one game unit roughly equal to 1.5 cm)
In this case, the quest stage acts like a DoOnce type control. During stage 30 of our quest, the game will repeatedly check to see if the player is inside the cottage cell. When the player is finally found inside the cell, the stage will be changed, and this IF block will never be true again (unless the stage is changed back to 30 for some reason).


We will use the distance 300 which is fairly close to but not necessarily on top of the x marker we made. When the character gets close we want to move to stage 40. We can use the stage to limit when the active part of the script runs. We first need to add stage 40 in the stage tab. Now add this below the current IF-End if block inside the begin block of our quest script.
You can add a journal entry for stage 40 to keep the player updated:
''I found the courier's cottage. I should look around for some clues.''


[b]If (GetStage BGM001 == 30)
===Finding the clues===
If (player.GetDistance BgCourierLodgeXMarker <= 300)
Now we need to write a bit of script to handle the two clues we left in the cottage. There's more than one way to do this, but for now we will add a script to each of the clue items, and a couple of new variables to the main quest script.
SetStage BGM001 40
EndIf
EndIf[/b]


In this case the quest stage acts as a DoOnce type control.
First, add the two new variables into the main quest script:
Short HasAmulet
Short HasPaper


Now we need to write a bit of script to check if and when the player collects the two clues needed to allow Hubart to identify the criminal gang.
Then set up the two Object-type scripts. Open the script editor from the Gameplay menu, and make sure to set the script type before saving.


We have to set up a counter variable which I have called QObjectCount. (Type short). Each time a player adds one of the quest objects to their inventory we need to bump this counter by one. 
This is the script that will be attached to the torn letter:
<pre>
SCN BGPartialLetterSCRIPT


We also want to know when each item is picked up so we can display a suitable message informing the player to keep looking. Again this is hand holding, and can be left out for a greater challenge and a deeper immersion.  
Begin OnAdd Player
If (BGM001.HasAmulet == 0)
MessageBox "I found a torn document. I should continue to look for more clues."
Else
SetStage BGM001 50
EndIf
Set BGM001.HasPaper to 1
End
</pre>


We are going to write some script. Experienced scripter will throw their hands up at the clumsy nature of this bit of the script, but it gets the job done and I believe it is easier to follow the logic of why each line is added in this version.
And this is the script that will be attached to the amulet:
<pre>
SCN BGEmbossedAmuletSCRIPT


Perhaps one of the greats will re-write this in a more concise form at some point.
Begin OnAdd Player
 
If (BGM001.HasPaper == 0)
So we declare the three variables to add to our variable list at the top of the script. You will notice that the list keeps growing as we find we need new variables.
MessageBox "I found a strange amulet in the cottage. I should continue to look for more clues."
 
Else
[b]Short Qobjectcount
SetStage BGM001 50
Short Count1Once
Short Count 2 Once[/b]
 
We will add to the script already inside the current Begin GameMode block. We could always add a new Begin Block, but why add lines that we don’t need. Note the use of indents in an IF statement is purely for clarity and has no bearing on the running of the script.
 
We want this script to work if the amount of clues (QObjectCount) is less than 2.
Once we have both we don’t want it to work.
 
So we set an IF condition
 
[i]If (QObjectCount < 2)[/i]
 
Now we can use a nested IF statement. This is an IF statement within an IF statement. We will also use the && (AND) command. This combines IF conditions so that BOTH must be met for the first bit of script to work. If either or both fail the IF block moves on to any elseIF, or else statements. Otherwise it ends that block.
We want to check if the player has a copy of the BGPartialLetter in their inventory (GetItemCount) and that we have never checked this before(Count1Once).
If this is true we add one to the clue counter (QObjectCount) and add one to the DoOnce counter Count1Once.  
This will stop the script from counting this item again the next time it runs (5 secs)
If (Player.GetItemCount "BGPartialLetter" >=1) && (Count1Once==0)
Set QObjectCount to QObjectCount +1
Set Count1Once to 1
EndIf
 
We repeat this for the second clue item the BGEmbossedAmulet
 
If (Player.GetItemCount "BGEmbossedAmulet" >=1) && (Count2Once==0)
Set QObjectCount to QObjectCount +1
Set Count2Once to 1
EndIf
EndIf
Set BGM001.HasAmulet to 1
End
</pre>


Finally, we add
Add these scripts to the appropriate objects by opening up their details window and selecting them from the Script drop-down menu.
 
EndIf
 
To finish this whole block
 
It should read.
 
[b]If (QObjectCount < 2)
If (Player.GetItemCount "BGPartialLetter" >=1) && (Count1Once==0)
Set QObjectCount to QObjectCount +1
Set Count1Once to 1
EndIf
If (Player.GetItemCount "BGEmbossedAmulet" >=1) && (Count2Once==0)
Set QObjectCount to QObjectCount +1
Set Count2Once to 1
EndIf


EndIf[/b]
The scripts are very similar. Here's how they work: [[OnAdd]] is a hook that will be called by the object when it is added to an inventory. If you examine the wiki page for OnAdd, you will see that a parameter can be added so that the block is only triggered when the item is added to a particular inventory. In our case, we want that to be the player's inventory, so we used "OnAdd Player".


We now have the following bits of info in usable mathematical form.  
Then, inside the OnAdd block, we check to see whether or not the player has found the OTHER clue. If the play has NOT found the other clue, we give them a message that tells them to continue looking. If the player DOES have the other clue, they are done looking, and we can bump the quest stage to 50.


We know when we have both clues - QObjectCount
After the check, we change the appropriate quest variable to indicate that the player has found that item.
We know when we have each individual clue - Count1Once and Count2Once


We want to display different messages depending on what combination of clues we have. There are four possibilities leading to four simple IF statements.
Remember to create stage 50, and then add this journal entry for it:
The values of the new variable MessageStage are just so we can clearly tell them apart.
I chose 100, 50, 25, and 10. It could be any number you like.
You will need to declare the variable MessageStage first.
Do this and then type this script, once again inside the Begin End block.


[b]If (count1Once == 0) && (Count2Once==0)
''I found some clues for Captain Hubart to work with. I should return to him in Chorrol.''
Set MessageState to 100
EndIf
If (count1Once == 0) && (Count2Once==1)
Set MessageState to 50
EndIf
If (count1Once == 1) && (Count2Once==0)
Set MessageState to 25
EndIf
If (count1Once == 1) && (Count2Once==1)
Set MessageState to 10
EndIf[/b]
Now we use the message state to set the on screen message. This part of the script is very clumsy and can be cleaned up. We will do this in lesson eight.
Again we need to set some DoOnce variables to stop the messages being displayed again and again. I have called these DoM2Once etc.
The first message state can be ignored because we don’t need to prompt them again to search for clues.
[b]If (DoM2Once == 0) && (MessageStage == 50)
MessageBox "I have found a strange amulet. I should continue to look for clues"
Set DoM2Once to 1
EndIf
 
If (DoM3Once == 0) && (MessageStage == 25)
MessageBox "I have found a torn document. I should look for more clues"
Set DoM3Once to 1
EndIf[/b]
 
The final situation does not require a MessageBox. As the quest journal can convey the message. But we do need to bump the quest stage. Again create stage 50 first.
 
[b]If (DoM4Once == 0) && (MessageStage == 10)
Set DoM4Once to 1
SetStage BGM001 50
EndIf
[/b]
 
This produces a stage bump. Add stage 50 and this journal entry.
 
I should now return to see Captain Hubart with these clues


===Returning the clues===
Now we can now set up the next bit of interaction with Hubart.  
Now we can now set up the next bit of interaction with Hubart.  
We use the topic BGCluesFound that was added earlier. We want one response if the player has not collected the clues yet, and another for when they have collected the clue. We can use the quest stage as a condition. Set up the responses so that a new topic called BGRedRose is added if we have the clues.
TOPIC
BGCluesFound


RESPONSE
We use the topic ''BGCluesFound'' that was added earlier. We want one response if the player has not collected the clues yet, and another for when they have collected the clue. We can use the quest stage as a condition. Set up the responses so that a new topic called ''BGRedRose'' is added if we have the clues.
I recognise this amulet. It belongs to a gang of thieves called the Red Rose Brigade


CONDITIONS
{| border="1" cellpadding="5"
GetIsId  BGCptHubart == 1
!colspan=2| '''BGCluesFound'''
GetQuestStage BGM001 == 50
|-
!  TOPIC TEXT
|  "Clues"
|-
!  RESPONSE
|
*"I recognize this amulet! It bears the mark of a gang of thieves that call themselves the Red Rose Brigade."
*"Did you find the key or deed mentioned in the letter there? No? Then those thieves must have taken them..."
|-
CONDITIONS
* GetIsId  'BGCptHubart' == 1
* GetStage 'BGM001' == 50
|-
!  OPTIONS
|
*Say Once
|-
!  ADD TOPICS
* BGRedRose
|-
!  RESULT SCRIPT
|
<pre>
Player.RemoveItem "BGPartialLetter" 1
Player.RemoveItem "BGEmbossedAmulet" 1
Player.RemoveItem "BGCourierKey" 1
</pre>
|}


ADD TOPICS
The script simulates Cpt. Hubart taking the clues and key from us. The "Say Once" option should be checked because we only want this dialogue and script to run once (obviously), but our condition checks won't ensure that as is. We haven't changed the stage or anything like that.
BGRedRose
RESULT SCRIPT


And
If the player only has one of the clues, this response will be available:
TOPIC
BGCluesFound


RESPONSE
{| border="1" cellpadding="5"
I need more clues to work with.
!colspan=2| '''BGCluesFound'''
|-
!  TOPIC TEXT
|  "Clues"
|-
RESPONSE
|  "I need more to work with."
|-
!  CONDITIONS
* GetIsId  'BGCptHubart' == 1
* GetStage 'BGM001' == 40
* GetQuestVariable 'BGM001.HasAmulet' == 1 ''OR''
* GetQuestVariable 'BGM001.HasPaper' == 1 ''OR''
|-
!  ADD TOPICS
|  ''No add topic''
|-
!  RESULT SCRIPT
|  ''No script''
|}


CONDITIONS
This is the first time we've checked the ''OR'' flag on a condition. If any of the ''OR'' conditions are true, we basically get a TRUE for that entire set of ''OR'' conditions. So if the player has either the amulet or the paper, the stage is 40, and the actor is Cpt. Hubart, this response will show up. The ''OR'' statements by themselves would also work if we had BOTH of the objects (both would be true), but because we already would have changed the stage to 50 in that case, the stage condition here fails and eliminates the response. (50 != 40)
GetIsId  BGCptHubart  == 1
GetQuestStage BGM001 < 50


ADD TOPICS
===Leading the player to the next phase===
RESULT SCRIPT
For the Red Rose topic add this response and add a new topic called ''BGSmith''.


For the Red Rose topic add this response and add a new topic called BGSmith.
{| border="1" cellpadding="5"
TOPIC
!colspan=2| '''BGRedRose'''
BGRedRose (Red Rose Brigade)
|-
 
TOPIC TEXT
RESPONSE
| "Red Rose Brigade"
They are a nasty bunch led by a couple of villains called Blair and Brown.
|-
I know they have a secret hide out in the mountains.
RESPONSE
Your best bet is to talk to an ex gang member by the name of Smith.
I am surprised. I never took Brown for a killer.
* "They're a nasty bunch led by a couple of villains named Blair and Brown."
 
* "They have a hideout in the mountains."
CONDITIONS
* "If you want to find them, your best bet is to talk to an ex-member named Smith."
GetIsId BGCptHubart == 1
* "I'm surprised... I never took Brown for a killer."
GetQuestStage BGM001 == 50
|-
 
CONDITIONS
ADD TOPICS
BGSmith
* GetIsId 'BGCptHubart' == 1
RESULT SCRIPT
* GetStage 'BGM001' == 50
 
|-
We can remove the quest clues as they are no longer needed.
ADD TOPICS
* BGSmith
|-
RESULT SCRIPT
|  ''No script''
|}


Finally add the Brandy, if you wish. Alternatively we could omit this and allow the player to make his choices
Finally add the Brandy, if you wish. Alternatively we could omit this and allow the player to make his choices


TOPIC BGSmith (Smith)
{| border="1" cellpadding="5"
 
!colspan=2| '''BGSmith'''
RESPONSE
|-
Yeah, he quit the gang a while back. you'll find him hanging out at the Aleswell Inn
TOPIC
He's partial to a drop of Brandy. That might help loosen his lips.
|  "Smith"
I take back the cottage key and hold on to this document
|-
 
RESPONSE
CONDITIONS
GetIsId BGCptHubart == 1
* "He quit the gang a while back and moved to Aleswell. You'll probably find him in the inn there."
GetQuestStage BGM001 == 50
* "He's partial to a drop of brandy. Here, this might help loosen his lips."
 
|-
ADD TOPICS
CONDITIONS
 
RESULT SCRIPT
* GetIsId 'BGCptHubart' == 1
* GetStage 'BGM001' == 50
|-
ADD TOPICS
|  ''No add topic''
|-
RESULT SCRIPT
<pre>
Player.Additem "PotionCyrodiilicBrandy" 1
Player.Additem "PotionCyrodiilicBrandy" 1
Player.RemoveItem "BGPartialLetter" 1
Player.RemoveItem "BGCourierKey" 1
Player.RemoveItem "BGEmbossedAmulet" 1
SetStage BGM001 60
SetStage BGM001 60
</pre>
|}
To complete this section we need to update the journal and move on to Aleswell.
To complete this section we need to update the journal and move on to Aleswell.
Add this to the Stage 60 journal entry.
Add this to the Stage 60 journal entry.


I should travel to Aleswell and talk to ex red Rose Gang member Smith. He may be able to help me locate the gangs hide out
''Captain Hubart told me that the amulet I found near the courier's body belongs to a gang of thieves named the Red Rose Brigade. He told me that my best chance of finding them is to talk with an ex-member named Smith, who now lives in Aleswell.''
 
[b]Aleswell Phase.[/b]


Objectives: - [i]This is the last section prior to the big show down. We want to set up a disposition based dialogue in which Smith, once he likes you enough, will give you the location and key to the hidden Red Rose Brigade cave system.[/i]
==Aleswell Phase==


We need to create
This is the last section prior to the big show down. We want to set up a disposition based dialogue in which Smith, once he likes you enough, will give you the location and key to the hidden Red Rose Brigade cave system.


[i]Hideout Key.
We need to create:
NPC called Smith.
a map marker to the exterior of the Cave system.
the Cave system (if you are not using the base files)[/i]


First we want set up our NPC.
* Hideout Key
We need this so we can add a quest target.
* NPC called Smith
I used a member of the thieves guide as a base. I again stripped out his AI, but I left him as a member of the thief’s guild. This will help fellow guild members get a bit of a boost to their disposition.
* Map marker to the exterior of the Cave system
* The Cave system (if you are not using the base files)


I have chosen Aleswell as a set for this part of the quest because it is actually a lousy location to use. Aleswell is the setting for an interesting Miscellaneous Quest. In this quest all the inhabitants of the town are invisible. If the user has completed this quest before they load this mod, they will be no problem. However, if this id the first time a player has entered the in, they will find themselves immediately involved in this quest. We need to make sure our mod interacts with this quest.  
===Creating Smith===
First we want set up our NPC.


We could of course use some scripts (see lesson 8) that hides Smith in amongst the invisible folk until you solve this one. This in effects gives our quest a bit of a bonus making our storyline even longer.  
I used a member of the Thieves Guild as a base. I stripped out his AI, but I left him as a faction member of the Thieves Guild. This will help fellow guild members get a bit of a boost to their disposition.  


But as is so often the case, the simplest solution, is to just brush over it with a quick bit of dialogue.  
I have chosen Aleswell as the location for this part of the quest because it is actually a lousy location to use. Aleswell is the setting for an interesting Miscellaneous Quest. In this quest all the inhabitants of the town are invisible. If the user has completed this quest before they load this mod, there will be no problem. However, if this is the first time a player has entered the inn, they will find themselves immediately involved in this quest. We need to make sure our mod interacts with this quest.  
We can set up a GREETING for Smith. Here we use the quest stage for the miscellaneous quest called MS47  Zero Visibility. This is the stage where the people of Aleswell become visible.  


TOPIC
We could use some scripts (see lesson 8) to make Smith invisible along with the rest of the citizens. But, as is so often the case, the simplest solution is to just brush over it with a quick bit of dialogue.
GREETING


RESPONSE
We can set up a GREETING for Smith. Here we use the quest stage for the miscellaneous quest called MS47 Zero Visibility. This is the stage where the people of Aleswell become visible.  
This is so weird. Everyone is invisible. I came here to blend in with a crowd. Just my luck


CONDITIONS
{| border="1" cellpadding="5"
GetIsId  BGMSmith == 1
!colspan=2| '''GREETING'''
GetStage MS47 < 50
|-
!  TOPIC TEXT
|  GREETING
|-
!  RESPONSE
|  "This is so weird. Everyone here is invisible. I came here to blend in with the crowd.. just my luck."
|-
CONDITIONS
* GetIsId  'BGMSmith' == 1
* GetStage 'MS47' < 50
|-
!  ADD TOPICS
|  ''No add topic''
|-
!  RESULT SCRIPT
|  ''No script''
|}


ADD TOPICS
===Information gathering===
RESULT SCRIPT
The next bit of the quest is a bit tricky.  
The next bit of the quest is a bit tricky.  


Line 286: Line 287:
Let’s do that now.
Let’s do that now.


TOPIC
{| border="1" cellpadding="5"
BGRedRoseBrigade
!colspan=2| '''BGRedRose'''
 
|-
RESPONSE
TOPIC TEXT
I don't know you, and I don't think I want to talk to you about them
|  "Red Rose Brigade"
|-
CONDITIONS
RESPONSE
GetIsId BGMSmith == 1
|  "Hey, I'm done with them. That's all I have to say about that."
GetDisposition < 90
|-
 
CONDITIONS
ADD TOPICS
BGBrandy
* GetIsId 'BGMSmith' == 1
* GetDisposition [TARGET] < 90
|-
!  OPTIONS
|
*Info Refusal
|-
ADD TOPICS
* BGBrandy
|-
!  RESULT SCRIPT
|  ''No script''
|}


RESULT SCRIPT
The "Info Refusal" flag will make sure that the topic text does not get grayed out, so that the player knows there is still more information available for that topic.
We then check the[b] Info Refusal[/b] flag.
This means this topic can be revisited and the response will be re-evaluated.


As long as the disposition to the player is less than 90, Smith will give us the brush off when we talk about the Red Rose Brigade.
As long as the disposition to the player is less than 90, Smith will give us the brush off when we talk about the Red Rose Brigade.


Somehow we will need to get that disposition up. If the PC is a member of the thieves guide that will help. We can bribe the NPC or play the disposition game. Of course PC’s with good speech craft will also get a bonus. However, I have deliberately set the threshold high because I want to use the BRANDY idea we set up in Chorrol.  
Somehow we will need to get that disposition up. If the PC is a member of the Thieves Guild, that will help. We can also bribe the NPC or play the disposition game with him. Of course if the player is good with speech craft, that will also get them a bonus. However, I have deliberately set the threshold high because I want to use the brandy idea we set up in Chorrol.


[b]Designing an Object Script[/b]
====Using choices in dialogue====
To do this we will set up a bit of dialogue where the player can choose give Smith some brandy.


The first bit of scripting we did was to overcome the lack of an NPC to progress our quest. This time the problem is a little less clear. We want to set the game up so that giving some Brandy to Smith that boosts his disposition towards us.  
First, create the choice topics: BGBrandyYes, and BGBrandyNo.


It is no great chore to add a choices response to the Brandy topic.
{| border="1" cellpadding="5"
!colspan=2| '''BGBrandyNo'''
|-
!  TOPIC TEXT
|  "No, sorry."
|-
!  RESPONSE
|  "Aw, that's a shame..."
|-
!  CONDITIONS
* GetIsId 'BGMSmith' == 1
* GetStage 'BGM001' == 60
|-
!  ADD TOPICS
|  ''No add topics''
|-
!  RESULT SCRIPT
|  ''No result script''
|}


Choice 1 – Gives him the brandy and bump disposition via a result script
This is just a simple piece of dialogue.
Choice 2 – Refuses to give him brandy.


This is how I initially set it up. However there are two big problems with this solution.  
The "Yes" choice will be more complicated. We will have to check the player's inventory to see if they have any brandy, and if they do, run a script to change the player's disposition.


The first problem is that it is a one time only action. You can’t keep giving him Brandy because the result script as we have set up the quest only allows this script to run once.
{| border="1" cellpadding="5"
!colspan=2| '''BGBrandyYes'''
|-
!  TOPIC TEXT
|  "I sure do. Here, have some!"
|-
!  RESPONSE
|  "Wonderful! Uh.. what? Oh no! Has the brandy turned invisible, too?!"
|-
!  CONDITIONS
* GetIsId 'BGMSmith' == 1
* GetStage 'BGM001' == 60
* '''GetItemCount 'PotionCyrodiilicBrandy' == 0 (RUN ON TARGET)'''
|-
!  ADD TOPICS
|  ''No add topics''
|-
!  RESULT SCRIPT
|  ''No result script''
|}


The second problem is more serious. If we give him some Brandy we have to remove it from the players inventory. But what happens if the player does not have any Brandy in his inventory. Perhaps he drunk the supply Hubart gave him, or sold it, or put it in a safe place and forgot it. The RemoveItem function does not check if an item is there. If it is not the item is removed and the inventory is set at -1.  
This is the response that the player will get if they have no brandy. You MUST check the "Run on Target" box for the [[GetItemCount]] condition in order for this to work. Otherwise, the GetItemCount will check the Smith NPC's inventory! (The player is the target in this case.)


This is not a good situation. Of course the player can reset it to zero by obtaining some more Brandy, but it is messy. It also is silly that the player hands smith a bottle of Brandy when he hasn’t got one.
Before making the next response, quickly go back the Smith NPC that you dropped in AleswellInn. Open up the details for the one you dropped - the reference, not the base NPC itself - and name it ''BGMSmithREF''. The ''Persistent Reference'' box should also be checked already.


We need to have some kind of if statements that check the Brandy is in the inventory, and another option to offer more.
{| border="1" cellpadding="5"
!colspan=2| '''BGBrandyYes'''
|-
!  TOPIC TEXT
|  "I sure do. Here, have some!"
|-
!  RESPONSE
|  "Wonderful! Cheers!"
|-
!  CONDITIONS
* GetIsId 'BGMSmith' == 1
* GetStage 'BGM001' == 60
* '''GetItemCount 'PotionCyrodiilicBrandy' >= 1 (RUN ON TARGET)'''
|-
!  ADD TOPICS
|  ''No add topics''
|-
!  RESULT SCRIPT
|
<pre>
BGMSmithREF.ModDisposition Player 15
Player.RemoveItem "PotionCyrodiilicBrandy" 1
</pre>
|}


The solution is to Script this. Here is a working script that does this. We can use a bit of dialogue to set the value of the variable BrandyTalk. Before we look in detail at the script. Take a look through it. Try to work out what each bit is doing. This is a great way to learn scripting. Scour the forums for examples of scripts and try to work out what is happening. 
The ModDisposition function will simply increase the NPCs disposition towards the player by 15. Then one bottle of brandy will be taken from the player's inventory. Then we'll set up the dialogue that leads to these two choices:


[b]Scriptname BGM001SmithScript


Short DoOnce
{| border="1" cellpadding="5"
Short Button
!colspan=2| '''BGBrandy'''
Short BrandyTalk
|-
Begin GameMode
!  TOPIC TEXT
|  "Brandy"
|-
!  RESPONSE
|  "Yeah, I love the stuff. Have you any to spare?"
|-
!  CONDITIONS
* GetIsId 'BGMSmith' == 1
* GetStage 'BGM001' == 60
|-
!  CHOICES
|
*BGBrandyYes
*BGBrandyNo
|-
!  ADD TOPICS
|  ''No add topics''
|-
!  RESULT SCRIPT
|  ''No result script''
|}


If (BrandyTalk == 1) && (GetStage BGM001 == 60)
The ''Choices'' list is right under the ''Add Topics'' list. Add the choice topics in the same way you would add an add topic in.
If (Player.GetItemCount "PotionCyrodiilicBrandy" >=1)
If (DoOnce==0)
MessageBox "How many Bottles of brandy would you like to give to Smith", "None", "One", "Two", "Three", "Four"
Set DoOnce to 1
EndIf
EndIf
Else
Return
EndIf


If (DoOnce==1) &&(GetStage BGM001 == 60)
===Success===
Set Button to GetButtonPressed
By a combination of speech craft, factions, bribes disposition games and brandy gifts the Player should be able to raise the disposition to 90 eventually. This will trigger the next bit of dialogue and send us towards the quest climax. Return to the BGRedRose topic and add this:
EndIf


If (Button>= -1)&&(GetStage BGM001 == 60)
{| border="1" cellpadding="5"
If (Button == 0)
!colspan=2| '''BGRedRose'''
Set BGM001.BrandyTalk to 0
|-
Return
!  TOPIC
EndIf
|  "Red Rose Brigade"
|-
!  RESPONSE
* Ok, the truth is I've fallen out with the gang. They've threatened to kill me for leaving."
* "You look like you can take care of them."
* "Watch out for Blair, though, he's a nasty bit of work."
* "I'll mark the hideouts location on your map. And here's my old key... I hope it still works."
* "Mind you, I'm surprised at Brown. He was a decent chap when I was in the gang..."
|-
!  CONDITIONS
* GetIsId 'BGMSmith' == 1
* GetStage 'BGM001' == 60
* GetDisposition [TARGET] >= 90
|-
!  ADD TOPICS
|  ''No add topic''
|-
!  RESULT SCRIPT
<pre>
SetStage BGM001 70
Player.Additem "BGHideoutKey" 1
ShowMap BGCaveMapMarker
</pre>
|}
===Map markers===
The result script bumps the quest stage to 70 and gives the player the key and map marker. In the quest stage section for stage 70 we can add an appropriate journal entry.


If (Button == 1)
Of course before we do this we need to add the MapMarker to the exterior of our cave. The cave system cell is ''BGmodtSugglersCaveCOPY0000'' in the ''Interiors'' worldspace. The cave exterior cell is ''BGTutMCaveExt'' in the ''Tamriel'' worldspace.
If(Player.GetItemCount "PotionCyrodiilicBrandy" >=1)
Player.RemoveItem "PotionCyrodiilicBrandy" 1
BGMSmithRef.ModDisposition player 15
Set BrandyTalk to 0
Else
Message “You don't have enough Brandy"
EndIf
EndIf


If (Button == 2)
If(Player.GetItemCount "PotionCyrodiilicBrandy" >=2)
Player.RemoveItem "PotionCyrodiilicBrandy" 2
BGMSmithRef.ModDisposition player 30
Set BrandyTalk to 0
Else
Message “You don't have enough Brandy"
EndIf
EndIf
If (Button == 3)
If(Player.GetItemCount "PotionCyrodiilicBrandy" >=3)
Player.RemoveItem "PotionCyrodiilicBrandy" 3
BGMSmithRef.ModDisposition player 45
Set BrandyTalk to 0
Else
Message “You don't have enough Brandy"
EndIf
EndIf
If (Button == 4)
If(Player.GetItemCount "PotionCyrodiilicBrandy" >=4)
Player.RemoveItem "PotionCyrodiilicBrandy" 4
BGMSmithRef.ModDisposition player 60
Set BrandyTalk to 0
Else
Message “You don't have enough Brandy"
EndIf
EndIf
EndIf
End[/b]
(you may have to edit “ marks for script, problem with my text ecitor)
We attach this script once compiled to the NPC character BGMsmith using the script box in the character interface.
Let’s look more closely at this script.
We use the top section to declare variables.
The script is broken into 3 sections contained in a Begin GameMode Block.
Firstly
[i]If (BGM001.BrandyTalk == 1) && (GetStage BGM001 == 60)
If (Player.GetItemCount "PotionCyrodiilicBrandy" >=1)
If (DoOnce==0)
MessageBox "How many Bottles of brandy would you like to give to Smith", "None", "One", "Two", "Three", "Four"
Set DoOnce to 1
EndIf
EndIf
Else
Return
EndIf
[/i]
(Note the MessageBox statement should all be on one line, it is only the result of wrap around text in this document that produces the look above . It should be
MessageBox "How many Bottles of brandy would you like to give to Smith", "None", "One", "Two", "Three", "Four"
This is the control part of the script. It checks that a number of conditions are true.
Firstly it checks the status of a variable called BrandyTalk. We set this to 1 using a conversation between the PC and Smith. Until this happens the script will fail it conditions and skip to the
[i]Else
Return[/i]
This terminates the script and prevents any further processing.
The second check is the GetStage check. This will prevent the script from running later in the quests progress.
If we have talked to Smith about Brandy, the core bit of this check runs.
[i]If (Player.GetItemCount "PotionCyrodiilicBrandy" >=1)
If (DoOnce==0)
MessageBox "How many Bottles of brandy would you like to give to Smith", "None", "One", "Two", "Three", "Four"
Set DoOnce to 1
EndIf
EndIf
[/i]
We again carry out some relevant tests. The first checks that the player does indeed have Brandy in his inventory. This uses the GetItemCount function.  We then set up a DoOnce loop to prevent the message box from being displayed again and again.
MessageBox is one of the two communication functions. It displays the text in the form of a pop-up box which will also produce a number of labelled buttons. We will look in more detail at some other functions of MessageBox in a later lesson.
The second block will only run once the value of DoOnce has been set to one in the above block
[i]If (DoOnce==1) &&(GetStage BGM001 == 60)
Set Button to GetButtonPressed
EndIf
[/i]
GetButtonPressed returns a value equivalent to the ‘buttons’ position in the message box list. It is normally set at -1 but takes the values 0-9 depending on the button selected.
MessageBox “Some Message that appears in the Box” ,Option A, OptionB, OptionC
[i]OptionA selected GetButtonPressed=0
OptionB selected GetButtonPressed=1
OptionC selected GetButtonPressed=2
[/i]
The value selected and assigned to the variable Button is then used in the third part of the script.
This is a little longer. It begins with a check that we have assigned a value by pressing the button.
[i]If (Button>= -1)&&(GetStage BGM001 == 60)[/i]
Then we move onto the working parts of the script.
If we select none, the script resets the value of BrandyTalk and DoOnce to zero. We are then able to use the script again later.
[i]if (Button == 0)
Set BGM001.BrandyTalk to 0
Set DoOnce to 0
return
EndIf[/i]
If we select one bottle. Then the next bit of script checks if we have enough brandy in our inventory to give Smith one bottle. It takes the bottle from your inventory. It then increases Smiths Disposition towards you by 15.
Finally It resets the control variables to allow the script to run again later.
Note in this version we don’t actually give Smith the brandy. There is no technical need to do so. 
If you don’t have enough you get a message and then it  resets the controlling  variables.
[i]If (Button == 1)
If(Player.GetItemCount "PotionCyrodiilicBrandy" >=1)
Player.RemoveItem "PotionCyrodiilicBrandy" 1
BGMSmithRef.ModDisposition player 15
Set BGM001.BrandyTalk to 0
Set DoOnce to 0
Else
Message “You don't have enough Brandy"
Set BGM001.BrandyTalk to 0
Set DoOnce to 0
EndIf
EndIf[/i]
The remainder of the script is a repeat of this for the options 2 bottles, 3 bottles, and 4 bottles.
The trick with any script is to exercise some control over when the script runs. We are controlling this script using a key quest variable called BrandyTalk. Before we can compile our script we will have to add this variable to the quest script.
We adjust its value using  topics called BGBrandy, BGBrandyChoice1, and BGBrandyChoice2
TOPIC
BGBrandy
RESPONSE
Yeah, I love the stuff. Have you  any to spare?
CONDITIONS
GetIsId  BGMSmith == 1
GetStage BGM001 == 50
ADD TOPICS
(in Choices) BGBrandyChoice1, BGBrandyChoice2
RESULT SCRIPT
We can then use the choices to set our control variable to 1. 
But the problem still remains that this result script will only be carried out once.
The solution is simply to make copies of the response and use another variable to increment through them so that each one becomes valid.
You can do this as many times as you like.
I settled for 4. I think it is unlikely you will need more than three turns but the option is there.
Add another quest variable to the quest script called DoNextBrandy
TOPIC
BGBrandyChoice1(Yes, I might have)
RESPONSE
I think I might warm to you.
CONDITIONS
GetIsId  BGMSmith == 1
GetStage BGM001 == 50
GetQuestVariable BGM001.DoNextBrandy == 0
ADD TOPICS
RESULT SCRIPT
Set BGM001.BrandyTalk to 1
Set BGM001. DoNextBrandy to 1
The second response info reads
TOPIC
BGBrandyChoice1(Yes, I might have)
RESPONSE
I think I might warm to you.
CONDITIONS
GetIsId  BGMSmith == 1
GetStage BGM001 == 50
GetQuestVariable BGM001.DoNextBrandy == 1
ADD TOPICS
RESULT SCRIPT
Set BrandyTalk to 1
Set DoNextBrandy to 2
Add another couple of responses, make all of them goodbyes using the Good bye flag. this ends the dialogue automatically, closes the topic menu and forces the now active script to run.
We also need to add a negative response. Note there is no result for this one, and you don’t need to make it a goodbye.
TOPIC
BGBrandyChoice2 (No sorry I’m out)
RESPONSE
Pity, I might have liked you more if you did.
CONDITIONS
GetIsId  BGMSmith == 1
GetStage BGM001 == 50
ADD TOPICS
RESULT SCRIPT
By a combination of speech craft, factions, bribes disposition games and brandy gifts the Player should be able to raise the disposition to 90 eventually. This will trigger the next bit of dialogue and send us towards the quest climax. Return to the BGRedRoseBrigade topic and add this
TOPIC
BGRedRoseBrigade
RESPONSE
Ok, the truth is I've fallen out with the gang. They've threatened to kill me for leaving
You look like you can take care of them.
Watch out for Blair he is a nasty bit of work.
Here's the hideout key, and I'll mark the hideouts location on your map.
Mind you I am surprised at Brown. He was a decent chap when I was in the gang
CONDITIONS
GetIsId  BGMSmith == 1
GetDisposition >=90
ADD TOPICS
RESULT SCRIPT
SetStage BGM001 70
We can then use the result script to bump the stage to 70
In the quest stage section for stage 70 we can add an appropriate journal entry and a quest stage result script to add a key and activate another map marker.
Of course before we do this we need to add the MapMarker to the exterior of our cave. The cave system is called BGmodRRBCave.
Again we can use the door teleport marker to get ourselves to the exterior location.  
Again we can use the door teleport marker to get ourselves to the exterior location.  
Drop in a MapMarker and give it a Suitable reference name like BGCaveMapMarker.  
Drop in a MapMarker and give it a Suitable reference name like ''BGCaveMapMarker''.  


Journal entry
Journal entry:
[i]Smith has given me a key for the Red Rose Brigades hideout. I should go to the hideout and see if I can recover my uncles Key and House deed.[/i]
''Smith gave me a key for the Red Rose Brigade's hideout. I should go to the hideout and see if I can recover my uncle's key and house deed.''


Result script
==Red Rose Hideout Phase==
This is the climax of our quest. The player will travel to a cave and finally have his showdown with the Red Rose Brigade. We also want to set up a treasure chest as an additional reward. To make the player's task a little harder, we will need to add some goons to fight along the way.


[i]Player.Additem "BGHideoutKey" 1
We will need:
ShowMap BGCaveMapMarker
[/i]


[b]Red Rose Hideout Phase[/b]
* Dungeon/Cave system
* Letter, adding extra clue from Brown about chest
* Several NPC goons
* NPC called Brown
* NPC called Blair
* Key to Brown's cell
* Key to Uncle's House
* First Deed Document
* A special chest
* Some traps, etc.


Objectives:- [i]This is the climax of our quest. The player will travel to a cave/dungeon, and will finally have his show down with the boss villain. We also want to set up a treasure chest as an additional reward. To make the players task a little harder, we will need to add some goons to fight along the way.
===Dungeon Design Ideas===
[/i]


We will need  
The first thing we will need is a cave system, or dungeon, for the player to delve into. The dungeon pieces are a little harder to work with compared to the standard building interiors, as they are not complete pieces. Instead they slot together, piece by piece, to create whole rooms.


[i]Dungeon/Cave system
A lot of the CS building parts work this way. Castles, Large Basements, Caves, ruins, and Dungeons are all created using this slotting method. First, make sure you switch on the snap-to guides and the angle rotation guides; it makes life easier. Then open File->Preferences and change the snap-to value to 1. This alters the sensitivity of the snap, giving a closer fit.
Letter, adding extra clue from Brown about chest
Several NPC goons
NPC called Brown
NPC called Blair
Key to Browns cell
Key to House
First Deed Document
A special chest.
Some traps etc
[/i]


[b]Dungeon Design Ideas[/b]
The best source of information and design ideas is the game and the CS. You should get into the habit of making note of ‘cool’ locations or quests and looking them up in the CS to see how they work.


The first thing we will need is a cave system or Dungeon for the player to delve. The dungeon pieces are a little harder to work with compared to the standard building interiors, as they are not complete pieces. Instead they slot together, piece by piece to create whole rooms.  
The cave system I set up for this tutorial was created in a hurry. I simply copied chambers from other cave systems in the CS and then pasted them together.


A lot of the CS building parts work this way. Castles, Large Basements, Caves, ruins, and Dungeons are all created using this slotting method. Firstly make sure you switch on the snap to guides and the angle rotation guides, it makes life easier. Then open files/preferences and alter the snap to value to 1.
It’s funny how you can come full circle. I now realize that the problem with the [[My First Dungeon]] tutorial in the Wiki is that it chose to illustrate its techniques using a dungeon. Had the Wiki went for "My First House" instead, it would have been much better off. However, we now know what we are doing, and working on dungeons should be no problem.  
This alters the sensitivity of the snap, giving a closer fit.


Again the best source of information and design ideas is the game and the CS. You should by now of got into the habit of making note of ‘cool’ locations and looking them up in the CS.  
I don’t intend to give you a click by click guide to building dungeons. If you get stuck, use the PLAYTEST version as a guide.


The cave system I have set up for this tutorial, was created in a hurry. I simply visited other cave systems in the CS, and cut and pasted chambers that I then linked together.
===Dressing the Dungeon===


It’s funny how you can come full circle. I now realise that the problem with the My First Dungeon tutorial in the Wiki is that it choose to illustrate it techniques using a dungeon. Had the Wiki went for my first house instead, it would have been much better of. However, we now know what we are doing, and working dungeons should be no problem.  
Ok, let’s add some bits to help move our story forward. First, let's write a piece of script in the main quest script's ''GameMode'' block to update the quest stage when the player enters the hideout.


As I have said the tutorials dungeon supplied in the files is not the greatest dungeon in the world. Far from it. It is a simple multi chamber linear cave system. This means the PC has very little choice how he progresses. He must make his way through each room, and face each challenge. This is both an advantage and a disadvantage. If I was building this cave system for ‘Full Mod’, I must admit I would have spent much more time on it.  
<pre>
If (GetStage BGM001 == 70)
    If (Player.GetInCell BGmodtSugglersCaveCOPY0000 == 1)
          SetStage BGM001 80
    EndIf
EndIf
</pre>


It would for instance have been nice to give players alternative paths, so those who prefer to avoid ‘hack and Slash’ trawling could sneak pat a few goons. Of course you would then have to set up a few more traps to keep them on their toes. One of things I have been disappointed about has been the lack of intelligent traps in Oblivion. By that I mean traps and puzzles where you have to stop and think of a solution. The game mechanics don’t easily lend them selves to this but it is a shame.
We can also add a journal entry for stage 80:


I don’t intend to give you a click by click, bit by bit guide to building dungeons. If you get stuck use the PLAYTEST version as a guide.  
''I've arrived at the Red Rose Brigade's hideout. If those thieves stole the deed and house key, I should find them here.''


[b]
Although this first chamber is quite large, I have decided to limit the threat to a single small random creature: a rat or a crab (''LL0NuissanceBeast100''). Why? Two reasons: I want to be able to escalate my threat, and I want to build suspense.
Dressing the Dungeon.[/b]


Okay, let’s add some bits to help move our story forward. First let’s add an Xmarkerheading close to the interior door. We can then use the marker as a reference in an addition to our growing quest script.
One of the design choices you will have to make is how to balance risk against reward. You should also try to escalate the threat as the story progresses. For instance, it would be very easy to throw five or six Daedra into the first chamber of our dungeon. But where do you go from there? If you start with too big a threat then you have little room to escalate that threat later. Also, try to give a little thought to the user who has minimum specifications. I’ve seen a few works in progress where they have designed a really cool crypt with 30 or so monsters in it. But I know that on my poor little PC, I’ll get a frame rate of about 3 frames per week. This is not a mod I'll be playing. Bigger doesn’t mean better, more is sometimes less.


[i]if (GetStage BGM001 == 70)
The player is also expecting to meet bad guys. Hopefully he will edge his character down into the first chamber fully expecting an army of trolls. I want to disappoint him. I want him to start to think this is easy before we hit him/her with the big stuff.
if (player.GetDistance BGRRCaveMarkerRef <= 300)
SetStage BGM001 80
endif
endif[/i]


We can also update the Journal
I also want to set the scene a little. For this I created another corpse, and placed a letter near it which informs the player about the special treasure chest and Brown's imprisonment.


[i]I've Arrived at the Red Rose Brigades Hideout. I will need to move cautiously. I need that house key.[/i]
Make the corpse and the letter. I also added a leveled nuisance creature at the far end of the chamber, so that the player will have to deal with the annoyance of a one hit kill creature after picking up the letter.


Although this first chamber is quite large, I have decided to limit the threat to a single small random creature, a rat or a crab (LL0NuissanceBeast100). Why? Two reasons I want to be able to escalate my threat and I want to build suspense.
The text for the letter is:
 
<pre><font face=5>
One of the design choices you will have to make is how to balance threat against reward. You should also try to escalate the threat as the story progresses. For instance it would be very easy to throw five or six deadra into the first chamber of our dungeon. However, the question is then where do we go from there. If you start with too big a threat then, you have little room  to escalate that threat later. Also try to give a little thought to the user who has minimum specifications. I’ve seen a few works in progress where they have designed a really cool crypt with 30 or so monsters in it. But I know that on my poor little PC, I’ll get a frame rate of about 3 frames a week. Consequently this is not a mod I’ll be playing. Bigger doesn’t mean better, more is sometimes less.
 
The player is also expecting to meet bad guys, hopefully he will edge his character down into the first chamber fully expecting an army of trolls. I want to disappoint him. I want him to start to think this is easy before we hit him/her with the big stuff.
I also want to set the scene a little. For this I created another corpse, and placed near it a letter which informs them about the special treasure chest and Browns imprisonment.
Make a corpse and the letter. Don’t give the corpse too much inventory, after all this is a freebee. I also added a levelled nuisance creature at the far end of the chamber; this should allow the PC to get to the corpse and then have to deal with the annoyance of a one hit kill creature.
 
The text for the letter is
[i]<br>
<font face=5><br>
Dear Smith,
Dear Smith,
<br>
<br>
<br>
<br>
I beg of you, please help me. Blair has gone mad. I have been imprisoned<br>
I beg of you, please help me. Blair has gone mad. I have been imprisoned.<br>
<br>
<br>
It all began when we attacked the White Horse Courier near Chorrol. It was supposed to be a simple robbery. But when Blair found that the only treasure was a key to a house and a deed which had to be registered in the Imperial City he went beserk.  
It all began when we attacked the White Horse Courier near Chorrol.
It was supposed to be a simple robbery. But when Blair found out that the only loot was a key and a house deed he went berserk.  
<br>
<br>
He killed the courier in cold blood. I wanted no part of it.<br>
He killed the courier in cold blood. I wanted no part of it.<br>
I suggested the gang might do better with me in charge. He accused me of being a member of our rivals, the Torch Gang. Now he's had me locked up because I know how to open his treasure chest. He wants to kill me but he fears the other gang members might turn on him.
I suggested the gang might do better with me in charge. He accused me of being a
double-agent for our rivals, the Torch Gang. Now he's had me locked up because I know how to open his treasure chest. He wants to kill me but he fears the other gang members might turn on him.
<br>
<br>
Please Smith, send help.I have asked one of gang member loyal to me to take this letter to you. I hope he makes it. Blair is watching my every move.
Please Smith, send help. I have asked one of the gang members who's loyal to me to take this letter to you. I hope he makes it. Blair is watching my every move.
<br>
<br>
<br>
<br>
Your old friend,
Your old friend,<br>
<br>
Brown</pre>
Brown[/i]
 
We make and add the following script to the letter
We make and add the following script to the letter


[b]Scriptname BGM001BrownScript
<pre>Scriptname BGM001BrownsLetterSCRIPT


Begin OnAdd Player
Begin OnAdd Player


if (GetStage BGm001>= 80)
  If (GetStage BGM001 >= 80)
SetStage BGm001 90
    SetStage BGM001 90
EndIf
  EndIf
 
End</pre>


End
Again we can bump the stage and enter another journal entry for stage 90:
[/b]


Again we can bump the stage and enter another journal entry for stage 90
''I have found a letter from Brown. It appears the Red Rose leader has imprisoned him. Brown has knowledge of a secret treasure. I should try to talk to him.''


[i]I have found a letter from Brown. It appears the Red Rose leader has imprisoned him. Brown has knowledge of a secret treasure. I should try to talk to him
Finally, I messed about with the lighting to try to create a little more atmosphere. Clearly, caves should be darker than the outside world. Try to use spot lights to pick out areas you want the PC to notice and to hide threats that you want to be a surprise.
[/i]
Finally I messed about with the lighting, to try to create a little more atmosphere. Clearly caves should be darker than the normal world. Try to use spot lights to pick out the bit you want the PC to see and to hide threats you want to be a surprise.


The second chamber will contain a single NPC. We want all the Red Rose Brigade NPC’s to act as a team. How? Factions are the answer.
The second chamber will contain a single NPC. We want all the Red Rose Brigade NPC’s to act as a team. How? With Factions.


[b]Factions[/b]
===Factions===


Factions are used in three ways by the game. Firstly they are used to establish a hierarchy or internal structure for organisations the PC can join. Secondly they are used to group NPC’s into teams with similar behaviours; these teams will act to protect each other when threatened. The final use of factions is to collect NPC’s together to allow grouped conditions statements.
Factions are used in three ways by the game:
#To establish a hierarchy or internal structure for organizations the PC can join
#To group NPCs into teams with similar behaviors.
#To make groups of NPCs that can be used in condition statements. (e.g., when we used the ICFaction to apply conditions to citizens of the Imperial City)


To create a new faction opens up the faction box from the menu. In the column on the left is a list of all the existing factions. Rick click and select new. Give the Faction a unique name. Say BGRedRoseBrigade. Now, add a name to the top. Red Rose Brigade.  
To create a new faction, open up the Faction box from the Character menu. The column on the left lists all of the existing factions. Rick-click in the column and select New. Give the Faction a unique ID, such as ''BGRedRoseBrigade''. Now, add the name to the top: ''Red Rose Brigade''.  


The flag at the top which reads hide from player, basic controls whether or not a player can enter the faction or not. Leave this as hidden.
The "Hidden from PC" flag at the top basically controls whether or not a player can enter that faction. Check this box.


The central box controls the ranks and titles within the faction. Note the ranks are split to offer the choice of alternative titles based on gender. In the case of our faction these have no meaning at all. However, since this is only chance we will get to look at lets set up a simple three tier structure for practice.
The ''Rank Data'' box in the center controls the ranks and titles within the faction. Note that the ranks are split to offer the choice of alternative titles based on gender. In the case of our faction, these have no meaning at all.


The final box at the bottom is the most useful.
For us, the ''Interfaction Relations'' box at the bottom will be most useful.
   
   
It controls the disposition of a group to other factions or groups. Again it’s the standard right click new to add a group from the existing list into the disposition modifier box. You need add a numerical modifier ranging from +100 to -100. This modifier is applied to all members of the group.  
It controls the disposition of members of one factions towards members of another faction. The ''Mod'' value is a numerical modifier ranging from -100 to +100. This modifier is applied to all members of the group.  


The results are cumulative. Let’s say we decide that the Red Rose Brigade is closely affiliated with the various Bandits who occupy Tamriel. We can add a modifier of say (+) 70 to that group. Rick  click select new, scroll down and find Bandit faction. Select it. Now alter the modifier to 70. From now on every member of the Red Rose faction will add 70 to there disposition towards bandits. We can add as many groups as we like.  
The results are cumulative. Let’s say we decide that the Red Rose Brigade is closely affiliated with the various Bandits who occupy Tamriel. We can add a modifier of, say, +70 to that group. Create a new entry for the Bandit faction, and set the modifier to 70. From now on every member of the Red Rose faction will add 70 to there disposition towards bandits. We can add as many groups as we like.  


We want the Red Rose member to be openly hostile to the PC. This is achieved because there is a faction called the PlayerFaction which has a solitary member, the PC. We can adjust the Red Rose disposition for this faction to -100. This means they will hate us and attack on site.
We want the Red Rose members to be openly hostile to the PC. For this we can use ''PlayerFaction'', which has a solitary member: the player. We can adjust the disposition for this faction to -100. This means they will attack the player on sight.
Create a NPC. I used the BanditMelee character as a base Template. This character already comes with levelled armour etc. Although the will appear to be naked in the render window.


I also popped in a chest, renamed it so I could alter it contents and add a few coins. The levelness of a NPC is controlled by the flags and boxes to the left of the character box.  
We also want Red Rose members to be friendly with one another. Add another disposition entry for the Red Rose faction itself, with a relatively high disposition value.


We can make two choices.
Finally, we need to add a separate faction for Brown, so that (1) the Red Rose members don't kill their prisoner and (2) the prisoner won't attack the player.
Name it something like ''BGRRPrisoner''. For the prisoner's faction, add a positive disposition towards the player. Then go back to the ''Red Rose Brigade'' faction and add a positive disposition towards the prisoner's faction.


[b]Level to a value[/b]: In this option we select a pre ordained level for the NPC. The advantage is that we can control how tough a NPC is, and therefore the challenge set by that enemy. This is ideal if we have a particular reward which we feel should be earned by high ranking, or indeed low ranking PC’s. Suppose you design a one hit kill sword. This is a big reward. The player should have to earn this reward by defeating a big boss.
===Enemy NPCs===
Equally, perhaps the reward is a few coins. Then it may be appropriate to set a simple challenge.
Create an NPC. I used the BanditMelee character as a base template. This character already comes with [[Leveled_Item|leveled item lists]] (even though they will appear to be naked in the preview render).
The disadvantage is that if you set an NPC at level 40, only a small number of players will meet this challenge, and many may simple unplug your mod.
[b]
Level against PC:[/b] This is one of the more controversial developments in Oblivion. Many Morrowind veterans have been particularly vocal in their criticism of these technique. The advantage is that no matter what level your PC is at you will meet a decent challenge which will test your PC. It allows access to all PC’s and does not exclude any. However, it has disadvantages as well. This approach does mean that sometime the risk does not match the reward.  


For this tutorial I have chosen to use the Level against PC method as this is the Oblivion norm. It is of course a matter for each designer to choose. I would suggest that what ever method you choose is consistent through out the mod. If you mix and match you could have the situation where the first goons is 10 levels above your boss, or a situation where after defeating a series of level 2 goons you suddenly encounter a level 30 boss.
The level of an NPC is controlled by the flags and boxes to the left of the character box.  


We also want this first goon to be a little bit easier than those coming up so lets set the value to -2 levels. Using the offset box. The bandit already has a suitable levelled inventory.
We can make two choices:


The main central chamber will contain 3 NPC’s. Again add the Red Rose Faction to their faction list and delete the others. I used more bandits as a base for these.  
'''Level''': In this option we select a specific level for the NPC. The advantage is that we can control exactly how challenging an NPC should be. This is ideal if we have a particular reward which we feel should be earned only by well developed player characters. Suppose you design a one hit kill sword. This is a big reward. The player should have to earn this reward by defeating a big boss.  


I also set the offset at -1.  
On the other hand, you might even want to make an NPC particularly weak, which you could easily do by setting a low level.


Finally I messed around with the lighting a bit. I wanted to give a stealthy player a chance. I remove the lighting from the linking corridor and close to the entrance.
The disadvantage is that if you set an NPC to level 40, for example, only a small number of players will meet this challenge. Many may simply unplug your mod.  
[b]
The Final Chamber.[/b]


This consists of a large chamber with two ante chambers. In the first ante chamber we create a cell by placing a door in the corridor. We can use this to house NPC BGBrown. I used the Bandit Boss as a model, but removed his factions.. Remember do not make Brown a member of the faction.  
'''PC Level Offset''': This is one of the more controversial developments in Oblivion. Many Morrowind veterans have been particularly vocal in their criticism of this technique. The advantage is that no matter what level your PC is at you will meet a decent challenge which will test your PC. It allows PC's of all levels to access quests. However, it has disadvantages as well. This approach does mean that some times the risk does not match the reward.  


Final we create Blair. He is our Boss. I made him +2 above the PC.  I am going to say very little about this PC, because here is where you get to have the most fun making your own bad guy. Once created
For this tutorial I have chosen to use the PC Level Offset method as this is the Oblivion norm. It is, of course, up to each individual designer to choose what they want to do. I would suggest that whatever method you choose is consistent throughout the mod. If you mix and match you could have a situation where the first few goons are 10 levels above the end boss, or where after defeating a series of level 2 goons you suddenly encounter a level 30 boss.


Add the key to Browns cell door. Make the cell door, locked and set it to ‘Needs a key‘.  
We also want this first goon to be a little bit easier than those coming up so lets set the value to -2 levels using the offset box. The bandit already has a suitable leveled inventory.


You will also need to set up the Prize house.
The central chamber will contain 3 NPCs. Remember to add the Red Rose Faction to their faction lists and delete the others. I used more bandits as a base for these. I also set the PC level offset to -1.
Go to the interior cell BGmodtut4 which is the interior of the house. It has three door. One leads to the basement. The other two are linked to the exterior. Lock the exterior doors and set the ownership to our old buddy BGDummyPlayer.  
Set the interior cell ownership to BGDummyPlayer as well.
Add the BGTopViewKey to the house to Blairs inventory. Now create a ’uncertified’ deed and add this to his inventory.  


[i]Deed Text.
Finally, I messed around with the lighting a bit. I wanted to give stealthy players a chance to sneak. I removed the lighting from the linking corridor and the entrance.


==The Final Chamber==
===Setting up the resources===
This consists of a large chamber with two antechambers. In the first antechamber we create a cell by placing a door in the corridor. We can use this to house NPC ''BGBrown''. Remember, Brown must be added to the separate prisoner faction.
Finally, we create Blair. He is our Boss. I made his level offset +2. I am going to say very little about this NPC, because this is where you get to have the most fun making your own bad guy. Once created, add the cell door key to his inventory. Make the cell door locked, and set it to ‘Needs a key‘.
Add ''BGTopViewKey'' (the key to the house) to Blair's inventory. Now create an "uncertified" deed and add this to his inventory.
''BGTopViewUncertifiedDeed'':
<pre>
<font face=5>
<font face=5>
<BR>
<BR>
<BR>
<BR>
This document hereby states that the bearer is the sole owner and possessor of the domicile currently known as Top View. Said domicile is located North of the Imperial City and South of the city of Bruma in the territory known as Cyrodiil.<BR>
This document hereby states that the bearer is the sole owner and possessor of the
domicile currently known as Top View. Said domicile is located North of the Imperial
City and South of the city of Bruma in the territory known as Cyrodiil.<BR>
<BR>
<BR>
The bearer has full ownership rights to all of the structures, flora and land within the property borders as defined in the Tamerial Construction Charter. The bearer is responsible for all matters pertaining to or occurring on said property.<BR>
The bearer has full ownership rights to all of the structures, flora and land within
the property borders as defined in the Tamriel Construction Charter. The bearer is
responsible for all matters pertaining to or occurring on said property.<BR>
<BR>
<BR>
This document also empowers the bearer transfer rights to reassign the property as he sees fit. The bearer may amend this document to rename the manor  by submitting the proper forms and payments to the Tamerial Construction Charter and by filing duplicate forms with the Documents Division of the Imperial City Archives.
This document also empowers the bearer transfer rights to reassign the property as he
THIS DOCUMENT MUST BE REGISTERED IN THE IMPERIAL CITY BY A QUALIFIED NOTARY PUBLIC TO GAIN LEGAL FORCE
sees fit. The bearer may amend this document to rename the manor  by submitting the
[/i]
proper forms and payments to the Tamriel Construction Charter and by filing
duplicate forms with the Documents Division of the Imperial City Archives.<BR>
THIS DOCUMENT MUST BE REGISTERED IN THE IMPERIAL CITY BY A QUALIFIED NOTARY PUBLIC TO GAIN LEGAL FORCE.<BR></pre>


This document explains why we have to return to the Imperial City
This document explains why we have to return to the Imperial City.


Both Blair and Brown will need special AI’s to get them to work properly.  
Both Blair and Brown will need special AI packages to get them to work properly.  


I also wanted to make sure the player no matter how good a sneak is forced to confront Blair. How do we do this. Easy we script it. We also have set the adventure up so that you have to kill Blair to move the quest on.
I also want to make sure that the player, no matter how good they are at sneaking, will be forced to confront Blair. How do we do this? Easy, we script it. We will also design the quest so that you will have to kill Blair to move on to the next stage. We can also do this through scripts.


How does the game know he is dead? Scripts of course. We can combine both functions into a single script.
===Setting up Blair===
[b]Scriptname BGBlairDeathScript
Add a new variable to the main quest script called ''BlairGreeted''. Then attach this script to the Blair NPC:<br>
 
<pre>
short doOnce
SCN BGBlairSCRIPT


Begin OnDeath
Begin OnDeath
 
SetStage BGM001 95
SetStage BGM001 95
 
End
End


Begin GameMode
Begin GameMode
If BGM001.BlairGreeted == 0
If GetDistance Player <= 500
StartConversation Player GREETING
EndIf
EndIf
End
</pre>


if ( GetStage BGM001<95 ) && ( doOnce == 0 )
Then set up the new ''GREETING''.


if ( player.GetDistance BGBlairRef <= 500)
{| border="1" cellpadding="5"
StartConversation Player BGMBlairGreet
!colspan=2| '''GREETING'''
set doOnce to 1
|-
endif
!  TOPIC TEXT
|  "GREETING"
|-
!  RESPONSE
|  "I heard you've been snooping around. Prepare to die!"
|-
!  CONDITIONS
* GetIsID 'BGBlair' == 1
* GetStage 'BGM001' >= 80
|-
!  ADD TOPICS
|  ''No add topics''
|-
!  RESULT SCRIPT
|
<pre>
Set BGM001.BlairGreeted to 1
StartCombat Player
</pre>
|}


endif
In order for this to actually work, we need to change Blair's [[aggression]] stat so that he doesn't attack the player on sight (the topic result script will initiate combat for us). Open up the Blair NPC form, and click the AI button. In ''AI Attributes'', set ''Aggression'' to 0.


End[/b]
When the PC kills Blair, we can also update the journal by adding an entry for stage 95.


We now have to set up the conversation. We use the conversation tab rather than the topic tab. Also set this conversation up as a goodbye, to terminate any further discussion.
''I have killed Blair. I should search his body for the deed and house key. I should also see if he has a key to Brown's cell. I can then return to the Imperial City to see Vilanus.''


CONVERSATION
===Setting up Brown===
BGMBlairGreet
We can set up an optional reward for players who choose to free Brown from his cell. Open up Brown's form and make sure he doesn't have a high aggression level, just to make sure Brown won't attack the player on sight. It should at least be lower than whatever positive disposition you gave the prisoner faction towards the player, but it wouldn't hurt to just set it to 0.
RESPONSE
You are a fool for coming here. Now prepare to die.


CONDITIONS
Then set up a greeting for Brown:
GetIsId  BGBlair== 1
GetStage BGM001<95


GetStage
{| border="1" cellpadding="5"
  BGM001 == 90
!colspan=2| '''GREETING'''
ADD TOPICS
|-
RESULT SCRIPT
!  TOPIC TEXT
|  GREETING
|-
!  RESPONSE
|  "Please, please, don't kill me! I had no hand in this. Just let me go."
|-
!  CONDITIONS
* GetIsID 'BGBrown' == 1
* GetStage 'BGM001' >= 95
|-
ADD TOPICS
* BGBrownChoice1
* BGBrownChoice2
|-
RESULT SCRIPT
|  ''No result script''
|}


When the PC kills Blair we can then update the journal
Each response will advance the quest to a different stage, which will have appropriate journal entries and result scripts.


[i]I have killed Blair. I should search his body for the deed and my house key. I should also see if he has a key so I can release Brown. I can then return to the Imperial City to see Vilanus[/i].
{| border="1" cellpadding="5"
!colspan=2| '''BGBrownChoice1'''
|-
!  TOPIC TEXT
|  You can go.
|-
!  RESPONSE
|  "Thank you! Thank you! The code is one, four, seven."
|-
!  CONDITIONS
* GetIsID  'BGBrown' == 1
* GetStage 'BGM001' >= 95
|-
!  ADD TOPICS
| ''No add topics''
|-
!  RESULT SCRIPT
|  <pre>SetStage BGM001 100</pre>
|}


We have set the quest up so that as well as the reward of the house the player can also get access to the treasure chest if they get the combination this is dictated by setting up a choices dialogue through Brown.
For stage 100, add the following journal entry:


Initially we set up a greeting.  
''Brown gave me the code for the combination lock on the chest. I need to enter 1-4-7 to unlock it. Once I've done that, I will need to go see Vilanus Villa in  Imperial City. Vilanus will need to transfer ownership of my uncle's house to me.''
TOPIC
Greeting


RESPONSE
{| border="1" cellpadding="5"
Please, Please, don't kill me. I just want to get away from here. Please let me go
!colspan=2| '''BGBrownChoice2'''
|-
!  TOPIC TEXT
|  No.
|-
RESPONSE
|  "You'll regret this!"
|-
!  CONDITIONS
* GetIsID  'BGBrown' == 1
* GetStage 'BGM001' >= 95
|-
!  ADD TOPICS
|  ''No add topics''
|-
!  RESULT SCRIPT
|  <pre>SetStage BGM001 101</pre>
|}


CONDITIONS
Add another entry for stage 101:
GetIsId  BGBrown == 1
GetStage
BGM001 == 90


ADD TOPICS
''I left Brown to rot in his cell. I need to go see Vilanus Villa in  Imperial City so he can transfer my uncle's property to me.''
BgBrownChoice1,BgBrownChoice2


RESULT SCRIPT
The stage result script is used to remove the quest object status from a number of items which are no longer needed and which the PC can now dispose of. This should be applied to BOTH of the possible stages. (Use whichever IDs you chose when creating these items.)
The positive response info for BGBrownC1 gives a stage boost, the negative one does not.


TOPIC
<pre>
BGBrownC1
SetQuestObject BGHideoutCELLKey 0
 
RESPONSE
Thank You! Thank you! The code is 1 4 7
 
CONDITIONS
GetIsId  BGBrown == 1
GetStage BGM001 >= 90
 
ADD TOPICS
RESULT SCRIPT SetStage BGM001 100
We update the journal and run a bit of script as a result
 
[i]Brown has given me the code to the Combination Chest I need to enter the numbers 147 to unlock it. Once I've done that I will need to go and see Vilanus Villa in the Imperial City. Vilanus will need to transfer ownership of my uncle's house to me.[/i]
 
The script is used to remove the quest object status from a number of items which are no longer needed and which the PC can now dispose of.
 
[b]SetQuestObject BGHideoutCELLKey 0
SetQuestObject BGHideoutKey 0
SetQuestObject BGHideoutKey 0
SetQuestObject BGBrownLetter 0
SetQuestObject BGBrownLetter 0
SetQuestObject BGPartialLetter 0
SetQuestObject BGPartialLetter 0
[/b]
</pre>
 
TOPIC
BGBrownC2
 
RESPONSE
Then you'll never learn the entry code.


CONDITIONS
GetIsId  BGBrown == 1
GetStage BGM001 >= 90


ADD TOPICS
We will need to look at altering Brown's behavior for the final release. We will need to add some AI in the next lesson to get him to run away.
RESULT SCRIPT
We will need to look at altering Browns behaviour for the final release. We will need to add some Ai in the next lesson to get him to run away.


What we do need to look at now is another hefty bit of scripting which controls the treasure chest
===Scripting the chest===
What we need to look at now is another hefty bit of scripting which will control the combination lock on the treasure chest.


Again here it is in its entirety. Look through it and try to work out what it is doing.
Here it is in its entirety. Look through it and try to work out what it is doing.


It controls a chest with a three digit combination style lock.
It controls a chest with a three digit combination style lock.


[b]Scriptname BGCombinationChestScript
<PRE>
SCN BGBlairsChestSCRIPT


Short DigitCount
Short Button1
Short Button1
Short Button2
Short Button2
Short Button3
Short Button3
Short CombiRight
Short Frame
Short ChestOpen
Short Unlocked
Short GoldCount
Short GoldCount
Short DoOnce


Begin OnActivate
Begin OnActivate


If (ChestOpen == 2)
  If Unlocked == 1
  Activate
    Activate
Else
  Else
Set ChestOpen to 1
;Begin combination menu
EndIf
Set Frame to 1
  EndIf


End
End
Begin GameMode
Begin GameMode
 
If Frame != 0
;-----------------------------------------------------------
;Get the first digit
If (ChestOpen == 1)
If Frame == 1
;------------------------------------------------------------
MessageBox "First digit" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
If (DigitCount == 0)
Set Frame to 2
MessageBox, "Please input the first digit of thecombination","0","1","2","3","4","5","6","7","8","9"
Set DigitCount to 1
EndIf
EndIf


if (DigitCount == 1)
;Save first digit entered, get the second digit
set button1 to GetButtonPressed
If Frame == 2
if button1 == -1
Set Button1 to GetButtonPressed
return
If Button1 == -1
 
Return
Else
EndIf
Set DigitCount to 2
MessageBox "Second digit" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
EndIf
Set Frame to 3
EndIf
EndIf


If (DigitCount == 2)
;Save second digit entered, get third digit
MessageBox, "Please input the second digit of the combination","0","1","2","3","4","5","6","7","8","9"
If Frame == 3
Set DigitCount to 3
Set Button2 to GetButtonPressed
EndIf
If Button2 == -1
 
Return
if (DigitCount == 3)
EndIf
set button2 to GetButtonPressed
MessageBox "Third digit" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
if button2 == -1
Set Frame to 4
return
 
Else
Set DigitCount to 4
EndIf
EndIf
 
If (DigitCount == 4)
MessageBox, “Please input the third digit of the combination","0","1","2","3","4","5","6","7","8","9"
Set DigitCount to 5
EndIf
 
if (DigitCount == 5)
set button3 to GetButtonPressed
if button3 == -1
return
 
Else
Set DigitCount to 6
EndIf
EndIf
EndIf
;---------------------------------------------------------------


if (DigitCount == 6)
;Save third digit entered, then check combination.
If button1 == 1
If Frame == 4
Set CombiRight to CombiRight +1
Set Button3 to GetButtonPressed
If Button3 == -1
Return
EndIf
EndIf
If button2 == 4
Set CombiRight to CombiRight +1
EndIf
If button3 == 7
Set CombiRight to CombiRight +1
EndIf
EndIf


;---------------------------------------------------------------
If Button1 == 1 && Button2 == 4 && Button3 == 7
 
;Correct combination result
If (DigitCount == 6) && (CombiRight ==3)
MessageBox "The combination pad unlocks."
Set ChestOpen to 2
Set Unlocked to 1
set DigitCount to 0
Set Frame to 0
return
Else
EndIf
;Bad combination result
;---------------------------------------------------------------
MessageBox, "Suddenly your pockets feel a bit lighter."
 
Set Frame to 0
If (DigitCount == 6) && (CombiRight <=2)
If (Player.GetItemCount "gold001") >= 100
MessageBox, "Naughty, naughty. Now take your punishment"
If (Player.GetItemCount "gold001") >=100
Player.RemoveItem "gold001" 100
Player.RemoveItem "gold001" 100
BGBlairChestref.additem "gold001" 100
AddItem "gold001" 100
      Set DigitCount to 0
Set ChestOpen to 0
return
Else
Else
Set GoldCount to Player.GetItemCount "gold001"  
Set GoldCount to Player.GetItemCount "gold001"  
Set GoldCount to GoldCount - 1
Player.RemoveItem "gold001" GoldCount
Player.RemoveItem "gold001" GoldCount
BGBlairChestref.additem "Gold001" GoldCount
AddItem "Gold001" GoldCount
Player.Additem "gold001" 1
Set DigitCount to 0
Set ChestOpen to 0
EndIf
EndIf
 
EndIf ;Correct combo
EndIf
EndIf ; Frame 4
;-----------------------------------------------------------------
EndIf; Frame != 0
elseIF (ChestOpen == 0)
return
ElseIF (ChestOpen == 2)
If DoOnce == 0
set DoOnce to 1
Activate
return
EndIf
else
return
EndIf
End
End
In this case we control when the script runs using what I call a two block script. The first block sets up the conditions in which the second block works.
</PRE>


Begin OnActivate
Now it's time to wrap up our little adventure. We move the scene back to the Imperial City.


If (ChestOpen == 2)
==Imperial City Phase Two==
  Activate
Else
Set ChestOpen to 1
EndIf
 
End
[/b]
This first block runs only when the chest is activated. It uses a control variable called ChestOpen.


This in fact has 3 states or values.
In this phase the player will return to Vilanus, who will set about transferring the ownership of the property to you. We will add a delay so that the player has to wait 24 game hours before the process is finished.
0 = Chest has not been activated and the combination is has not been entered
1= Chest has been activated and the combination has not been entered
2= Chest has been activated and the combination has been entered correctly
The Activate function has to be included to get the chest to open. Note since we will attach this script to the chest we need no reference id.  


The first script checks if we have already opened the chest. If so it opens it again. If not it sets the ChestOpen to 1. This enables the GameMode script.
We need:


Begin GameMode
* A completed version of the deed
* The prize house
* A map marker for the house


We use the Chest Open == 1 to enable the main body of the script.
To set up the prize house, go to the interior cell ''BGmodtut4'', which is the interior of the house. It has three doors. One leads to the basement. The other two are linked to the exterior. Lock the exterior doors and set the ownership to our old buddy ''BGDummyOwner''. Set the interior cell ownership to ''BGDummyOwner'' as well.
[i]
If (ChestOpen == 1)[/i]


For this we use another variable called DigitCount to help work through the different stages of the script
===New dialogue===
We begin by adding more dialogue for Vilanus Villa.


[i]If (DigitCount == 0)
First, set up three new topics:
MessageBox, "Please input the first digit of the combination","0","1","2","3","4","5","6","7","8","9"
*BGDeedCheck
Set DigitCount to 1
*BGRecoverYes
EndIf
*BGRecoverNo
[/i]
Note here that the message box statement must all be on one line of code. On some editors the word wrap may make it look like this is on two or even three lines. If you cut and paste, the script editor may pick this up.  The PC can now  select the first digit.


[i]if (DigitCount == 1)
Then add a new greeting:
set button1 to GetButtonPressed
if button1 == -1
return


Else
{| border="1" cellpadding="5"
Set DigitCount to 2
!colspan=2| '''GREETING'''
EndIf
|-
EndIf
!  TOPIC TEXT
[/i]
|  "GREETING"
|-
!  RESPONSE
|  "Hello, have you managed to recover the key and deed?"
|-
!  CONDITIONS
* GetIsID 'BGVilanusVilla' == 1
* GetStage BGM001 >= 20
* GetStage BGM001 < 110
|-
!  ADD TOPICS
|  ''No add topics''
|-
!  CHOICES
|
*BGRecoverYes
*BGRecoverNo
|-
!  RESULT SCRIPT
|  ''No result script''
|}


We then set the value of  Button1. We also bump DigitCount up one to enable the next step. If no button is pressed the script halt for that frame only using the return command. We then repeat this process to get the second and third  digits.
Then edit the choices.
[i]If (DigitCount == 2)
MessageBox, “Please input the second digit of the combination","0","1","2","3","4","5","6","7","8","9"
Set DigitCount to 3
EndIf


if (DigitCount == 3)
{| border="1" cellpadding="5"
set button2 to GetButtonPressed
!colspan=2| '''BGRecoverNo'''
if button2 == -1
|-
return
!  TOPIC TEXT
|  "No, not yet."
|-
!  RESPONSE
|  "I can't help you until you've found both the key and the deed."
|-
!  CONDITIONS
* GetIsID 'BGVilanusVilla' == 1
* GetStage 'BGM001' < 95
|-
!  ADD TOPICS
|  ''No add topics''
|-
!  RESULT SCRIPT
|  ''No result script''
|}
<br>
{| border="1" cellpadding="5"
!colspan=2| '''BGRecoverYes'''
|-
!  TOPIC TEXT
|  "Yes. Here they are."
|-
!  RESPONSE
|  "Excellent. I will take the deed to the property registrar today. Come back tomorrow, the transfer should be complete by then."
|-
!  CONDITIONS
* GetIsID 'BGVilanusVilla' == 1
* GetStage 'BGM001' >= 95
* GetItemCount 'BGTopViewKey' == 1
* GetItemCount 'BGTopViewUncertifiedDeed' == 1
|-
!  ADD TOPICS
*BGDeedCheck
|-
!  RESULT SCRIPT
<pre>
Player.RemoveItem BGTopViewUncertifiedDeed 1
SetStage BGM001 110
</pre>
|}


Else
Stage 110 Journal Update:
Set DigitCount to 4
''Vilanus told me that he is going to take the deed to the property registrar, and that I should check back with him tomorrow when the transfer is complete.''
EndIf
EndIf


If (DigitCount == 4)
We want to set up a delay of one day before we can collect the finished documents. This gives us an excellent opportunity to look at and practice timers.
MessageBox, “Please input the third digit of the combination","0","1","2","3","4","5","6","7","8","9"
Set DigitCount to 5
EndIf


if (DigitCount == 5)
===Timers===
set button3 to GetButtonPressed
if button3 == -1
return


Else
Timers are another bit of scripting that gets used again and again. The game uses a number of global variables to report the progress of time.  
Set DigitCount to 6
EndIf
EndIf
[/i]
Once Digit count is at 6 we can test to see if the combination is indeed 1 4 7. We use another variable called CombiRight to track this. If this reaches 3 the PC has opened the chest.
i[i]f (DigitCount == 6)
If button1 == 1
Set CombiRight to CombiRight +1
EndIf
If button2 == 4
Set CombiRight to CombiRight +1
EndIf
If button3 == 7
Set CombiRight to CombiRight +1
EndIf
EndIf
[/i]
We test that CombiRight is indeed 3. If it is we set the chest open variable to 2, and we reset the digit count to zero to end any further progression.


[i]If (DigitCount == 6) && (CombiRight ==3)
The two most used are:
Set ChestOpen to 2
set DigitCount to 0
return
EndIf
[/i]


If it fails we want to punish the player for his failure, and nothing hurts quite lick taking a chunk of gold off the PC.
*[[GetSecondsPassed]]
*[[GameDaysPassed]]


[i]If (DigitCount == 6) && (CombiRight <=2)
We can use the seconds passed to establish timed events. GetSecondsPassed returns a float value, so we must set up a float type variable to save it in.
[/i]
This bit of script displays a message


[i]MessageBox, “Naughty, naughty. Now take your punishment"[/i]
Here is an example script that takes 10 Septims from the player and then gives them back 25 seconds later.  


Then checks that the PC can afford the ‘fine’
<pre>
Scriptname ExampleTimerScript


[i]If (Player.GetItemCount "gold001") >=100
float Timer
[/i]
short State
It takes away the gold from the PC and then adds it to the chest. It then resets the control variable so the player  can try to open the chest again.


[i]Player.RemoveItem "gold001" 100
Begin GameMode
BGBlairChestref.additem "gold001" 100
      Set DigitCount to 0
  If State == 0
Set ChestOpen to 0
    Set Timer to 25.0
Return[/i]
    Set State to 1
    Player.RemoveItem "gold001" 10
  ElseIf State == 1
    If Timer > 0
      Set Timer to Timer - GetSecondsPassed
    Else
      Player.AddItem "gold001" 10
      Set State to 2
    EndIf
  EndIf


Of course the player may not have 100 septims, so we use a variable called gold count which we set to the value of the player’s current gold count
End
</pre>


[i]Else
If you're writing a script where you're only interested in the number of in-game days that have passed, you can use GameDaysPassed instead (which is a short).
Set GoldCount to Player.GetItemCount "gold001" [/i]


Then we take that away and add it to the chest.
In the quest script add three short variables called ''State'', ''StartDay'', and ''DeedFinished''.


[i]Player.RemoveItem "gold001" GoldCount
Then add this to the GameMode block:
BGBlairChestref.additem "Gold001" GoldCount
<pre>
Player.Additem "gold001" 1
If GetStage BGM001 == 110
Set DigitCount to 0
If State == 0
Set ChestOpen to 0
Set StartDay to GameDaysPassed
Set State to 1
ElseIf State == 1
If GameDaysPassed > StartDay
Set DeedFinished to 1
Set State to 2
EndIf
EndIf
EndIf[/i]
Finally we wrap the script up with a couple of brief tidy ups. The first deals with the fact that the game mode block will run every frame while we are in the dungeon cell. Not just the room. Prior to touching the chest the chest open status is 0. If this is so the script returns and does nothing for the frame.
[i]elseIF (ChestOpen == 0)
Return
[/i]
This bit opens the chest if we have the correct combination.
[i]ElseIF (ChestOpen == 2)
If DoOnce == 0
set DoOnce to 1
BGBlairChestref.Activate Player
return
EndIf
else
return
EndIf
End[/i]
Now its time to wrap up our little adventure. We move the scene back to the Imperial City
[b]Imperial City Phase Two.[/b]
Objective:- [i]In this phase the player will again meet Vilanus, who will set about transferring the deeds of the property over to you. After 24 hours you can revisit and he will have the documents ready.[/i]
We will need
[i]A second complete deed document.
The Prize House.
A map marker.[/i]
We begin with another dialogue pair involving Vilanus Villa.
One for before you have the key and deed.
The second for when you are successful.
Again we need to add a small bit of script to the Quest Script to check for this.
If (Player.GetItemCount "BGM001HouseDeedUC">=1) &&(Player.GetItemCount "BGTopViewKey">=1) {ALL ON ONE LINE}
[indent]If DoOnce3 ==0
Set QuestWon to 1
Set DoOnce3 to 1/[indent]
EndIf
EndIf
TOPIC
Greeting
RESPONSE
I can't help you until you find the key and deed
You have to go back and get the deed and key. Check if Blair has it.
CONDITIONS
GetIsId  BGVilanusVilla == 1
GetStage BGM001 >= 80
GetQuestVariable BGM001.QuestWon == 0
ADD TOPICS
RESULT SCRIPT
and
TOPIC
Greeting
RESPONSE
Hello, Have you managed to recover the deed and key.
CONDITIONS
GetIsId  BGVilanusVilla == 1
GetStage BGM001 >= 80
GetQuestVariable BGM001.QuestWon == 1
ADD TOPICS
RESULT SCRIPT
AddTopic BGTopView (add topic via script to avoid issue with GREETINGS add topic's not appearing in the game)
For the new topic we add several responses. This first info tell the player to come back later
TOPIC
BGTopView (Top View Cottage?)
RESPONSE
Excellent, I will take the deed to the Property Registrar today. Come back tomorrow and I'll complete the transfer
CONDITIONS
GetIsId  BGVilanusVilla == 1
GetQuestVariable BGM001.QuestWon == 1
ADD TOPICS
BGTopView
RESULT SCRIPT
Player.RemoveItem "BGM001HouseDeeduc" 1
SetStage BGM001 110
Stage 110 Journal Update
[i]I have met with Vilanus Villa again. He has taken the deed to Top View and will complete the registration. I should come back in 24 hours to complete the transfer
[/i]
We want to set up a delay of one day before we can collect the finished documents. This gives us an excellent opportunity to look at and practice timers
[b]
Timers[/b]
Timers are another bit of scripting that gets used again and again. The game uses a number of global variables to report the progress of time.
The two most used are
[i]GetSecondsPassed
GameDaysPassed
[/i]
We can use the seconds passed to establish timed events. We must use a float variable to interact with the GetSecondsPassed function.
Ok this example script is really pointless it takes 10 septims from the player, then gives them back 25 seconds later.
However, the structure is what counts.
If you change the bits in bold to suit your needs, you will have a perfectly functional timer script.
The Remove function can be replaced with any script you want to run prior to the countdown.
The 25 controls how long the script will run for.
The Add function can be replaced by whatever you want to happen after the event.
[i]Scriptname ExampleTimerScript
float Timer
short DoOnce
begin GameMode
if SetZero == 0
set timer to 25
set DoOnce to 1
Player.RemoveItem ‘gold001’ 10
else
if timer > 0
set timer to timer - GetSecondsPassed
else
Player.Additem ‘gold001’ 10
EndIf
EndIf
EndIf
EndIf
end
</pre>
[/i]
 
When you plan to script longer events where precision is not essential you can use the courser GameDaysPassed function.
 
In the quest script we add some variables called StartDay, Timer, and DeedDone.
[i]
If(GetStage BGM001 == 110)
If(Timer == 0)
Set StartDay to GameDaysPassed
Set Timer to 1
EndIf
EndIf
 
If (Timer == 1)
If((GameDaysPassed - StartDay) >=1)
Set DeedDone to 1
Set Timer to 2
Else
EndIf
EndIf[/i]
The timer variable controls which bits of script work.  
This piece of script goes through three states:
The DeedDone variable is used to enable dialogue.
#Stage 110 has begun. Initialize the StartDay value, and change to second state.
#StartDay has been set. Check to see if the value of the current in-game date is more than StartDay (this will be true on any day after the starting day, including the first day after, which is what we want). Change to third state.
#Finished. Do nothing.


The key pair of script lines are
===More dialogue===
The ''DeedFinished'' variable will tell us when the game day is passed and the deed should be finished. We can use this variable for the next piece of dialogue. There will be two possible responses for this topic. One for when the deed is finished, and one for when it's not.


Set StartDay to GameDaysPassed
{| border="1" cellpadding="5"
!colspan=2| '''BGDeedCheck'''
|-
!  TOPIC TEXT
|  "House Deed"
|-
!  RESPONSE
|  "It should be finished by tomorrow. Check back with me then."
|-
!  CONDITIONS
* GetIsID 'BGVilanusVilla' == 1
* GetStage 'BGM001' == 110
* GetQuestVariable 'BGM001.DeedFinished' == 0
|-
!  ADD TOPICS
|  ''No add topics''
|-
!  RESULT SCRIPT
|  ''No result script''
|}
<br>
{| border="1" cellpadding="5"
!colspan=2| '''BGDeedCheck'''
|-
!  TOPIC TEXT
|  "House Deed"
|-
!  RESPONSE
|
*"The paperwork went through and you are now the owner of the Top View cottage."
*"Here's the certified deed. I'll mark the location of the house on your map."
*"May the Gods be with you."
|-
!  CONDITIONS
* GetIsID 'BGVilanusVilla' == 1
* GetStage 'BGM001' == 110
* GetQuestVariable 'BGM001.DeedFinished' == 1
|-
!  ADD TOPICS
|  ''No add topics''
|-
!  RESULT SCRIPT
|
<pre>
Player.AddItem BGTopViewDeed 1
SetStage BGM001 120
</pre>
|}
<br>


((GameDaysPassed - StartDay) >=1)
The new deed, ''BGTopViewDeed'', is just a copy of the old one without the very last line about needing to get it notarized. You do NOT need to make this a quest item. We don't need to force the player to keep it in their inventory.


You replace the number 1 with the number of days you want the event to last.
Journal Update for Stage 120:
''The paperwork is finished and I now have a certified deed for the Top View Cottage. I should go visit the property.''


When the deed has not been completed (DeedDone== 0) use
===Finishing up===
TOPIC
Add a new map marker outside of the house (in Tamriel->TopViewCottage). Call it ''BGTopViewMapMarker''. Then edit the names of the two exit doors, to something like ''BGTVDoor1'' and ''BGTVDoor2''.
BGTopView (Top View Cottage?)
 
RESPONSE
I haven't quite finished the paperwork check with me later.
 
CONDITIONS
GetIsId  BGVilanusVilla == 1
GetQuestVariable BGM001.QuestWon == 1
GetQuestVariable BGM001.DeedDone == 0
 
ADD TOPICS
RESULT SCRIPT
Once the deed is done you produce this message
TOPIC
BGTopView (Top View Cottage?)
 
RESPONSE
Congratulations, you are new the proud Owner of Top View.
Here is the paperwork. I'll mark it's location on the map for you.
May the gods be with you
 
CONDITIONS
GetIsId  BGVilanusVilla == 1
GetQuestVariable BGM001.QuestWon == 1
GetQuestVariable BGM001.DeedDone == 0
 
ADD TOPICS
RESULT SCRIPT
SetStage BGM001 120
and add a Journal Update for Stage 120
[i]
Vilanus has completed the paperwork. I should now go visit my new home.[/i]


Once again we need to add a mapmarker to the outside of the house. Call it BGTopViewMapMarker
Then add the following quest stage result script for stage 120:
And the following quest stage result script is then added and complied
[b]
Results Script[/b]


[i]Player.additem "BGM001HouseDeed" 1
<pre>
TopViewPlayerDoor1Ref.SetOwnership
BGTVDoor1.SetOwnership
TopViewPlayerDoor2Ref.SetOwnership
BGTVDoor2.SetOwnership
SetCellOwnership Bgmodtut4
SetCellOwnership BGModTut4
SetCellOwnership Bgmodtu4base
SetCellOwnership BGModTu4Base
ShowMap BGTopViewMapMarker
ShowMap BGTopViewMapMarker
[/i]
</pre>


This script does the ownership transfer.
This script transfers ownership of the house doors and cells to the player, and then enables the map marker.
It sets the ownership of the two doors, and the two interior cells to the player.
It also adds the finished certified document. Note this document is not a quest item.


We can also add the following as an end of quest rep;ly from Vilanus.
We then complete the quest script with a final block to check when the PC arrives at the house.


TOPIC
<pre>
BGTopView (Top View Cottage?)
If GetStage BGM001 == 120
If Player.GetInCell BGModTut4 || Player.GetInCell BGModTu4Base
SetStage BGM001 130
EndIf
EndIf
</pre>


RESPONSE
For this stage, you can check the ''Quest Complete'' box. Remember, this does not truly end the quest. To do that we must use the [[StopQuest]] function.
I hope you enjoy the house


CONDITIONS
The final journal entry:
GetIsId BGVilanusVilla == 1
  ''I have reached Top View. I am now free to explore my new home.''
GetQuestVariable BGM001.QuestWon == 1
GetQuestVariable BGM001.DeedDone == 1
GetStage BGM001 >= 120


ADD TOPICS
Finally, we add this quest stage result script to stage 130.
RESULT SCRIPT
We then complete the quest script with a final block to check when the PC arrives at the house. Of course we will need
[i]if (GetStage BGM001 == 120)
if (player.GetDistance BGTopViewXMarker <= 300)
SetStage BGM001 130
EndIf
EndIf[/i]


This gives a final journal entry. We should also mark the quest as complete using the tab. Remember this does not end the quest. To do that we must use the StopQuest function
<pre>
 
[b]
I have reached Top View. I am now free to explore my new home.[/b]
And finally we add this result script. This removes the essential status from the three essential characters so you can go ahead and kill them now. It boosts the player fame (optional), and finally stops the quest.
[i]
ModPCFame 1
ModPCFame 1
SetEssential BGVilanusVilla 0
SetEssential BGVilanusVilla 0
SetEssential BGMSmith 0
SetEssential BGMSmith 0
SetEssential BGCptHubart 0
SetEssential BGCptHubart 0
StopQuest BGM001[/i]
StopQuest BGM001
</pre>
 
The [[SetEssential]] commands remove the essential status from all of the essential characters we created earlier. [[ModPCFame]] boosts the player's fame by 1 point (optional). StopQuest stops the quest from running, and disables all of its dialogue.
So there you have it. A complete functional quest.  
So there you have it. A completely functional quest.  
 
However, if we really want to wow the public with our release we will need to add some AI to our NPC’s and look at our options regarding Audio and Lip Sync, and that’s what lesson 8 will be about.
 
'''Till then, happy modding!'''
 
== Thanks ==


However, if you really want to wow the public with our release we will need to add some AI to our NPC’s and look at our options regarding Audio and Lip Sync, and that’s is what lesson 8 will be about.
Thanks to dtom, who posted the [http://www.elderscrolls.com/forums/index.php?showtopic=517001 guide] on the [http://www.bethsoft.com/bgsforums/index.php?showforum=24 Elder Scrolls Forums] that this article is based on.


[b]Till Then Happy Modding.[/b]
[[Category: A beginner's guide]]

Latest revision as of 23:45, 16 August 2010


PreambleEdit

This is the Seventh in a proposed series of Tutorial Lessons aimed at teaching how to mod TES IV: Oblivion aimed at beginners. It will build up into a Complete Modding Course. Don't worry there are no exams, though there is some homework.

FilesEdit

I have uploaded some files which we will use to accompany the next few tutorials. It contains

A. BGModTutBase.esp This contains a building, a farmhouse, and a dungeon that we will use as sets in lessons 6, 7 and 8. This file is referred to in the text as the BASE files

B. BGModTutPlayTest.esp This is the interim quest mod illustrating the stage you should have reached prior to polishing the mod. This is referred to in the text as the PLAYTEST files

C. BGModAnvilCheat.esp: This is a small optional cheat mod to give users 5000 septims to allow them to follow this tutorial if they have not completed the quest. (See Introduction to lesson 4)

D. A RTF document containing the text for the first 7 lessons (as requested).

Download the files here.

IntroductionEdit

We have already begun building a quest. This lesson continues directly where Lesson 6 left off. We have set up a cottage which the PC will need to investigate to gain clues to identify who has stolen the deed and key. We have learned how to add dialogue using Topic/Response combinations and conditional statements to limit who gets to say the dialogue.

We have seen how to use a limited amount of scripting to progress our quest. While there is loads more dialogue to include in this part of the quest, we will focus far more on the use of scripting.

Cottage PhaseEdit

Entering the cottageEdit

We cannot rely on dialogue to progress our quest because the courier is dead.

The next stage bump is done via another addition to the main quest script which will check if the player is inside the cottage or not. We can use the GetInCell function to do this. If you examine the wiki page, you will see that the usage for that function is:

[ActorID].GetInCell CellName

The square brackets indicate that providing an ActorID is optional. In this case, the actor ID will be Player. If you're using the base file provided at the beginning of the tutorial, the cell name will be BGModCourierCottage. If not, it will be whatever you called the cottage cell.

When the character enters the cell we want to move to stage 40. We can use the stage to limit when the active part of the script runs. We first need to add stage 40 in the stage tab. Then add this piece of script to the GameMode block in BGM001QuestScript.

 If (GetStage BGM001 == 30)
   If (Player.GetInCell BGModCourierCottage == 1)
     SetStage BGM001 40
   EndIf
 EndIf

In this case, the quest stage acts like a DoOnce type control. During stage 30 of our quest, the game will repeatedly check to see if the player is inside the cottage cell. When the player is finally found inside the cell, the stage will be changed, and this IF block will never be true again (unless the stage is changed back to 30 for some reason).

You can add a journal entry for stage 40 to keep the player updated:

I found the courier's cottage. I should look around for some clues.

Finding the cluesEdit

Now we need to write a bit of script to handle the two clues we left in the cottage. There's more than one way to do this, but for now we will add a script to each of the clue items, and a couple of new variables to the main quest script.

First, add the two new variables into the main quest script:

Short HasAmulet
Short HasPaper

Then set up the two Object-type scripts. Open the script editor from the Gameplay menu, and make sure to set the script type before saving.

This is the script that will be attached to the torn letter:

SCN BGPartialLetterSCRIPT

Begin OnAdd Player
	If (BGM001.HasAmulet == 0)
		MessageBox "I found a torn document. I should continue to look for more clues."
	Else
		SetStage BGM001 50
	EndIf
	Set BGM001.HasPaper to 1
End

And this is the script that will be attached to the amulet:

SCN BGEmbossedAmuletSCRIPT

Begin OnAdd Player
	If (BGM001.HasPaper == 0)
		MessageBox "I found a strange amulet in the cottage. I should continue to look for more clues."
	Else
		SetStage BGM001 50
	EndIf
	Set BGM001.HasAmulet to 1
End

Add these scripts to the appropriate objects by opening up their details window and selecting them from the Script drop-down menu.

The scripts are very similar. Here's how they work: OnAdd is a hook that will be called by the object when it is added to an inventory. If you examine the wiki page for OnAdd, you will see that a parameter can be added so that the block is only triggered when the item is added to a particular inventory. In our case, we want that to be the player's inventory, so we used "OnAdd Player".

Then, inside the OnAdd block, we check to see whether or not the player has found the OTHER clue. If the play has NOT found the other clue, we give them a message that tells them to continue looking. If the player DOES have the other clue, they are done looking, and we can bump the quest stage to 50.

After the check, we change the appropriate quest variable to indicate that the player has found that item.

Remember to create stage 50, and then add this journal entry for it:

I found some clues for Captain Hubart to work with. I should return to him in Chorrol.

Returning the cluesEdit

Now we can now set up the next bit of interaction with Hubart.

We use the topic BGCluesFound that was added earlier. We want one response if the player has not collected the clues yet, and another for when they have collected the clue. We can use the quest stage as a condition. Set up the responses so that a new topic called BGRedRose is added if we have the clues.

BGCluesFound
TOPIC TEXT "Clues"
RESPONSE
  • "I recognize this amulet! It bears the mark of a gang of thieves that call themselves the Red Rose Brigade."
  • "Did you find the key or deed mentioned in the letter there? No? Then those thieves must have taken them..."
CONDITIONS
  • GetIsId 'BGCptHubart' == 1
  • GetStage 'BGM001' == 50
OPTIONS
  • Say Once
ADD TOPICS
  • BGRedRose
RESULT SCRIPT
Player.RemoveItem "BGPartialLetter" 1
Player.RemoveItem "BGEmbossedAmulet" 1
Player.RemoveItem "BGCourierKey" 1

The script simulates Cpt. Hubart taking the clues and key from us. The "Say Once" option should be checked because we only want this dialogue and script to run once (obviously), but our condition checks won't ensure that as is. We haven't changed the stage or anything like that.

If the player only has one of the clues, this response will be available:

BGCluesFound
TOPIC TEXT "Clues"
RESPONSE "I need more to work with."
CONDITIONS
  • GetIsId 'BGCptHubart' == 1
  • GetStage 'BGM001' == 40
  • GetQuestVariable 'BGM001.HasAmulet' == 1 OR
  • GetQuestVariable 'BGM001.HasPaper' == 1 OR
ADD TOPICS No add topic
RESULT SCRIPT No script

This is the first time we've checked the OR flag on a condition. If any of the OR conditions are true, we basically get a TRUE for that entire set of OR conditions. So if the player has either the amulet or the paper, the stage is 40, and the actor is Cpt. Hubart, this response will show up. The OR statements by themselves would also work if we had BOTH of the objects (both would be true), but because we already would have changed the stage to 50 in that case, the stage condition here fails and eliminates the response. (50 != 40)

Leading the player to the next phaseEdit

For the Red Rose topic add this response and add a new topic called BGSmith.

BGRedRose
TOPIC TEXT "Red Rose Brigade"
RESPONSE
  • "They're a nasty bunch led by a couple of villains named Blair and Brown."
  • "They have a hideout in the mountains."
  • "If you want to find them, your best bet is to talk to an ex-member named Smith."
  • "I'm surprised... I never took Brown for a killer."
CONDITIONS
  • GetIsId 'BGCptHubart' == 1
  • GetStage 'BGM001' == 50
ADD TOPICS
  • BGSmith
RESULT SCRIPT No script

Finally add the Brandy, if you wish. Alternatively we could omit this and allow the player to make his choices

BGSmith
TOPIC "Smith"
RESPONSE
  • "He quit the gang a while back and moved to Aleswell. You'll probably find him in the inn there."
  • "He's partial to a drop of brandy. Here, this might help loosen his lips."
CONDITIONS
  • GetIsId 'BGCptHubart' == 1
  • GetStage 'BGM001' == 50
ADD TOPICS No add topic
RESULT SCRIPT
Player.Additem "PotionCyrodiilicBrandy" 1
SetStage BGM001 60

To complete this section we need to update the journal and move on to Aleswell.

Add this to the Stage 60 journal entry.

Captain Hubart told me that the amulet I found near the courier's body belongs to a gang of thieves named the Red Rose Brigade. He told me that my best chance of finding them is to talk with an ex-member named Smith, who now lives in Aleswell.

Aleswell PhaseEdit

This is the last section prior to the big show down. We want to set up a disposition based dialogue in which Smith, once he likes you enough, will give you the location and key to the hidden Red Rose Brigade cave system.

We need to create:

  • Hideout Key
  • NPC called Smith
  • Map marker to the exterior of the Cave system
  • The Cave system (if you are not using the base files)

Creating SmithEdit

First we want set up our NPC.

I used a member of the Thieves Guild as a base. I stripped out his AI, but I left him as a faction member of the Thieves Guild. This will help fellow guild members get a bit of a boost to their disposition.

I have chosen Aleswell as the location for this part of the quest because it is actually a lousy location to use. Aleswell is the setting for an interesting Miscellaneous Quest. In this quest all the inhabitants of the town are invisible. If the user has completed this quest before they load this mod, there will be no problem. However, if this is the first time a player has entered the inn, they will find themselves immediately involved in this quest. We need to make sure our mod interacts with this quest.

We could use some scripts (see lesson 8) to make Smith invisible along with the rest of the citizens. But, as is so often the case, the simplest solution is to just brush over it with a quick bit of dialogue.

We can set up a GREETING for Smith. Here we use the quest stage for the miscellaneous quest called MS47 Zero Visibility. This is the stage where the people of Aleswell become visible.

GREETING
TOPIC TEXT GREETING
RESPONSE "This is so weird. Everyone here is invisible. I came here to blend in with the crowd.. just my luck."
CONDITIONS
  • GetIsId 'BGMSmith' == 1
  • GetStage 'MS47' < 50
ADD TOPICS No add topic
RESULT SCRIPT No script

Information gatheringEdit

The next bit of the quest is a bit tricky.

First let’s review what we want to do.

We are going to set up a situation in which Smith is reluctant to tell us any information regarding the hideout until he likes us enough.

This is called an Information refusal. We can set up the refusal very easily.

Let’s do that now.

BGRedRose
TOPIC TEXT "Red Rose Brigade"
RESPONSE "Hey, I'm done with them. That's all I have to say about that."
CONDITIONS
  • GetIsId 'BGMSmith' == 1
  • GetDisposition [TARGET] < 90
OPTIONS
  • Info Refusal
ADD TOPICS
  • BGBrandy
RESULT SCRIPT No script

The "Info Refusal" flag will make sure that the topic text does not get grayed out, so that the player knows there is still more information available for that topic.

As long as the disposition to the player is less than 90, Smith will give us the brush off when we talk about the Red Rose Brigade.

Somehow we will need to get that disposition up. If the PC is a member of the Thieves Guild, that will help. We can also bribe the NPC or play the disposition game with him. Of course if the player is good with speech craft, that will also get them a bonus. However, I have deliberately set the threshold high because I want to use the brandy idea we set up in Chorrol.

Using choices in dialogueEdit

To do this we will set up a bit of dialogue where the player can choose give Smith some brandy.

First, create the choice topics: BGBrandyYes, and BGBrandyNo.

BGBrandyNo
TOPIC TEXT "No, sorry."
RESPONSE "Aw, that's a shame..."
CONDITIONS
  • GetIsId 'BGMSmith' == 1
  • GetStage 'BGM001' == 60
ADD TOPICS No add topics
RESULT SCRIPT No result script

This is just a simple piece of dialogue.

The "Yes" choice will be more complicated. We will have to check the player's inventory to see if they have any brandy, and if they do, run a script to change the player's disposition.

BGBrandyYes
TOPIC TEXT "I sure do. Here, have some!"
RESPONSE "Wonderful! Uh.. what? Oh no! Has the brandy turned invisible, too?!"
CONDITIONS
  • GetIsId 'BGMSmith' == 1
  • GetStage 'BGM001' == 60
  • GetItemCount 'PotionCyrodiilicBrandy' == 0 (RUN ON TARGET)
ADD TOPICS No add topics
RESULT SCRIPT No result script

This is the response that the player will get if they have no brandy. You MUST check the "Run on Target" box for the GetItemCount condition in order for this to work. Otherwise, the GetItemCount will check the Smith NPC's inventory! (The player is the target in this case.)

Before making the next response, quickly go back the Smith NPC that you dropped in AleswellInn. Open up the details for the one you dropped - the reference, not the base NPC itself - and name it BGMSmithREF. The Persistent Reference box should also be checked already.

BGBrandyYes
TOPIC TEXT "I sure do. Here, have some!"
RESPONSE "Wonderful! Cheers!"
CONDITIONS
  • GetIsId 'BGMSmith' == 1
  • GetStage 'BGM001' == 60
  • GetItemCount 'PotionCyrodiilicBrandy' >= 1 (RUN ON TARGET)
ADD TOPICS No add topics
RESULT SCRIPT
BGMSmithREF.ModDisposition Player 15
Player.RemoveItem "PotionCyrodiilicBrandy" 1

The ModDisposition function will simply increase the NPCs disposition towards the player by 15. Then one bottle of brandy will be taken from the player's inventory. Then we'll set up the dialogue that leads to these two choices:


BGBrandy
TOPIC TEXT "Brandy"
RESPONSE "Yeah, I love the stuff. Have you any to spare?"
CONDITIONS
  • GetIsId 'BGMSmith' == 1
  • GetStage 'BGM001' == 60
CHOICES
  • BGBrandyYes
  • BGBrandyNo
ADD TOPICS No add topics
RESULT SCRIPT No result script

The Choices list is right under the Add Topics list. Add the choice topics in the same way you would add an add topic in.

SuccessEdit

By a combination of speech craft, factions, bribes disposition games and brandy gifts the Player should be able to raise the disposition to 90 eventually. This will trigger the next bit of dialogue and send us towards the quest climax. Return to the BGRedRose topic and add this:

BGRedRose
TOPIC "Red Rose Brigade"
RESPONSE
  • Ok, the truth is I've fallen out with the gang. They've threatened to kill me for leaving."
  • "You look like you can take care of them."
  • "Watch out for Blair, though, he's a nasty bit of work."
  • "I'll mark the hideouts location on your map. And here's my old key... I hope it still works."
  • "Mind you, I'm surprised at Brown. He was a decent chap when I was in the gang..."
CONDITIONS
  • GetIsId 'BGMSmith' == 1
  • GetStage 'BGM001' == 60
  • GetDisposition [TARGET] >= 90
ADD TOPICS No add topic
RESULT SCRIPT
SetStage BGM001 70
Player.Additem "BGHideoutKey" 1
ShowMap BGCaveMapMarker

Map markersEdit

The result script bumps the quest stage to 70 and gives the player the key and map marker. In the quest stage section for stage 70 we can add an appropriate journal entry.

Of course before we do this we need to add the MapMarker to the exterior of our cave. The cave system cell is BGmodtSugglersCaveCOPY0000 in the Interiors worldspace. The cave exterior cell is BGTutMCaveExt in the Tamriel worldspace.

Again we can use the door teleport marker to get ourselves to the exterior location. Drop in a MapMarker and give it a Suitable reference name like BGCaveMapMarker.

Journal entry:

Smith gave me a key for the Red Rose Brigade's hideout. I should go to the hideout and see if I can recover my uncle's key and house deed.

Red Rose Hideout PhaseEdit

This is the climax of our quest. The player will travel to a cave and finally have his showdown with the Red Rose Brigade. We also want to set up a treasure chest as an additional reward. To make the player's task a little harder, we will need to add some goons to fight along the way.

We will need:

  • Dungeon/Cave system
  • Letter, adding extra clue from Brown about chest
  • Several NPC goons
  • NPC called Brown
  • NPC called Blair
  • Key to Brown's cell
  • Key to Uncle's House
  • First Deed Document
  • A special chest
  • Some traps, etc.

Dungeon Design IdeasEdit

The first thing we will need is a cave system, or dungeon, for the player to delve into. The dungeon pieces are a little harder to work with compared to the standard building interiors, as they are not complete pieces. Instead they slot together, piece by piece, to create whole rooms.

A lot of the CS building parts work this way. Castles, Large Basements, Caves, ruins, and Dungeons are all created using this slotting method. First, make sure you switch on the snap-to guides and the angle rotation guides; it makes life easier. Then open File->Preferences and change the snap-to value to 1. This alters the sensitivity of the snap, giving a closer fit.

The best source of information and design ideas is the game and the CS. You should get into the habit of making note of ‘cool’ locations or quests and looking them up in the CS to see how they work.

The cave system I set up for this tutorial was created in a hurry. I simply copied chambers from other cave systems in the CS and then pasted them together.

It’s funny how you can come full circle. I now realize that the problem with the My First Dungeon tutorial in the Wiki is that it chose to illustrate its techniques using a dungeon. Had the Wiki went for "My First House" instead, it would have been much better off. However, we now know what we are doing, and working on dungeons should be no problem.

I don’t intend to give you a click by click guide to building dungeons. If you get stuck, use the PLAYTEST version as a guide.

Dressing the DungeonEdit

Ok, let’s add some bits to help move our story forward. First, let's write a piece of script in the main quest script's GameMode block to update the quest stage when the player enters the hideout.

If (GetStage BGM001 == 70)
     If (Player.GetInCell BGmodtSugglersCaveCOPY0000 == 1)
          SetStage BGM001 80
     EndIf
EndIf

We can also add a journal entry for stage 80:

I've arrived at the Red Rose Brigade's hideout. If those thieves stole the deed and house key, I should find them here.

Although this first chamber is quite large, I have decided to limit the threat to a single small random creature: a rat or a crab (LL0NuissanceBeast100). Why? Two reasons: I want to be able to escalate my threat, and I want to build suspense.

One of the design choices you will have to make is how to balance risk against reward. You should also try to escalate the threat as the story progresses. For instance, it would be very easy to throw five or six Daedra into the first chamber of our dungeon. But where do you go from there? If you start with too big a threat then you have little room to escalate that threat later. Also, try to give a little thought to the user who has minimum specifications. I’ve seen a few works in progress where they have designed a really cool crypt with 30 or so monsters in it. But I know that on my poor little PC, I’ll get a frame rate of about 3 frames per week. This is not a mod I'll be playing. Bigger doesn’t mean better, more is sometimes less.

The player is also expecting to meet bad guys. Hopefully he will edge his character down into the first chamber fully expecting an army of trolls. I want to disappoint him. I want him to start to think this is easy before we hit him/her with the big stuff.

I also want to set the scene a little. For this I created another corpse, and placed a letter near it which informs the player about the special treasure chest and Brown's imprisonment.

Make the corpse and the letter. I also added a leveled nuisance creature at the far end of the chamber, so that the player will have to deal with the annoyance of a one hit kill creature after picking up the letter.

The text for the letter is:

<font face=5>
Dear Smith,
<br>
<br>
I beg of you, please help me. Blair has gone mad. I have been imprisoned.<br>
<br>
It all began when we attacked the White Horse Courier near Chorrol.
It was supposed to be a simple robbery. But when Blair found out that the only loot was a key and a house deed he went berserk. 
<br>
He killed the courier in cold blood. I wanted no part of it.<br>
I suggested the gang might do better with me in charge. He accused me of being a
double-agent for our rivals, the Torch Gang. Now he's had me locked up because I know how to open his treasure chest. He wants to kill me but he fears the other gang members might turn on him.
<br>
Please Smith, send help. I have asked one of the gang members who's loyal to me to take this letter to you. I hope he makes it. Blair is watching my every move.
<br>
<br>
Your old friend,<br>
Brown

We make and add the following script to the letter

Scriptname BGM001BrownsLetterSCRIPT

Begin OnAdd Player

  If (GetStage BGM001 >= 80)
    SetStage BGM001 90
  EndIf

End

Again we can bump the stage and enter another journal entry for stage 90:

I have found a letter from Brown. It appears the Red Rose leader has imprisoned him. Brown has knowledge of a secret treasure. I should try to talk to him.

Finally, I messed about with the lighting to try to create a little more atmosphere. Clearly, caves should be darker than the outside world. Try to use spot lights to pick out areas you want the PC to notice and to hide threats that you want to be a surprise.

The second chamber will contain a single NPC. We want all the Red Rose Brigade NPC’s to act as a team. How? With Factions.

FactionsEdit

Factions are used in three ways by the game:

  1. To establish a hierarchy or internal structure for organizations the PC can join
  2. To group NPCs into teams with similar behaviors.
  3. To make groups of NPCs that can be used in condition statements. (e.g., when we used the ICFaction to apply conditions to citizens of the Imperial City)

To create a new faction, open up the Faction box from the Character menu. The column on the left lists all of the existing factions. Rick-click in the column and select New. Give the Faction a unique ID, such as BGRedRoseBrigade. Now, add the name to the top: Red Rose Brigade.

The "Hidden from PC" flag at the top basically controls whether or not a player can enter that faction. Check this box.

The Rank Data box in the center controls the ranks and titles within the faction. Note that the ranks are split to offer the choice of alternative titles based on gender. In the case of our faction, these have no meaning at all.

For us, the Interfaction Relations box at the bottom will be most useful.

It controls the disposition of members of one factions towards members of another faction. The Mod value is a numerical modifier ranging from -100 to +100. This modifier is applied to all members of the group.

The results are cumulative. Let’s say we decide that the Red Rose Brigade is closely affiliated with the various Bandits who occupy Tamriel. We can add a modifier of, say, +70 to that group. Create a new entry for the Bandit faction, and set the modifier to 70. From now on every member of the Red Rose faction will add 70 to there disposition towards bandits. We can add as many groups as we like.

We want the Red Rose members to be openly hostile to the PC. For this we can use PlayerFaction, which has a solitary member: the player. We can adjust the disposition for this faction to -100. This means they will attack the player on sight.

We also want Red Rose members to be friendly with one another. Add another disposition entry for the Red Rose faction itself, with a relatively high disposition value.

Finally, we need to add a separate faction for Brown, so that (1) the Red Rose members don't kill their prisoner and (2) the prisoner won't attack the player. Name it something like BGRRPrisoner. For the prisoner's faction, add a positive disposition towards the player. Then go back to the Red Rose Brigade faction and add a positive disposition towards the prisoner's faction.

Enemy NPCsEdit

Create an NPC. I used the BanditMelee character as a base template. This character already comes with leveled item lists (even though they will appear to be naked in the preview render).

The level of an NPC is controlled by the flags and boxes to the left of the character box.

We can make two choices:

Level: In this option we select a specific level for the NPC. The advantage is that we can control exactly how challenging an NPC should be. This is ideal if we have a particular reward which we feel should be earned only by well developed player characters. Suppose you design a one hit kill sword. This is a big reward. The player should have to earn this reward by defeating a big boss.

On the other hand, you might even want to make an NPC particularly weak, which you could easily do by setting a low level.

The disadvantage is that if you set an NPC to level 40, for example, only a small number of players will meet this challenge. Many may simply unplug your mod.

PC Level Offset: This is one of the more controversial developments in Oblivion. Many Morrowind veterans have been particularly vocal in their criticism of this technique. The advantage is that no matter what level your PC is at you will meet a decent challenge which will test your PC. It allows PC's of all levels to access quests. However, it has disadvantages as well. This approach does mean that some times the risk does not match the reward.

For this tutorial I have chosen to use the PC Level Offset method as this is the Oblivion norm. It is, of course, up to each individual designer to choose what they want to do. I would suggest that whatever method you choose is consistent throughout the mod. If you mix and match you could have a situation where the first few goons are 10 levels above the end boss, or where after defeating a series of level 2 goons you suddenly encounter a level 30 boss.

We also want this first goon to be a little bit easier than those coming up so lets set the value to -2 levels using the offset box. The bandit already has a suitable leveled inventory.

The central chamber will contain 3 NPCs. Remember to add the Red Rose Faction to their faction lists and delete the others. I used more bandits as a base for these. I also set the PC level offset to -1.

Finally, I messed around with the lighting a bit. I wanted to give stealthy players a chance to sneak. I removed the lighting from the linking corridor and the entrance.

The Final ChamberEdit

Setting up the resourcesEdit

This consists of a large chamber with two antechambers. In the first antechamber we create a cell by placing a door in the corridor. We can use this to house NPC BGBrown. Remember, Brown must be added to the separate prisoner faction.

Finally, we create Blair. He is our Boss. I made his level offset +2. I am going to say very little about this NPC, because this is where you get to have the most fun making your own bad guy. Once created, add the cell door key to his inventory. Make the cell door locked, and set it to ‘Needs a key‘.

Add BGTopViewKey (the key to the house) to Blair's inventory. Now create an "uncertified" deed and add this to his inventory.

BGTopViewUncertifiedDeed:

<font face=5>
<BR>
<BR>
This document hereby states that the bearer is the sole owner and possessor of the
domicile currently known as Top View. Said domicile is located North of the Imperial
City and South of the city of Bruma in the territory known as Cyrodiil.<BR>
<BR>
The bearer has full ownership rights to all of the structures, flora and land within
the property borders as defined in the Tamriel Construction Charter. The bearer is
responsible for all matters pertaining to or occurring on said property.<BR>
<BR>
This document also empowers the bearer transfer rights to reassign the property as he
sees fit. The bearer may amend this document to rename the manor  by submitting the
proper forms and payments to the Tamriel Construction Charter and by filing
duplicate forms with the Documents Division of the Imperial City Archives.<BR>
THIS DOCUMENT MUST BE REGISTERED IN THE IMPERIAL CITY BY A QUALIFIED NOTARY PUBLIC TO GAIN LEGAL FORCE.<BR>

This document explains why we have to return to the Imperial City.

Both Blair and Brown will need special AI packages to get them to work properly.

I also want to make sure that the player, no matter how good they are at sneaking, will be forced to confront Blair. How do we do this? Easy, we script it. We will also design the quest so that you will have to kill Blair to move on to the next stage. We can also do this through scripts.

Setting up BlairEdit

Add a new variable to the main quest script called BlairGreeted. Then attach this script to the Blair NPC:

SCN BGBlairSCRIPT

Begin OnDeath
	SetStage BGM001 95
End

Begin GameMode
	If BGM001.BlairGreeted == 0
		If GetDistance Player <= 500
			StartConversation Player GREETING
		EndIf
	EndIf
End

Then set up the new GREETING.

GREETING
TOPIC TEXT "GREETING"
RESPONSE "I heard you've been snooping around. Prepare to die!"
CONDITIONS
  • GetIsID 'BGBlair' == 1
  • GetStage 'BGM001' >= 80
ADD TOPICS No add topics
RESULT SCRIPT
Set BGM001.BlairGreeted to 1
StartCombat Player

In order for this to actually work, we need to change Blair's aggression stat so that he doesn't attack the player on sight (the topic result script will initiate combat for us). Open up the Blair NPC form, and click the AI button. In AI Attributes, set Aggression to 0.

When the PC kills Blair, we can also update the journal by adding an entry for stage 95.

I have killed Blair. I should search his body for the deed and house key. I should also see if he has a key to Brown's cell. I can then return to the Imperial City to see Vilanus.

Setting up BrownEdit

We can set up an optional reward for players who choose to free Brown from his cell. Open up Brown's form and make sure he doesn't have a high aggression level, just to make sure Brown won't attack the player on sight. It should at least be lower than whatever positive disposition you gave the prisoner faction towards the player, but it wouldn't hurt to just set it to 0.

Then set up a greeting for Brown:

GREETING
TOPIC TEXT GREETING
RESPONSE "Please, please, don't kill me! I had no hand in this. Just let me go."
CONDITIONS
  • GetIsID 'BGBrown' == 1
  • GetStage 'BGM001' >= 95
ADD TOPICS
  • BGBrownChoice1
  • BGBrownChoice2
RESULT SCRIPT No result script

Each response will advance the quest to a different stage, which will have appropriate journal entries and result scripts.

BGBrownChoice1
TOPIC TEXT You can go.
RESPONSE "Thank you! Thank you! The code is one, four, seven."
CONDITIONS
  • GetIsID 'BGBrown' == 1
  • GetStage 'BGM001' >= 95
ADD TOPICS No add topics
RESULT SCRIPT
SetStage BGM001 100

For stage 100, add the following journal entry:

Brown gave me the code for the combination lock on the chest. I need to enter 1-4-7 to unlock it. Once I've done that, I will need to go see Vilanus Villa in  Imperial City. Vilanus will need to transfer ownership of my uncle's house to me.
BGBrownChoice2
TOPIC TEXT No.
RESPONSE "You'll regret this!"
CONDITIONS
  • GetIsID 'BGBrown' == 1
  • GetStage 'BGM001' >= 95
ADD TOPICS No add topics
RESULT SCRIPT
SetStage BGM001 101

Add another entry for stage 101:

I left Brown to rot in his cell. I need to go see Vilanus Villa in  Imperial City so he can transfer my uncle's property to me.

The stage result script is used to remove the quest object status from a number of items which are no longer needed and which the PC can now dispose of. This should be applied to BOTH of the possible stages. (Use whichever IDs you chose when creating these items.)

SetQuestObject BGHideoutCELLKey 0
SetQuestObject BGHideoutKey 0
SetQuestObject BGBrownLetter 0
SetQuestObject BGPartialLetter 0


We will need to look at altering Brown's behavior for the final release. We will need to add some AI in the next lesson to get him to run away.

Scripting the chestEdit

What we need to look at now is another hefty bit of scripting which will control the combination lock on the treasure chest.

Here it is in its entirety. Look through it and try to work out what it is doing.

It controls a chest with a three digit combination style lock.

SCN BGBlairsChestSCRIPT

Short Button1
Short Button2
Short Button3
Short Frame
Short Unlocked
Short GoldCount

Begin OnActivate

  If Unlocked == 1
    Activate
  Else
	;Begin combination menu
	Set Frame to 1
  EndIf

End

Begin GameMode
If Frame != 0
	;Get the first digit
	If Frame == 1
		MessageBox "First digit" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
		Set Frame to 2
	EndIf

	;Save first digit entered, get the second digit
	If Frame == 2
		Set Button1 to GetButtonPressed
		If Button1 == -1
			Return
		EndIf
		MessageBox "Second digit" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
		Set Frame to 3
	EndIf

	;Save second digit entered, get third digit
	If Frame == 3
		Set Button2 to GetButtonPressed
		If Button2 == -1
			Return
		EndIf
		MessageBox "Third digit" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
		Set Frame to 4
	EndIf

	;Save third digit entered, then check combination.
	If Frame == 4
		Set Button3 to GetButtonPressed
		If Button3 == -1
			Return
		EndIf

		If Button1 == 1 && Button2 == 4 && Button3 == 7
			;Correct combination result
			MessageBox "The combination pad unlocks."
			Set Unlocked to 1
			Set Frame to 0
		Else
			;Bad combination result
			MessageBox, "Suddenly your pockets feel a bit lighter."
			Set Frame to 0			
			If (Player.GetItemCount "gold001") >= 100
				Player.RemoveItem "gold001" 100
				AddItem "gold001" 100
			Else
				Set GoldCount to Player.GetItemCount "gold001" 
				Set GoldCount to GoldCount - 1
				Player.RemoveItem "gold001" GoldCount
				AddItem "Gold001" GoldCount
			EndIf
		EndIf ;Correct combo
	EndIf ; Frame 4
EndIf; Frame != 0
End

Now it's time to wrap up our little adventure. We move the scene back to the Imperial City.

Imperial City Phase TwoEdit

In this phase the player will return to Vilanus, who will set about transferring the ownership of the property to you. We will add a delay so that the player has to wait 24 game hours before the process is finished.

We need:

  • A completed version of the deed
  • The prize house
  • A map marker for the house

To set up the prize house, go to the interior cell BGmodtut4, which is the interior of the house. It has three doors. One leads to the basement. The other two are linked to the exterior. Lock the exterior doors and set the ownership to our old buddy BGDummyOwner. Set the interior cell ownership to BGDummyOwner as well.

New dialogueEdit

We begin by adding more dialogue for Vilanus Villa.

First, set up three new topics:

  • BGDeedCheck
  • BGRecoverYes
  • BGRecoverNo

Then add a new greeting:

GREETING
TOPIC TEXT "GREETING"
RESPONSE "Hello, have you managed to recover the key and deed?"
CONDITIONS
  • GetIsID 'BGVilanusVilla' == 1
  • GetStage BGM001 >= 20
  • GetStage BGM001 < 110
ADD TOPICS No add topics
CHOICES
  • BGRecoverYes
  • BGRecoverNo
RESULT SCRIPT No result script

Then edit the choices.

BGRecoverNo
TOPIC TEXT "No, not yet."
RESPONSE "I can't help you until you've found both the key and the deed."
CONDITIONS
  • GetIsID 'BGVilanusVilla' == 1
  • GetStage 'BGM001' < 95
ADD TOPICS No add topics
RESULT SCRIPT No result script


BGRecoverYes
TOPIC TEXT "Yes. Here they are."
RESPONSE "Excellent. I will take the deed to the property registrar today. Come back tomorrow, the transfer should be complete by then."
CONDITIONS
  • GetIsID 'BGVilanusVilla' == 1
  • GetStage 'BGM001' >= 95
  • GetItemCount 'BGTopViewKey' == 1
  • GetItemCount 'BGTopViewUncertifiedDeed' == 1
ADD TOPICS
  • BGDeedCheck
RESULT SCRIPT
Player.RemoveItem BGTopViewUncertifiedDeed 1
SetStage BGM001 110

Stage 110 Journal Update:

Vilanus told me that he is going to take the deed to the property registrar, and that I should check back with him tomorrow when the transfer is complete.

We want to set up a delay of one day before we can collect the finished documents. This gives us an excellent opportunity to look at and practice timers.

TimersEdit

Timers are another bit of scripting that gets used again and again. The game uses a number of global variables to report the progress of time.

The two most used are:

We can use the seconds passed to establish timed events. GetSecondsPassed returns a float value, so we must set up a float type variable to save it in.

Here is an example script that takes 10 Septims from the player and then gives them back 25 seconds later.

Scriptname ExampleTimerScript

float Timer
short State

Begin GameMode
	
  If State == 0 
    Set Timer to 25.0
    Set State to 1
    Player.RemoveItem "gold001" 10
  ElseIf State == 1
    If Timer > 0
      Set Timer to Timer - GetSecondsPassed
    Else
      Player.AddItem "gold001" 10
      Set State to 2
    EndIf
  EndIf

End

If you're writing a script where you're only interested in the number of in-game days that have passed, you can use GameDaysPassed instead (which is a short).

In the quest script add three short variables called State, StartDay, and DeedFinished.

Then add this to the GameMode block:

	If GetStage BGM001 == 110
		If State == 0
			Set StartDay to GameDaysPassed
			Set State to 1
		ElseIf State == 1
			If GameDaysPassed > StartDay
				Set DeedFinished to 1
				Set State to 2
			EndIf
		EndIf
	EndIf

This piece of script goes through three states:

  1. Stage 110 has begun. Initialize the StartDay value, and change to second state.
  2. StartDay has been set. Check to see if the value of the current in-game date is more than StartDay (this will be true on any day after the starting day, including the first day after, which is what we want). Change to third state.
  3. Finished. Do nothing.

More dialogueEdit

The DeedFinished variable will tell us when the game day is passed and the deed should be finished. We can use this variable for the next piece of dialogue. There will be two possible responses for this topic. One for when the deed is finished, and one for when it's not.

BGDeedCheck
TOPIC TEXT "House Deed"
RESPONSE "It should be finished by tomorrow. Check back with me then."
CONDITIONS
  • GetIsID 'BGVilanusVilla' == 1
  • GetStage 'BGM001' == 110
  • GetQuestVariable 'BGM001.DeedFinished' == 0
ADD TOPICS No add topics
RESULT SCRIPT No result script


BGDeedCheck
TOPIC TEXT "House Deed"
RESPONSE
  • "The paperwork went through and you are now the owner of the Top View cottage."
  • "Here's the certified deed. I'll mark the location of the house on your map."
  • "May the Gods be with you."
CONDITIONS
  • GetIsID 'BGVilanusVilla' == 1
  • GetStage 'BGM001' == 110
  • GetQuestVariable 'BGM001.DeedFinished' == 1
ADD TOPICS No add topics
RESULT SCRIPT
Player.AddItem BGTopViewDeed 1
SetStage BGM001 120


The new deed, BGTopViewDeed, is just a copy of the old one without the very last line about needing to get it notarized. You do NOT need to make this a quest item. We don't need to force the player to keep it in their inventory.

Journal Update for Stage 120:

The paperwork is finished and I now have a certified deed for the Top View Cottage. I should go visit the property.

Finishing upEdit

Add a new map marker outside of the house (in Tamriel->TopViewCottage). Call it BGTopViewMapMarker. Then edit the names of the two exit doors, to something like BGTVDoor1 and BGTVDoor2.

Then add the following quest stage result script for stage 120:

BGTVDoor1.SetOwnership
BGTVDoor2.SetOwnership
SetCellOwnership BGModTut4
SetCellOwnership BGModTu4Base
ShowMap BGTopViewMapMarker

This script transfers ownership of the house doors and cells to the player, and then enables the map marker.

We then complete the quest script with a final block to check when the PC arrives at the house.

	If GetStage BGM001 == 120
		If Player.GetInCell BGModTut4 || Player.GetInCell BGModTu4Base
			SetStage BGM001 130
		EndIf
	EndIf

For this stage, you can check the Quest Complete box. Remember, this does not truly end the quest. To do that we must use the StopQuest function.

The final journal entry:

I have reached Top View. I am now free to explore my new home.

Finally, we add this quest stage result script to stage 130.

ModPCFame 1
SetEssential BGVilanusVilla 0
SetEssential BGMSmith 0
SetEssential BGCptHubart 0
StopQuest BGM001

The SetEssential commands remove the essential status from all of the essential characters we created earlier. ModPCFame boosts the player's fame by 1 point (optional). StopQuest stops the quest from running, and disables all of its dialogue.

So there you have it. A completely functional quest.

However, if we really want to wow the public with our release we will need to add some AI to our NPC’s and look at our options regarding Audio and Lip Sync, and that’s what lesson 8 will be about.

Till then, happy modding!

ThanksEdit

Thanks to dtom, who posted the guide on the Elder Scrolls Forums that this article is based on.