by FDARI » Sun Aug 25, 2013 11:18 pm
Extended GetActorProperty would be: int GetActorProperty (int tid, int property, int pointer)
Extended SetActorProperty would be: void SetActorProperty (int tid, int property, int value, int pointer)
Actor is chosen by TID, as usual. TID can be 0 as usual. If pointer is non 0 (AAPTR_DEFAULT) then the pointer is applied from the chosen actor. (This is the same logic that applies to SetActivator)
One thing I'm not sure of: Can SetActorProperty affect multiple actors with the same TID?
If so, SetActorProperty with non-0 tid and a pointer should go through all the actors at the given tid, and from each of them use the pointer to get the chosen actor for the function. This should be uncomplicated most of the time. The possibility of setting the same actor's value several times per call would exist, because different actors can have pointers to the same actors, but usually the number of times a value has been set is not relevant. (If assignment immediately triggers a repeatable effect, it might matter.)
Since I'm posting I'll also mention two workarounds. One is messy, the other bloody.
Spoiler: Messy
Code: Select all
int original_tid = ActivatorTID();
int temporary_tid = UniqueTID(); // Unique tid must not live until end of script/terminate/delay of any kind; original_tid should always be restored before any such event
Thing_ChangeTID(0, temporary_tid);
if (SetActivator(<whatever>))
{
<activities with some other activator>
<if you need a few operations on the original activator>
SetActivator(temporary_tid);
<activities>
SetActivator(<whatever>);
<activities>
}
// Return to original activator and restore the original tids so that other code won't know it was ever changed
SetActivator(temporary_tid);
Thing_ChangeTID(0, original_tid);
// do what you need to do
This takes a bit of writing. It is quite reliable, but the code you call must not be in danger of triggering unknown external scripts that could depend on the original tid.
Spoiler: Bloody?
Code: Select all
script "xtacs:GetActorProperty" (int tid, int property, int pointer) // using a separate script causes a SetActivator() call to leave the original context unaffected
{
if (pointer == AAPTR_DEFAULT) SetResultValue(GetActorProperty(tid, property));
else if (SetActivator(tid, pointer)) SetResultValue(GetActorProperty(0, property));
else SetResultValue(0); // seems necessary if script with result is called several times in the same tick
}
script "xtacs:SetPointerProperty" (int property, int value, int pointer)
{
if (pointer == AAPTR_DEFAULT || SetActivator(0, pointer)) SetActorProperty(0, property, value); // ACS does short-circuiting?
}
Spoiler: Functionification
Code: Select all
function int ExtGetActorProperty(int tid, int property, int pointer)
{
return ACS_NamedExecuteWithResult("xtacs:GetActorProperty", property, value, pointer);
}
function void ExtSetPointerProperty(int property, int value, int pointer)
{
ACS_NamedExecuteWithResult("xtacs:SetPointerProperty", property, value, pointer);
}
This one is robust.
The workarounds can apply immediately to any acs function, unlike the patches that must be created specifically for each function. Still, they have some limitations, require extra management and might reduce compatibility between mods (since otherwise compatible mods might contain overlapping & conflicting workarounds).
Extended GetActorProperty would be: int GetActorProperty (int tid, int property, int pointer)
Extended SetActorProperty would be: void SetActorProperty (int tid, int property, int value, int pointer)
Actor is chosen by TID, as usual. TID can be 0 as usual. If pointer is non 0 (AAPTR_DEFAULT) then the pointer is applied from the chosen actor. (This is the same logic that applies to SetActivator)
One thing I'm not sure of: Can SetActorProperty affect multiple actors with the same TID?
If so, SetActorProperty with non-0 tid and a pointer should go through all the actors at the given tid, and from each of them use the pointer to get the chosen actor for the function. This should be uncomplicated most of the time. The possibility of setting the same actor's value several times per call would exist, because different actors can have pointers to the same actors, but usually the number of times a value has been set is not relevant. (If assignment immediately triggers a repeatable effect, it might matter.)
Since I'm posting I'll also mention two workarounds. One is messy, the other bloody.[spoiler=Messy][code]int original_tid = ActivatorTID();
int temporary_tid = UniqueTID(); // Unique tid must not live until end of script/terminate/delay of any kind; original_tid should always be restored before any such event
Thing_ChangeTID(0, temporary_tid);
if (SetActivator(<whatever>))
{
<activities with some other activator>
<if you need a few operations on the original activator>
SetActivator(temporary_tid);
<activities>
SetActivator(<whatever>);
<activities>
}
// Return to original activator and restore the original tids so that other code won't know it was ever changed
SetActivator(temporary_tid);
Thing_ChangeTID(0, original_tid);
// do what you need to do[/code]This takes a bit of writing. It is quite reliable, but the code you call must not be in danger of triggering unknown external scripts that could depend on the original tid.[/spoiler][spoiler=Bloody?][code]script "xtacs:GetActorProperty" (int tid, int property, int pointer) // using a separate script causes a SetActivator() call to leave the original context unaffected
{
if (pointer == AAPTR_DEFAULT) SetResultValue(GetActorProperty(tid, property));
else if (SetActivator(tid, pointer)) SetResultValue(GetActorProperty(0, property));
else SetResultValue(0); // seems necessary if script with result is called several times in the same tick
}
script "xtacs:SetPointerProperty" (int property, int value, int pointer)
{
if (pointer == AAPTR_DEFAULT || SetActivator(0, pointer)) SetActorProperty(0, property, value); // ACS does short-circuiting?
}[/code][spoiler=Functionification][code]function int ExtGetActorProperty(int tid, int property, int pointer)
{
return ACS_NamedExecuteWithResult("xtacs:GetActorProperty", property, value, pointer);
}
function void ExtSetPointerProperty(int property, int value, int pointer)
{
ACS_NamedExecuteWithResult("xtacs:SetPointerProperty", property, value, pointer);
}[/code][/spoiler]This one is robust.[/spoiler]The workarounds can apply immediately to any acs function, unlike the patches that must be created specifically for each function. Still, they have some limitations, require extra management and might reduce compatibility between mods (since otherwise compatible mods might contain overlapping & conflicting workarounds).