Tutorial: Detect Nearby Actors Using Quest Aliases

Post » Sun Aug 24, 2014 10:54 am

Using a Quest + Aliases to Detect Nearby Actors (or other objects)

Quick tutorial in case it proves helpful to anyone.

I'll use an example from something I set up recently. For a skill learning system I've implemented, I need to know whenever there are actors near the player that have the ability to spread disease (like skeevers, vampires, etc).

To do this, I first set up a quest with several aliases that can detect nearby actors that meet that description.

Setting Up the Quest

http://imgur.com/a/zyBnz#0

A few things to notice:

  • The quest is set up to NOT be Start Game Enabled. We only want to start this when we decide its time to detect actors.
  • The first Alias is not optional, but all additional aliases ARE optional -- this is to ensure that the quest will start successfully as long as there is at least one actor that meets the conditions.
  • Each alias has the same conditions, which check if the actor is one of a number of disease-spreading actor types, and if the actor is also within a close distance to the player (2500 units).

Using The Quest To Detect Actors

The way that I use this quest is, whenever I want to see whether there are any disease-spreading actors near the player, all I have to do is start this quest, and the aliases will fill automatically. I have named the Quest property in my script "DiseaseAntenna." So all I need is just a simple

DiseaseAntenna.start()

After starting the quest from a script (or script fragment), all aliases are automatically filled. You can then check whether the first (and any other) alias filled successfully to see if any disease-spreaders were nearby:

if (NearbyDiseaseSpreader1.getReference() as Actor) 

If there were no disease-spreaders that met the necessary conditions, this will equal NONE, and nothing will happen.

Once you've detected whether your desired actors are nearby, and you've reacted appropriately to any actors in your aliases, you can simply stop the quest:

DiseaseAntenna.stop()

and then wait until the next time you would like to detect this kind of actor again, at which point you just Start() the quest up again. The script I've shared is just one example of how you could use this quest -- but as long as you remember to Stop() and then re-Start() your quest, you can do this as often as you would like. Each time the quest is started, all nearby actors meeting the conditions will fill into the proper aliases.

Tips:

  • It's super easy to duplicate Aliases in the creation kit. Just set up your first alias or two, and then all you have to do is right click and "Duplicate" to create as many as you need. This is useful if you want to detect, say, up to 50 actors (instead of just 3)
  • If you DO have a lot of aliases, consider adding them all to an array to check whether they were filled using a simple loop
  • Just a reminder - make sure you fill all the necessary properties in your script before testing this (including your Quest and any ReferenceAlias properties you want to check)

Additional Info:

In case you'd like a text version of the script seen in the screenshot above, I'll paste it here:

Spoiler
Scriptname EA_Learn_ResistDisease extends EA_Learn_TemplateAME;effect conditioned to be active only while in combat, so this will check at the beginning of each combat;Note to self: I should also implement a Story Manager event for player gaining a disease, then add experience as long as it lasts.Quest           property  DiseaseAntenna          autoReferenceAlias  property  NearbyDiseaseSpreader1  autoReferenceAlias  property  NearbyDiseaseSpreader2  autoReferenceAlias  property  NearbyDiseaseSpreader3  autoObjectReference diseasedCreature1ObjectReference diseasedCreature2ObjectReference diseasedCreature3Event OnEffectStart(Actor target, Actor caster)    DiseaseAntenna.start()    RegisterForSingleUpdate(1.0)EndEventEvent OnUpdate()    if (NearbyDiseaseSpreader1.getReference() as Actor)        diseasedCreature1 = NearbyDiseaseSpreader1.getReference()        diseasedCreature2 = NearbyDiseaseSpreader2.getReference()        diseasedCreature3 = NearbyDiseaseSpreader3.getReference()        GoToState("Active")    else        GoToState("Disabled")    endifEndEventState Active    Event OnHit(ObjectReference aggressor, Form source, Projectile proj, bool powAtk, bool snkAtk, bool bashAtk, bool hitBlocked)        GoToState("Paused")        if (aggressor == diseasedCreature1 || aggressor == diseasedCreature2 || aggressor == diseasedCreature3)            learnManager.LearnResistDisease()            Utility.Wait(7.0)        endif        Utility.Wait(3.0)        GoToState("Active")    EndEventEndStateEvent OnEffectFinish(Actor target, Actor caster)    DiseaseAntenna.stop()EndEvent 

If you're interested in the complete setup I used for this disease detection example, you can also take a look at the ability I used to turn this detection script on and off for the player. The script above is actually attached to a magic effect, which is used in an ability I've added to the player.

http://imgur.com/a/tbV6C#1

Since the OnCombatStateChanged event doesn't work for the player, I attached this ability to the player instead, using an IsInCombat condition. What this results in, is that the script seen above will be initialized every time the player starts combat -- and thus, each time combat starts, the script will start up the DiseaseAntenna quest to check if any disease-spreaders are near the actor. If they are, I award the actor some special experience each time they are hit during this round of combat (which helps them get better at using "Resist Disease" enchantments).

User avatar
Javier Borjas
 
Posts: 3392
Joined: Tue Nov 13, 2007 6:34 pm

Post » Sun Aug 24, 2014 10:36 am

Would you mind if I added this to my site?

See http://www.gamesas.com/topic/1506027-writing-tutorials-can-you-help/ for an explanation of what I mean.

User avatar
+++CAZZY
 
Posts: 3403
Joined: Wed Sep 13, 2006 1:04 pm


Return to V - Skyrim