Scriptname _00E_Smoking_CrossLeggedMarkerScript extends activemagiceffect  

visualeffect property _00E_Smoking_PipeSmokingSmokeExhaleEffect auto

Spell Property _00E_Smoking_CrossLeggedMarkerSP Auto

Actor Target
Int AnimationStage
Bool bIsFinished

Event OnEffectStart(Actor akTarget, Actor akCaster)
	; Debug.Trace(self + ": OnEffectStart, " + akTarget)

	Target = akTarget
	GotoState("Smoking")
EndEvent

state Smoking

	event OnBeginState()
		; Debug.Trace(self + ": Registering for updates, " + Target)
		AnimationStage = 0
		RegisterForSingleUpdate(1.5)
		RegisterForSleep()
	endevent

	Event OnUpdate()
		_LockAnimationUpdates()

		If AnimationStage == 0 && Target.GetSitState() != 3
			; Debug.Trace(self + ": OnUpdate, " + Target + ", stage " + AnimationStage + ", waiting...")
			RegisterForSingleUpdate(1.0)
		ElseIf bIsFinished == False
			AnimationStage += 1

			; Debug.Trace(self + ": OnUpdate, " + Target + ", stage " + AnimationStage)

			If AnimationStage == 1
				Target.SetHeadtracking(False)
				Target.SetDontMove(True)
				Debug.SendAnimationEvent(Target, "pipesmokingcrossleggedstartblaze")
				Debug.SendAnimationEvent(Target, "pipesmokingcrossleggedblazed")
				RegisterForSingleUpdate(2.5)
			ElseIf AnimationStage == 2
				Debug.SendAnimationEvent(Target, "pipesmokingcrosslegged")
				_00E_Smoking_PipeSmokingSmokeExhaleEffect.Play(Target, -1 as Float, none)
			EndIf
		EndIf

		_UnlockAnimationUpdates()
	EndEvent

	Event OnSleepStart(float afSleepStartTime, float afDesiredSleepEndTime)
		; Debug.Trace(self + ": OnSleepStart, " + Target)

		; Force reset of the animations to make the NPC re-enter the furniture (if it wishes).
		; Fixes NPCs creeping away from the furniture while the player is sleeping in the same location.
		_LockAnimationUpdates()

		If bIsFinished == False
			UnregisterForUpdate()
			StopAnimations(True)
			Target.RemoveSpell(_00E_Smoking_CrossLeggedMarkerSP)
		EndIf

		_UnlockAnimationUpdates()
	EndEvent

	Event OnCellDetach()
		GotoState("")
	endEvent

	event OnEndState()
		; Debug.Trace(self + ": Unregistering for updates, " + Target)
		UnregisterForUpdate()
		UnregisterForSleep()
	endevent

endstate

Event OnCellAttach()
	If ! bIsFinished
		GotoState("Smoking")
	endif
endEvent

Event OnPackageChange(Package akOldPackage)	
	; Debug.Trace(self + ": OnPackageChange, " + Target + ", old package " + akOldPackage)

	; Failsafe auto-stop smoking on package change
	Target.RemoveSpell(_00E_Smoking_CrossLeggedMarkerSP)
EndEvent

Event OnEffectFinish(Actor akTarget, Actor akCaster)
	; Debug.Trace(self + ": OnEffectFinish, " + Target)

	bIsFinished = True
	Target.RemoveSpell(_00E_Smoking_CrossLeggedMarkerSP)

	_LockAnimationUpdates()
	StopAnimations(False)
	_UnlockAnimationUpdates()
EndEvent

Function StopAnimations(Bool bQuickStop)
	If AnimationStage > 0
		If bQuickStop
			Debug.SendAnimationEvent(Target, "IdleForceDefaultState")
		Else
			Debug.SendAnimationEvent(Target, "pipesmokingcrossleggedexit")
		EndIf

		If AnimationStage > 1
			_00E_Smoking_PipeSmokingSmokeExhaleEffect.Stop(Target)
		EndIf
		Target.SetHeadtracking(True)

		If bQuickStop == False
			Utility.Wait(2.5)
			Debug.SendAnimationEvent(Target, "IdleForceDefaultState")
		EndIf

		Target.SetDontMove(False)

		AnimationStage = 0
	EndIf
EndFunction

Bool _bAnimationUpdatesLocked = False

Function _LockAnimationUpdates()
	While _bAnimationUpdatesLocked
		Utility.Wait(0.1)
	EndWhile
	_bAnimationUpdatesLocked = True
EndFunction

Function _UnlockAnimationUpdates()
	_bAnimationUpdatesLocked = False
EndFunction