Scriptname _00E_AbWispCombatAnimationFixScript extends activemagiceffect  
{ Dirty workaround for Wisps and Wisp Shades getting stuck in an animation if hit (too often?).
On being hit, wait for X seconds, and if the NPC does not do cast or attack actions in this time, consider it stuck and cast "stagger self" to reset it. }


Actor Property PlayerRef Auto
Spell Property _00E_StaggerSelf Auto
Faction Property WispBusyFaction Auto

Actor TargetRef
Bool bIsDead
Bool bFailsaveActive

Event OnEffectStart(Actor akTarget, Actor akCaster)
	If akCaster == None || akCaster == PlayerRef
		Dispel()
		Return
	EndIf

	TargetRef = akCaster
EndEvent

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
	If bIsDead == False
		bFailsaveActive = True
		RegisterForSingleUpdate(5.0)
		_RegisterForActions()
	EndIf
EndEvent

Event OnActorAction(int actionType, Actor akActor, Form source, int slot)
	If akActor == TargetRef
		_StopFailsave()
	EndIf
EndEvent

Event OnDying(Actor akKiller)
	bIsDead = True
	_StopFailsave()
EndEvent

Event OnUpdate()
	If TargetRef.IsInFaction(WispBusyFaction) ; Busy (fleeing, attacking, casting, staggered, recoiling)?
		If bIsDead == False && bFailsaveActive
			RegisterForSingleUpdate(1.0)
		EndIf
		Return
	EndIf

	If bFailsaveActive == False ; Just in case
		Return
	EndIf	

	bFailsaveActive = False

	If _TryUnequipSpell(1) ; Right hand
		; Do nothing
	; ElseIf _TryUnequipSpell(0) ; Left hand
	;	; Do nothing
	Else
		If bIsDead == False
			_00E_StaggerSelf.Cast(TargetRef, TargetRef) ; As the last resort, stagger the wisp to unstuck it
		EndIf
	EndIf

	If bFailsaveActive == False
		_UnregisterForActions()
	EndIf

EndEvent

Bool Function _TryUnequipSpell(Int iHand)
	Spell spellInHand = TargetRef.GetEquippedSpell(iHand)
	If spellInHand
		If bIsDead == False
			TargetRef.UnequipSpell(spellInHand, iHand)
		EndIf
		Return True
	EndIf

	Return False
EndFunction

Function _RegisterForActions()
	RegisterForActorAction(2) ; Spell Fire (Spells and staves).
	RegisterForActorAction(0) ; Weapon Swing (Melee weapons that are swung including Hand to Hand.)
	; RegisterForActorAction(6) ; Bow Release.
EndFunction

Function _UnregisterForActions()
	UnRegisterForActorAction(2) ; Spell Fire (Spells and staves).
	UnRegisterForActorAction(0) ; Weapon Swing (Melee weapons that are swung including Hand to Hand.)
	; UnRegisterForActorAction(6) ; Bow Release.
EndFunction

Function _StopFailsave()
	If bFailsaveActive
		bFailsaveActive = False
		UnregisterForUpdate()
		_UnregisterForActions()
	EndIf
EndFunction