ScriptName footprintsFootstepsScriptWerecreature Extends ActiveMagicEffect
{
 NOTE: Most werecreatures will have a bone typo:
	boneBackLeft  = NPC L Foot [Lft ]
	boneBackRight = NPC R Foot [Lft ]
}

footprintsRefCountScript Property footprintsQuest Auto

string Property boneFrontLeft  Auto
string Property boneFrontRight Auto
string Property boneBackLeft   Auto
string Property boneBackRight  Auto

ImpactDataSet[] Property footprintsIPDS Auto
ImpactDataSet[] Property footprintsIPDSNoFX Auto
{
	footprintsNPCWerecreatureFootWalkImpactsetL			0
	footprintsNPCWerecreatureFootWalkImpactsetR			1
	footprintsNPCWerecreatureFootSprintFrontImpactsetL	2
	footprintsNPCWerecreatureFootSprintFrontImpactsetR	3
	footprintsNPCWerecreatureFootSprintBackImpactsetL	4
	footprintsNPCWerecreatureFootSprintBackImpactsetR	5
	footprintsNPCWerecreatureFootLStrafeLImpactset 		6
	footprintsNPCWerecreatureFootLStrafeRImpactset		7
	footprintsNPCWerecreatureFootRStrafeLImpactset		8
	footprintsNPCWerecreatureFootRStrafeRImpactset		9
}

Spell Property parentSpell Auto

Actor Property playerRef Auto

Actor selfRef

float fDirection
int strafeDir

bool refCounted = False


Function Register()
	If ( !refCounted )
		If ( !footprintsQuest.IncrementRefCount() )
			;Debug.Trace( "footprintsFootstepsScriptWerecreature - NPC Footprints at max limit, aborting." )
			GoToState( "dead" )
			return
		EndIf
		refCounted = True
	EndIf
EndFunction

Function Unregister()
	If ( refCounted )
		refCounted = False
		footprintsQuest.DecrementRefCount()
	EndIf
EndFunction

Event OnEffectStart( Actor target, Actor caster )
	If ( !boneFrontLeft  || !boneFrontRight || !boneBackLeft  || !boneBackRight )
		Debug.Trace( "One of the bone strings is empty on " + self + ". Aborting..." )
		GoToState( "dead" )
		return
	EndIf
	
	If ( footprintsIPDS.Length != 10 || footprintsIPDSNoFX.Length != 10 )
		Debug.Trace( "An IPDS array is incorrect length on " + self + ". Aborting..." )
		GoToState( "dead" )
	EndIf
	
	selfRef = target
	If ( !selfRef )
		GoToState( "dead" )
		return
	EndIf
	
	If ( selfRef != playerRef )
		;Debug.Trace("Werewolf Effect applied to " + selfRef + ". Race: " + selfRef.GetRace() +" on (" + self +")")
		If ( footprintsQuest \
			&& RegisterForAnimationEvent( selfRef, "FootLeft" ) && RegisterForAnimationEvent( selfRef, "FootRight" ) \
			&& RegisterForAnimationEvent( selfRef, "FootBack" ) && RegisterForAnimationEvent( selfRef, "FootFront" ) )
			
			If ( footprintsQuest.FXCountLimitReached() )
				GoToState( "alive_nofx" )
			Else
				GoToState( "alive" )
			EndIf
		EndIf
	Else
		If ( RegisterForAnimationEvent( selfRef, "FootLeft" ) && RegisterForAnimationEvent( selfRef, "FootRight" ) \
			&& RegisterForAnimationEvent( selfRef, "FootBack" ) && RegisterForAnimationEvent( selfRef, "FootFront" ) \
			&& RegisterForAnimationEvent( selfRef, "JumpUp" ) && RegisterForAnimationEvent( selfRef, "JumpDown" ) )
			GoToState( "alive_player" )
		EndIf
	EndIf
EndEvent

Function PlayImpact( ImpactDataSet[] ipds, ObjectReference akSelfRef, string e )
	If ( (akSelfRef as Actor).IsSprinting() )
		If ( e == "FootFront" )
			akSelfRef.PlayImpactEffect( ipds[3], boneFrontRight, 0, 0, -1, 512 )
			akSelfRef.PlayImpactEffect( ipds[2], boneFrontLeft, 0, 0, -1, 512 )
			return
		ElseIf ( e == "FootBack" )
			akSelfRef.PlayImpactEffect( ipds[4], boneBackLeft, 0, 0, -1, 512 )
			akSelfRef.PlayImpactEffect( ipds[5], boneBackRight, 0, 0, -1, 512 )
			return
		EndIf
	Else
		If ( e == "FootRight" )
			akSelfRef.PlayImpactEffect( ipds[1], boneBackRight, 0, 0, -1, 512 )
			return
		ElseIf ( e == "FootLeft" )
			akSelfRef.PlayImpactEffect( ipds[0], boneBackLeft, 0, 0, -1, 512 )
			return
		EndIf
	EndIf
EndFunction

State alive

	Event OnBeginState()
		If ( footprintsQuest )
			Register()
			footprintsQuest.IncrementFXCount()
		EndIf
	EndEvent

	Event OnAnimationEvent( ObjectReference akSelfRef, string e )
		If ( akSelfRef )
			PlayImpact( footprintsIPDS, akSelfRef, e )
		EndIf
	EndEvent
	
	Event OnDying( Actor killer )
		;Debug.Trace( "footprintsFootstepsScriptWerecreature - OnDying event on " + selfRef )
		GoToState( "dead" )
	EndEvent
	
	Event OnEffectFinish( Actor akTarget, Actor akCaster )
		;Debug.Trace( "footprintsFootstepsScriptWerecreature - OnEffectFinish event on " + selfRef )
		GoToState( "dead" )
	EndEvent
	
	Event OnEndState()
		If ( footprintsQuest )
			Unregister()
			footprintsQuest.DecrementFXCount()
		EndIf
	EndEvent
	
