How do you catch events from the actor a magic effect is on?

Post » Tue Jun 19, 2012 8:11 pm

OK, I want to have a magic effect respond to certain events of the target of the effect.

With this kind of thing, you could do things like trigger a healing effect when the target is hit, or deal damage to/cast a spell at the aggressor when the target is hit (Like a cloak spell, but reactive only, not a constant AOE), or respond to the end of a Translation, etc.

Can a script that extends ActiveMagicEffect catch events on it's target?

If so, How?

I want to be able to catch said events without going out and attaching a script to every single actor and object in the game.
User avatar
JUDY FIGHTS
 
Posts: 3420
Joined: Fri Jun 23, 2006 4:25 am

Post » Tue Jun 19, 2012 8:52 pm

Events called on an http://www.creationkit.com/Actor_Script are automatically passed to all http://www.creationkit.com/ActiveMagicEffect_Script running on it. Because of this, you can use events such as http://www.creationkit.com/OnHit_-_ObjectReference in a script extending ActiveMagicEffect as though the script were attached directly to the Actor on which the effect is running.

Cipscis
User avatar
Dj Matty P
 
Posts: 3398
Joined: Sat Jun 09, 2007 12:31 am

Post » Tue Jun 19, 2012 2:23 pm

I was using a script that extended ActiveMagicEffect instead of Actor for the same reason... until I ran into some trouble that I couldn't find a way around. But depending on what you want to do, you may have better success.

I used this to find out what actor the effect was attached to...

ACTOR property ThisActor autoEvent OnEffectStart(Actor akTarget, Actor akCaster)  ThisActor = akTargetendEvent

After that, you can use an OnHit event to do things to the attached actor when struck... and also to the attacker...

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \  bool abBashAttack, bool abHitBlocked)ThisActor.dosomething() ;does something to the scripted actorakAggressor.dosomething() ;does something to the attackerendEvent


I believe that's what I did. There is more flexibility to using a script that extends Actor, though. I believe that SkyProc can apply scripts to every actor through a patch. At least, that's what I'm hoping for ;-P
User avatar
Music Show
 
Posts: 3512
Joined: Sun Sep 09, 2007 10:53 am

Post » Wed Jun 20, 2012 2:23 am

The problem I was encountering was caused by my failure to properly set a property...ouchie.

Now if only I can figure out what's causing the rubberbanding back to the start point, my Monty Python Flying Spell will work:

Script on the FlyTarget Item:
Spoiler
Scriptname FlightNodeTargetScript extends ObjectReference  import gameimport utilityimport mathfloat property DX autofloat property DY autofloat property Dz autofloat property RotX autofloat property RotY autofloat property RotZ autoFloat property FlySpeed autoBool property DoingMath = True autoBool Property DidMathAlready = False AutoObjectReference property CannonObject AutoFloat Function MoveToNextPoint()	While DoingMath		wait(0.1) ; Make sure the math is done before trying to move.	endwhile	MoveTo(self,DX,DY,DZ) ; get to our new spot.	SetAngle(GetAngleX()+RotX,GetAngleY()+RotY,GetAngleZ()+RotZ)	Debug.Notification("Range To Target: " + GetDistance(Gvar.Node))	DidMathAlready = False	return FlySpeedEndFunctionFunction StartComputing(ObjectReference CalledFrom)	CannonObject = CalledFrom	RegisterForSingleUpdate(1)EndFunctionEvent OnUpdate()	if !DidMathAlready		DoingMath = True		DX = (Gvar.Node.X - x) / 2.0		DY = (Gvar.Node.Y - y) / 2.0		float GroundRange = SQRT(DX*DX+DY*DY)		if GroundRange > 10000.0			DZ = (Gvar.Node.Z - z) / 2.0 + 5000 ; If we're a long long way away, go to cruising altitude		elseif GroundRange > 5000.0			DZ = (Gvar.Node.Z - z) / 2.0 + 2000 ; Getting close, begin descending		elseif GroundRange > 2000.0			DZ = (Gvar.Node.Z - z) / 2.0 + 1000 ; Coming in for a landing		elseif GroundRange > 1000.0			DZ = (Gvar.Node.Z - z) / 2.0 + 500 ; Almost there		else			DZ = (Gvar.Node.Z - z) / 2.0 + 100 ; Landing.		endif		RotX = RandomFloat(-360.0,360.0)		RotY = RandomFloat(-360.0,360.0)		RotZ = RandomFloat(-360.0,360.0) ; Tumble at random		FlySpeed = GetDistance(Gvar.Node) / 2.0		if CannonObject			RegisterForSingleUpdate(1) ; Kill yourself if the object that created you goes away.		else			Disable()			Delete()		endif		DoingMath = False		DidMathAlready = True	endifEndEventNodeVariablescript Property Gvar Auto

