@@ -88,11 +88,11 @@ BSTEventResult QuestService::OnEvent(const TESQuestStartStopEvent* apEvent, cons
8888
8989
9090 spdlog::info (__FUNCTION__ " : quest {} formId: {:X}, questStage: {}, questType: {}, name: {}" ,
91- pQuest->IsStopped () ? " stopped" : " started" ,
92- pQuest->formID ,
93- pQuest->currentStage ,
94- static_cast <std::underlying_type_t <TESQuest::Type>>(pQuest->type ),
95- pQuest->fullName .value .AsAscii ());
91+ pQuest->IsStopped () ? " stopped" : " started" ,
92+ pQuest->formID ,
93+ pQuest->currentStage ,
94+ static_cast <std::underlying_type_t <TESQuest::Type>>(pQuest->type ),
95+ pQuest->fullName .value .AsAscii ());
9696
9797 m_world.GetRunner ().Queue ([&, formId = pQuest->formID , stageId = pQuest->currentStage ,
9898 stopped = pQuest->IsStopped (), type = pQuest->type ]()
@@ -137,22 +137,6 @@ BSTEventResult QuestService::OnEvent(const TESQuestStageEvent* apEvent, const Ev
137137 if (IsNonSyncableQuest (pQuest))
138138 return BSTEventResult::kOk ;
139139
140- // Party leaders can always advance quests. Members can only advance quest stages when their controls are enabled
141- // This prevents party members from interfering with cutscenes (which almost always freeze players,
142- // and almost always end with a quest stage advance which can catch things up)
143- const bool canAdvanceQuestStages =
144- m_world.Get ().GetPartyService ().IsLeader () || PlayerControls::IsMovementControlsEnabled ();
145-
146- if (!canAdvanceQuestStages)
147- {
148- spdlog::info (__FUNCTION__ " : quest update by member blocked while player controls disabled, "
149- " quest gameId {:X} questStage {} questType {} formId {:X}, name {}" ,
150- Id.LogFormat (), pQuest->currentStage ,
151- static_cast <std::underlying_type_t <TESQuest::Type>>(pQuest->type ),
152- pQuest->formID , pQuest->fullName .value .AsAscii ());
153- return BSTEventResult::kOk ;
154- }
155-
156140 if (pQuest->type == TESQuest::Type::None || pQuest->type == TESQuest::Type::Miscellaneous)
157141 {
158142 spdlog::info (__FUNCTION__ " : queuing type none/misc quest update gameId {:X} questStage {} "
@@ -162,7 +146,6 @@ BSTEventResult QuestService::OnEvent(const TESQuestStageEvent* apEvent, const Ev
162146 pQuest->fullName .value .AsAscii ());
163147 }
164148
165-
166149 spdlog::info (__FUNCTION__ " : quest updated formId: {:X}, questStage: {}, questType: {}, name: {}" ,
167150 pQuest->formID , pQuest->currentStage , static_cast <std::underlying_type_t <TESQuest::Type>>(pQuest->type ), pQuest->fullName .value .AsAscii ());
168151
@@ -203,8 +186,20 @@ void QuestService::OnQuestUpdate(const NotifyQuestUpdate& aUpdate) noexcept
203186 aUpdate.ClientQuestType , formId, pQuest->fullName .value .AsAscii ());
204187 }
205188
189+ // Don't accept decreases in quest stage while playing a scene. This can abosolutely happen
190+ // as Members & Leader desync while stepping through complex long-running scenes. Disabling
191+ // because we're in a Scene that generate its own quest stage changes, and presumably the
192+ // scene is playing for all members. When they aren't perfectly in sync or due to network
193+ // delays you can receive an earlier stage from the leader that just took a while to get here.
206194 bool bResult = false ;
207195 bool bRunning = pQuest->getState () == TESQuest::State::Running;
196+ if (bRunning && aUpdate.Status != NotifyQuestUpdate::Stopped && aUpdate.Stage < pQuest->currentStage && !PlayerControls::IsMovementControlsEnabled ())
197+ {
198+ spdlog::info (__FUNCTION__ " : suppressing quest stage rewind while playing a scene gameId: {:X}, questStage: {}, questStatus: {}, questType: {}, formId: {:X}, name: {}" ,
199+ aUpdate.Id .LogFormat (), aUpdate.Stage , aUpdate.Status , aUpdate.ClientQuestType , formId, pQuest->fullName .value .AsAscii ());
200+ return ;
201+ }
202+
208203 switch (aUpdate.Status )
209204 {
210205 case NotifyQuestUpdate::Started:
0 commit comments