Original function: bool SetActivator(int tid)
New function: bool SetActivator(int tid[, int pointer_selector]);
Using only a single parameter, or passing AAPTR_DEFAULT as the second parameter, performs the same operation as the original function:
Setting activator to NULL (world) for TID 0. (Return false)
Setting activator to NULL (world) for TID not found. (Return false)
Setting activator to first instance of TID found. (Return true)
If a non-default second parameter is passed:
Step 1
* Setting origin to SELF for TID 0.
* Setting origin to NULL for tid not found.
* Setting origin to first instance of TID found.
Step 2
* Setting activator according to the pointer selector, using the selected origin. (If AAPTR_TARGET were used, set activator to origin's target.)
Step 3
* return activator != NULL
This extends the behaviour of SetActivator, but cannot exactly duplicate SetActivatorToTarget, because I chose non-existence-handling to be consistent with SetActivator.
"SetActivator(sometid, AAPTR_PLAYER_GETTARGET|AAPTR_TARGET)" most closely duplicates "SetActivatorToTarget(sometid)". The difference occurs when a non-null activator without a valid target makes the call: Both functions will return false, but SetActivator will change the activator to NULL (world). For some reason, this has been carefully avoided in SetActivatorToTarget, and explicitly depended on in SetActivator.
Spoiler: AAPTR-recap
The available values for AAPTR are the same as for other functions of this kind:
Priority 1, player-only selectors (used if specified with a player origin):
AAPTR_PLAYER_GETTARGET
AAPTR_PLAYER_GETCONVERSATION (I will perform some tests to find out if this is useful in ACS)
Priority 2, any-actor selectors (used if specified with any non-null origin):
#include "zcommon.acs"
script 1 (void) net
{
int strbuild = StrParam(s:"Script 1 was triggered by ", n:0);
int i;
for (i = AAPTR_PLAYER1; i <= AAPTR_PLAYER8; i = i<<1)
{
if (SetActivator(0, i))
{
strbuild = StrParam(s:strbuild,c:'\n',n:0,s:" is in the game");
if (SetActivator(0, AAPTR_PLAYER_GETTARGET))
{
strbuild = StrParam(s:strbuild,s:" and looking at ",n:0);
}
}
}
printbold(s:strbuild);
}
script 2 (void) net
{
int strbuild;
if (SetActivator(0, AAPTR_TARGET|AAPTR_PLAYER_GETTARGET))
{
strbuild = StrParam(n:0);
if (SetActivator(0, AAPTR_TARGET|AAPTR_PLAYER_GETTARGET))
{
print(s:strbuild,s:" has you targeted");
// This message does not necessarily go to the original caller of the script, or even a player...
}
}
}
Spoiler: Minor internal change
ALSO, I couldn't quite help myself: There's a minimal internal improvement to SetActivatorToTarget. The code contained two subsequent if-blocks:
if (actor != NULL)
{
// assignment of new value to "actor"
}
if (actor != NULL)
{
// assignment of actor to activator, return true
}
Since actor is guaranteed to be null if you did not enter the first conditional branch, and since the second conditional branch returns when the condition is true, I put the second conditional branch inside the first one, at the end.
Test of special 84 (ACS_ExecuteWithResult) from strife dialogue (lump CMONSTR) with SetActivator and AAPTR_PLAYER_GETCONVERSATION.
Use it to give some clips to the archvile when it isn't busy burning badasses on your behalf. Sorry about the mess. (Load with Doom II IWAD and run new game.)