EndState

State alive_nofx

	Event OnBeginState()
		If ( footprintsQuest )
			Register()
		EndIf
	EndEvent

	Event OnAnimationEvent( ObjectReference akSelfRef, string e )
		If ( !akSelfRef )
			return
		EndIf
		
		If ( !footprintsQuest.FXCountLimitReached() )
			GoToState( "alive" )
			return
		EndIf
		
		PlayImpact( footprintsIPDSNoFX, akSelfRef, e )
	EndEvent
	
	Event OnDying( Actor killer )
		;Debug.Trace( "footprintsFootstepsScriptWerecreature - OnDying event on " + selfRef )
		GoToState( "dead" )
	EndEvent
	
	Event OnEffectFinish( Actor akTarget, Actor akCaster )
		;Debug.Trace( "footprintsFootstepsScriptWerecreature - OnEffectFinish event on " + selfRef )
		GoToState( "dead" )
	EndEvent
	
	Event OnEndState()
		If ( footprintsQuest )
			Unregister()
		EndIf
	EndEvent
	
EndState

State alive_player

	Event OnBeginState()
		RegisterForSingleUpdate( 2.0 )
	EndEvent

	Event OnUpdate()
		strafeDir = StrafeDir()
		RegisterForSingleUpdate( 1.0 )
	EndEvent

	Event OnAnimationEvent( ObjectReference akSelfRef, string e )
		If ( !akSelfRef )
			return
		EndIf
		
		;Debug.Trace("AnimEvent: " + e + " delivered by " + (akSelfRef as Actor).GetRace() + "("+self+") ")
		If ( (akSelfRef as Actor).IsSprinting() )
			If ( e == "FootFront" )
					akSelfRef.PlayImpactEffect( footprintsIPDS[3], boneFrontRight, 0, 0, -1, 512 )
					akSelfRef.PlayImpactEffect( footprintsIPDS[2], boneFrontLeft, 0, 0, -1, 512 )
			ElseIf ( e == "FootBack" )
					akSelfRef.PlayImpactEffect( footprintsIPDS[4], boneBackLeft, 0, 0, -1, 512 )
					akSelfRef.PlayImpactEffect( footprintsIPDS[5], boneBackRight, 0, 0, -1, 512 )
			EndIf
		ElseIf ( strafeDir == 0 )
			;Debug.Trace( "Werecreature footsteps: Not strafing" )
			If ( e == "FootRight" ) 
				akSelfRef.PlayImpactEffect( footprintsIPDS[1], boneBackRight, 0, 0, -1, 512 )
			ElseIf ( e == "FootLeft")
				akSelfRef.PlayImpactEffect( footprintsIPDS[0], boneBackLeft, 0, 0, -1, 512 )
			ElseIf ( e == "JumpDown" || e == "JumpUp" )
				akSelfRef.PlayImpactEffect( footprintsIPDS[1], boneBackRight, 0, 0, -1, 512 )
				akSelfRef.PlayImpactEffect( footprintsIPDS[0], boneBackLeft, 0, 0, -1, 512  )
			EndIf
		ElseIf ( strafeDir == -1 )
			;Debug.Trace( "Werecreature footsteps: Strafing Left" )
			If ( e == "FootRight" ) 
				akSelfRef.PlayImpactEffect( footprintsIPDS[7], boneBackRight, 0, 0, -1, 512 )
			ElseIf ( e == "FootLeft" )
				akSelfRef.PlayImpactEffect( footprintsIPDS[6], boneBackLeft, 0, 0, -1, 512 )
			ElseIf ( e == "JumpDown" || e == "JumpUp" )
				akSelfRef.PlayImpactEffect( footprintsIPDS[7], boneBackRight, 0, 0, -1, 512 )
				akSelfRef.PlayImpactEffect( footprintsIPDS[6], boneBackLeft, 0, 0, -1, 512 )
			EndIf
		ElseIf ( strafeDir == 1 )
			;Debug.Trace( "Werecreature footsteps: Strafing Right" )
			If ( e == "FootRight" ) 
				akSelfRef.PlayImpactEffect( footprintsIPDS[9], boneBackRight, 0, 0, -1, 512 )
			ElseIf ( e == "FootLeft" )
				akSelfRef.PlayImpactEffect( footprintsIPDS[8], boneBackLeft, 0, 0, -1, 512 )
			ElseIf ( e == "JumpDown" || e == "JumpUp" )
				akSelfRef.PlayImpactEffect( footprintsIPDS[9], boneBackRight, 0, 0, -1, 512 )
				akSelfRef.PlayImpactEffect( footprintsIPDS[8], boneBackLeft, 0, 0, -1, 512 )
			EndIf
		EndIf
	EndEvent

	Event OnDying( Actor killer )
		; NOTHING!
	EndEvent

EndState

State dead
	Event OnBeginState()
		If ( selfRef && parentSpell )
			selfRef.RemoveSpell( parentSpell )
		EndIf
	EndEvent
EndState

Event OnUpdate()
	; nothing
EndEvent

Event OnDying( Actor killer )
	; nothing
EndEvent
	
Event OnRaceSwitchComplete()
	; nothing
EndEvent

int Function StrafeDir()
	fDirection = selfRef.GetAnimationVariableFloat( "Direction" )
	If ( fDirection == 0.25 )
		; Right
		return 1
	ElseIf ( fDirection == 0.75 )
		; Left
		return -1
	EndIf
	return 0
EndFunction
