ScriptName footprintsPlayerScript Extends ReferenceAlias

footprintsVCScript Property footprintsVCQuest Auto
footprintsRefCountScript Property footprintsQuest Auto

GlobalVariable Property fp_IsFootprintsDisabled Auto
GlobalVariable Property fp_UseCustomFootprints Auto
GlobalVariable Property fp_FootprintsRefCount Auto

FormList Property footprintsSpellsFLST Auto
FormList Property footprintsCustomPlayerSpellsFLST Auto

Spell Property footprintsCloakAbility Auto
Spell Property footprintsCloakDispelAbility Auto

Keyword Property footprintsFootstepsEffect Auto
Keyword Property ActorTypeNPC Auto
Spell 	Property footprintsFootstepsAbilityPlayer Auto

Race[] 	Property FootprintsRacesV1 Auto
Spell[] Property FootprintsSpellsV1 Auto

Actor Property PlayerRef Auto

Quest Property MQ101 Auto
Quest Property DGIntimidateQuest Auto
Quest Property C00 Auto


Event OnInit()
	If ( !MQ101.IsStageDone( 250 ) )
		GoToState( "Waiting" )
		return
	EndIf

	Init()
EndEvent

Event OnPlayerLoadGame()
	If ( !MQ101.IsStageDone( 250 ) )
		GoToState( "Waiting" )
		return
	EndIf

	bool newGame = Init()
	If ( !newGame )
		Debug.Trace( "~~~~~ Footprints: Running Maintenance ~~~~~" )
		Maintenance()
	EndIf
EndEvent

Event OnUpdate()

	If ( fp_IsFootprintsDisabled.GetValue() )
		Debug.Trace( "~~~~~ Footprints: Main Script Disabling ~~~~~" )
		PlayerRef.RemoveSpell( footprintsCloakAbility )
		GoToState( "Dead" )
		return
	EndIf

	;Debug.Trace( fp_FootprintsRefCount.GetValue() as Int )

	If ( footprintsQuest.RefCountLimitReached() \
		|| (DGIntimidateQuest.IsRunning() && DGIntimidateQuest.GetStage() < 100) \
		|| (C00.IsRunning() && C00.GetStage() == 20) )
		;Debug.Trace( "~~~~~ Footprints: Pausing Cloak ~~~~~" )
	Else
		;Debug.Trace( "~~~~~ Footprints: Cloaking ~~~~~" )
		PlayerRef.AddSpell( footprintsCloakAbility, False )
		Utility.Wait( 0.5 )
		;Debug.Trace( "~~~~~ Footprints: Uncloaking ~~~~~" )
		PlayerRef.RemoveSpell( footprintsCloakAbility )
	EndIf

	RegisterForSingleUpdate( 4.0 )

EndEvent

Event OnRaceSwitchComplete()
	;Debug.Trace( "footprintsPlayerScript - OnRaceSwitchComplete: " + PlayerRef.GetRace() )
	ResetPlayer()
EndEvent

bool Function Init()
	Debug.Trace( "~~~~~ Footprints: Initializing ~~~~~" )

	bool result = False
	If ( !footprintsVCQuest.IsVCInstalled() )
		; Brand new user, Install here
		Debug.Trace( "~~~~~ Footprints: Installing VC ~~~~~" )
		footprintsVCQuest.Start()
		footprintsVCQuest.VersionCheckStart()

		result = True
	EndIf
	
	UnregisterForUpdate()
	ResetPlayer()
	RegisterForSingleUpdate( 4.0 )

	return result
EndFunction

Function Maintenance()
	If ( fp_IsFootprintsDisabled.GetValue() )
		; In case somehow Footprints is disabled but does not enter the "dead" state
		Debug.Trace( "~~~~~ Footprints: Reinstalling ~~~~~" )
		fp_IsFootprintsDisabled.SetValue( 0 )
	EndIf
	
	footprintsVCQuest.VersionCheckStart()
	Utility.Wait( 1.0 )
EndFunction

Function ResetPlayer()
	;Debug.Trace( "~~~~~ Footprints: Cloaking (Dispel) ~~~~~" )
	PlayerRef.AddSpell( footprintsCloakDispelAbility, False )
	Utility.Wait( 0.5 )
	PlayerRef.RemoveSpell( footprintsCloakDispelAbility )
	
	RemoveAllFootsteps()
	Utility.Wait( 0.5 )
	ReapplySpell()
EndFunction

Function RemoveAllFootsteps()
	If ( !RemoveFootstepsInList( footprintsSpellsFLST ) )
		RemoveFootstepsInList( footprintsCustomPlayerSpellsFLST )
	EndIf
EndFunction

