Difference between revisions of "Useful Scripts"
imported>Cipscis (Removed water purifier script - doesn't really belong on this page) |
imported>Cuceta m (→Hotkey) |
||
(13 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
[[category:Scripting]] | |||
= GECK = | = GECK = | ||
==Gender Unlock== | |||
Script Type:Object | |||
<small>To be placed on an [[door]], or [[container]], Uses your gender (Male, Female) to [[unlock]] a the door, container.</small> | |||
<pre> | |||
ScriptName VaultGenderUnlock | |||
Begin Gamemode | |||
If Player.GetIsSex gender ;Place male,female where it says Gender. Can't be both. | |||
Unlock | |||
endif | |||
End | |||
</pre> | |||
==Timed Doors== | ==Timed Doors== | ||
Line 304: | Line 323: | ||
</pre> | </pre> | ||
==Simulating Global Functions in your Mod== | |||
Global functions, or behavior that acts as though it's a global function can be simulated through the use of a shared script (i.e. a Quest script) and setting properties on it as though it were a state machine. | |||
It must be understood that scripts execute all the way through, each tick, and | |||
many times the result from a function call won't be readable until the next tick has occurred. Some parts in this example use NVSE (FOSE works as well for Fallout3). | |||
The first script is called ExampleScript and is a Quest type script for the Quest called Example. Note that referencing variables in a script from outside of the script must be done by referencing the Quest name, not the Script name. (i.e. Example.Initialized instead of ExampleScript.Initialized). | |||
If you have any questions, email me at nyteshade.geck@gmail.com. | |||
<pre> | |||
ScriptName ExampleScript | |||
Short Initialized | |||
Short Msg_FnSum | |||
Short Msg_FnSum_Done | |||
Short Msg_FnProduct | |||
Short Msg_FnProduct_Done | |||
Short Param1 ; best to name these something better | |||
Short Param2 ; if you are not going to share them | |||
Short ReturnValue | |||
Begin GameMode | |||
If Initialized == 0 || GetGameLoaded || GetGameRestarted ; last two are from NVSE | |||
Set Initialized to 1 | |||
Set Param1 to 0 | |||
Set Param2 to 0 | |||
Set ReturnValue to 0 | |||
Set Msg_FnSum to 0 | |||
Set Msg_FnSum_Done to 0 | |||
Set Msg_FnProduct to 0 | |||
Set Msg_FnProduct_Done to 0 | |||
EndIf | |||
If Msg_FnSum != 0 | |||
Set ReturnValue to Param1 + Param2 | |||
Set Msg_FnSum to 0 | |||
Set Msg_FnSum_Done to 1 | |||
ElseIf Msg_FnProduct != 0 | |||
Set ReturnValue to Param1 * Param2 | |||
Set Msg_FnProduct to 0 | |||
Set Msg_FnProduct_Done to 1 | |||
EndIf | |||
End | |||
</pre> | |||
The calling script can be anything really. You will notice in this script, the calling of the Msg_FnSum and Msg_FnProduct occur in separate time ticks than the Msg_FnSum_Done and Msg_FnProduct_Done code. The entire script is ready every tick but the conditions triggered by the code in the ExampleScript will not have taken place in the first pass. | |||
<pre> | |||
ScriptName Other | |||
Short SumValue | |||
Short ProductValue | |||
Begin GameMode | |||
If SomeCondition == 1 | |||
; Let's call function Sum | |||
Set Example.Param1 to 2 ; Set parameter 1 | |||
Set Example.Param2 to 5 ; Set parameter 2 | |||
Set Example.Msg_FnSum to 1 ; Call Msg_FnSum on next tick | |||
ElseIf SomeCondition == 2 | |||
; Let's call function Product | |||
Set Example.Param1 to 2 ; Set parameter 1 | |||
Set Example.Param2 to 5 ; Set parameter 2 | |||
Set Example.Msg_FnProduct to 1 ; Call Msg_FnProduct on next tick | |||
EndIf | |||
; Occurs in a later 'tick' than the calling code | |||
If Example.Msg_FnSum_Done == 1 | |||
; Do something with the value | |||
; The value of Example.ReturnValue is now 7 | |||
Set Example.ReturnValue to 0 ; Clean up return value (be nice) | |||
Set Example.Msg_FnSum_Done to 0 ; Prevent this code block from executing next tick | |||
ElseIf Example.Msg_FnProduct_Done == 1 | |||
; Do something with the value | |||
; The value of Example.ReturnValue is now 10 | |||
Set Example.ReturnValue to 0 ; Clean up return value (be nice) | |||
Set Example.Msg_FnProduct_Done to 0 ; Prevent this code block from executing next tick | |||
EndIf | |||
End | |||
</pre> | |||
= + [[Fallout Script Extender|FOSE]] = | = + [[Fallout Script Extender|FOSE]] = | ||
Line 374: | Line 477: | ||
endif | endif | ||
endif | endif | ||
End | |||
</pre> | |||
Note: Your attached <b>Quest</b> should have a small <b>script Processing delay</b>, otherwise the key event may not work. | |||
== Iterating through multiple lists == | |||
Script Type: Object | |||
;Script requires the [[Fallout Script Extender]]. | |||
This is a good technique for making simulated 2 dimension arrays in tes script | |||
There are a few technically unnecessary variables but this loop is setup to be used as part of a series. | |||
To use in series, just copy everything from ";Main Loop" to the last "EndIf". The only thing you need to change is the value of "MainList". | |||
If you use this on any list that may be empty it is a good idea to surround any use of CurrentRef with an if block checking if the ref == 0 | |||
Sorry for any errors, I'm writing this from memory | |||
<pre> | |||
scn Test2Dim | |||
; Counter vars | |||
long Count1 | |||
long Count2 | |||
; Max Count vars | |||
long MaxCount1 | |||
long MaxCount2 | |||
; Label vars | |||
short Label1 | |||
short Label2 | |||
; Lists | |||
ref MainList | |||
ref CurrentList | |||
ref CurrentRef | |||
Begin onActivate | |||
; setup counters | |||
Set Label1 To 0 | |||
Set Label2 To 1 | |||
;Main Loop | |||
Set MainList To TopLevelListHere | |||
Set Label1 To Label1 + 2 ; 2 Because its the number af labels | |||
Set Label2 To Label2 + 2 | |||
Set Count1 To 0 | |||
Set MaxCount1 To ListGetCount MainList | |||
Label Label1 | |||
Set Count2 To 0 | |||
Set CurrentList To ListGetNthForm MainList Count1 | |||
Set MaxCount2 To ListGetCount CurrentList | |||
Label Label2 | |||
Set CurrentRef To ListGetNthForm CurrentList Count2 | |||
; Use CurrentRef here | |||
If Count2 < MaxCount2 | |||
Set Count2 To Count2 + 1 | |||
GoTo Label2 | |||
EndIf | |||
If Count1 < MaxCount1 | |||
Set Count1 To Count1 + 1 | |||
GoTo Label1 | |||
EndIf | |||
End | |||
</pre> | |||
== Iterate Through Disabled Objects== | |||
Script Type: Object | |||
;Script requires the [[Fallout Script Extender]]. | |||
<small>To be placed on an [[Activator]], and linked to a reference. | |||
Usage involves linking the activator to a disabled reference. The disabled reference is linked in a loop with several other disabled references. Each activation will disable the previous reference and enable the next reference.</small> | |||
<pre> | |||
ScriptName LoopThroughReferences | |||
ref currentRef | |||
ref previousRef | |||
ref nextRef | |||
Begin OnActivate player | |||
set previousRef to getSelf | |||
Label 1 | |||
set currentRef to previousRef.getLinkedRef | |||
set nextRef to currentRef.getLinkedRef | |||
if currentRef.getDisabled == 0 | |||
currentRef.disable | |||
nextRef.enable | |||
else | |||
set previousRef to currentRef | |||
goto 1 | |||
endif | |||
End | End | ||
</pre> | </pre> |
Latest revision as of 06:43, 29 January 2014
GECK[edit | edit source]
Gender Unlock[edit | edit source]
Script Type:Object
To be placed on an door, or container, Uses your gender (Male, Female) to unlock a the door, container.
ScriptName VaultGenderUnlock Begin Gamemode If Player.GetIsSex gender ;Place male,female where it says Gender. Can't be both. Unlock endif End
Timed Doors[edit | edit source]
Script Type:Object
To be placed on an activator, Uses Persistent References to design Objects.
ScriptName VaultpTimedDoor ;By BEArbiter ;Explaination: ;This script is to make TimedDoors, Elevators,... ;Once you press the button, Isactivated is set to 1, so pressing the button againt won't do anything, it need to be Reset to 0 ; ;Then, each 1 second, One or more Door will be ;opened/closed. When All the door have been activated, the script ;will reset the Activator. ;It use Persitent Reference of the doors, So You need one ;Script per Activator/Elevator,.... ; ;A Timing Issue Is possible(if you place Two or more activator ;and activate both at little interval), It can be ;Solve by Create An Global Variable instead of Isactivated ;Then, all the button witch use a copy of this ;script won't be useable while a Door is opened float timer ;For a Global Variable, Go to Global, create a ;new short var named isactivated and delete theses line: int isactivated :<end of delete action> Begin Onactivate ;If the button have been pressed before and ;not been reseted, the activator won't do anything if isactivated == 0 set isactivated to 1 Activate else ;If you want the Activation to do something endif end begin gamemode If isactivated == 1 if timer < 8 if timer < 1; elseif Timer < 2;After One second, do the following if Door1.GetOpenState == 3 Door1.SetOpenState 1 ;Door3.SetOpenState 1 ;You can Activate more than one door at a time. elseif Door1.GetOpenState == 1 Door1.SetOpenState 0 ;Door3.SetOpenState 0 Endif Elseif Timer < 3 If Door2.GetOpenState == 3 Door2.SetOpenState 1 Elseif Door2.GetOpenState == 1 Door2.SetOpenState 0 Endif Elseif Timer < 4 If Door3.GetOpenState == 3 Door3.SetOpenState 1 Elseif Door3.GetOpenState == 1 Door3.SetOpenState 0 Endif Endif Else Set isactivated to 0 Set timer to 0 Endif Endif End
Light switch[edit | edit source]
Script Type:Object
To be placed on an activator, and linked to a light source or x-marker Enable Parent.
ScriptName LightSwitchScript ref light Begin OnActivate if light == 0 set light to GetLinkedRef endif if light.GetDisabled light.Enable else light.Disable endif Activate End
Ground area mark that follows the crosshair[edit | edit source]
You can see the effect of this script in this video
Script Type: Quest or Effect
For a Quest script, use a GameMode block. For an Effect script, use a ScriptEffectUpdate block.
Instead of activator put the name of the activator or actor you want to use, in order to use the EditorRefID of your reference in a script like this, it must be a persistent reference.
float xang float zang float x float y float z float playerheight float lont begin gamemode set xang to player.getangle x set zang to player.getangle z * -1 + 90 if xang <= 5 set lont to 1300; you can change this value if you need to else if player.issneaking == 0 set playerheight to 322 else set playerheight to 252 endif set lont to (playerheight*cos xang/sin xang * 0.34118010537042257764) endif set xang to player.getangle x * -1 set x to lont * cos xang * cos zang set y to lont * cos xang * sin zang Activator.moveto player x y 0 end
Forced Relative Orientation[edit | edit source]
Script Type: Quest, Object or Effect
For a Quest or Object script, use a GameMode block. For an Effect script, use a ScriptEffectUpdate block.
In order to use the EditorRefID of your reference in a script like this, it must be a persistent reference.
float fAngle float fRelativePos Begin GameMode set fRelativePos to player.GetPos z + <Z OFFSET> myREF.setPos z fRelativePos set fAngle to player.GetAngle Z + <ANGLE OFFSET> myREF.SetAngle Z fAngle set fRelativePos to player.GetPos Y + <PLAYER OFFSET> * cos fAngle myREF.SetPos Y fRelativePos set fRelativePos to player.GetPos X + <PLAYER OFFSET> * sin fAngle myREF.SetPos X fRelativePos End
- <Z OFFSET> determines the reference's z offset from the player's feet. The higher this is, the further above the player's feet the reference will appear. If <Z OFFSET> should be determined by where the player is looking, this should be used:
set fAngle to player.GetAngle X set fRelativePos to player.GetPos Z - <PLAYER OFFSET> * sin fAngle
- <ANGLE OFFSET> determines the reference's position relative to the players. As <ANGLE OFFSET> increases, the reference's position will move around the player in an anti-clockwise direction. When <ANGLE OFFSET> is 0, the reference will appear directly in front of the player.
- <PLAYER OFFSET> determine's the horizontal distance between the reference and the player. As <PLAYER OFFSET> increases, the reference appears further and further from the player
The player can be substituted for any other reference here and the script will still work. Note that the reference may appear to move through solid objects, especially when <PLAYER OFFSET> is set to a particularly large value.
Autoclosing door[edit | edit source]
Script Type: Object
Scriptname AutoClosingDoor float doorTimer short closeDoor Begin GameMode if closeDoor == 1 if doorTimer > 0 set doorTimer to doorTimer - getSecondsPassed elseif GetOpenState == 1 ; if the door is still open SetOpenState 0 ; close the door set closeDoor to 0 endif endif End Begin OnActivate if GetOpenState == 3 ; if the door is closed if IsActionRef Player == 0 ; if it should work for the player remove this... set doorTimer to 5 set closeDoor to 1 endif ; ...and this endif Activate End
Karma Effects on Items[edit | edit source]
Script Type: Effect
For armour, you can use a scripted Object Effect. This allows the armour to safely be equipped and unequipped via EquipItem and UnequipItem
ScriptName KarmaEffect ref rWearer Begin ScriptEffectStart set rWearer to GetSelf if rWearer.GetIsReference player RewardKarma -650 endif End Begin ScriptEffectFinish if rWearer.GetIsReference player RewardKarma 650 endif End
Script Type: Object
For weapons, you'll have to use an Object Script. "Weapon" type Object Effects are applied to that weapon's target, and are therefore unsuitable for applying effects to the wielder
ScriptName KarmaEffect Begin OnEquip player player.RewardKarma -650 End Begin OnUnequip player player.RewardKarma 650 End
Pusheffect[edit | edit source]
Script Type: Effect
spell effect script for a weapon that knocks people far away and creates a trail of smoke or fire along the way.
NOTE - Only works correctly when the player has the weapon equipped.
scn CALFPeffectSCR short ActorValue1 short ActorValue2 short ActorValue3 short DamageValue Begin ScriptEffectStart ; places initial explosion when hit, just in case there's no specified explosion effect in the weapons projectile ; also useful if you'd want a melee weapon or fist to cause explosions on hit placeatme {ExplosionType} Player.PushActorAway Target 104 ; this is the part of the script in which you can specify a certain damage formula ; the formula can be added to the base damage amount set in the weapons tab ; -or you can set the damage in the tab to zero and fully rely on the formula to calculate damage ; it can be the target NPC/creature's actor value or the player's ; it's also fine not to make a certain damage formula set ActorValue1 to Player.GetAv {ActorValue1} set ActorValue2 to Player.GetAv {ActorValue2} set ActorValue3 to Player.GetAv {ActorValue3} set Damage to -1 * ( {formula incorporating actor values} ) ModAv Health DamageValue ; make the effect play a certain sound-you could also use the sound of the explosion and not specify a specific sound Playsound3D Play a certain sound End Begin ScriptEffectUpdate ; this is the part where you place a smoke effect on every axis the NPC/Creature is located ; it makes as if the smoke is always coming out of the target while the effect is taking place placeatme {smokeeffect} ; alternatively add a smoke actor effect on the character CastImmediateOnSelf {smoke actor effect} End begin ScriptEffectFinish ;if you used the above alternative, this segment removes the smoke effect from the character RemoveSpell {smoke actor effect} end
Simulating Global Functions in your Mod[edit | edit source]
Global functions, or behavior that acts as though it's a global function can be simulated through the use of a shared script (i.e. a Quest script) and setting properties on it as though it were a state machine.
It must be understood that scripts execute all the way through, each tick, and many times the result from a function call won't be readable until the next tick has occurred. Some parts in this example use NVSE (FOSE works as well for Fallout3).
The first script is called ExampleScript and is a Quest type script for the Quest called Example. Note that referencing variables in a script from outside of the script must be done by referencing the Quest name, not the Script name. (i.e. Example.Initialized instead of ExampleScript.Initialized).
If you have any questions, email me at nyteshade.geck@gmail.com.
ScriptName ExampleScript Short Initialized Short Msg_FnSum Short Msg_FnSum_Done Short Msg_FnProduct Short Msg_FnProduct_Done Short Param1 ; best to name these something better Short Param2 ; if you are not going to share them Short ReturnValue Begin GameMode If Initialized == 0 || GetGameLoaded || GetGameRestarted ; last two are from NVSE Set Initialized to 1 Set Param1 to 0 Set Param2 to 0 Set ReturnValue to 0 Set Msg_FnSum to 0 Set Msg_FnSum_Done to 0 Set Msg_FnProduct to 0 Set Msg_FnProduct_Done to 0 EndIf If Msg_FnSum != 0 Set ReturnValue to Param1 + Param2 Set Msg_FnSum to 0 Set Msg_FnSum_Done to 1 ElseIf Msg_FnProduct != 0 Set ReturnValue to Param1 * Param2 Set Msg_FnProduct to 0 Set Msg_FnProduct_Done to 1 EndIf End
The calling script can be anything really. You will notice in this script, the calling of the Msg_FnSum and Msg_FnProduct occur in separate time ticks than the Msg_FnSum_Done and Msg_FnProduct_Done code. The entire script is ready every tick but the conditions triggered by the code in the ExampleScript will not have taken place in the first pass.
ScriptName Other Short SumValue Short ProductValue Begin GameMode If SomeCondition == 1 ; Let's call function Sum Set Example.Param1 to 2 ; Set parameter 1 Set Example.Param2 to 5 ; Set parameter 2 Set Example.Msg_FnSum to 1 ; Call Msg_FnSum on next tick ElseIf SomeCondition == 2 ; Let's call function Product Set Example.Param1 to 2 ; Set parameter 1 Set Example.Param2 to 5 ; Set parameter 2 Set Example.Msg_FnProduct to 1 ; Call Msg_FnProduct on next tick EndIf ; Occurs in a later 'tick' than the calling code If Example.Msg_FnSum_Done == 1 ; Do something with the value ; The value of Example.ReturnValue is now 7 Set Example.ReturnValue to 0 ; Clean up return value (be nice) Set Example.Msg_FnSum_Done to 0 ; Prevent this code block from executing next tick ElseIf Example.Msg_FnProduct_Done == 1 ; Do something with the value ; The value of Example.ReturnValue is now 10 Set Example.ReturnValue to 0 ; Clean up return value (be nice) Set Example.Msg_FnProduct_Done to 0 ; Prevent this code block from executing next tick EndIf End
+ FOSE[edit | edit source]
Terminals[edit | edit source]
Script Type: Object
- Script requires the Fallout Script Extender.
To be placed on a terminal, it changes the usual "Robco" headers to your liking.
ScriptName TerminalChange Short toggle Float minitimer Short activated Begin OnActivate player set activated to 1 Activate ;For people without FOSE, still works. con_setgamesetting sComputersHeader1 "GREAT ACADEMY OF VALHALLA" con_setgamesetting sComputersHeader2 "Republic of Valhalla" con_setgamesetting sHackingHeader "VALHALLA REPUBLIC TERMLINK PROTOCOL" con_setgamesetting shackingintro01 "WELCOME TO VALHALLA REPUBLIC TERMLINK" con_setgamesetting shackingintro06 "Initializing Valhalla Republic MF Boot Agent v2.1.9" con_setgamesetting shackingintro09 "Copyright 2156-2234 Academy of Valhalla" End Begin MenuMode if activated == 1 set activated to 2 endif End Begin GameMode if activated == 2 set activated to 0 ;On shutting down the terminal. Makes sure it doesn't show up on others. con_setgamesetting sComputersHeader1 "ROBCO INDUSTRIES UNIFIED OPERATING SYSTEM" con_setgamesetting sComputersHeader2 "COPYRIGHT 2075-2077 ROBCO INDUSTRIES " con_setgamesetting sHackingHeader "ROBCO INDUSTRIES (TM) TERMLINK PROTOCOL" con_setgamesetting shackingintro01 "WELCOME TO ROBCO INDUSTRIES (TM) TERMLINK" con_setgamesetting shackingintro06 "Initializing Robco Industries(TM) MF Boot Agent v2.3.0" con_setgamesetting shackingintro09 "Copyright 2201-2203 Robco Ind." endif End
Hotkey[edit | edit source]
Script Type: Quest
- Script requires the Fallout Script Extender.
To be placed on a quest, it will run some code when a key is released. See FOSEs Command Docs for additional DirectX Scancodes
ScriptName HotkeyReleased Short sToggle Begin GameMode if IsKeyPressed 25 != sToggle set sToggle to IsKeyPressed 25 if sToggle ;Button pressed ;Do things when button 'p' is pressed, in this case, decrease karma RewardKarma -650 else ;Button released ;Do things when button 'p' is released, in this case, increase karma RewardKarma 650 endif endif End
Note: Your attached Quest should have a small script Processing delay, otherwise the key event may not work.
Iterating through multiple lists[edit | edit source]
Script Type: Object
- Script requires the Fallout Script Extender.
This is a good technique for making simulated 2 dimension arrays in tes script There are a few technically unnecessary variables but this loop is setup to be used as part of a series.
To use in series, just copy everything from ";Main Loop" to the last "EndIf". The only thing you need to change is the value of "MainList".
If you use this on any list that may be empty it is a good idea to surround any use of CurrentRef with an if block checking if the ref == 0
Sorry for any errors, I'm writing this from memory
scn Test2Dim ; Counter vars long Count1 long Count2 ; Max Count vars long MaxCount1 long MaxCount2 ; Label vars short Label1 short Label2 ; Lists ref MainList ref CurrentList ref CurrentRef Begin onActivate ; setup counters Set Label1 To 0 Set Label2 To 1 ;Main Loop Set MainList To TopLevelListHere Set Label1 To Label1 + 2 ; 2 Because its the number af labels Set Label2 To Label2 + 2 Set Count1 To 0 Set MaxCount1 To ListGetCount MainList Label Label1 Set Count2 To 0 Set CurrentList To ListGetNthForm MainList Count1 Set MaxCount2 To ListGetCount CurrentList Label Label2 Set CurrentRef To ListGetNthForm CurrentList Count2 ; Use CurrentRef here If Count2 < MaxCount2 Set Count2 To Count2 + 1 GoTo Label2 EndIf If Count1 < MaxCount1 Set Count1 To Count1 + 1 GoTo Label1 EndIf End
Iterate Through Disabled Objects[edit | edit source]
Script Type: Object
- Script requires the Fallout Script Extender.
To be placed on an Activator, and linked to a reference.
Usage involves linking the activator to a disabled reference. The disabled reference is linked in a loop with several other disabled references. Each activation will disable the previous reference and enable the next reference.
ScriptName LoopThroughReferences ref currentRef ref previousRef ref nextRef Begin OnActivate player set previousRef to getSelf Label 1 set currentRef to previousRef.getLinkedRef set nextRef to currentRef.getLinkedRef if currentRef.getDisabled == 0 currentRef.disable nextRef.enable else set previousRef to currentRef goto 1 endif End