So, yeah, this has been annoying me. For ActiveMagicEffect.psc, it would have been nice to have something like an OnHitCaster event, but unfortunately, there isn't.
Anyways, what I'm trying to accomplish is when a target with an active magic effect hits the one who cast it on them, the active effect is in some way, changed or manipulated. It's slightly complicated, I think.
Anyway, here's my script for the active magic effect:
ScriptName _ACGMagicEffectBrisingrActor Extends ActiveMagicEffectActor RefCaster ; NOTE - should this be a property?Actor Property RefTarget Auto ; Is a property so that other scripts can check the value here.MagicEffect Property RefMEffect Auto ; Reference for _ACGTestMagicEffectBrisingrActor.Float MEffectBaseTimeCost = 1.0 ; per second - NOTE - needs tuning.Float MEffectBaseDistanceCost = 0.1 ; per foot - NOTE - needs tuning.Float TargetDistance ; Distance in feet.Float TotalCost ; Total Magicka cost.Float Property HealthDamage = 20.0 Auto ; per second. Also, damage managed here because Papyrus, even with SKSE, ; has no way of manipulating spell effect item magnitude on the fly.Float UpdateInterval = 0.2 ; Update interval for RegisterForUpdate()Bool Property DeathDispel = True Auto ; For non-Essential Actors.Bool Property BleedoutDispel = True Auto ; For Essential Actors.Bool DoOnce = False ; Temporary, for debugging purposes.Event OnInit() RefCaster = Self.GetCasterActor() RefTarget = Self.GetTargetActor() RegisterForControl("Shout") RegisterForModEvent("MagickaRunout", "OnMagickaRunout") RegisterForSingleUpdate(UpdateInterval)EndEventEvent OnUpdate() ; 64 Skyrim units equals approximately 3 feet, so 64 divided 3 gives the amount to divide TargetDistance by. TargetDistance = RefCaster.GetDistance(RefTarget) / 21.33333333333333333333 TotalCost = (MEffectBaseDistanceCost * TargetDistance) * (MEffectBaseTimeCost * UpdateInterval) RefCaster.DamageActorValue("Magicka", TotalCost) If RefCaster.GetActorValue("Magicka") <= 0 SendModEvent("MagickaRunout") EndIf ; deal a relative amount of damage in relation to the UpdateInterval period. RefTarget.DamageActorValue("Health", (HealthDamage * UpdateInterval)) If !DoOnce ; Shows only one first update event. Debug.Notification("Magicka cost (per second): " + (TotalCost / UpdateInterval) as String) Debug.Notification("Distance (feet): " + TargetDistance as String) Debug.Notification("Distance (metres): " + (TargetDistance * 0.3048) as String) DoOnce = True EndIf RegisterForSingleUpdate(UpdateInterval)EndEventEvent OnMagickaRunout(string eventName, string strArg, float numArg, Form sender) Self.Dispel()EndEventEvent OnControlDown(String Control); If Control == "Shout" Self.Dispel() EndIfEndEvent; Will only affect non-Essential Actors.Event OnDeath(Actor akKiller) If DeathDispel Self.Dispel() EndIfEndEvent; Will only affect Essential Actors.Event OnEnterBleedout() If RefTarget.IsEssential() If BleedoutDispel Self.Dispel() EndIf EndIfEndEvent
So, to reiterate, when the one with this script attached to them hits the one who cast it, this script does something like dispelling the effect or reducing HealthDamage depending on the difference between the caster's old health percentage and new health percentage.
Any advice?
This has really been annoying me, so many thanks in advance!
Edit: I updated the script with Terra Nova's RegisterForSingleUpdate() suggestion in mind.