Activation Functions

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search

(Preamble note: if you use OBSE, consider using User Functions.)


In-game functions are basically scripts on objects (placed in the game) that can be called from any other script. You can also pass variables in and out of that function easily without reference to independent global variables.

In-game functions are easier to create and do not have the restrictions that Stage functions have, e.g. number of lines, reference object calls, variable definiton, etc. You can do almost anything you can from any other script with them, but you might also find them useful to avoid writing huge scripts or as an alternative way to add global variables to the game (one that is more forgiving to script updates than quest script variables). A minor variation on the basic principle allows you to also use them for static 'spell' effects.


CREATING AN IN-GAME FUNCTION


1) Copy any object that takes a script (e.g. Gold or an Evil Stone). Rename to, e.g., TargFunction.

2) Place a copy somewhere suitable in the world - preferably where you already have something or in your own cell.

3) Mark the object persistent. Give it a suiable name, e.g. TargFunc01.

4) Place a script on the object to do your function. Typically this will just consist of the OnActivate block and variables that can be accessed from other scripts. (See example script below.)

5) Call this function using the Activate command. (See below.)


STATIC FUNCTIONS


If you really want a static function then your best option is to use a remote persistent object - i.e. a true world activator object (e.g. a switch) placed in some hidden location. To call your function:

 [set IGFActRef.someInputVar to someInput]
 IGFActRef.Activate player 1
 [set someOutput IGFActRef.someOutputVar]


LOCAL STATIC FUNCTIONS


This is the same principle but the object is an item (something you can carry) and therefore movable, e.g. a gold coin. The idea is that you move it to the player location so it's GameMode/MenuMode blocks are also active. The item must be a persistant object and (initially) disabled so it is invisible when near the player.

The call syntax is slightly different:

 [set IGFLActRef.someInputVar to someInput]
 set IGFLActRef.enabled to 1
 IGFLActRef.MoveTo player

In this case you are enabling the GameMode/MenuMode block by bringing the object to you. However, you may need to deactivate it sometime later or otherwise make a safety switch to prevent it functioning when you dont expect it to.

You can have the item script do most of the work and instead call the activate method to do the equivalent of a ScriptEffectStart block for spells - the GameMode block being equivalent to the ScriptEffectUpdate block.

 [set IGFActRef.someInputVar to someInput]
 IGFActRef.Activate player 1
 IGFLActRef.MoveTo player
 [set someOutput IGFActRef.someOutputVar]


USEFUL EXAMPLE IGF


Here is an example of a method that you can call to get the position of the target cross hairs and the direction the player is looking:

scn TargFunctionScript

; initial position vector
float xPos
float yPos
float zPos

; fly vector
float dx
float dy
float dz

; private
float ang
float x
float x2
float sin
float cos

Begin OnActivate

; horizontal fly vector
set ang to player.GetAngle z
if ang > 180
  set ang to (ang)-360
endif
set x to ang*0.0174532925
set x2 to x*x
set sin to x*(1-(x2/6)*(1-(x2/20)*(1-(x2/42)*(1-(x2/72)*(1-x2/110)))))
set cos to 1-0.5*x2*(1-(x2/12)*(1-(x2/30)*(1-(x2/56)*(1-x2/90))))
set dx to 10*sin
set dy to 10*cos

; vertical fly vector
set ang to player.GetAngle x
set x to -ang*0.0174532925
set x2 to x*x
set sin to x*(1-(x2/6)*(1-(x2/20)*(1-(x2/42)*(1-(x2/72)*(1-x2/110)))))
set cos to 1-0.5*x2*(1-(x2/12)*(1-(x2/30)*(1-(x2/56)*(1-x2/90))))
set dz to 10*sin

; initial position vector (to add to player coords)
set xPos to 5*dx*cos
set yPos to 5*dy*cos
set zPos to 118-25*(player.IsSneaking)+5*dz

End

To use this function:

; some script
;...
TargFunc01.Activate player 1
set xPos to (TargFunc01.xPos)+(player.GetPos x)
set yPos to (TargFunc01.yPos)+(player.GetPos y)
set zPos to (TargFunc01.zPos)+(player.GetPos z)

set dx to TargFunc01.dx
set dy to TargFunc01.dy
set dz to TargFunc01.dz


NOTES


1. Best to always use the '1' flag when you use the Activate command. This prevents any default activation method being triggered, e.g. ending up in your inventory for item IGFs. For static activators this isn't so important but mixing up Activate commands w/ and w/o the '1' flag can lead to 'wierd' effects.

2. Do not try to make too many calls to the same activator in the same frame. There appears to be some kind of recursion catch that stops calls working if the same script is called within the same frame more than ~4 times. (A similar thing happens if you do PlaceAtMe for scripted objects.)

3. Quest Stage Functions: Apart from being useful in their own right, these have one nice feature that IGFs do not: a call funcion-by-number utility, i.e.

set x to 10; any value between 0-255
SetStage MyQuest x

This may be used to create small linked-lists, stacks, arrays, random effects, etc.