Difference between revisions of "Useful Scripts"
m
→Hotkey
imported>Qazaaq (→Autoclosing door: shouldn't -> should (or change the script, this is how it works)) |
imported>Cuceta m (→Hotkey) |
||
(30 intermediate revisions by 10 users not shown) | |||
Line 1: | Line 1: | ||
== | [[category:Scripting]] | ||
Script Type: Object | = 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== | |||
Script Type:Object | |||
<small>To be placed on an [[activator]], Uses Persistent References to design Objects.</small> | |||
<pre> | |||
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 | |||
</pre> | |||
==Light switch== | |||
Script Type:Object | |||
<small>To be placed on an [[activator]], and [[Reference#Linked_Ref|linked]] to a light source or x-marker [[Reference#Enable_Parent|Enable Parent]].</small> | |||
<pre> | <pre> | ||
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 | End | ||
</pre> | |||
==Ground area mark that follows the crosshair== | |||
You can see the effect of this script in this [http://www.youtube.com/watch?v=Utc5SvInb3c video] | |||
Script Type: Quest or Effect | |||
<small>For a Quest script, use a [[GameMode]] block. For an Effect script, use a [[ScriptEffectUpdate]] block.<br>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.</small> | |||
<pre> | |||
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 | |||
</pre> | |||
==Forced Relative Orientation== | |||
Script Type: Quest, Object or Effect | |||
<small>For a Quest or Object script, use a [[GameMode]] block. For an Effect script, use a [[ScriptEffectUpdate]] block.<br />In order to use the EditorRefID of your reference in a script like this, it must be a persistent reference.</small> | |||
<pre>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 | End | ||
</pre> | </pre> | ||
<ul> | |||
<li><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:<pre>set fAngle to player.GetAngle X | |||
set fRelativePos to player.GetPos Z - <PLAYER OFFSET> * sin fAngle | |||
</pre> | |||
</li> | |||
<li><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.</li> | |||
<li><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</li> | |||
</ul> | |||
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== | ==Autoclosing door== | ||
Line 24: | Line 210: | ||
Begin GameMode | 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 | End | ||
Begin OnActivate | 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 | |||
</pre> | |||
==Karma Effects on Items== | |||
Script Type: Effect<br /> | |||
<small>For armour, you can use a scripted Object Effect. This allows the armour to safely be equipped and unequipped via [[EquipItem]] and [[UnequipItem]]</small> | |||
<pre> | |||
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 | |||
</pre> | |||
Script Type: Object<br /> | |||
<small>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</small> | |||
<pre>ScriptName KarmaEffect | |||
Begin OnEquip player | |||
player.RewardKarma -650 | |||
End | |||
Begin OnUnequip player | |||
player.RewardKarma 650 | |||
End | End | ||
</pre> | </pre> | ||
Line 100: | Line 323: | ||
</pre> | </pre> | ||
== | ==Simulating Global Functions in your Mod== | ||
Script Type:Object | 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]] = | |||
== Terminals == | |||
Script Type: Object | |||
;Script requires the [[Fallout Script Extender]]. | |||
<small>To be placed on a [[terminal]], it changes the usual "Robco" headers to your liking.</small> | |||
<pre> | |||
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 | |||
</pre> | |||
== Hotkey == | |||
Script Type: Quest | |||
;Script requires the [[Fallout Script Extender]]. | |||
<small>To be placed on a [[:Category: Quests|quest]], it will run some code when a key is released. See [http://fose.silverlock.org/fose_command_doc.html#DirectX_Scancodes FOSEs Command Docs] for additional DirectX Scancodes</small> | |||
<pre> | |||
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 | |||
</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 [[ | <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> | <pre> | ||
ScriptName LoopThroughReferences | |||
ref | 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 | |||
</pre> | </pre> |