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

Jump to navigation Jump to search
→‎The Final Chamber: Editing English, tables, scripts
imported>Pyrocow2
(→‎Imperial City Phase Two: prize house stuff. to be edited more)
imported>Pyrocow2
(→‎The Final Chamber: Editing English, tables, scripts)
Line 632: Line 632:
<BR>
<BR>
The bearer has full ownership rights to all of the structures, flora and land within
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
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>
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
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
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
proper forms and payments to the Tamriel Construction Charter and by filing
duplicate forms with the Documents Division of the Imperial City Archives.
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.</pre>
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.
Line 645: Line 645:
Both Blair and Brown will need special AI packages to get them to work properly.  
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.
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.
Attach this script to the Blair NPC:<br>
 
<pre>Scriptname BGBlairScript
<pre>Scriptname BGBlairDeathScript


Short DoOnce
Short DoOnce
Line 689: Line 688:
|-
|-
!  ADD TOPICS
!  ADD TOPICS
|   
''No add topics''
* (none)
|-
|-
!  RESULT SCRIPT
!  RESULT SCRIPT
|   
''No result script''
* (none)
|}  
|}  


When the PC kills Blair we can then update the journal
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 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 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.''


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.  
We can set up an optional reward for players who choose to free Brown from his cell.


Initially we set up a greeting.  
First, we set up a greeting for Brown.


{| border="1" cellpadding="5"
{| border="1" cellpadding="5"
!colspan=2| '''GREETING'''
|-
|-
!  TOPIC
!  TOPIC TEXT
|   
|  GREETING
* GREETING
|-
|-
!  RESPONSE
!  RESPONSE
|   
|  Please, please, don't kill me! I had no hand in this. Just let me go.
* Please, Please, don't kill me. I just want to get away from here. Please let me go
|-
|-
!  CONDITIONS
!  CONDITIONS
|   
|   
* GetIsId BGBrown == 1
* GetIsID 'BGBrown' == 1
* GetStage BGM001 >= 95
* GetStage 'BGM001' >= 95
|-
|-
!  ADD TOPICS
!  ADD TOPICS
|   
|   
* BgBrownChoice1
* BGBrownChoice1
* BgBrownChoice2
* BGBrownChoice2
|-
|-
!  RESULT SCRIPT
!  RESULT SCRIPT
|   
''No result script''
* (none)
|}
|}
The positive response info for BGBrownC1 gives a stage boost, the negative one does not.
 
The positive response, ''BGBrownChoice1'', will give a stage boost. The negative response, ''BGBrownChoice2'', will not.


{| border="1" cellpadding="5"
{| border="1" cellpadding="5"
!colspan=2| '''BGBrownChoice1'''
|-
|-
!  TOPIC
!  TOPIC TEXT
|   
You can go.
* BGBrownC1
|-
|-
!  RESPONSE
!  RESPONSE
|   
|  Thank you! Thank you! The code is one, four, seven.
* Thank You! Thank you! The code is 1 4 7
|-
|-
!  CONDITIONS
!  CONDITIONS
|   
|   
* GetIsId BGBrown == 1
* GetIsID 'BGBrown' == 1
* GetStage BGM001 >= 95
* GetStage 'BGM001' >= 95
|-
|-
!  ADD TOPICS
!  ADD TOPICS
|
| ''No add topics''
* (none)
|-
|-
!  RESULT SCRIPT
!  RESULT SCRIPT
|   
|  <pre>SetStage BGM001 100</pre>
<pre>SetStage BGM001 100</pre>
|}
|}


We update the journal and run a bit of script as a result
We update the journal and run a bit of script as a result.


''Brown has given me the code to the Combination Chest I need to enter the numbers 1 4 7 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.''
''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.''


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.
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.


SetQuestObject BGHideoutCELLKey 0
<pre>
SetQuestObject BGHideoutKey 0
SetQuestObject BGHideoutCELLKey 0
SetQuestObject BGBrownLetter 0
SetQuestObject BGHideoutKey 0
SetQuestObject BGPartialLetter 0
SetQuestObject BGBrownLetter 0
SetQuestObject BGPartialLetter 0
</pre>


{| border="1" cellpadding="5"
{| border="1" cellpadding="5"
!colspan=2| '''BGBrownChoice2'''
|-
|-
!  TOPIC
!  TOPIC TEXT
|   
No.
* BGBrownC2
|-
|-
!  RESPONSE
!  RESPONSE
|   
You'll regret this!
* Then you'll never learn the entry code.
|-
|-
!  CONDITIONS
!  CONDITIONS
|   
|   
* GetIsId BGBrown == 1
* GetIsID 'BGBrown' == 1
* GetStage BGM001 >= 95
* GetStage 'BGM001' >= 95
|-
|-
!  ADD TOPICS
!  ADD TOPICS
|   
''No add topics''
* (none)
|-
|-
!  RESULT SCRIPT
!  RESULT SCRIPT
|   
''No result script''
* (none)
|}
|}


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.
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.


What we do need to look at now is another hefty bit of scripting which controls the treasure 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.


<pre>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
Set Frame to 1
   EndIf
   EndIf


Line 820: Line 812:


Begin GameMode
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 (ChestOpen == 1)
If Frame == 2
;------------------------------------------------------------
Set Button1 to GetButtonPressed
    If (DigitCount == 0)
If Button1 == -1
      MessageBox, "Please input the first digit of thecombination",
Return
        "0","1","2","3","4","5","6","7","8","9" ;one line
EndIf
      Set DigitCount to 1
MessageBox "Second digit" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
    EndIf
Set Frame to 3
EndIf


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


    If (DigitCount == 2)
;Save third digit entered, then check combination.
      MessageBox, "Please input the second digit of the combination",
