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() if bIsFinished UnregisterForUpdate() UnregisterForSleep() GotoState("") return endif _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) if bIsFinished UnregisterForSleep() UnregisterForUpdate() GotoState("") return endif ; 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 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 if Target Target.RemoveSpell(_00E_Smoking_CrossLeggedMarkerSP) endif EndEvent Event OnEffectFinish(Actor akTarget, Actor akCaster) ; Debug.Trace(self + ": OnEffectFinish, " + Target) bIsFinished = True Target.RemoveSpell(_00E_Smoking_CrossLeggedMarkerSP) _LockAnimationUpdates() StopAnimations(False) _UnlockAnimationUpdates() Target = None 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