bool function RemoveFootstepsInList( FormList flst )
	int iSpellIndex = flst.GetSize()
	bool spellRemoved = False
	While ( iSpellIndex > 0 )
		iSpellIndex -= 1
		Spell currSpell = flst.GetAt( iSpellIndex ) as Spell
		If ( PlayerRef.DispelSpell( currSpell ) )
			PlayerRef.RemoveSpell( currSpell )
			spellRemoved = True
		EndIf
	EndWhile
	return spellRemoved
EndFunction

Function ReapplySpell()

	Race playerRace = PlayerRef.GetRace()

	If ( fp_UseCustomFootprints.GetValue() )
		;Debug.Trace( "footprintsPlayerScript - Checking for custom race..." )
		int iCustomFLSTSize = footprintsCustomPlayerSpellsFLST.GetSize()
		;Debug.Trace( "footprintsCustomPlayerSpellsFLST size: " + iCustomFLSTSize )
		While ( iCustomFLSTSize )
			iCustomFLSTSize -= 1
			Spell CustomSpell = footprintsCustomPlayerSpellsFLST.GetAt( iCustomFLSTSize ) as Spell
			;Debug.Trace( "footprintsPlayerScript - Attempting to add " + CustomSpell + " to " + PlayerRef )
			If ( CustomSpell && PlayerRef.AddSpell( CustomSpell, False ) )
				If ( PlayerRef.HasMagicEffectWithKeyword( footprintsFootstepsEffect ) )
					;Debug.Trace( "footprintsPlayerScript - Added CUSTOM spell to PLAYER " + playerRace )
					return
				Else
					PlayerRef.RemoveSpell( CustomSpell )
				EndIf
			EndIf
		EndWhile
	EndIf

	If ( playerRace.HasKeyword( ActorTypeNPC ) )
		PlayerRef.RemoveSpell( footprintsFootstepsAbilityPlayer ) ; Ensures magic effect gets reapplied
		Utility.Wait( 0.1 )
		If ( PlayerRef.AddSpell( footprintsFootstepsAbilityPlayer, False ) )
			;Debug.Trace( "footprintsPlayerScript - Adding " + footprintsFootstepsAbilityPlayer + " to PLAYER " + playerRace )
			return
		EndIf
	EndIf

	int i = FootprintsRacesV1.Find( playerRace )
	If ( i >= 0 )
		;Debug.Trace( "footprintsPlayerScript - Found Race at Index " + i )
		PlayerRef.RemoveSpell( FootprintsSpellsV1[1] ) ; Ensures magic effect gets reapplied
		Utility.Wait( 0.1 )
		If ( PlayerRef.AddSpell( FootprintsSpellsV1[i], False ) )
			;Debug.Trace( "footprintsPlayerScript - Adding " + FootprintsSpellsV1[i] + " to PLAYER " + playerRace )
			return
		EndIf
	EndIf

EndFunction

State Waiting

	Event OnBeginState()
		;Debug.Trace( "~~~~~ Footprints: Begin Waiting ~~~~~" )
		RegisterForSingleUpdate( 15.0 )
	EndEvent

	Event OnUpdate()
		If ( MQ101.IsStageDone( 250 ) )
			;Debug.Trace( "~~~~~ Footprints: MQ101 Stage 250 Complete ~~~~~" )
			Init()
			GoToState("")
		Else
			;Debug.Trace( "~~~~~ Footprints: MQ101 Stage 250 Incomplete ~~~~~" )
			RegisterForSingleUpdate( 15.0 )
		EndIf
	EndEvent

EndState

State Dead

	Event OnBeginState()
		Debug.Trace( "~~~~~ Footprints: Main Script Disabled ~~~~~" )
		RemoveAllFootsteps()
		RegisterForSingleUpdate( 5.0 )
	EndEvent

	Event OnPlayerLoadGame()

	EndEvent

	Event OnUpdate()

		If ( footprintsQuest.GetRefCount() > 0 )
			;Debug.Trace( "~~~~~ Footprints: Cloaking (Dispel) ~~~~~" )
			PlayerRef.AddSpell( footprintsCloakDispelAbility, False )
			Utility.Wait( 0.5 )
			;Debug.Trace( "~~~~~ Footprints: Uncloaking (Dispel) ~~~~~" )
			PlayerRef.RemoveSpell( footprintsCloakDispelAbility )
		EndIf

		If ( !fp_IsFootprintsDisabled.GetValue() )
			Debug.Trace( "~~~~~ Footprints: Re-enabling ~~~~~" )
			RegisterForSingleUpdate( 1.0 )
			GoToState("")
			ReapplySpell()
			return
		Else
			RegisterForSingleUpdate( 5.0 )
		EndIf
	EndEvent

	Event OnRaceSwitchComplete()

	EndEvent

	Function Maintenance()

	EndFunction

	Function ReapplySpell()

	EndFunction

EndState