If Frame == 4
        "0","1","2","3","4","5","6","7","8","9" ;one line
Set Button3 to GetButtonPressed
      Set DigitCount to 3
If Button3 == -1
    EndIf
Return
EndIf


    If (DigitCount == 3)
If Button1 == 1 && Button2 == 4 && Button3 == 7
      Set Button2 to GetButtonPressed
;Correct combination result
      If Button2 == -1
MessageBox "The combination pad unlocks."
        Return
Set Unlocked to 1
      Else
Set Frame to 0
        Set DigitCount to 4
Else
      EndIf
;Bad combination result
    EndIf
MessageBox, "Suddenly your pockets feel a bit lighter."
 
Set Frame to 0
    If (DigitCount == 4)
If (Player.GetItemCount "gold001") >= 100
      MessageBox, "Please input the third digit of the combination",
Player.RemoveItem "gold001" 100
        "0","1","2","3","4","5","6","7","8","9" ;one line
AddItem "gold001" 100
      Set DigitCount to 5
Else
    EndIf
Set GoldCount to Player.GetItemCount "gold001"  
 
Set GoldCount to GoldCount - 1
    If (DigitCount == 5)
Player.RemoveItem "gold001" GoldCount
      Set Button3 to GetButtonPressed
AddItem "Gold001" GoldCount
      If button3 == -1
EndIf
        Return
EndIf ;Correct combo
      Else
EndIf ; Frame 4
        Set DigitCount to 6
EndIf; Frame != 0
      EndIf
End
    EndIf
</PRE>
;---------------------------------------------------------------
 
    If (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
 
;---------------------------------------------------------------
 
    If (DigitCount == 6) && (CombiRight ==3)
      Set ChestOpen to 2
      Set DigitCount to 0
      Return
    EndIf
;---------------------------------------------------------------
 
    If (DigitCount == 6) && (CombiRight <= 2)
      MessageBox, "Naughty, naughty. Now take your punishment"
      If (Player.GetItemCount "gold001") >= 100
        Player.RemoveItem "gold001" 100
        BGBlairChestref.AddItem "gold001" 100
        Set DigitCount to 0
        Set ChestOpen to 0
        Return
      Else
        Set GoldCount to Player.GetItemCount "gold001"
        Player.RemoveItem "gold001" GoldCount
        BGBlairChestref.AddItem "Gold001" GoldCount
        Player.AddItem "gold001" 1
        Set DigitCount to 0
        Set ChestOpen to 0
      EndIf
 
    EndIf
;-----------------------------------------------------------------
  ElseIf (ChestOpen == 0)
    Return
  ElseIf (ChestOpen == 2)
    If DoOnce == 0
      Set DoOnce to 1
      Activate
      Return
    EndIf
  Else
    Return
  EndIf
End</pre>
 
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
 
  If (ChestOpen == 2)
    Activate
  Else
    Set ChestOpen to 1
  EndIf
 
End</pre>
 
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.
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.
 
Begin GameMode
 
We use the Chest Open == 1 to enable the main body of the script.
 
  If (ChestOpen == 1)
 
For this we use another variable called DigitCount to help work through the different stages of the script
 
<pre>  If (DigitCount == 0)
    MessageBox, "Please input the first digit of the combination",
      "0","1","2","3","4","5","6","7","8","9" ;should be one line
    Set DigitCount to 1
  EndIf</pre>
 
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.
 
<pre>  If (DigitCount == 1)
    Set Button1 to GetButtonPressed
    If Button1 == -1
      Return
    Else
      Set DigitCount to 2
    EndIf
  EndIf</pre>
 
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.
<pre>  If (DigitCount == 2)
    MessageBox, "Please input the second digit of the combination",
      "0","1","2","3","4","5","6","7","8","9" ;again, one line
    Set DigitCount to 3
  EndIf
 
  If (DigitCount == 3)
    Set Button2 to GetButtonPressed
    If button2 == -1
      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" ;one line
    Set DigitCount to 5
  EndIf
 
  If (DigitCount == 5)
    Set Button3 to GetButtonPressed
    If button3 == -1
      Return
    Else
      Set DigitCount to 6
    EndIf
  EndIf</pre>
 
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.
 
<pre>  If (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</pre>
 
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.
 
<pre>  If (DigitCount == 6) && (CombiRight ==3)
    Set ChestOpen to 2
    Set DigitCount to 0
    Return
  EndIf</pre>
 
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.
 
  If (DigitCount == 6) && (CombiRight <=2)
 
This bit of script displays a message
 
    MessageBox, "Naughty, naughty. Now take your punishment"[/i]
 
Then checks that the PC can afford the ‘fine’
 
  If (Player.GetItemCount "gold001") >= 100
 
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.
 
    Player.RemoveItem "gold001" 100
    BGBlairChestref.additem "gold001" 100
    Set DigitCount to 0
    Set ChestOpen to 0
    Return
 
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
 
    Else
      Set GoldCount to Player.GetItemCount "gold001"
 
Then we take that away and add it to the chest.
 
      Player.RemoveItem "gold001" GoldCount
      BGBlairChestRef.AddItem "Gold001" GoldCount
      Player.AddItem "gold001" 1
      Set DigitCount to 0
      Set ChestOpen to 0
    EndIf
  EndIf
 
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.
 
  ElseIf (ChestOpen == 0)
    Return
 
This bit opens the chest if we have the correct combination.
 
  ElseIf (ChestOpen == 2)
    If DoOnce == 0
      Set DoOnce to 1
      BGBlairChestRef.Activate Player
      Return
    EndIf
  Else
    Return
  EndIf
End


Now its time to wrap up our little adventure. We move the scene back to the Imperial City
Now its time to wrap up our little adventure. We move the scene back to the Imperial City
Anonymous user

Navigation menu