Hello @ll,
I have some questions regarding scripts running on actors.
My mod EGM utilizes the token / token script method to achieve this.
Here is a code snippet how this is achieved, how the tokens get distributed, through a function call from a quest script running always.
scn egmFNDispatcher
ref tempref
array_var actors
short index
short arrSize
short minus
begin _function { }
let actors := GetHighActors
let arrSize := ar_Size actors
let index := 0
while (index < arrSize)
let tempref := actors[index]
if eval (tempref && IsFormValid tempref)
if eval !(tempref.IsCreature)
if eval !(tempref.GetDead)
if eval !(tempref.GetItemCount EGMFatigueEffectToken)
tempref.addItemNS EGMFatigueEffectToken 1
if (egmDebugLevel == 4) || (egmDebugLevel == 40)
PrintC "egmDispatcher: %i:%n is GetHighActors OK, adding EGMFatigueEffectToken", tempref, tempref
endif
endif
else ; T_Pose prevention
if eval !(tempref.GetDisabled)
let minus := -1
tempref.PushActorAway tempref minus
endif
endif
endif
endif
let index += 1
loop
let actors := ar_Null
end
There is also a T-Pose preventer, dont get confused.
My first question is, does this work with temporary actors as well. I know it does, for the short while i have tested it, but are there any other culprits?
In order to drop the token correctly, the token script provides its own routine.
Below is the part of the token script, which calls a function to check if the actor is still in the array returned by GetHighActors, and the checking function itself
...
;***************************************************************************************************
; token processing validation test
if eval (myself.GetInSameCell playerref == 0)
let fRemoveTokenTimer += GetSecondsPassed
if(fRemoveTokenTimer > 10)
let fRemoveTokenTimer := 0
let bRunscript := call egmFNCheckActorQuit myself
if (bRunScript == 0)
let bRemoveToken := 1
if eval(egmDebugLevel == 40 || egmDebugLevel == 4)
PrintC "egmFatigueToken: %i:%n removing Fatigue Effects -- NO HIGH/MID AI", myself, myself
endif
return
endif
endif
endif
...
the token script uses the above algorithm to drop the token itself by 'RemoveMe', as soon as the Actor isnt part of the array anymore, which is returned by GetHighActor.
The script will wait 10 seconds, in order to reduce working load.
This routine, as far as i know, must be run in Gamemode, as only the OnAdd block is guranteed to run once, when the token is added to the actor, but not the OnDrop block, when the actor gets killed, or disabled.
scn egmFNCheckActorQuit
ref tempref
array_var actors
short index
short arrSize
short bRunScript
ref myself
begin _Function { myself }
let bRunScript := 1
if eval !(myself.GetInSameCell playerref)
let bRunScript := 0
let actors := GetHighActors
let arrSize := ar_Size actors
let index := 0
while (index < arrSize)
let tempref := actors[index]
if (tempref == myself)
if eval(egmDebugLevel == 40 || egmDebugLevel == 4)
PrintC "egmFatigueToken: %i:%n is GetHighActors OK", myself, myself
endif
let bRunScript := 1
Break
endif
let index += 1
loop
let actors := ar_Null
endif
SetFunctionValue bRunScript
end
Second question is regarding the worldspace transitions.
GetHighActor includes all actors in the same cell, 1 cell adjacent to the player, or in the same interior.
As far as I know, if the player makes a transition to another worldspace (for example leaves an interior) the token scripts on those actors still in the old world space will run only every 30 seconds from then on.
Is there any chance this messes things up, as I noticed a CTD when reentering a certain interior (only a certain dungeon/ruin so far, Fort Nickel located next to Weye).
The CTD could be caused by something else, as it happened with EGM deinstalled as well, but i want to be on the safe side.