Since GetHighActors isn't all that reliable, I've decided to create a function script in my SDR.esm file that I can call that uses the GetFirstRef technique, but also includes some of the more common filters that I usually apply.
I haven't used the GetFirstRef technique in a long time, so feedback would be great. See below.
scn sdrGetCellActors ; a more reliable alternative to the OBSE functions GetHighActors, GetMidHighActors, etc.
array_var aActorList
ref rActor
short iCellDepth ; 0 = current player cell, 1 = current cell + surrounding 8, 2 = current cell + surrounding 24, etc. Actors are still in play up to a cell depth of 4 in exterior settings.
short iProcessLevel ; 0 = High Processing, 1 = Med-High, 2 = Med-Low, 3 = Low Processing
short iSkipDead ; 0 = dead actors will be included, 1 = dead actors are not added to the list
short iSkipDisabled ; 0 = disabled actors will be included, 1 = disabled actors are not added to the list
short iSkipInCombat ; 0 = actors in combat will be included, 1 = actors in combat are not added to the list
Begin Function{iCellDepth, iProcessLevel, iSkipDead, iSkipDisabled, iSkipInCombat}
Let aActorList := ar_Construct Array
Let rActor := GetFirstRef 69 iCellDepth
Label 10
if (rActor)
if rActor.GetProcessLevel != iProcessLevel ; skips actors who are not the correct process level
Let rActor := GetNextRef
Goto 10
endif
if iSkipDead ; skips dead actors
if rActor.GetDead
Let rActor := GetNextRef
Goto 10
endif
endif
if iSkipDisabled ; skips disabled actors
if rActor.GetDisabled
Let rActor := GetNextRef
Goto 10
endif
endif
if iSkipInCombat ; skips actors in combat
if rActor.IsInCombat
Let rActor := GetNextRef
Goto 10
endif
endif
ar_Append aActorList rActor
endif
SetFunctionValue aActorList
return
End