Script on the Cannon:
Spoiler
Scriptname BallisticLaunchingScript extends ObjectReference{Lancelot, Galahad, and I jump out of the rabbit...}import gameimport utilityimport RedwoodsToolsfloat ForceBool FirstUpdate = TrueFlightNodeTargetScript property FlyTarget auto; a marker in the airActivator Property FlyTargetType Auto ; The object type being used to keep track of the "next" position to fly to.ObjectReference MoveWhat ; Me. Saves tons of function calls to Game.GetPlayer()Float property FlySpeed auto; How fast to move.Sound BoomSound Whooshfunction PlayCannon(objectreference Here)	Boom = BoomSound	Whoosh = WhooshSound	Boom.Play(Here)	Whoosh.Play(Here)endfunctionfunction FindCannonPosition(ObjectReference A, ObjectReference B) ; Do the math before we play the sounds		Moveto(A,0.0,0.0,-5000.0)		Force = DistanceBetween(A,B) / 30.0		if Force > 80.0			Force = 80.0		endifendfunctionfunction FireCannon(float ForceFactor) ; Use the FusRohDah Cannon!	PushActorAway(Game.GetPlayer(),Force *  ForceFactor)endFunctionEvent OnInit()	MoveWhat = GetPlayer()	FindCannonPosition(MoveWhat,Gvar.Node) ; Find start position for the cannon	if !FlyTarget		FlyTarget = (PlaceAtMe(FlyTargetType,1) as FlightNodeTargetScript)		FlyTarget.MoveTo(MoveWhat,0.0,0.0,10000.0) ; Start the target at high altitude.		FlySpeed = 5000.0	endif	PlayCannon(MoveWhat)	FireCannon(1.0)	RegisterForSingleUpdate(4) ; To give the player time to get up high.	FlyTarget.StartComputing(self) ; Start the FlyTarget thinking about where it should go next.EndEventEvent OnUpdate() ; Start moving the player with translates	if FirstUpdate		FirstUpdate = False		MoveWhat.TranslateToRef(FlyTarget,FlySpeed) ; Move player to the fly object. Once in motion, the active magic effect will handle the rest.		FlySpeed = FlyTarget.MoveToNextPoint() ; Move FlyTarget to it's next position	endif	if MoveWhat.GetDistance(Gvar.Node) < 200.0 ; At the destination case.		Delete()	else		RegisterForSingleUpdate(1.0)	endifEndEventSound Property WhooshSound AutoSound Property BoomSound Auto ; Using VOCShoutFXFireBreathCNodeVariableScript Property GVar Auto

Script on the MagicEffect:
Spoiler
Scriptname NodeFusRohDahCannonPlayer extends activemagiceffect  import utilityimport GameBallisticLaunchingScript Cannonfloat FlySpeedFlightNodeTargetScript FlyTargetEvent OnEffectStart(Actor Target, Actor Caster)	Cannon = (Target.PlaceAtMe(CannonType,1,false,false) as BallisticLaunchingScript)	Wait(1.0)	while !FlyTarget		FlyTarget = Cannon.FlyTarget	endWhile	Wait(1.0)	FlySpeed = FlyTarget.MoveToNextPoint() ; Get Ready for First Move.EndEventEvent OnEffectFinish(Actor Target, Actor Caster)	Debug.Notification("Spell Invulnerability shield Down")EndEventEvent OnTranslationComplete()	if GetPlayer().GetDistance(FlyTarget) > 200.0		GetPlayer().TranslateToRef(FlyTarget,FlySpeed) ; Move me to the fly object.	elseif GetPlayer().GetDistance(Gvar.Node) > 1000		GetPlayer().TranslateToRef(Gvar.Node,FlySpeed)	endif	FlySpeed = FlyTarget.MoveToNextPoint() ; Get Ready for the next move.EndEventEvent OnTranslationAlmostComplete();	Debug.Notification("Translation Almost Complete")EndEventEvent OnTranslationFailed()	Debug.Notification("Translation Failed")EndEventActivator property CannonType autoNodeVariableScript property Gvar Auto

The target item is tracking the target location correctly, getting halfway there with each movement (at least it seems to), but I keep winding up back where I first cast the spell at the start of each translation (X/Y Coordinates, but not Z Coordinate, which is weird) for no readily discernible reason.

At first I thought it might be the push that was doing it, but when I commented out the push, it still happens
User avatar
Jimmie Allen
 
Posts: 3358
Joined: Sun Oct 14, 2007 6:39 am


Return to V - Skyrim