Scriptname _00E_Smoking_WallMarkerScript extends activemagiceffect visualeffect property _00E_Smoking_PipeSmokingSmokeExhaleEffect auto Spell Property _00E_Smoking_WallMarkerSP Auto Package Property CQJ02_SC02_JesparSitLedge02 Auto Actor Target Int AnimationStage Bool bIsFinished Event OnEffectStart(Actor akTarget, Actor akCaster) ; Debug.Trace(self + ": OnEffectStart, " + akTarget) Target = akTarget 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) Debug.SendAnimationEvent(Target, "WallPipeSmokingEnter") RegisterForSingleUpdate(2.5) ElseIf AnimationStage == 2 Debug.SendAnimationEvent(Target, "WallPipeSmokingSmokeLoop") _00E_Smoking_PipeSmokingSmokeExhaleEffect.Play(Target, -1 as Float, none) EndIf EndIf _UnlockAnimationUpdates() EndEvent Event OnPackageChange(Package akOldPackage) ; Debug.Trace(self + ": OnPackageChange, " + Target + ", old package " + akOldPackage) if akOldPackage != CQJ02_SC02_JesparSitLedge02 ; Force exit of the furniture on package change ; A workaround for the magic effect having no IsPathing == 0 condition ; (with that condition NPCs get stuck in a enter-exit loop after fleeing combat from the furniture) Target.RemoveSpell(_00E_Smoking_WallMarkerSP) EndIf 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_WallMarkerSP) EndIf _UnlockAnimationUpdates() EndEvent Event OnEffectFinish(Actor akTarget, Actor akCaster) ; Debug.Trace(self + ": OnEffectFinish, " + Target) bIsFinished = True Target.RemoveSpell(_00E_Smoking_WallMarkerSP) _LockAnimationUpdates() StopAnimations(False) _UnlockAnimationUpdates() EndEvent Function StopAnimations(Bool bQuickStop) If AnimationStage > 0 If bQuickStop Debug.SendAnimationEvent(Target, "IdleForceDefaultState") Else Debug.SendAnimationEvent(Target, "WallPipeSmokingExit") EndIf If AnimationStage > 1 _00E_Smoking_PipeSmokingSmokeExhaleEffect.Stop(Target) EndIf Target.SetHeadtracking(True) If bQuickStop == False Utility.Wait(1.75) Debug.SendAnimationEvent(Target, "IdleForceDefaultState") EndIf AnimationStage = 0 EndIf EndFunction Bool _bAnimationUpdatesLocked = False Function _LockAnimationUpdates() While _bAnimationUpdatesLocked Utility.Wait(0.1) EndWhile _bAnimationUpdatesLocked = True EndFunction Function _UnlockAnimationUpdates() _bAnimationUpdatesLocked = False EndFunction