Difference between revisions of "Talk:FindClosestActorFromRef - Game"

From the CreationKit Wiki
Jump to navigation Jump to search
imported>Rasikko
(Created page with "== SKSE alternative == You basically have to make your own findref function with SKSE, if you want to avoid certain references, but especially the player because it's so easy...")
 
imported>Rasikko
m (→‎SKSE alternative: Cleaned up function to make more readible.)
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
== SKSE alternative ==
== SKSE alternative ==
You basically have to make your own findref function with SKSE, if you want to avoid certain references, but especially the player because it's so easy for it to be the return value. First of all you need to pass this keyword into the function:
You basically have to make your own version of this function with SKSE, if you want to avoid certain references, but especially the player because it's so easy for it to be the return value.
<source lang="papyrus">
<source lang="papyrus">
Keyword property PlayerKeyword auto
Actor Function GetClosestActorFromRef(ObjectReference akCenter) Global
</source>
;/ Returns the closest actor to akCenter. akCenter is excluded from the search.
And now for the function:
          *1. Check if there is more than 128 actors or only akCenter.
<source lang="papyrus">
          *2. Iterate through all actors found and record their distances to the player.
Actor Function FindClosestActorFromRefWithoutKeyword(ObjectReference akCenter, Keyword akKeyword)
          *3. Find the smallest distance from the player and return the actor.
; returns all references of the specified type that doesn't have this keyword.
          *4. Valid types for actors: 43 or 62
        /;
ObjectReference[] kActorRefs = new ObjectReference[128]
ObjectReference[] kRefs = new ObjectReference[128]
Float[] fDistances = new Float[128]
Cell kCell = akCenter.GetParentCell()
Cell kCell = akCenter.GetParentCell()
Int CellRefs = kCell.GetNumRefs(43)
Float fLowestValue = 1000000.0
Int i
Int i
Int CellRefs = kCell.GetNumRefs(62) ; kCharacter
Float[] fDistances = new Float[128]
if (CellRefs >= 129 || CellRefs == 1)
Float fLowestValue = 10000000.0
if (CellRefs == 0 || CellRefs >= 129)
return none
return none
endif
endif
While i < CellRefs
while i < CellRefs
            if kCell.GetNthRef(i, 62).HasKeyword(akKeyword) == false
ObjectReference kActors = kCell.GetNthRef(i, 43)
        kActorRefs[i] = kCell.GetNthRef(i, 62)
if kActors != akCenter
        fDistances[i] = kCell.GetNthRef(i, 62).GetDistance(akCenter)
kRefs[i] = kActors
        Float fCurrentValue = fDistances[i]
fDistances[i] = kActors.GetDistance(akCenter)
        if fCurrentValue <= flowestValue
    fLowestValue = fCurrentValue
Float fCurrentValue = fDistances[i]
        endif
        if fCurrentValue <= fLowestValue
    endif
fLowestValue = fCurrentValue
    i += 1
endif
EndWhile
endif
i += 1
endWhile
Int refIndex = fDistances.Find(fLowestValue)
Int refIndex = fDistances.Find(fLowestValue)
return kActorRefs[refIndex] as Actor
return kRefs[refIndex] as Actor
EndFunction
EndFunction
</source>
</source>
This will return the closest actor. It's not efficient, and on the slow side but it's the best I could come up with. --[[User:Rasikko|Rasikko]] ([[User talk:Rasikko|talk]]) 2017-12-15T14:47:39 (EST)
How fast this function returns, depends on how many actors are in the cell. --[[User:Rasikko|Rasikko]] ([[User talk:Rasikko|talk]]) 2018-01-02T02:58:34 (EST)

Latest revision as of 02:58, 2 January 2018

SKSE alternative[edit source]

You basically have to make your own version of this function with SKSE, if you want to avoid certain references, but especially the player because it's so easy for it to be the return value.

Actor Function GetClosestActorFromRef(ObjectReference akCenter) Global
	;/ Returns the closest actor to akCenter. akCenter is excluded from the search.
          *1. Check if there is more than 128 actors or only akCenter.
          *2. Iterate through all actors found and record their distances to the player.
          *3. Find the smallest distance from the player and return the actor.
          *4. Valid types for actors: 43 or 62
        /;
		
	ObjectReference[] kRefs = new ObjectReference[128]
	Float[] fDistances = new Float[128]
	Cell kCell = akCenter.GetParentCell()
	Int CellRefs = kCell.GetNumRefs(43) 
	Float fLowestValue = 1000000.0
	Int i
		
	if (CellRefs >= 129 || CellRefs == 1)
		return none
	endif
		
	while i < CellRefs
		ObjectReference kActors = kCell.GetNthRef(i, 43)
		if kActors != akCenter
			kRefs[i] = kActors
			fDistances[i] = kActors.GetDistance(akCenter)
			
			Float fCurrentValue = fDistances[i]
		        if fCurrentValue <= fLowestValue
				fLowestValue = fCurrentValue
			endif
		endif
		i += 1
	endWhile
		
	Int refIndex = fDistances.Find(fLowestValue)
		
	return kRefs[refIndex] as Actor
EndFunction

How fast this function returns, depends on how many actors are in the cell. --Rasikko (talk) 2018-01-02T02:58:34 (EST)