Jump to content

Getting references of nearby actors via scripting


TheMrDomino

Recommended Posts

I have a script that's working, but I'm only about 95% happy with its functionality right now. It's purpose is to prevent a glitch. This is it, in its entirety:

Scriptname zKillmoveControlGlitchFix extends ActiveMagicEffect

GlobalVariable Property KillMove  Auto  
GlobalVariable Property killmovesInitialValue  Auto  

import Debug

Float initialValue
Actor thisActor

Event OnEffectStart(Actor akTarget, Actor akCaster) ;get the original killmove setting
Debug.Notification("oneffectstart event triggered")
initialValue = killmovesInitialValue.GetValue()
thisActor = akCaster
RegisterForUpdate(1)
EndEvent

Event OnDying(Actor akKiller)
KillMove.SetValue(initialValue)
Debug.Notification("actor killed, killmove reset")
UnregisterForUpdate()
EndEvent

Event OnUpdate()
;If Game.GetPlayer().GetCombatTarget() == thisActor  too precise, switched to line of sight
;If Game.GetPlayer().HasLOS(thisActor)  caused issues with multiple actors deactivating/activating
If thisActor.IsNearPlayer()	
	If KillMove.GetValue() == 1
		KillMove.SetValue(0)
		Debug.Notification("is combat target, killmoves disabled")
	Else
		Debug.Notification("killmoves already disabled")
	EndIf
;		GoToState("targeted")
;	ElseIf Game.GetPlayer().GetCombatTarget() != thisActor  unneeded, too buggy
;		GoToState("waiting")  unneeded, too buggy
Else
	KillMove.SetValue(initialValue)
	Debug.Notification("no longer target, killmoves reset")
EndIf
EndEvent

 

What this does is, when the player sees whatever the script is attached to, it changes some globals around, and on death it resets their value. This code compiles and runs well, and performs admirably, doing what I need it to. It is, in fact, doing exactly what I tell it to. My dissatisfaction arises when fighting multiple actors with this script attached. What happens is when one actor dies, the ondying() event triggers and the global is restored to its original value. Because the script only updates once every second, there is a brief opportunity after killing one actor where the glitch can occur if the player kills another actor quickly. I tried decreasing the update time, even as low as .05, but that didn't help, and truth be told I'd be loathe to use that as a solution even if it did for fear of getting stacking onupdate() events.

 

What I'd like to do is add a condition to the ondying() event so that it only runs the code if the player does not have line of sight to any similar actors. Something like 'if nearby actor has this spell' or 'if player has line of sight to an actor with this spell' or 'player has line of sight/is near actors with a certain keyword' . My problem lies in defining an Actor variable to hold that infomation.

 

I thought perhaps trying a quest alias would work, having it populate with references to actors with a specific keyword/spell that were near the player, but from my understanding the alias only holds one reference, and it only updates when the quest starts. Is it possible for an alias to hold multiple actor references, and if so, is it possible to attach a script to the quest holding the alias that would update it at regular intervals, refreshing the references in the alias?

 

Ultimately I'm just looking for a way to get actors nearby the player.

Edited by TheMrDomino
Link to comment
Share on other sites

First of all I don't get what's with that OnDying() event, it's not defined for ActiveMagicEffect, is an Actor event. Who calls that in your case?

Anyway, from your description and in general issues with doing the same thing "quickly" again are synchronization issues. You may want to look at http://www.creationkit.com/Threading_Notes_%28Papyrus%29 and consider solutions there like states.

 

"My problem lies in defining an Actor variable to hold that infomation."

For those things you use quest aliases and you need a quest of course. You may consider one started by http://www.creationkit.com/OnStoryKillActor_-_Quest and get the actor from the event, or if you have a script running at that moment you can start it with http://www.creationkit.com/OnStoryScript_-_Quest and pass the actor when you fire the event.

Link to comment
Share on other sites

The spell this script is attached to is attached to actors. When that's the case, you can use Actor events even though it extends ActiveMagicEffect.

 

The issue is one of syncing across multiple actors, not just one.

 

As of right now the spell is attached to skeletons. When fighting one skeleton everything is fine. However, when a second is added, upon killing the first the OnDying() event triggers, and sets the variable back to it's initial value (let's say 1 for simplicity's sake). In the half-second it takes to update, if the player attacks the second skeleton, they will suffer from the glitch. Waiting just a moment allows the script to update and set the variable to 0. The most logical way to fix this I can think of is to add a condition that if the player is fighting any other actor with this spell, don't trigger the script in OnDying(), but I don't know how to do that.

 

You mention quest aliases, and I initially thought of them, but I must not understand them fully, as I thought they were only populated when the quest initialized, and I'd need that list to be updating like the script I posted. Is that possible?

 

Also, can an alias hold a reference to more than one actor? It feels like I should be able to use the Find Matching Reference option of filling the alias with the In Loaded Area checkbox, and then set a condition to only add actors that have a specific spell or keyword.

Link to comment
Share on other sites

  • 2 years later...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...