Difference between revisions of "Scripting Tutorial: Working with FormLists"
Scripting Tutorial: Working with FormLists (edit)
Revision as of 04:26, 10 August 2010
, 04:26, 10 August 2010no edit summary
imported>Omzy |
imported>Omzy |
||
(12 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
==IMPORTANT== | ==IMPORTANT== | ||
'''You will need [[Fallout Script Extender|Fallout Script Extender (FOSE)]] for this tutorial.''' | '''You will need [[Fallout Script Extender|Fallout Script Extender (FOSE)]] for this tutorial.''' | ||
Line 52: | Line 49: | ||
===Creating a List=== | ===Creating a List=== | ||
FormLists must be created in the GECK, as there are no functions at this time to generate them from scripts. | *FormLists must be created in the GECK, as there are no functions at this time to generate them from scripts. | ||
#Navigate in the Object Window to Miscellaneous -> Form List. | |||
#Right click, select New. | |||
#Enter an ID for your FormList. | |||
===Adding Forms to a List=== | ===Adding Forms to a List=== | ||
Line 81: | Line 78: | ||
*You can use the [[ListGetCount]] function. | *You can use the [[ListGetCount]] function. | ||
== | =Using Lists to Create Floating Text= | ||
As it would seem, a FormList is also an object in the editor, which has its own FormID. That makes a FormList a Form. What this means is that FormLists can contain other FormLists. | This example goes beyond what a casual modder might attempt to accomplish, but it displays the abilities of lists quite well. | ||
Suppose we have added 27 textured meshes into the GECK, corresponding to the letters of the English alphabet plus a space character. These meshes are added as forms (e.g. we have objects in the editor letterA, letterB, etc.). Now suppose we want to use these to display a list of names on a sign board in Fallout 3. | |||
We have determined: | |||
*The first letter of the first name should be positioned at (1000,1000,1000) in our cell with angle positions of (0,0,0). | |||
*The offset to the next letter is (0,5,0), meaning if the first letter of a name is at x=1000,y=1000,z=1000 in a cell, the next letter should be at x=1000,y=1005,z=1000. | |||
*The offset to the next name is (0,10,0), meaning if the first letter of the first name is at x=1000,y=1000,z=1000 in a cell, the first letter of the second name should be at x=1000,y=1000,z=1010. | |||
*Our names are (courtesy of FF7): | |||
#Cloud | |||
#Barret | |||
#Tifa | |||
#Aeris | |||
#Red XIII | |||
#Yuffie | |||
#Vincent | |||
#Cait Sith | |||
#Cid | |||
Let us create a [[FormList]] for each name that contains the letters of that name. The name of each list will be ''nameX'' where ''X'' is the name (e.g. ''nameCloud''). If we try dragging and dropping ''B, a, r, r, e, t'' into a FormList for the name Barret, we will not be able to add the second ''r'' because dragging and dropping allows us only to add base forms to a FormList once, since they have the same FormID. So, we must add the letters as references via a script using [[ListAddReference]] OR by placing the letters into the world in a cell somewhere and dragging their references from the Cell View window. For this example, lets assume we've added them to a test cell somewhere so we can use [[MoveTo]] to relocate them to their destinations. We will add the letters so that the first letter of each name is at index 0. | |||
===Inefficient Script=== | |||
If we wish to print these names into the world somewhere, we can use the [[Label]]/[[GoTo]] loop, one loop for each FormList of letters: | |||
scn floatingNamesScript | |||
;vars (not listed for brevity) | |||
Begin GameMode | |||
;set first letter's position | |||
set firstLetterPosX to 1000 | |||
set firstLetterPosY to 1000 | |||
set firstLetterPosZ to 1000 | |||
;initialize current letter's position | |||
set letterPosX to firstLetterPosX | |||
set letterPosY to firstLetterPosY | |||
set letterPosZ to firstLetterPosZ | |||
;distance to the next letter | |||
set letterOffsetX to 0 | |||
set letterOffsetY to 5 | |||
set letterOffsetZ to 0 | |||
;distance to the next name | |||
set nameOffsetX to 0 | |||
set nameOffsetY to 0 | |||
set nameOffsetZ to 10 | |||
;PRINT FIRST NAME | |||
set letterList to nameCloud | |||
Label 1 | |||
set currentLetter to ListGetNthForm letterList count1 | |||
currentLetter.MoveTo Player | |||
currentLetter.SetPos X letterPosX | |||
currentLetter.SetPos Y letterPosY | |||
currentLetter.SetPos Z letterPosZ | |||
;add offsets for next letter | |||
set letterPosX to letterPosX + letterOffsetX | |||
set letterPosY to letterPosY + letterOffsetY | |||
set letterPosZ to letterPosZ + letterOffsetZ | |||
set count1 to count1 + 1 | |||
if count1 < ListGetCount letterList | |||
GoTo 1 | |||
endif | |||
;set position of next name's first letter | |||
set letterPosX to firstLetterPosX | |||
set letterPosY to firstLetterPosY | |||
set letterPosZ to firstLetterPosZ | |||
set letterPosX to letterPosX + nameOffsetX | |||
set letterPosY to letterPosY + nameOffsetY | |||
set letterPosZ to letterPosZ + nameOffsetZ | |||
;PRINT SECOND NAME | |||
set letterList to nameBarret | |||
Label 2 | |||
set currentLetter to ListGetNthForm letterList count2 | |||
currentLetter.MoveTo Player | |||
currentLetter.SetPos X letterPosX | |||
currentLetter.SetPos Y letterPosY | |||
currentLetter.SetPos Z letterPosZ | |||
;add offsets for next letter | |||
set letterPosX to letterPosX + letterOffsetX | |||
set letterPosY to letterPosY + letterOffsetY | |||
set letterPosZ to letterPosZ + letterOffsetZ | |||
set count2 to count2 + 1 | |||
if count2 < ListGetCount letterList | |||
GoTo 2 | |||
endif | |||
(etc) | |||
End | |||
The script was cut short because it is a bit tedious, since we have 9 names to print. The script could also quickly get long if we put more instructions into each loop, like angle and scale information. | |||
===Lists of Lists=== | |||
As it would seem, a FormList is also an object in the editor, which has its own FormID. That makes a FormList a Form. What this means is that FormLists can contain other FormLists. Lets use this to our advantage by making another FormList named ''namesList''. Now we will drag and drop all 9 of our name FormLists into this new FormList. | |||
===Efficient Script=== | |||
Our script just got a whole lot shorter: | |||
scn floatingNamesScript | |||
;vars (not listed for brevity) | |||
Begin GameMode | |||
;set first letter's position | |||
set firstLetterPosX to 1000 | |||
set firstLetterPosY to 1000 | |||
set firstLetterPosZ to 1000 | |||
;initialize current letter's position | |||
set letterPosX to firstLetterPosX | |||
set letterPosY to firstLetterPosY | |||
set letterPosZ to firstLetterPosZ | |||
;distance to the next letter | |||
set letterOffsetX to 0 | |||
set letterOffsetY to 5 | |||
set letterOffsetZ to 0 | |||
;distance to the next name | |||
set nameOffsetX to 0 | |||
set nameOffsetY to 0 | |||
set nameOffsetZ to 10 | |||
;PRINT NAMES | |||
Label 1 | |||
set letterList to ListGetNthForm namesList countNames | |||
set countLetters to 0 | |||
Label 2 | |||
set currentLetter to ListGetNthForm letterList countLetters | |||
currentLetter.MoveTo Player | |||
currentLetter.SetPos X letterPosX | |||
currentLetter.SetPos Y letterPosY | |||
currentLetter.SetPos Z letterPosZ | |||
;add offsets for next letter | |||
set letterPosX to letterPosX + letterOffsetX | |||
set letterPosY to letterPosY + letterOffsetY | |||
set letterPosZ to letterPosZ + letterOffsetZ | |||
set countLetters to countLetters + 1 | |||
if countLetters < ListGetCount letterList | |||
GoTo 2 | |||
endif | |||
set countNames to countNames + 1 | |||
;set position of next name's first letter | |||
set letterPosX to firstLetterPosX + nameOffsetX * countNames | |||
set letterPosY to firstLetterPosY + nameOffsetY * countNames | |||
set letterPosZ to firstLetterPosZ + nameOffsetZ * countNames | |||
if countNames < ListGetCount namesList | |||
GoTo 1 | |||
endif | |||
End | |||
That was the entire script to print all 9 names in a cell. If these initial positions are changed, this script can print these names anywhere in the game world. If we add more names or want to change the names, this can easily be done in the editor without modifying the script. | |||
The moral of the story is: '''there is a lot you can accomplish by working with FormLists'''. | |||
[[Category:Scripting]] | |||
[[Category:Tutorials]] | |||
[[Category:Advanced_Modding_Techniques]] |