Difference between revisions of "Activate"

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search
imported>Kkuhlmann
imported>Bruneauinfo
(added Activate2 reference at See Also)
 
(36 intermediate revisions by 14 users not shown)
Line 1: Line 1:
__NOTOC__
'''Syntax:'''
'''Syntax:'''
  Activate ''ActivatorID (optional)'','' NormalActivationFlag (optional)''
  ''ObjectToActivateRef:rec''.'''Activate''' [ActivatorID:rec] [RunOnActivateBlock:bin]
(note on syntax: ''Italics'' = object that's acted on, '''Bold''' = function name, <nowiki>[Brackets]</nowiki> = optional field, "rec" = record, "bin" = binary. See discussion for more info)
 
'''Example:'''
'''Example:'''
  Activate player  
  Activate player  
  Activate  
  ContainerRef.Activate  
  Activate player, 1  
  ActivatorRef.Activate player, 1  
 
This function tells the object to perform its default activation.
 
If ActivatorID is omitted, the Activate command will use the calling reference's "current activator". This is very useful inside of OnActivate blocks where you want the activation to proceed normally except under certain circumstances.
If ActivatorID is included, the calling reference will perform its default activation as if activated by ActivatorID.


If the RunOnActivateBlock is set to zero (default) this function makes the object only perform its default activation, bypassing any OnActivate Block in its script.


The default activations for the player are:
{|border="1" cellpadding="5" cellspacing="0" align="center"
{|border="1" cellpadding="5" cellspacing="0" align="center"
|-
|-
Line 34: Line 33:
|}
|}


For [[Enable]]d NPCs, activating an item will force them to pick it up (even if they're [[SetUnconscious|unconscious]]). However, containers won't pick up the item.


If NormalActivationFlag is omitted, the calling reference performs its default activation, bypassing any OnActivate script that might be on it. This is normally how you want to use Activate, since most times you are calling Activate on the object itself from inside an OnActivate block.
If the ''RunOnActivateFlag'' is set to 1, then the [[OnActivate]] block of the object (if any) will be run ''instead'' of the default activation. (In other words, act just as if ''ActivatorID'' activated it directly -- NPC used it, Player moused over and clicked on it, etc.)
 
If the NormalActivationFlag is 1, the calling reference will be activated normally, including triggering any OnActivate script on it. Use this with care -- if you call Activate on the object itself from inside an OnActivate block you will trigger an infinite loop.  


'''Example 1:'''


If you call this script on a door, the door will behave as if the player had activated it (i.e. if a load door, the player will be teleported to the door's target location).
If the ''ObjectToActivateRef'' flag isn't set then the object will activate itself (as with most functions). There are a couple of tricks you can pull with this:
 
#You can use '''''Activate''''' inside of an object's [[OnActivate]] block to make it ''also'' perform it's default activation
Activate player  
#You can use '''''Activate player, 1''''' inside of an object's onActivate block to make it run it's [[OnActivate]] block again (see [[Activate#Nesting|Nesting]] below)
#You can use '''''Activate player, 1''''' to make an item activate itself ''while inside an inventory''. By having the item continuously check a persistent variable, you can make external scripts "activate" the item by controlling the persistent variable.




'''Example 2:'''  
The ''ActivatorID'' flag determines the ActionRef for that activation, as if the ActionRef had activated the object. This is useful if you use [[IsActionRef]] or [[GetActionRef]] inside of the [[OnActivate]] block of the object. If the ''ActivatorID'' flag is omitted, the calling reference's ActionRef will be used instead.


Whatever triggered the OnActivate block will also Activate, just as if this script wasn't here.
'''That means that this:'''
Activate


begin OnActivate
'''Is equivalent to this:'''
  if MyCrazyCondition == 1
  ref actingref
  Activate
  set actingref to GetActionRef
  else
  Activate actingref
  ; do something else
  endif
end


If the calling reference doesn't have an ActionRef (for example, if the calling reference is a quest) then the object won't be activated and the line will be ignored (the calling reference's script will continue).


'''Example 3:'''  
==Guaranteed CTD==
Calling '''activate player 1''' on a container with a scripted item on it will lead to a CTD.  See [[Crashes#Activating_a_Container_.28including_NPC.29|Activating a Container (including NPCs)]] for more info.


This script will trigger an infinite loop -- once the scripted object is activated the OnActivate block will continue to be run forever.
==Buggy Bug Bug of a Weird, Weird Bug==
   
There are a number of peculiarities (both good and bad) and bugs with the '''Activate''' function:
float infinity
#When you use the ''RunOnActivate'' flag, the script of the activated object/item will run immediately, meaning the next line of the activator's script won't be processed until the entire activated script (including blocks other than [[onActivate]]) finishes. If the activated script doesn't have an [[onActivate]] block, it won't run.
begin OnActivate
#You have to use an ''ActivatorID'' when using the ''RunOnActivateBlock'' flag.
  ; you should NEVER do this!!
#Calling '''''Activate''''' with the RunOnActivateBlock set to 0 on an object which doesn't have an '''''onActivate''''' block in its script, or has no script at all, will prevent that object from being activated normally ever again. For example, if Activate is called on an unscripted container, the player will no longer be able to open that container by activating it with the spacebar; similarly, calling Activate on unscripted NPCs prevents the player from being able to talk to them. Therefore, use RunOnActivateBlock = 0 only if you know for sure the object has an OnActivate block and, for some reason, you don't want that code to run.   
  set infinity to infinity + .1
#You can use 'Activate player, 1', while an item is in an inventory, to have it run it's own [[onActivate]] block. However, you have to place the onActivate block on the top of the script. See [[Crashes#Activate_Self|Activate Self]] for more info.
  message "Infinity = %.1f", infinity
#If you add a MessageBox to the OnActivate block of a container and then issue the Activate command somewhere after the call to the MessageBox, the in-game result will be an opened inventory dialog box of the container with a MessageBox behind it without the ability to select any items in the inventory screen or be able to exit the inventory screen or be able to see the message in order to click the OK button...basically, you will be stuck.
  activate player 1
end


==Nesting==
You can nest activations within other activations. For instance, a quest script activates an activator
SomeActivator.Activate player, 1
which in turn activates another activator
<pre>scn SomeActivatorScript


'''Example 4:'''  
begin onActivate
  SomeOtherActivator.Activate player, 1
end</pre>
You can only nest 5-6 activations at a time. At a time is a little hard to define here, since [[OnActivate]] blocks run instantly and before the next line of code is processed. This really means that if 4 other scripts are still being processed and an activation is made during the 5th script, that last activation will be ignored (the script skips the line). This applies to any activation, even if they're different objects or different scripts.
*Using a result script to activate the next script, the limit is still 5-6.


This is the proper way to use the NormalActivationFlag
==See Also==
* [[OnActivate]]
begin OnActivate
* [[PlayGroup]]
  ; trigger some other reference when I am activated by the player
* [[Activate2]]
  if IsActionRef player == 1
      MyGate.Activate player 1
  endif
end


[[Category: Functions]]
[[Category: Functions]]
[[Category: Object Functions]]
[[Category: Functions (CS)]]
[[Category: Functions (CS 1.0)]]
[[Category: Inventory Functions]]
[[Category: Inventory Functions (CS 1.0)]]

Latest revision as of 21:43, 17 December 2010

Syntax:

ObjectToActivateRef:rec.Activate [ActivatorID:rec] [RunOnActivateBlock:bin] 

(note on syntax: Italics = object that's acted on, Bold = function name, [Brackets] = optional field, "rec" = record, "bin" = binary. See discussion for more info)

Example:

Activate player 
ContainerRef.Activate 
ActivatorRef.Activate player, 1 

If the RunOnActivateBlock is set to zero (default) this function makes the object only perform its default activation, bypassing any OnActivate Block in its script.

The default activations for the player are:

Object Type Activation
NPC Dialogue
Container Opens
Door Opens
Weapon, armor, etc Picks Up
Book/Scroll Reads

For Enabled NPCs, activating an item will force them to pick it up (even if they're unconscious). However, containers won't pick up the item.

If the RunOnActivateFlag is set to 1, then the OnActivate block of the object (if any) will be run instead of the default activation. (In other words, act just as if ActivatorID activated it directly -- NPC used it, Player moused over and clicked on it, etc.)


If the ObjectToActivateRef flag isn't set then the object will activate itself (as with most functions). There are a couple of tricks you can pull with this:

  1. You can use Activate inside of an object's OnActivate block to make it also perform it's default activation
  2. You can use Activate player, 1 inside of an object's onActivate block to make it run it's OnActivate block again (see Nesting below)
  3. You can use Activate player, 1 to make an item activate itself while inside an inventory. By having the item continuously check a persistent variable, you can make external scripts "activate" the item by controlling the persistent variable.


The ActivatorID flag determines the ActionRef for that activation, as if the ActionRef had activated the object. This is useful if you use IsActionRef or GetActionRef inside of the OnActivate block of the object. If the ActivatorID flag is omitted, the calling reference's ActionRef will be used instead.

That means that this:

Activate

Is equivalent to this:

ref actingref
set actingref to GetActionRef
Activate actingref

If the calling reference doesn't have an ActionRef (for example, if the calling reference is a quest) then the object won't be activated and the line will be ignored (the calling reference's script will continue).

Guaranteed CTD[edit | edit source]

Calling activate player 1 on a container with a scripted item on it will lead to a CTD. See Activating a Container (including NPCs) for more info.

Buggy Bug Bug of a Weird, Weird Bug[edit | edit source]

There are a number of peculiarities (both good and bad) and bugs with the Activate function:

  1. When you use the RunOnActivate flag, the script of the activated object/item will run immediately, meaning the next line of the activator's script won't be processed until the entire activated script (including blocks other than onActivate) finishes. If the activated script doesn't have an onActivate block, it won't run.
  2. You have to use an ActivatorID when using the RunOnActivateBlock flag.
  3. Calling Activate with the RunOnActivateBlock set to 0 on an object which doesn't have an onActivate block in its script, or has no script at all, will prevent that object from being activated normally ever again. For example, if Activate is called on an unscripted container, the player will no longer be able to open that container by activating it with the spacebar; similarly, calling Activate on unscripted NPCs prevents the player from being able to talk to them. Therefore, use RunOnActivateBlock = 0 only if you know for sure the object has an OnActivate block and, for some reason, you don't want that code to run.
  4. You can use 'Activate player, 1', while an item is in an inventory, to have it run it's own onActivate block. However, you have to place the onActivate block on the top of the script. See Activate Self for more info.
  5. If you add a MessageBox to the OnActivate block of a container and then issue the Activate command somewhere after the call to the MessageBox, the in-game result will be an opened inventory dialog box of the container with a MessageBox behind it without the ability to select any items in the inventory screen or be able to exit the inventory screen or be able to see the message in order to click the OK button...basically, you will be stuck.

Nesting[edit | edit source]

You can nest activations within other activations. For instance, a quest script activates an activator

SomeActivator.Activate player, 1

which in turn activates another activator

scn SomeActivatorScript

begin onActivate
  SomeOtherActivator.Activate player, 1
end

You can only nest 5-6 activations at a time. At a time is a little hard to define here, since OnActivate blocks run instantly and before the next line of code is processed. This really means that if 4 other scripts are still being processed and an activation is made during the 5th script, that last activation will be ignored (the script skips the line). This applies to any activation, even if they're different objects or different scripts.

  • Using a result script to activate the next script, the limit is still 5-6.

See Also[edit | edit source]