enderalse/source/scripts/_00e_bardaudiencescript.psc

165 lines
4.0 KiB
Plaintext

Scriptname _00E_BardAudienceScript extends Actor
Faction Property BardAudienceStateFaction Auto
_00E_BardDialogueFunctions Property BardDialogue Auto
Package Property CrossedArmsListenPackage Auto
Bool Property NoApplaud Auto
Bool Property NoHeadtrackingBard Auto
Int Property STATE_NONE = -1 AutoReadOnly
Int Property STATE_APPLAUD = 0 AutoReadOnly
Int Property STATE_LISTEN = 1 AutoReadOnly
Bool bBardIsPlaying = False
;=====================================================================================
; EVENTS
;=====================================================================================
Event OnLoad()
If IsDead() == False
GoToState("Spectating")
RegisterForModEvent("BardSongStarted", "OnBardSongStarted")
RegisterForModEvent("BardSongApplaud", "OnBardSongApplaud")
RegisterForModEvent("BardSongEnded", "OnBardSongEnded")
EndIf
EndEvent
State Spectating
Event OnUnload()
Terminate()
EndEvent
Event OnDying(Actor akKiller)
Terminate()
EndEvent
Event OnDeath(Actor akKiller)
Terminate()
EndEvent
EndState
Event OnBardSongStarted(string a_eventName, string a_strArg, float a_numArg, Form a_sender)
If Is3DLoaded() == False
Terminate()
Return
EndIf
bBardIsPlaying = True
If TryLockStateUpdate()
WaitRandom(1.0, 2.0)
SetAudienceState(STATE_LISTEN)
UnlockStateUpdate()
EndIf
EndEvent
Event OnBardSongApplaud(string a_eventName, string a_strArg, float a_numArg, Form a_sender)
If Is3DLoaded() == False
Terminate()
Return
EndIf
bBardIsPlaying = False
If TryLockStateUpdate()
If NoApplaud == False
If CrossedArmsListenPackage != None && GetCurrentPackage() == CrossedArmsListenPackage
SetAudienceState(STATE_LISTEN + 1)
Debug.SendAnimationEvent(self, "IdleOffsetStop") ; This is the way to exit OffsetArmsCrossedStart idle
Utility.Wait(1.0)
Else
WaitRandom(0.01, 0.25)
EndIf
SetAudienceState(STATE_APPLAUD)
WaitRandom(7.0, 7.5)
Else ; No applauding
WaitRandom(5.0, 5.5)
EndIf
If Is3DLoaded() && bBardIsPlaying
SetAudienceState(STATE_LISTEN)
Else
SetAudienceState(STATE_NONE)
EndIf
UnlockStateUpdate()
EndIf
EndEvent
Event OnBardSongEnded(string a_eventName, string a_strArg, float a_numArg, Form a_sender)
If Is3DLoaded() == False
Terminate()
Return
EndIf
bBardIsPlaying = False
If TryLockStateUpdate()
WaitRandom(1.0, 2.0)
SetAudienceState(STATE_NONE)
UnlockStateUpdate()
EndIf
EndEvent
;=====================================================================================
; FUNCTIONS
;=====================================================================================
Function Terminate()
GoToState("")
bBardIsPlaying = False
UnregisterForAllModEvents()
RemoveFromFaction(BardAudienceStateFaction)
EndFunction
Function WaitRandom(Float fMinWaitSecs, Float fMaxWaitSecs)
Utility.Wait(Utility.RandomFloat(fMinWaitSecs, fMaxWaitSecs))
EndFunction
Function SetAudienceState(Int iNewState)
If iNewState >= 0
If iNewState == STATE_LISTEN
iNewState = Utility.RandomInt(1, 100)
EndIf
SetFactionRank(BardAudienceStateFaction, iNewState)
EvaluatePackage()
; Look at
If NoHeadtrackingBard == False
ObjectReference lookTarget = BardDialogue.GetSingingBardActor()
If lookTarget
SetLookAt(lookTarget)
Else
ClearLookAt()
EndIf
EndIf
Else
RemoveFromFaction(BardAudienceStateFaction)
EvaluatePackage()
If NoHeadtrackingBard == False
ClearLookAt()
EndIf
; The NPC might not switch from their _00E_AnimTest_SC package if they are in combat, so they need an additional kick here
_00E_AnimTest_SC myAnimTest = ((Self as Actor) as _00E_AnimTest_SC)
If myAnimTest
myAnimTest.CombatResetAnimations()
EndIf
EndIf
EndFunction
Bool bStateUpdateLocked = False
Bool Function TryLockStateUpdate()
If bStateUpdateLocked
Return False
EndIf
bStateUpdateLocked = True
Return True
EndFunction
Function UnlockStateUpdate()
bStateUpdateLocked = False
EndFunction