4
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

286 lines
9.2 KiB

Scriptname _00E_BardDialogueFunctions extends Quest Conditional
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
ReferenceAlias Property SingingBard Auto
LocationAlias Property Location_Alias Auto
Quest Property BardAudience Auto
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
Idle Property IdleStop Auto
Scene[] BardSongList
Int nBardSongsTotal
Bool bSongHasQuestAudience = False
Bool bQuestAudienceCheering = False
Scene NextSongScene = None
Scene Property LastSongScene1 Auto Conditional Hidden
Scene LastSongScene2 = None
Scene LastSongScene3 = None
Int Property QUEST_AUDIENCE_CHANCE = 67 AutoReadOnly
;=====================================================================================
; FUNCTIONS
;=====================================================================================
Function Setup(Actor akBard, Scene _LastSongScene)
bSongHasQuestAudience = False
bQuestAudienceCheering = False
NextSongScene = None
LastSongScene1 = _LastSongScene
LastSongScene2 = None
LastSongScene3 = None
SingingBard.ForceRefTo(akBard)
PlayRandomSong(0.1)
EndFunction
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
BardAudience.SetStage(iAudienceInitialStage)
EndIf
EndIf
EndIf
bQuestAudienceCheering = False
EndFunction
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
Function CheerAudience() ; When a song ends normally, time for the audience to cheer. Called from the scenes.
SendModEvent("BardSongApplaud")
If IsQuestAudienceLocation() && BardAudience.IsRunning()
Int iCurrentAudienceStage = BardAudience.GetStage()
If iCurrentAudienceStage >= 10 && iCurrentAudienceStage <= 20
BardAudience.SetStage(100)
bQuestAudienceCheering = True
EndIf
EndIf
EndFunction
Function OnSongEnd() ; When a song ends normally or is interrupted. Called from the scenes.
Actor akBard = SingingBard.GetActorRef() ; If akBard is None in OnSongEnd, most likely it's the player just left the cell and the quest is stopping
Bool bLongDelay = False
If akBard
akBard.PlayIdle(IdleStop)
EndIf
SendModEvent("BardSongEnded")
If bSongHasQuestAudience == False && BardAudience.IsRunning() && BardAudience.GetStage() < 100
BardAudience.Stop()
EndIf
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)
EndIf
EndFunction
Function PlayRandomSong(Float fDelay)
LockNextSongUpdate()
If NextSongScene == None
BuildSongList(False)
PickRandomSongFromSongList()
EndIf
UnlockNextSongUpdate()
RegisterForSingleUpdate(fDelay)
EndFunction
Function PlayRequestedSong(Scene requestedSongScene)
LockNextSongUpdate()
If requestedSongScene
NextSongScene = requestedSongScene
Else
BuildSongList(True)
PickRandomSongFromSongList()
EndIf
UnlockNextSongUpdate()
RegisterForSingleUpdate(0.1)
EndFunction
Event OnUpdate()
Actor akBard = SingingBard.GetActorRef()
If akBard == None
Stop()
Return
EndIf
If akBard.IsInDialogueWithPlayer()
RegisterForSingleUpdate(1.0)
Return
EndIf
bSongHasQuestAudience = False
If NextSongScene
NextSongScene.ForceStart()
EndIf
EndEvent
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
If bOnlyVocalSongs == False
AddSongToList(BardDialogue_VatyraInstrumental)
AddSongToList(BardDialogue_WaywardWandererInstrumental)
AddSongToList(BardDialogue_TheAgedManInstrumental)
AddSongToList(BardDialogue_LastSunsetInstrumental)
AddSongToList(BardDialogue_Instrumental20) ; Drum Instrumental
EndIf
EndFunction
Function AddSongToList(Scene songScene)
If songScene == LastSongScene1 || songScene == LastSongScene2 || songScene == LastSongScene3
Return ; Has been already played recently
EndIf
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
BardSongList[nBardSongsTotal] = songScene
nBardSongsTotal += 1
EndFunction
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
Actor Function GetSingingBardActor()
Return SingingBard.GetActorRef()
EndFunction
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
EndFunction
;=====================================================================================
; NEXT SONG LOCK
;=====================================================================================
Bool bNextSongUpdateLocked = False
Function LockNextSongUpdate()
While bNextSongUpdateLocked
Utility.WaitMenuMode(0.1)
EndWhile
bNextSongUpdateLocked = True
EndFunction
Function UnlockNextSongUpdate()
bNextSongUpdateLocked = False
EndFunction