Get a Ref of a leveled Actor with FindRef

Post » Wed Jun 20, 2012 6:22 am

Becoming bald since days, i ask for a bit of help.

I'm trying to get the Ref of a leveled Actor (LvlAnimalCanyonPrey) around the Player with a script.

Scriptname AASSAliasScript extends ReferenceAliasActor Property PlayerRef AutoActorBase Property EncGoatWild AutoActorBase Property LvlAnimalCanyonPrey AutoObjectReference Goat01RefObjectReference Goat02RefEVENT OnUpdate()Goat01Ref = FindClosestReferenceOfTypeFromRef(LvlAnimalCanyonPrey, PlayerRef, 1000.0) ; leveled Actorif ( Goat01Ref != None )Debug.Notification("Here's the goat !")endifGoat02Ref = FindClosestReferenceOfTypeFromRef(EncGoatWild, PlayerRef, 1000.0) ; ActorBase used in LCharAnimalCanyonPrey (Template of leveled Actor)if ( Goat02Ref != None )Debug.Notification("Here's the goat !")endifEndEVENT


But it doesn't work. So i tested a lot of things, in vain, until this :

Actor ActorGoatActorGoat = FindRandomActorFromRef(PlayerRef, 500.0)if ( ActorGoat != None ) && ( ActorGoat != PlayerRef ) && ( ActorGoat.GetActorBase() == LvlAnimalCanyonPrey )Debug.Notification("Here's FINALLY the goat !")endif

And this is finally working, but the reads randomly return PlayerRef instead of the goat, so i would prefer to use a Ref & FindRef instead of an Actor.
Tried to use the first script with Actor casting; it works for "real" (non-leveled) EncGoatWild but not for leveled Actor.

Is something done wrong (cast and/or script extension) or is it simply not possible to get this Ref with FindRef functions ?
User avatar
MR.BIGG
 
Posts: 3373
Joined: Sat Sep 08, 2007 7:51 am

Post » Wed Jun 20, 2012 10:40 am

Please. I really need to do things with these goats. I'm in the Legion.
User avatar
Alyce Argabright
 
Posts: 3403
Joined: Mon Aug 20, 2007 8:11 pm

Post » Wed Jun 20, 2012 5:12 pm

you should do the finding from the alias tab and use conditions there, no need to do this from script.
http://www.creationkit.com/Alias#Fill_Type:
User avatar
April D. F
 
Posts: 3346
Joined: Wed Mar 21, 2007 8:41 pm

Post » Wed Jun 20, 2012 11:27 am

Yeah, it's easy to do from aliases...with scripts you can find either the closest one or a random one. Quest aliases can grab mutiples and get them in order of distance, etc.
User avatar
rolanda h
 
Posts: 3314
Joined: Tue Mar 27, 2007 9:09 pm

Post » Wed Jun 20, 2012 7:03 pm

You are right, well i considered this solution, but finally prefer to not create another quest just to fill Aliases. It would make me change a lot of code to be as accurate for fill/clear as it is now with scripts for what i'm doing.

The problem comes from LCharAnimalCanyonPrey, which is the Template of this leveled Actor and a Leveled Character. If i change this Template to a non-leveled Actor like EncGoatWild, the Ref is correctly returned with FindRef. And as it works well as it shall with FindActor functions, i would really like to understand why it is not working with FindRef functions.

I think i will just wait for SKSE, for things like GetCrossHairRef/GetFirstRef and so on.
User avatar
Amy Smith
 
Posts: 3339
Joined: Mon Feb 05, 2007 10:04 pm

Post » Wed Jun 20, 2012 3:46 pm

Your script could call a Detect Life spell having an Effect with Target Conditions to filter how you want. Then, you can specifically look for Goat Race in your Effect script.

In my case, I use something similar to detect if there are certain types of Actors nearby like this:

Event OnEffectStart(Actor akTarget, Actor akCaster)Race EnemyRace = akTarget.GetRace()If (EnemyRace == GiantRace)Debug.Notification("Giant Detected!")elseIf (EnemyRace == SabreCatRace)Debug.Notification("Sabre Cat Detected!")elseIf (EnemyRace == SabreCatSnowyRace)Debug.Notification("Snowy Sabre Cat Detected!").....

It beats messing around with FindClosestReferenceOfTypeFromRef and other similar methods.
User avatar
Ebou Suso
 
Posts: 3604
Joined: Thu May 03, 2007 5:28 am

Post » Wed Jun 20, 2012 3:21 pm

Here is some additional information I'm posting here in response to a PM I received:

I have spent the better part of a week testing functions like FindRandomActorNearRef and FindActorNearRef etc etc with varying degrees of success. I want my spell to find the closest enemy to my player, within LOS and a few other conditions like InCombat(PlayerRef) etc

