2021-10-05 22:15:58 +00:00
Scriptname _00E_BardDialogueFunctions extends Quest Conditional
2021-10-05 22:59:59 +00:00
Scene Property BardDialogue_Instrumental20 Auto
Scene Property BardDialogue_LastSunset Auto
Scene Property BardDialogue_LastSunsetInstrumental Auto
Scene Property BardDialogue_Song06 Auto
Scene Property BardDialogue_Song08 Auto
Scene Property BardDialogue_Song09 Auto
Scene Property BardDialogue_Song10 Auto
Scene Property BardDialogue_Song11 Auto
Scene Property BardDialogue_TheAgedMan Auto
Scene Property BardDialogue_TheAgedManInstrumental Auto
Scene Property BardDialogue_Vatyra Auto
Scene Property BardDialogue_VatyraInstrumental Auto
Scene Property BardDialogue_WaywardWanderer Auto
Scene Property BardDialogue_WaywardWandererInstrumental Auto
Scene Property BardDialogue_WelcomeYouDrunkards Auto
Scene Property BardDialogue_Whisperwood Auto
Scene Property BardDialogue_SongWaageScene Auto ; Added in FS
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
ReferenceAlias Property SingingBard Auto
LocationAlias Property Location_Alias Auto
Quest Property BardAudience Auto
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Location Property _00E_DunevilleInteriorLocation auto
Location Property _00E_FlusshaimTaverneLocation auto
Location Property _00E_SuntempleQuarters auto
Location Property _00E_UEEntr_FalseDog_Location auto
Location Property BauernkuesteRoterOchseLocation auto
Location Property CapitalCityTheFatLeoranLocation auto
Location Property SchneefelstaverneInteriorLocation auto
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Idle Property IdleStop Auto
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Scene[] BardSongList
Int nBardSongsTotal
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Bool bSongHasQuestAudience = False
Bool bQuestAudienceCheering = False
Scene NextSongScene = None
Scene Property LastSongScene1 Auto Conditional Hidden
Scene LastSongScene2 = None
Scene LastSongScene3 = None
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Int Property QUEST_AUDIENCE_CHANCE = 67 AutoReadOnly
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
;=====================================================================================
; FUNCTIONS
;=====================================================================================
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Function Setup(Actor akBard, Scene _LastSongScene)
bSongHasQuestAudience = False
bQuestAudienceCheering = False
NextSongScene = None
LastSongScene1 = _LastSongScene
LastSongScene2 = None
LastSongScene3 = None
SingingBard.ForceRefTo(akBard)
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
PlayRandomSong(0.1)
EndFunction
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Function PrepareAudience(Int iAudienceInitialStage) ; A song is about to start, prepare the audience. Called from the scenes.
SendModEvent("BardSongStarted")
If IsQuestAudienceLocation() && iAudienceInitialStage > 0
bSongHasQuestAudience = True
If BardAudience.IsRunning() == False && bQuestAudienceCheering == False
If iAudienceInitialStage == 10
Int iAudienceRoll = Utility.RandomInt(1, 100)
If iAudienceRoll <= QUEST_AUDIENCE_CHANCE
If iAudienceRoll < (QUEST_AUDIENCE_CHANCE / 2) ; Roughly a 50% chance it will be the more lively audience
iAudienceInitialStage = 20
EndIf
Else
iAudienceInitialStage = 0
EndIf
EndIf
If iAudienceInitialStage > 0
2024-01-10 14:08:24 +00:00
BardAudience.SetCurrentStageID(iAudienceInitialStage)
2021-10-05 22:59:59 +00:00
EndIf
EndIf
EndIf
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
bQuestAudienceCheering = False
EndFunction
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Function OnSongStart(Scene songScene) ; The bard is actually starting to sing or make instrumental sounds. Called from the scenes.
NextSongScene = None
LastSongScene3 = LastSongScene2
LastSongScene2 = LastSongScene1
LastSongScene1 = songScene
EndFunction
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Function CheerAudience() ; When a song ends normally, time for the audience to cheer. Called from the scenes.
SendModEvent("BardSongApplaud")
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
If IsQuestAudienceLocation() && BardAudience.IsRunning()
2024-01-10 14:08:24 +00:00
Int iCurrentAudienceStage = BardAudience.GetCurrentStageID()
2021-10-05 22:59:59 +00:00
If iCurrentAudienceStage >= 10 && iCurrentAudienceStage <= 20
2024-01-10 14:08:24 +00:00
BardAudience.SetCurrentStageID(100)
2021-10-05 22:59:59 +00:00
bQuestAudienceCheering = True
EndIf
2021-10-05 22:15:58 +00:00
EndIf
2021-10-05 22:59:59 +00:00
EndFunction
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Function OnSongEnd() ; When a song ends normally or is interrupted. Called from the scenes.
2023-12-08 02:57:30 +00:00
Actor akBard = SingingBard.GetActorReference() ; If akBard is None in OnSongEnd, most likely it's the player just left the cell and the quest is stopping
2021-10-05 22:59:59 +00:00
Bool bLongDelay = False
If akBard
akBard.PlayIdle(IdleStop)
2021-10-05 22:15:58 +00:00
EndIf
2021-10-05 22:59:59 +00:00
SendModEvent("BardSongEnded")
2024-01-10 14:08:24 +00:00
If bSongHasQuestAudience == False && BardAudience.IsRunning() && BardAudience.GetCurrentStageID() < 100
2021-10-05 22:59:59 +00:00
BardAudience.Stop()
2021-10-05 22:15:58 +00:00
EndIf
2021-10-05 22:59:59 +00:00
If akBard
Float fNextSongDelay
If bQuestAudienceCheering
; A longer gap between songs is needed if the quest audience is applauding
; because otherwise the bard fails to properly pick up the "play intrument" animation at the start of the next song
fNextSongDelay = Utility.RandomFloat(5.0, 6.0)
Else
fNextSongDelay = Utility.RandomFloat(1.5, 3.0)
EndIf
PlayRandomSong(fNextSongDelay)
2021-10-05 22:15:58 +00:00
EndIf
2021-10-05 22:59:59 +00:00
EndFunction
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Function PlayRandomSong(Float fDelay)
LockNextSongUpdate()
If NextSongScene == None
BuildSongList(False)
PickRandomSongFromSongList()
2021-10-05 22:15:58 +00:00
EndIf
2021-10-05 22:59:59 +00:00
UnlockNextSongUpdate()
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
RegisterForSingleUpdate(fDelay)
EndFunction
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Function PlayRequestedSong(Scene requestedSongScene)
LockNextSongUpdate()
If requestedSongScene
NextSongScene = requestedSongScene
Else
BuildSongList(True)
PickRandomSongFromSongList()
2021-10-05 22:15:58 +00:00
EndIf
2021-10-05 22:59:59 +00:00
UnlockNextSongUpdate()
RegisterForSingleUpdate(0.1)
EndFunction
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Event OnUpdate()
2023-12-08 02:57:30 +00:00
Actor akBard = SingingBard.GetActorReference()
2021-10-05 22:59:59 +00:00
If akBard == None
Stop()
Return
2021-10-05 22:15:58 +00:00
EndIf
2021-10-05 22:59:59 +00:00
If akBard.IsInDialogueWithPlayer()
RegisterForSingleUpdate(1.0)
Return
2021-10-05 22:15:58 +00:00
EndIf
2021-10-05 22:59:59 +00:00
bSongHasQuestAudience = False
If NextSongScene
NextSongScene.ForceStart()
2021-10-05 22:15:58 +00:00
EndIf
2021-10-05 22:59:59 +00:00
EndEvent
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Function BuildSongList(Bool bOnlyVocalSongs)
BardSongList = New Scene[16]
nBardSongsTotal = 0
Location bardLoc = Location_Alias.GetLocation()
If bardLoc == CapitalCityTheFatLeoranLocation || bardLoc == _00E_DunevilleInteriorLocation || bardLoc == _00E_UEEntr_FalseDog_Location ; VT_Gerril
AddSongToList(BardDialogue_WaywardWanderer)
AddSongToList(BardDialogue_TheAgedMan)
AddSongToList(BardDialogue_LastSunset)
AddSongToList(BardDialogue_Whisperwood)
AddSongToList(BardDialogue_Song06) ; Black Guardian
AddSongToList(BardDialogue_Vatyra)
AddSongToList(BardDialogue_Song08) ; Wild Mages
AddSongToList(BardDialogue_Song09) ; Lost Ones
AddSongToList(BardDialogue_Song10) ; Crimson Star
AddSongToList(BardDialogue_Song11) ; Winter Sky (Firmament)
AddSongToList(BardDialogue_WelcomeYouDrunkards)
ElseIf bardLoc == _00E_FlusshaimTaverneLocation || bardLoc == _00E_SuntempleQuarters ; VT_Liliath
AddSongToList(BardDialogue_WaywardWanderer)
AddSongToList(BardDialogue_TheAgedMan)
AddSongToList(BardDialogue_LastSunset)
AddSongToList(BardDialogue_Whisperwood)
AddSongToList(BardDialogue_Song06) ; Black Guardian
AddSongToList(BardDialogue_Vatyra)
AddSongToList(BardDialogue_Song08) ; Wild Mages
AddSongToList(BardDialogue_Song09) ; Lost Ones
AddSongToList(BardDialogue_Song10) ; Crimson Star
ElseIf bardLoc == BauernkuesteRoterOchseLocation ; VT_FS_Bard
AddSongToList(BardDialogue_Vatyra)
AddSongToList(BardDialogue_Song11) ; Winter Sky (Firmament)
AddSongToList(BardDialogue_TheAgedMan)
AddSongToList(BardDialogue_SongWaageScene)
AddSongToList(BardDialogue_Song10) ; Crimson Star
AddSongToList(BardDialogue_WelcomeYouDrunkards)
ElseIf bardLoc == SchneefelstaverneInteriorLocation ; VT_Lara
If bOnlyVocalSongs
LastSongScene3 = None ; The list is too short
EndIf
AddSongToList(BardDialogue_WaywardWanderer)
AddSongToList(BardDialogue_Vatyra)
AddSongToList(BardDialogue_Song11) ; Winter Sky (Firmament)
Else
If bardLoc
Debug.Notification("ERROR BardDialogue: unsupported location!")
Debug.Trace("ERROR BardDialogue: unsupported location (" + bardLoc + ")")
EndIf
Return
EndIf
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
If bOnlyVocalSongs == False
AddSongToList(BardDialogue_VatyraInstrumental)
AddSongToList(BardDialogue_WaywardWandererInstrumental)
AddSongToList(BardDialogue_TheAgedManInstrumental)
AddSongToList(BardDialogue_LastSunsetInstrumental)
AddSongToList(BardDialogue_Instrumental20) ; Drum Instrumental
EndIf
2021-10-05 22:15:58 +00:00
EndFunction
2021-10-05 22:59:59 +00:00
Function AddSongToList(Scene songScene)
If songScene == LastSongScene1 || songScene == LastSongScene2 || songScene == LastSongScene3
Return ; Has been already played recently
EndIf
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
If nBardSongsTotal >= BardSongList.Length
Debug.Notification("ERROR BardDialogue: out of free slots for songs!")
Debug.Trace("ERROR BardDialogue: out of free slots for songs")
Return
EndIf
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
BardSongList[nBardSongsTotal] = songScene
nBardSongsTotal += 1
2021-10-05 22:15:58 +00:00
EndFunction
2021-10-05 22:59:59 +00:00
Function PickRandomSongFromSongList()
If nBardSongsTotal == 1
NextSongScene = BardSongList[0]
ElseIf nBardSongsTotal > 1
NextSongScene = BardSongList[Utility.RandomInt(0, nBardSongsTotal - 1)]
Else ; nBardSongsTotal < 1
NextSongScene = None
EndIf
EndFunction
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Actor Function GetSingingBardActor()
2023-12-08 02:57:30 +00:00
Return SingingBard.GetActorReference()
2021-10-05 22:59:59 +00:00
EndFunction
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Bool Function IsQuestAudienceLocation()
Location bardLoc = Location_Alias.GetLocation()
If bardLoc == _00E_FlusshaimTaverneLocation || bardLoc == _00E_DunevilleInteriorLocation || bardLoc == _00E_UEEntr_FalseDog_Location
Return True
Else
Return False
EndIf
2021-10-05 22:15:58 +00:00
EndFunction
2021-10-05 22:59:59 +00:00
2021-10-05 22:15:58 +00:00
;=====================================================================================
2021-10-05 22:59:59 +00:00
; NEXT SONG LOCK
2021-10-05 22:15:58 +00:00
;=====================================================================================
2021-10-05 22:59:59 +00:00
Bool bNextSongUpdateLocked = False
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Function LockNextSongUpdate()
While bNextSongUpdateLocked
Utility.WaitMenuMode(0.1)
EndWhile
bNextSongUpdateLocked = True
EndFunction
2021-10-05 22:15:58 +00:00
2021-10-05 22:59:59 +00:00
Function UnlockNextSongUpdate()
bNextSongUpdateLocked = False
EndFunction