Scriptname _00E_HeroldScript extends Actor

Actor Property PlayerREF Auto
Scene[] Property HeroldScenes Auto
Package Property Ark_Herold_SpeakPackage Auto
Keyword Property LinkPerformanceSpot Auto
WorldSpace Property CapitalCityMarketArea Auto

Quest Property MQ09 Auto
Quest Property MQ12b Auto
Quest Property ArkGenericDialogue Auto

Bool DoOnce
Bool bPlayerIsInsideTrigger
Bool bPauseBetweenHeroldScenes
Bool bSiegeScenePlayed
Bool bWarScenePlayed
Scene scCurrentHeroldScene
Int iLastHeroldScene = -1


;=====================================================================================
;              							EVENTS                  					 
;=====================================================================================

State WaitBetweenScenes
	Event OnUpdate()
		SetPauseBetweenHeroldScenes(False)
	EndEvent

	Event OnUpdateGameTime()
		SetPauseBetweenHeroldScenes(False)
	EndEvent
EndState

State WaitPlayNext
	Event OnUpdate()
		TryPlayNextHeroldScene()
	EndEvent
EndState

Event OnPackageStart(Package akNewPackage)
	If akNewPackage == Ark_Herold_SpeakPackage && bPlayerIsInsideTrigger
		TryPlayNextHeroldScene()
	EndIf
EndEvent

Function OnHeroldSceneStart(Scene scSceneStarted) ; Called from the scenes
	ResetWaitState()

	scCurrentHeroldScene = scSceneStarted
	iLastHeroldScene = HeroldScenes.Find(scSceneStarted)
	If iLastHeroldScene == 4
		bSiegeScenePlayed = True
	ElseIf iLastHeroldScene == 3
		bWarScenePlayed = True
	EndIf
EndFunction

Function EndHeroldScene() ; Called from the scenes
	scCurrentHeroldScene = None
	SetPauseBetweenHeroldScenes(True)
EndFunction


;=====================================================================================
;              							FUNCTIONS                  					 
;=====================================================================================

Function _TryPlayNextHeroldScene()
	ObjectReference speakMarkerRef = GetLinkedRef(LinkPerformanceSpot)

	If scCurrentHeroldScene
		If scCurrentHeroldScene.IsPlaying()
			Return
		Else
			scCurrentHeroldScene = None
		EndIf
	EndIf

	If PlayerREF.GetWorldSpace() == CapitalCityMarketArea && GetCurrentPackage() == Ark_Herold_SpeakPackage && (bPauseBetweenHeroldScenes == False)
		ResetWaitState()

		If GetDistance(speakMarkerRef) < 150.0
			; ArkGenericDialogue start failsafe?
			If DoOnce == False 
				DoOnce = True
				If ArkGenericDialogue.GetCurrentStageID() < 5
					ArkGenericDialogue.SetCurrentStageID(5)
					Utility.Wait(1.0) ; Warm up ArkGenericDialogue
				EndIf
			EndIf

			; Try start new scene
			Int iNewScene = 0

			If MQ12b.GetCurrentStageID() >= 10
				If bSiegeScenePlayed == False
					iNewScene = 4
				Else
					iNewScene = GetNextHeroldScene(3, 4)
				EndIf
			ElseIf MQ09.GetCurrentStageID() >= 10
				If bWarScenePlayed == False
					iNewScene = 3
				Else
					iNewScene = GetNextHeroldScene(0, 3)
				EndIf
			Else
				iNewScene = GetNextHeroldScene(0, 2)
			EndIf

			scCurrentHeroldScene = HeroldScenes[iNewScene]
			scCurrentHeroldScene.ForceStart()
		EndIf

		; Serves both as a wait for the herold to approach the marker and as a failsafe if the scene is not started
		GoToState("WaitPlayNext")
		RegisterForSingleUpdate(5.0)
		If scCurrentHeroldScene
			Utility.Wait(1.0) ; Give some time for the scene to start before unlocking TryPlayNextHeroldScene
		EndIf
	EndIf
EndFunction

Int Function GetNextHeroldScene(Int iMinScene, Int iMaxScene)
	Int iNewScene = iLastHeroldScene + 1
	If iNewScene >= iMinScene && iNewScene <= iMaxScene
		Return iNewScene
	Else
		Return iMinScene
	EndIf
EndFunction

Bool bSceneUpdatesLocked = False

Function TryPlayNextHeroldScene()
	While bSceneUpdatesLocked
		Utility.Wait(1.0)
	EndWhile
	bSceneUpdatesLocked = True

	_TryPlayNextHeroldScene()

	bSceneUpdatesLocked = False
EndFunction

Function SetPlayerInsideTrigger(Bool _bPlayerIsInsideTrigger)
	bPlayerIsInsideTrigger = _bPlayerIsInsideTrigger
	If bPlayerIsInsideTrigger
		TryPlayNextHeroldScene()
	EndIf
EndFunction

Function SetPauseBetweenHeroldScenes(Bool _bPauseBetweenHeroldScenes)
	ResetWaitState()

	bPauseBetweenHeroldScenes = _bPauseBetweenHeroldScenes
	If bPauseBetweenHeroldScenes
		GoToState("WaitBetweenScenes")
		RegisterForSingleUpdateGameTime(0.5)
	Else
		TryPlayNextHeroldScene()
	EndIf
EndFunction

Function ResetWaitState()
	GoToState("")
	UnregisterForUpdateGameTime()
	UnregisterForUpdate()
EndFunction