Like you, I spend a lot of time messing with the various Find functions, but I was never able to get any of them working to my satisfaction. I had almost (actually had) given up, when it occurred to me I could do it differently.

No need (in some cases) to use the various inadequate Find functions to locate nearby actors when the built-in Detect Life Effect Archetype already provides akTarget to work with.

In my case, I wanted an enhanced Detect Life spell. Here is how I did it:

Create a custom Detect Life spell (copy existing) which calls a custom Effect based on one of the standard Detect Effects. I'm using a Concentration spell (actually a Power) based on DetectLifeEnemyExteriorConcSelf (I removed the IsInInterior condition, because I want both interior and exterior).

Next, I create a script for my Detect Life Effect similar to this (snippet for detecting Giants):

Scriptname DovahkiinDetectEnemy extends activemagiceffect  Actor Property Player AutoActor Property EnemyActor AutoRace Property GiantRace  AutoString Property Aware AutoEvent OnEffectStart(Actor akTarget, Actor akCaster)If(!akTarget.IsDead())Player = Game.GetPlayer()Race EnemyRace = akTarget.GetRace()Int Dir = Player.GetHeadingAngle(akTarget) as Intbool Detected = Player.IsDetectedBy(akTarget)If (Detected)  Aware = " Enemy is Aware!"Else  Aware = " Enemy is Unaware"EndIfIf (EnemyRace == GiantRace)  Debug.Notification("Giant Detected at " + Dir + " degrees!" + Aware)else  ; some other race detectedEndIfEndIf

You can apply all the various Actor Script and other functions on akTarget. In your case, you might use GetDistance, HasLOS etc., depending on exactly what you are trying to do.

Hope that helps

[EDIT] Advanced Detect Life spell using above techniques is now available on Nexus: http://skyrim.nexusmods.com/downloads/file.php?id=15971
User avatar
gandalf
 
Posts: 3400
Joined: Wed Feb 21, 2007 6:57 pm

Post » Wed Jun 20, 2012 9:46 pm

Thanks for your replies. This method so should work with GetDistance(), i'm currently busy with SKSE but will give a try later.

EDIT : It works very well. I would like to use GetCrossHairRef at all cost, because IMO it's the best for what i'm doing, but until it comes i'll keep this. Thanks again.
User avatar
Ronald
 
Posts: 3319
Joined: Sun Aug 05, 2007 12:16 am

Post » Wed Jun 20, 2012 7:18 pm

Here is some additional information I'm posting here in response to a PM I received:



Like you, I spend a lot of time messing with the various Find functions, but I was never able to get any of them working to my satisfaction. I had almost (actually had) given up, when it occurred to me I could do it differently.

No need (in some cases) to use the various inadequate Find functions to locate nearby actors when the built-in Detect Life Effect Archetype already provides akTarget to work with.

In my case, I wanted an enhanced Detect Life spell. Here is how I did it:

Create a custom Detect Life spell (copy existing) which calls a custom Effect based on one of the standard Detect Effects. I'm using a Concentration spell (actually a Power) based on DetectLifeEnemyExteriorConcSelf (I removed the IsInInterior condition, because I want both interior and exterior).

Next, I create a script for my Detect Life Effect similar to this (snippet for detecting Giants):

Scriptname DovahkiinDetectEnemy extends activemagiceffect  Actor Property Player AutoActor Property EnemyActor AutoRace Property GiantRace  AutoString Property Aware AutoEvent OnEffectStart(Actor akTarget, Actor akCaster)If(!akTarget.IsDead())Player = Game.GetPlayer()Race EnemyRace = akTarget.GetRace()Int Dir = Player.GetHeadingAngle(akTarget) as Intbool Detected = Player.IsDetectedBy(akTarget)If (Detected)  Aware = " Enemy is Aware!"Else  Aware = " Enemy is Unaware"EndIfIf (EnemyRace == GiantRace)  Debug.Notification("Giant Detected at " + Dir + " degrees!" + Aware)else  ; some other race detectedEndIfEndIf

You can apply all the various Actor Script and other functions on akTarget. In your case, you might use GetDistance, HasLOS etc., depending on exactly what you are trying to do.

Hope that helps

[EDIT] Advanced Detect Life spell using above techniques is now available on Nexus: http://skyrim.nexusmods.com/downloads/file.php?id=15971

This is brilliant. I make tons of spells, and the solutions I've come up with are much less elegant. I'm tagging this thread.
User avatar
latrina
 
Posts: 3440
Joined: Mon Aug 20, 2007 4:31 pm

Post » Wed Jun 20, 2012 6:31 am

This is brilliant. I make tons of spells, and the solutions I've come up with are much less elegant. I'm tagging this thread.
Thanks Ducey. :biggrin:
User avatar
Roberto Gaeta
 
Posts: 3451
Joined: Tue Nov 06, 2007 2:23 am


Return to V - Skyrim