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