local g_loggingEnabled = false ZO_SceneManager_Follower = ZO_SceneManager_Base:Subclass() function ZO_SceneManager_Follower:Initialize(...) ZO_SceneManager_Base.Initialize(self, ...) EVENT_MANAGER:RegisterForEvent("SceneManager", EVENT_LEADER_TO_FOLLOWER_SYNC, function(eventId, ...) self:OnLeaderToFollowerSync(...) end) end function ZO_SceneManager_Follower:OnLeaderToFollowerSync(messageOrigin, syncType, currentSceneName, nextSceneName, sequenceNumber, currentSceneFragmentsComplete) if messageOrigin ~= ZO_REMOTE_SCENE_CHANGE_ORIGIN then local currentScene = self:GetScene(currentSceneName) local nextScene = self:GetScene(nextSceneName) --This case is just updating the destination for a show in progress if syncType == REMOTE_SCENE_SYNC_TYPE_CHANGE_NEXT_SCENE then self:Log(string.format("Changed Next Scene to %s", nextSceneName)) if nextScene == nil then --if the next scene is a scene that we don't know then use the base scene instead self:Log(string.format("Sync Next Scene (%s) Unknown. Setting Next to Base Scene", nextSceneName), self.baseScene:GetName()) nextScene = self.baseScene end self:SetNextScene(nextScene) -- When we start hiding the current scene we update its fragments based on what the next scene is -- If the next scene has the fragments then we will not hide them because they will be showing -- However, it is possible that the next scene is changed before we fully hide the current scene -- so we need to refresh the current scene's fragments so they hide/show as appropriate for the next scene if self.currentScene and self.currentScene:IsHiding() then self.currentScene:RefreshFragments() end else --This case is for a new hide or show, and also updating the fragment complete state of the current scene local syncTypeName = syncType == REMOTE_SCENE_SYNC_TYPE_SHOW_SCENE and "Show" or "Hide" self:Log(string.format("Sync %s: Current(%s) Next(%s) FragsDone(%s) Seq(%d)", syncTypeName, currentSceneName, nextSceneName, currentSceneFragmentsComplete and "T" or "F", sequenceNumber)) -- set current scene if currentSceneName == ZO_REMOTE_SCENE_NO_SCENE_IDENTIFIER then self:SetCurrentScene(nil) else local currentSceneToSet = currentScene if currentSceneToSet == nil then --if the current scene is a scene that we don't know then use the base scene instead self:Log(string.format("Sync Current Scene (%s) Unknown. Setting Current to Base Scene", currentSceneName), self.baseScene:GetName()) currentSceneToSet = self.baseScene end self:SetCurrentScene(currentSceneToSet) end -- set next scene if nextSceneName == ZO_REMOTE_SCENE_NO_SCENE_IDENTIFIER then self:SetNextScene(nil) else if nextScene == nil then --if the next scene is a scene that we don't know then use the base scene instead self:Log(string.format("Sync Next Scene (%s) Unknown. Setting Next to Base Scene", nextSceneName), self.baseScene:GetName()) nextScene = self.baseScene end self:SetNextScene(nextScene) end -- determine if we need to show/hide the current scene if syncType == REMOTE_SCENE_SYNC_TYPE_SHOW_SCENE then if currentScene == nil then --It's likely we were told about a scene changing that we don't have in our SceneManager, --so we will use our base scene (the empty scene) so we don't interfere with the unknown scene. --This is basically deactivating the scene manager until we hear about something we know. if not self.baseScene:IsShowing() then self:Log(string.format("Sync Show Scene (%s) Unknown. Showing Base Scene", currentSceneName), self.baseScene:GetName()) self:ShowScene(self.baseScene, sequenceNumber) else self:Log(string.format("Sync Show Scene (%s) Unknown. Base Scene Already Shown", currentSceneName), self.baseScene:GetName()) end else --We were just told to show a scene we do know about. First get the base scene (the empty scene) out of the way --then show the requested scene. The empty scene will hide instantly. This is like reactivating the scene manager. if self.baseScene:IsShowing() then self:HideScene(self.baseScene, sequenceNumber) end if not currentScene:IsShowing() then self:ShowScene(currentScene, sequenceNumber) end end elseif syncType == REMOTE_SCENE_SYNC_TYPE_HIDE_SCENE then if currentScene then if not currentScene:IsHiding() then self:HideScene(currentScene, sequenceNumber) end else --Ignore any hides that we don't know about. The shows we don't know about control the activate/deactivate. self:Log(string.format("Sync Hide Scene (%s) Unknown. It had no effect!", currentSceneName)) end end -- update scene if its remote scene has finished it fragment transition if currentSceneFragmentsComplete then self:OnRemoteSceneFinishedFragmentTransition(messageOrigin, currentSceneName, sequenceNumber) end end end end function ZO_SceneManager_Follower:OnSceneStateHidden(scene) local lastSceneGroup = scene:GetSceneGroup() local nextSceneGroup if self.nextScene then nextSceneGroup = self.nextScene:GetSceneGroup() end if lastSceneGroup ~= nextSceneGroup then if lastSceneGroup ~= nil then lastSceneGroup:SetState(SCENE_GROUP_HIDDEN) end if nextSceneGroup ~= nil then nextSceneGroup:SetState(SCENE_GROUP_SHOWING) end end end -- We don't have a stack, so we can only really check if it's the current scene function ZO_SceneManager_Follower:IsSceneOnStack(sceneName) if self.currentScene and self.currentScene:GetName() == sceneName then return true end return false end -- Without our own stack we don't know if a scene was ever on it, so return false function ZO_SceneManager_Follower:WasSceneOnStack(sceneName) return false end -- Without a stack we can only really check if the scene is the current scene -- and is being replaced function ZO_SceneManager_Follower:WasSceneOnTopOfStack(sceneName) if self.currentScene and self.nextScene then return self.currentScene:GetName() == sceneName end return false end function ZO_SceneManager_Follower:Push(sceneName) MakeRemoteSceneRequest(ZO_REMOTE_SCENE_CHANGE_ORIGIN, REMOTE_SCENE_REQUEST_TYPE_PUSH, sceneName) self:Log("Request Remote Push", sceneName) end function ZO_SceneManager_Follower:SwapCurrentScene(newCurrentSceneName) MakeRemoteSceneRequest(ZO_REMOTE_SCENE_CHANGE_ORIGIN, REMOTE_SCENE_REQUEST_TYPE_SWAP, newCurrentSceneName) self:Log("Request Remote Swap", newCurrentSceneName) end function ZO_SceneManager_Follower:Show(sceneName) MakeRemoteSceneRequest(ZO_REMOTE_SCENE_CHANGE_ORIGIN, REMOTE_SCENE_REQUEST_TYPE_SHOW, sceneName) self:Log("Request Remote Show", sceneName) end function ZO_SceneManager_Follower:Hide(sceneName) MakeRemoteSceneRequest(ZO_REMOTE_SCENE_CHANGE_ORIGIN, REMOTE_SCENE_REQUEST_TYPE_HIDE, sceneName) self:Log("Request Remote Hide", sceneName) end function ZO_SceneManager_Follower:RequestShowLeaderBaseScene() MakeRemoteSceneRequest(ZO_REMOTE_SCENE_CHANGE_ORIGIN, REMOTE_SCENE_REQUEST_TYPE_SHOW_BASE_SCENE, "") self:Log("Request Remote Show Base Scene", "") end function ZO_SceneManager_Follower:SendFragmentCompleteMessage() local currentScene = self:GetCurrentScene() local currentSceneName = currentScene:GetName() NotifyThatFollowerFinishedFragmentTransition(ZO_REMOTE_SCENE_CHANGE_ORIGIN, currentSceneName, currentScene:GetSequenceNumber()) end function ZO_SceneManager_Follower:Log(message, sceneName) if WriteToInterfaceLog and g_loggingEnabled then if sceneName then WriteToInterfaceLog(string.format("%s - %s - %s", ZO_Scene_GetOriginColor():Colorize(GetString("SI_SCENEMANAGERMESSAGEORIGIN", ZO_REMOTE_SCENE_CHANGE_ORIGIN)), message, sceneName)) else WriteToInterfaceLog(string.format("%s - %s", ZO_Scene_GetOriginColor():Colorize(GetString("SI_SCENEMANAGERMESSAGEORIGIN", ZO_REMOTE_SCENE_CHANGE_ORIGIN)), message)) end end end