Scriptname _00E_RandomConv_DebugTrackingSC extends Quest Conditional


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

Event OnStoryDialogue(Location akLocation, ObjectReference akActor1, ObjectReference akActor2)
	SpamCount += 1

	RegisterForModEvent("IdleChatterOff", "OnIdleChatterOff")
	If NextQuestGlobal
		RegisterForModEvent("NextRandomConversationGlobalChanged", "OnNextRandomConversationGlobalChanged")
	EndIf
	RegisterForSingleUpdate(3 * 60)
EndEvent

Event OnUpdate()
	; Force-stop no matter what (probably the quest got stuck)
	OnSceneEnd() 
EndEvent

Event OnIdleChatterOff(String eventName, String strArg, Float numArg, Form sender)
	; Abandon waiting and force-stop if idle chatter just became disabled
	OnSceneEnd()
EndEvent

Event OnNextRandomConversationGlobalChanged(String eventName, String strArg, Float numArg, Form sender)
	; Abandon waiting and force-stop if some other conversation just updated the same NextQuestGlobal
	If NextQuestGlobal.GetValue() > GameDaysPassed.GetValue()
		OnSceneEnd()
	EndIf
EndEvent


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

Function UpdateNextTimes()
	Float dayPassed = GameDaysPassed.GetValue()

	If NextQuestGlobal
		NextQuestGlobal.SetValue(dayPassed + BRANCH_PERIOD)
	EndIf

	If NextPackageGlobal
		NextPackageGlobal.SetValue(dayPassed + PACKAGE_PERIOD)
	EndIf

	RunCount += 1
	If IsRareConversation
		NextRunTime = dayPassed + QUEST_PERIOD_RARE * (RunCount as Float)
	Else
		; The formula: p * (r + 1) / 2, which means:
		; QUEST_PERIOD cooldown between the 1st and 2nd run of the conversasion
		; then it adds half of QUEST_PERIOD to the cooldown for each next run
		NextRunTime = dayPassed + QUEST_PERIOD * ((RunCount as Float) + 1.0) / 2.0 
	EndIf

	If NextQuestGlobal
		; Notify other running quests from the same branch that we just started this one
		SendModEvent("NextRandomConversationGlobalChanged")
	EndIf
EndFunction

Float Function CalcCooldownPeriod(Float fWaitPeriod, Float fPenaltyPerRun)
	Return fWaitPeriod + (RunCount as Float) * fPenaltyPerRun
EndFunction

Function OnSceneStart()
	SpamCount = 0 ; Reset spam counter on successful start of the scene

	UnregisterForAllModEvents()
	RegisterForSingleUpdate(3 * 60)
	UpdateNextTimes()
EndFunction

Function OnSceneEnd()
	If SpamCount > MAX_SPAM_COUNT
		Float nextTime = GameDaysPassed.GetValue() + 0.25

		If NextQuestGlobal && NextQuestGlobal.GetValue() < nextTime
			NextQuestGlobal.SetValue(nextTime)
		EndIf

		If NextPackageGlobal && NextPackageGlobal.GetValue() < nextTime
			NextPackageGlobal.SetValue(nextTime)
		EndIf

		If NextRunTime < nextTime
			NextRunTime = nextTime
		EndIf

		SpamCount = 0
	EndIf

	UnregisterForAllModEvents()
	UnregisterForUpdate()
	UnregisterForUpdateGameTime()
	Stop()
EndFunction


;=====================================================================================
;              							PROPERTIES                  					 
;=====================================================================================

Float Property BRANCH_PERIOD = 1.0 AutoReadOnly ; In days
Float Property QUEST_PERIOD = 7.0 AutoReadOnly ; In days
Float Property QUEST_PERIOD_RARE = 15.0 AutoReadOnly ; In days
Float Property PACKAGE_PERIOD = 3.0 AutoReadOnly ; In days

GlobalVariable Property NextQuestGlobal Auto
GlobalVariable Property NextPackageGlobal Auto
GlobalVariable Property GameDaysPassed Auto

Bool Property IsRareConversation = False Auto

Float Property NextRunTime Auto Conditional Hidden

Int Property RunCount Auto Hidden
Int Property SpamCount Auto Hidden
Int Property MAX_SPAM_COUNT = 10 AutoReadOnly