Difference between revisions of "Activation Functions"

809 bytes added ,  13:08, 23 June 2012
Byline removed
imported>Elder
m
imported>QQuix
(Byline removed)
 
(7 intermediate revisions by 5 users not shown)
Line 1: Line 1:
IN-GAME FUNCTIONS by Guidobot


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


This is an alternative to using stage functions.
It relies on the fact that the Activator method can be called on a persistant object at any time and operates immediately.


In-game functions are easier to create. They also do not have the restrictions that Stage functions have (number of lines, refernce object calls, variable definiton, etc.) and allow for looping code through clever use of the additional GameMode block (using flags, counters, etc.). Additionally, they are an alternative way to add global variables to the game.
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.


How to set up an in-game function:


CREATING AN IN-GAME FUNCTION


1) Copy any object that takes a script (I use Gold001). Rename to, e.g., TargFunction.
 
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.
2) Place a copy somewhere suitable in the world - preferably where you already have something or in your own cell.


3) Mark the object persistant. Mark it Initially Disabled. Give it a suiable name, e.g. TargFunc01.
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.


4) Place a script on the object to do what you want. (See below for a neat example.)
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.


5) Call this function by simply doing TargFunc01.Activate player 1.
  [set IGFActRef.someInputVar to someInput]
  IGFActRef.Activate player 1
  IGFLActRef.MoveTo player
  [set someOutput IGFActRef.someOutputVar]




Here is an example of a method that you can call to get the position of the target cross hairs:
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
  scn TargFunctionScript
Line 78: Line 111:
  ;...
  ;...
  TargFunc01.Activate player 1
  TargFunc01.Activate player 1
  set xPos to TargFunc01.xPos+player.GetPos x
  set xPos to (TargFunc01.xPos)+(player.GetPos x)
  set yPos to TargFunc01.yPos+player.GetPos y
  set yPos to (TargFunc01.yPos)+(player.GetPos y)
  set zPos to TargFunc01.zPos+player.GetPos z
  set zPos to (TargFunc01.zPos)+(player.GetPos z)
   
   
  set dx to TargFunc01.dx
  set dx to TargFunc01.dx
Line 87: Line 120:




IMPORTANT NOTES
NOTES
 
It turns out there is a bug that can occur if an in-game function is actively processing when the player enters a new cell. The effect is that the item bearing the script suddenly appears in your inventory as if 'IGFRef.Activate player' was called rather than 'IGFRef.Activate player 1'.
 
One way to fix this is to pass another actor ref instead of player. However, it depends on what you wish to achieve.
 
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). This has no such issues and has the advantage of accepting slightly neater call syntax:
 
IGFActRef.Activate player
 
(Additionally you do not have to mark the placed IGFRef as initially disabled unless you need it to activate as a sensor for when the player is nearby.)
 
The disadvantage of this is that the GameMode part of the script will never be that useful since the activator item is remote. If you use items, as described above, you can always teleport them to the player location so they trigger every frame. However, in this case you may be better off using an unplayable item (aka token) on the player and using the OnActivate method or switch it on using quest variables.




Another thing to watch for is how many times you call the same IGF activator within a single frame. Like Stage functions, they can 'time-out' if too many calls are made. Additionally, as with (recursive) PlaceAtMe calls, there appears to be a limit of only 4 or 5 activation calls you are allowed to make to the same base object in one frame - possibly due to a general hard-coded recursion call trap that the interpretor makes.(?)
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.)


One extra note on Stage functions. Apart from being useful in their own right, they have a very nice goto # / call # functionality.
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
  set x to 10; any value between 0-255
  SetStage MyQuest x
  SetStage MyQuest x


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


[[Category: Useful Code]]
[[Category: Useful Code]]
Anonymous user