443 lines
No EOL
14 KiB
Lua
443 lines
No EOL
14 KiB
Lua
local tonumber = tonumber
|
||
local tostring = tostring
|
||
local mathFloor = math.floor
|
||
local tableInsert = table.insert
|
||
local tableRemove = table.remove
|
||
local next = next
|
||
local CSMovieXMovieManagerInstance = CS.Movie.XMovieManager.Instance
|
||
|
||
local UI_MOVIE = "UiMovie"
|
||
local RESOLUTION_RATIO = CS.XResolutionManager.OriginWidth / CS.XResolutionManager.OriginHeight / CS.XUiManager.DefaultScreenRatio
|
||
local TIMELINE_SECONDS_TRANS = 1 / 60
|
||
local IS_DEBUG = XMain.IsDebug
|
||
|
||
local ActionClass = {
|
||
[101] = require("XMovieActions/XMovieActionBgSwitch"), --背景切换
|
||
[102] = require("XMovieActions/XMovieActionTheme"), --章节主题
|
||
|
||
[201] = require("XMovieActions/XMovieActionActorAppear"), --演员出现
|
||
[202] = require("XMovieActions/XMovieActionActorDisappear"), --演员消失
|
||
[203] = require("XMovieActions/XMovieActionActorShift"), --演员位移
|
||
[204] = require("XMovieActions/XMovieActionActorChangeFace"), --演员表情
|
||
|
||
[301] = require("XMovieActions/XMovieActionDialog"), --普通对话
|
||
[302] = require("XMovieActions/XMovieActionSelection"), --选择分支对话
|
||
[303] = require("XMovieActions/XMovieActionDelaySkip"), --延迟跳转
|
||
[304] = require("XMovieActions/XMovieActionFullScreenDialog"), --全屏字幕
|
||
[305] = require("XMovieActions/XMovieActionYieldResume"), --挂起/恢复
|
||
|
||
[401] = require("XMovieActions/XMovieActionSoundPlay"), --BGM/CV/音效 播放
|
||
[402] = require("XMovieActions/XMovieActionAudioInterrupt"), --BGM/CV/音效 打断
|
||
|
||
[501] = require("XMovieActions/XMovieActionEffectPlay"), --特效播放
|
||
[502] = require("XMovieActions/XMovieActionAnimationPlay"), --UI动画播放
|
||
[503] = require("XMovieActions/XMovieActionVideoPlay"), --视频播放
|
||
[504] = require("XMovieActions/XMovieActionSetGray"), --灰度设置
|
||
[505] = require("XMovieActions/XMovieActionUnLoad"), --动效卸载
|
||
[506] = require("XMovieActions/XMovieActionPrefabAnimation"), --预制体动画
|
||
|
||
[601] = require("XMovieActions/XMovieActionStaff"), --staff职员表
|
||
}
|
||
|
||
--可以通过上一页返回到的节点
|
||
local MovieBackFilter = {
|
||
[301] = true, --普通对话
|
||
}
|
||
|
||
XMovieManagerCreator = function()
|
||
local AllMovieActions = {}
|
||
local ActionIdToIndexDics = {}
|
||
|
||
local CurPlayingMovieId
|
||
local CurPlayingActionIndex
|
||
local AutoPlay
|
||
local WaitToPlayList = {}
|
||
local DelaySelectionDic = {}
|
||
local ReviewDialogList = {}
|
||
local EndCallBack
|
||
local IsPlaying
|
||
local IsYield
|
||
local IsPause = false
|
||
local YieldCallBack
|
||
local MovieBackStack = XStack.New()
|
||
|
||
local function InitMovieActions(movieId)
|
||
local movieActions = {}
|
||
local actionIdToIndexDic = {}
|
||
|
||
local findEnd = false
|
||
local movieCfg = XMovieConfigs.GetMovieCfg(movieId)
|
||
for index, actionData in ipairs(movieCfg) do
|
||
local actionClass = ActionClass[actionData.Type]
|
||
if not actionClass then
|
||
XLog.Error("XMovieManager.InitMovieActions 配置节点类型错误,找不到对应的节点,Type: " .. actionData.Type)
|
||
return
|
||
end
|
||
|
||
tableInsert(movieActions, actionClass.New(actionData))
|
||
actionIdToIndexDic[actionData.ActionId] = index
|
||
|
||
if actionData.IsEnd ~= 0 then
|
||
findEnd = true
|
||
end
|
||
end
|
||
|
||
if not findEnd then
|
||
XLog.Error("XMovieManager.InitMovieActions error:没有配置结束标记IsEnd, movieId: ", movieId)
|
||
return
|
||
end
|
||
|
||
AllMovieActions[movieId] = movieActions
|
||
ActionIdToIndexDics[movieId] = actionIdToIndexDic
|
||
|
||
return movieActions
|
||
end
|
||
|
||
local function GetMovieActions(movieId)
|
||
if not AllMovieActions[movieId] then
|
||
InitMovieActions(movieId)
|
||
end
|
||
|
||
if not AllMovieActions[movieId] then
|
||
XLog.Error("XMovieManager GetMovieActions error:actions not exsit, movieId is: ", movieId)
|
||
return
|
||
end
|
||
|
||
return AllMovieActions[movieId]
|
||
end
|
||
|
||
local function GetActionIndexById(movieId, actionId)
|
||
local dic = ActionIdToIndexDics[movieId]
|
||
if not dic then
|
||
XLog.Error("XMovieManager GetActionIndexById error:dic not exsit, movieId is: " .. movieId .. ", actionId is: " .. actionId)
|
||
return
|
||
end
|
||
|
||
local index = dic[actionId]
|
||
if not index then
|
||
XLog.Error("XMovieManager GetActionIndexById error:index not exsit, actionId is: " .. actionId)
|
||
end
|
||
return index
|
||
end
|
||
|
||
local function OnPlayBegin(movieId, hideSkipBtn)
|
||
CurPlayingMovieId = movieId
|
||
CurPlayingActionIndex = 1
|
||
WaitToPlayList = GetMovieActions(movieId)
|
||
ReviewDialogList = {}
|
||
MovieBackStack:Clear()
|
||
IsPlaying = true
|
||
IsPause = false
|
||
CsXGameEventManager.Instance:Notify(XEventId.EVENT_MOVIE_BEGIN, movieId)
|
||
XEventManager.DispatchEvent(XEventId.EVENT_MOVIE_BEGIN, movieId)
|
||
if not XLuaUiManager.IsUiShow(UI_MOVIE) then
|
||
XLuaUiManager.Open(UI_MOVIE, hideSkipBtn)
|
||
end
|
||
end
|
||
|
||
local function OnPlayEnd()
|
||
if not CurPlayingMovieId then return end
|
||
|
||
CurPlayingMovieId = nil
|
||
CurPlayingActionIndex = nil
|
||
AutoPlay = nil
|
||
ReviewDialogList = {}
|
||
DelaySelectionDic = {}
|
||
WaitToPlayList = {}
|
||
IsPlaying = nil
|
||
IsYield = nil
|
||
IsPause = false
|
||
YieldCallBack = nil
|
||
MovieBackStack:Clear()
|
||
|
||
CsXGameEventManager.Instance:Notify(XEventId.EVENT_MOVIE_END)
|
||
XEventManager.DispatchEvent(XEventId.EVENT_MOVIE_END)
|
||
|
||
if XLuaUiManager.IsUiShow(UI_MOVIE) then
|
||
XLuaUiManager.Close(UI_MOVIE)
|
||
end
|
||
end
|
||
|
||
--剧情UI完全关闭,所有节点清理行为结束
|
||
local function AfterUiClosed()
|
||
if EndCallBack then
|
||
EndCallBack()
|
||
EndCallBack = nil
|
||
end
|
||
end
|
||
|
||
local function DoAction(ignoreLock)
|
||
if not CurPlayingActionIndex or not next(WaitToPlayList) then
|
||
OnPlayEnd()
|
||
return
|
||
end
|
||
|
||
if IsYield then
|
||
return
|
||
end
|
||
|
||
if IsPause then
|
||
return
|
||
end
|
||
local action = WaitToPlayList[CurPlayingActionIndex]
|
||
|
||
if not ignoreLock and action:IsWaiting() then
|
||
return
|
||
end
|
||
|
||
if action:Destroy() then
|
||
if action:IsEnding() then
|
||
OnPlayEnd()
|
||
return
|
||
end
|
||
MovieBackStack:Push(CurPlayingActionIndex)
|
||
local indexChanged
|
||
|
||
local selectedActionId = action:GetSelectedActionId()
|
||
if selectedActionId ~= 0 then
|
||
CurPlayingActionIndex = GetActionIndexById(CurPlayingMovieId, selectedActionId)
|
||
indexChanged = true
|
||
end
|
||
|
||
local delaySelectedActionId = action:GetDelaySelectActionId()
|
||
if delaySelectedActionId ~= 0 then
|
||
CurPlayingActionIndex = GetActionIndexById(CurPlayingMovieId, delaySelectedActionId)
|
||
indexChanged = true
|
||
end
|
||
|
||
local resumeActionId = action:GetResumeActionId()
|
||
if resumeActionId ~= 0 then
|
||
CurPlayingActionIndex = GetActionIndexById(CurPlayingMovieId, resumeActionId)
|
||
indexChanged = true
|
||
end
|
||
|
||
if not indexChanged then
|
||
local nextActionId = action:GetNextActionId()
|
||
if nextActionId ~= 0 then
|
||
CurPlayingActionIndex = GetActionIndexById(CurPlayingMovieId, nextActionId)
|
||
indexChanged = true
|
||
end
|
||
end
|
||
|
||
if not indexChanged then
|
||
CurPlayingActionIndex = CurPlayingActionIndex + 1
|
||
end
|
||
|
||
action = WaitToPlayList[CurPlayingActionIndex]
|
||
if not action then
|
||
OnPlayEnd()
|
||
return
|
||
end
|
||
end
|
||
|
||
action:ChangeStatus()
|
||
end
|
||
|
||
local XMovieManager = {}
|
||
|
||
function XMovieManager.Init()
|
||
XEventManager.AddEventListener(XEventId.EVENT_MOVIE_BREAK_BLOCK, DoAction)
|
||
XEventManager.AddEventListener(XEventId.EVENT_MOVIE_UI_CLOSED, AfterUiClosed)
|
||
end
|
||
|
||
local function PlayOldMovie(movieId, cb)
|
||
if not CSMovieXMovieManagerInstance:CheckMovieExist(movieId) then return end
|
||
CSMovieXMovieManagerInstance:PlayById(movieId, function()
|
||
if cb then cb() end
|
||
end)
|
||
end
|
||
|
||
local function PlayNewMovie(movieId, cb, yieldCb, hideSkipBtn)
|
||
EndCallBack = cb
|
||
YieldCallBack = yieldCb
|
||
OnPlayBegin(movieId, hideSkipBtn)
|
||
end
|
||
|
||
function XMovieManager.PlayMovie(movieId, cb, yieldCb, hideSkipBtn)
|
||
movieId = tostring(movieId)
|
||
if XMovieConfigs.CheckMovieConfigExist(movieId) then
|
||
PlayNewMovie(movieId, cb, yieldCb, hideSkipBtn)
|
||
else
|
||
PlayOldMovie(movieId, cb)
|
||
end
|
||
end
|
||
|
||
function XMovieManager.StopMovie()
|
||
if not XMovieManager.IsPlayingMovie() then return end
|
||
if not XLuaUiManager.IsUiShow(UI_MOVIE) then return end
|
||
OnPlayEnd()
|
||
end
|
||
|
||
function XMovieManager.BackToLastAction()
|
||
local curAction = WaitToPlayList[CurPlayingActionIndex]
|
||
local lastId = MovieBackStack:Peek()
|
||
if lastId ~= CurPlayingActionIndex then
|
||
curAction:OnUndo()
|
||
curAction:OnReset()
|
||
end
|
||
if MovieBackStack:Count() == 0 then
|
||
CurPlayingActionIndex = 1
|
||
end
|
||
while(MovieBackStack:Count() ~= 0) do
|
||
local currIndex = MovieBackStack:Pop()
|
||
local action = WaitToPlayList[currIndex]
|
||
action:OnUndo()
|
||
action:OnReset()
|
||
if MovieBackFilter[action:GetType()] then
|
||
CurPlayingActionIndex = currIndex
|
||
break
|
||
end
|
||
if MovieBackStack:Count() == 0 then
|
||
CurPlayingActionIndex = 1
|
||
break
|
||
end
|
||
end
|
||
XEventManager.DispatchEvent(XEventId.EVENT_MOVIE_BREAK_BLOCK)
|
||
end
|
||
|
||
local function IsPlayingNewMovie()
|
||
return IsPlaying
|
||
end
|
||
|
||
local function IsPlayingOldMovie()
|
||
return CSMovieXMovieManagerInstance:IsPlayingMovie()
|
||
end
|
||
|
||
function XMovieManager.IsPlayingMovie()
|
||
return IsPlayingNewMovie() or IsPlayingOldMovie()
|
||
end
|
||
|
||
function XMovieManager.IsMovieYield()
|
||
if not XMovieManager.IsPlayingMovie() then return false end
|
||
return IsYield or false
|
||
end
|
||
|
||
function XMovieManager.YiledMovie()
|
||
if not YieldCallBack then return end --没有恢复回调时不允许挂起
|
||
|
||
IsYield = true
|
||
|
||
YieldCallBack()
|
||
YieldCallBack = nil
|
||
end
|
||
|
||
function XMovieManager.IsMoviePause()
|
||
if not XMovieManager.IsPlayingMovie() then return false end
|
||
return IsPause or false
|
||
end
|
||
|
||
function XMovieManager.SetMoviePause(isPause)
|
||
IsPause = isPause
|
||
end
|
||
|
||
function XMovieManager.SwitchMovieState()
|
||
IsPause = not IsPause
|
||
local action = WaitToPlayList[CurPlayingActionIndex]
|
||
if (not IsPause) and action:CanContinue() then
|
||
DoAction()
|
||
end
|
||
end
|
||
|
||
function XMovieManager.ResumeMovie(index)
|
||
if not IsPlayingNewMovie() then
|
||
if IsPlayingOldMovie() then
|
||
XLog.Error("XMovieManager.ResumeMovie Error: 老版剧情不支持挂起恢复操作")
|
||
return
|
||
end
|
||
|
||
XLog.Error("XMovieManager.ResumeMovie Error: 当前没有播放中的剧情")
|
||
return
|
||
end
|
||
|
||
local action = WaitToPlayList[CurPlayingActionIndex]
|
||
if not IsYield or not action.ResumeAtIndex then
|
||
XLog.Error("XMovieManager.ResumeMovie Error: 当前没有挂起中的剧情, action: ", action)
|
||
return
|
||
end
|
||
|
||
IsYield = nil
|
||
action:ResumeAtIndex(index)
|
||
DoAction()
|
||
end
|
||
|
||
function XMovieManager.PushInReviewDialogList(roleName, dialogContent)
|
||
roleName = roleName and roleName ~= "" and roleName .. ": " or ""
|
||
dialogContent = dialogContent and dialogContent ~= "" and '"' .. dialogContent .. '"' or ""
|
||
|
||
local data = {
|
||
RoleName = roleName,
|
||
Content = dialogContent,
|
||
}
|
||
tableInsert(ReviewDialogList, data)
|
||
end
|
||
|
||
function XMovieManager.RemoveFromReviewDialogList()
|
||
if ReviewDialogList and #ReviewDialogList > 0 then
|
||
tableRemove(ReviewDialogList)
|
||
end
|
||
end
|
||
|
||
function XMovieManager.DelaySelectAction(key, actionId)
|
||
DelaySelectionDic[key] = actionId
|
||
end
|
||
|
||
function XMovieManager.GetDelaySelectActionId(key)
|
||
local actionId = DelaySelectionDic[key]
|
||
if actionId then
|
||
DelaySelectionDic[key] = nil
|
||
else
|
||
actionId = 0
|
||
end
|
||
return actionId
|
||
end
|
||
|
||
function XMovieManager.SwitchAutoPlay()
|
||
AutoPlay = not AutoPlay
|
||
local action = WaitToPlayList[CurPlayingActionIndex]
|
||
if action and action:CanContinue() then
|
||
XEventManager.DispatchEvent(XEventId.EVENT_MOVIE_AUTO_PLAY, AutoPlay)
|
||
end
|
||
end
|
||
|
||
function XMovieManager.IsAutoPlay()
|
||
return AutoPlay
|
||
end
|
||
|
||
function XMovieManager.GetReviewDialogList()
|
||
return ReviewDialogList
|
||
end
|
||
|
||
function XMovieManager.ReplacePlayerName(str)
|
||
return XUiHelper.ReplaceWithPlayerName(str, XMovieConfigs.PLAYER_NAME_REPLACEMENT)
|
||
end
|
||
|
||
function XMovieManager.Fit(width)
|
||
return width * RESOLUTION_RATIO
|
||
end
|
||
|
||
function XMovieManager.ParamToNumber(param)
|
||
return param and param ~= "" and tonumber(param) or 0
|
||
end
|
||
|
||
function XMovieManager.TransTimeLineSeconds(time)
|
||
time = time or 0
|
||
local interger = mathFloor(time)
|
||
local decimal = time - interger
|
||
return interger + TIMELINE_SECONDS_TRANS * decimal
|
||
end
|
||
|
||
function XMovieManager.ReloadMovies()
|
||
if not IS_DEBUG then return end
|
||
|
||
AllMovieActions = {}
|
||
ActionIdToIndexDics = {}
|
||
XMovieConfigs.DeleteMovieCfgs()
|
||
end
|
||
|
||
function XMovieManager.GetMovieDescription()
|
||
return XMovieConfigs.GetMovieSkipSkipDesc(CurPlayingMovieId)
|
||
end
|
||
|
||
XMovieManager.Init()
|
||
return XMovieManager
|
||
end |