581 lines
14 KiB
Lua
581 lines
14 KiB
Lua
local uiCtrl = require_ex('UI/Panels/Base/UICtrl')
|
|
local PANEL_ID = PanelId.AIBark
|
|
local TIMEOUT_TIME = 15
|
|
|
|
local SINGLE_CELL_TEXT_HEIGHT_LIMIT = 152
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl = HL.Class('AIBarkCtrl', uiCtrl.UICtrl)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl.s_messages = HL.StaticField(HL.Table) << {
|
|
|
|
[MessageConst.STOP_AI_BARK] = 'AudioStopSingleAIBark',
|
|
[MessageConst.ON_SCENE_LOAD_START] = 'StopAllAIBark',
|
|
[MessageConst.ALL_CHARACTER_DEAD] = 'StopAllAIBark',
|
|
[MessageConst.ON_TELEPORT_SQUAD] = 'StopAllAIBark',
|
|
[MessageConst.PLAY_CG] = 'StopAllAIBark',
|
|
[MessageConst.ON_PLAY_CUTSCENE] = 'StopAllAIBark',
|
|
[MessageConst.ON_DIALOG_START] = 'StopAllAIBark',
|
|
[MessageConst.SHOW_RADIO] = 'StopAllAIBark',
|
|
[MessageConst.HIDE_GUIDE_STEP] = 'StopAllAIBark',
|
|
[MessageConst.START_GUIDE_GROUP] = 'StopAllAIBark',
|
|
[MessageConst.ON_ULTIMATE_SKILL_START] = 'StopAllAIBark',
|
|
[MessageConst.ON_ULTIMATE_SKILL_END] = 'StopAllAIBark',
|
|
}
|
|
|
|
|
|
AIBarkCtrl.s_inMainHud = HL.StaticField(HL.Boolean) << false
|
|
|
|
|
|
AIBarkCtrl.s_uniqueId = HL.StaticField(HL.Number) << 0
|
|
|
|
|
|
AIBarkCtrl.m_cellCache = HL.Field(HL.Table)
|
|
|
|
|
|
AIBarkCtrl.m_waitingCacheCells = HL.Field(HL.Table)
|
|
|
|
|
|
AIBarkCtrl.m_waitingTable = HL.Field(HL.Table)
|
|
|
|
|
|
AIBarkCtrl.m_timeoutTimer = HL.Field(HL.Number) << -1
|
|
|
|
|
|
AIBarkCtrl.m_tween = HL.Field(HL.Any)
|
|
|
|
|
|
AIBarkCtrl.s_showByExecute = HL.StaticField(HL.Boolean) << false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl.m_curPlayingBarks = HL.Field(HL.Table)
|
|
|
|
|
|
|
|
AIBarkCtrl.OnInMainHudChanged = HL.StaticMethod(HL.Table) << function(arg)
|
|
local inMainHud = unpack(arg)
|
|
if inMainHud then
|
|
AIBarkCtrl.OnEnterMainHud()
|
|
else
|
|
AIBarkCtrl.OnLeaveMainHud()
|
|
end
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl.OnEnterMainHud = HL.StaticMethod() << function()
|
|
AIBarkCtrl.s_inMainHud = true
|
|
end
|
|
|
|
|
|
AIBarkCtrl.OnLeaveMainHud = HL.StaticMethod() << function()
|
|
AIBarkCtrl.s_inMainHud = false
|
|
local res, ctrl = UIManager:IsOpen(PANEL_ID)
|
|
if res then
|
|
ctrl:StopAllAIBark()
|
|
end
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl.ShowAIBark = HL.StaticMethod(HL.Table) << function(arg)
|
|
AIBarkCtrl.s_showByExecute = true
|
|
local ctrl = AIBarkCtrl.AutoOpen(PANEL_ID, {}, true)
|
|
AIBarkCtrl.s_showByExecute = false
|
|
local data = unpack(arg)
|
|
ctrl:DoShowAIBark(data)
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl.OnCreate = HL.Override(HL.Any) << function(self, arg)
|
|
self.m_cellCache = {}
|
|
self.m_curPlayingBarks = {}
|
|
self.m_waitingCacheCells = {}
|
|
self.m_waitingTable = {}
|
|
self.m_tween = nil
|
|
end
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl.StopAllAIBark = HL.Method(HL.Opt(HL.Any)) << function(self, _)
|
|
logger.info("StopAllAIBark, count: ", #self.m_curPlayingBarks)
|
|
local count = #self.m_curPlayingBarks
|
|
if count > 0 then
|
|
for i = 1, count do
|
|
local targetIndex = #self.m_curPlayingBarks
|
|
if targetIndex <= 0 then
|
|
break
|
|
end
|
|
self:_DoStopSingleAIBark(targetIndex)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl.OnShow = HL.Override() << function(self)
|
|
|
|
if DeviceInfo.usingTouch then
|
|
local pos = self.view.mask.transform.anchoredPosition
|
|
self.view.mask.transform.anchoredPosition = Vector2(self.view.config.MOBILE_MASK_POS_X, pos.y)
|
|
end
|
|
|
|
if AIBarkCtrl.s_showByExecute then
|
|
GameWorld.aiBarkManager:UpdateFullScreenUICD()
|
|
end
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl.OnHide = HL.Override() << function(self)
|
|
self:_Reset()
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl._ClearStopTimer = HL.Method(HL.Number) << function(self, index)
|
|
self:_ClearTimer(index)
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl._StartStopTimer = HL.Method(HL.Number, HL.Number).Return(HL.Number) << function(self, duration, uniqueId)
|
|
return self:_StartTimer(duration, function()
|
|
self:_StopLastAIBark(uniqueId)
|
|
end)
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl._StartTimeoutTimer = HL.Method() << function(self)
|
|
self:_ClearTimeoutTimer()
|
|
self.m_timeoutTimer = self:_StartTimer(TIMEOUT_TIME, function()
|
|
logger.info("AIBark timeout StopAllAIBark")
|
|
self:StopAllAIBark()
|
|
end)
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl._ClearTimeoutTimer = HL.Method() << function(self)
|
|
if self.m_timeoutTimer > 0 then
|
|
self:_ClearTimer(self.m_timeoutTimer)
|
|
end
|
|
|
|
self.m_timeoutTimer = -1
|
|
end
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl.StopAIBarkUI = HL.Method(HL.Table) << function(self, arg)
|
|
local barkTextId, audioStop = unpack(arg)
|
|
self:StopSingleAIBark(barkTextId, audioStop)
|
|
end
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl.AudioStopSingleAIBark = HL.Method(HL.Table) << function(self, arg)
|
|
local barkTextId, audioStop, audioInterrupt = unpack(arg)
|
|
self:StopSingleAIBark(barkTextId, audioInterrupt)
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl.StopSingleAIBark = HL.Method(HL.Any, HL.Opt(HL.Boolean)) << function(self, voId, audioInterrupt)
|
|
local removeIndex = 0
|
|
local barkTextId
|
|
if type(voId) == 'table' then
|
|
barkTextId = unpack(voId)
|
|
else
|
|
barkTextId = voId
|
|
end
|
|
for index, bark in pairs(self.m_curPlayingBarks) do
|
|
if bark.barkTextId == barkTextId then
|
|
removeIndex = index
|
|
|
|
self.m_curPlayingBarks[index].needStopVoice = false
|
|
if not bark.isLastSentence then
|
|
self.m_curPlayingBarks[index].isLastSentence = true
|
|
local existTime = Time.time - bark.startTime - bark.duration
|
|
if existTime > 0 then
|
|
self.m_curPlayingBarks[index].timerId = self:_StartStopTimer(existTime, bark.uniqueId)
|
|
else
|
|
self:_StopLastAIBark(bark.uniqueId, audioInterrupt)
|
|
end
|
|
|
|
else
|
|
self:_StopLastAIBark(bark.uniqueId, audioInterrupt)
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl.OnBarkStopped = HL.StaticMethod(HL.String) << function(barkId)
|
|
GameWorld.aiBarkManager:UpdateBarkEndTime(barkId)
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl._CheckHeight = HL.Method().Return(HL.Boolean) << function(self)
|
|
LayoutRebuilder.ForceRebuildLayoutImmediate(self.view.content.transform)
|
|
return self.view.content.transform.rect.height <= self.view.mask.rect.height
|
|
end
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl._TryShowSingleBark = HL.Method(CS.Beyond.Gameplay.AIBarkManager.AIBarkRuntimeData) << function(self, aiBarkData)
|
|
local barkId = aiBarkData.barkId
|
|
local barkTextId = aiBarkData.barkTextId
|
|
local charTemplateId = aiBarkData.charTemplateId
|
|
local tDuration = aiBarkData.duration
|
|
local voiceHandleId = aiBarkData.voiceHandleId
|
|
local isLastSentence = aiBarkData.isLastSentence
|
|
local res, data = Tables.aIBarkText:TryGetValue(barkTextId)
|
|
if res then
|
|
self:Show()
|
|
local cell = self:_GenCell()
|
|
local barkText = UIUtils.resolveTextCinematic(data.barkText)
|
|
local duration = tDuration
|
|
if duration <= 0 then
|
|
local originText = UIUtils.resolveOriginalText(barkText)
|
|
duration = UIUtils.getTextShowDuration(originText, 1)
|
|
end
|
|
|
|
AIBarkCtrl.s_uniqueId = AIBarkCtrl.s_uniqueId + 1
|
|
|
|
local bark = {
|
|
barkId = barkId,
|
|
cell = cell,
|
|
voiceHandleId = voiceHandleId,
|
|
barkTextId = barkTextId,
|
|
barkText = barkText,
|
|
isLastSentence = isLastSentence,
|
|
needStopVoice = true,
|
|
timerId = -1,
|
|
uniqueId = AIBarkCtrl.s_uniqueId,
|
|
startTime = Time.time,
|
|
duration = duration,
|
|
}
|
|
|
|
cell.text:SetAndResolveTextStyle(barkText)
|
|
local sizeDelta = cell.text.rectTransform.sizeDelta
|
|
if cell.text.preferredHeight > SINGLE_CELL_TEXT_HEIGHT_LIMIT then
|
|
sizeDelta.y = SINGLE_CELL_TEXT_HEIGHT_LIMIT
|
|
else
|
|
sizeDelta.y = cell.text.preferredHeight
|
|
end
|
|
cell.text.rectTransform.sizeDelta = sizeDelta
|
|
|
|
local spriteName = UIConst.UI_AI_BARK_CHAR_HEAD_PREFIX .. "_" .. charTemplateId
|
|
cell.chrIcon:LoadSprite(UIConst.UI_SPRITE_AI_BARK_CHAR_HEAD, spriteName)
|
|
|
|
LayoutRebuilder.ForceRebuildLayoutImmediate(cell.transform)
|
|
LayoutRebuilder.ForceRebuildLayoutImmediate(self.view.content.transform)
|
|
|
|
|
|
for i = 1, #self.m_curPlayingBarks do
|
|
if self:_CheckHeight() then
|
|
break
|
|
end
|
|
self:_DoStopSingleAIBarkByUniqueId(self.m_curPlayingBarks[1].uniqueId, true)
|
|
end
|
|
if isLastSentence then
|
|
bark.timerId = self:_StartStopTimer(duration, bark.uniqueId)
|
|
logger.info("PlaySingleAIBark: ", barkText, ", duration: ", duration, "uniqueId: ", bark.uniqueId)
|
|
self:_ClearTimeoutTimer()
|
|
else
|
|
logger.info("PlaySingleAIBark: ", barkText, ", start timeout timer, uniqueId: ", bark.uniqueId)
|
|
self:_StartTimeoutTimer()
|
|
end
|
|
|
|
table.insert(self.m_curPlayingBarks, bark)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl._StopLastAIBark = HL.Method(HL.Number, HL.Opt(HL.Boolean)) << function(self, uniqueId, audioInterrupt)
|
|
local index = self:_GetIndexByUniqueId(uniqueId)
|
|
logger.info("_StopLastAIBark: ", uniqueId, ", index: ", index, ", totalCount: ", #self.m_curPlayingBarks)
|
|
if index > 0 and #self.m_curPlayingBarks >= index then
|
|
for i = index, 1, -1 do
|
|
local count = #self.m_curPlayingBarks
|
|
if i <= count and count > 0 then
|
|
self:_DoStopSingleAIBark(i, false, audioInterrupt)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl._GetIndexByUniqueId = HL.Method(HL.Number).Return(HL.Number) << function(self, uniqueId)
|
|
local index = -1
|
|
for i, cell in pairs(self.m_curPlayingBarks) do
|
|
if cell.uniqueId == uniqueId then
|
|
index = i
|
|
break
|
|
end
|
|
end
|
|
return index
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl._DoStopSingleAIBarkByUniqueId = HL.Method(HL.Number, HL.Opt(HL.Boolean)) << function(self, uniqueId, heightRemove)
|
|
local index = self:_GetIndexByUniqueId(uniqueId)
|
|
if index > 0 then
|
|
self:_DoStopSingleAIBark(index, heightRemove)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl._DoStopSingleAIBark = HL.Method(HL.Number, HL.Opt(HL.Boolean, HL.Boolean)) << function(self, index, heightRemove, audioInterrupt)
|
|
logger.info("_DoStopSingleAIBark start: index: ", index, ", totalCount: ", #self.m_curPlayingBarks)
|
|
local bark = self.m_curPlayingBarks[index]
|
|
if not bark then
|
|
return
|
|
end
|
|
|
|
local voiceHandleId = bark.voiceHandleId
|
|
local needStopVoice = bark.needStopVoice
|
|
local timerId = bark.timerId
|
|
local cell = bark.cell
|
|
|
|
if needStopVoice and voiceHandleId >= 0 then
|
|
VoiceManager:StopAIBarkNoNotify(voiceHandleId)
|
|
end
|
|
|
|
if timerId and timerId > 0 then
|
|
self:_ClearStopTimer(timerId)
|
|
end
|
|
|
|
local lastCell = not heightRemove and index == #self.m_curPlayingBarks
|
|
|
|
table.remove(self.m_curPlayingBarks, index)
|
|
|
|
self:_CacheCell(cell, lastCell)
|
|
|
|
if not audioInterrupt then
|
|
local barkId = bark.barkId
|
|
AIBarkCtrl.OnBarkStopped(barkId)
|
|
end
|
|
logger.info("_DoStopSingleAIBark finish: index: ", index, ", totalCount: ", #self.m_curPlayingBarks)
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl._CacheCell = HL.Method(HL.Table, HL.Boolean) << function(self, cell, lastCell)
|
|
if not self.m_waitingCacheCells[cell] then
|
|
self.m_waitingCacheCells[cell] = true
|
|
table.insert(self.m_waitingTable, cell)
|
|
end
|
|
|
|
self:_StartTween(lastCell)
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl._CacheAllWaiting = HL.Method() << function(self)
|
|
if #self.m_waitingTable > 0 then
|
|
for _, cell in pairs(self.m_waitingTable) do
|
|
for i = 1, #self.m_cellCache do
|
|
if self.m_cellCache[i] == cell then
|
|
|
|
end
|
|
end
|
|
|
|
cell.transform:SetParent(self.view.cacheRoot)
|
|
cell.gameObject:SetActive(false)
|
|
table.insert(self.m_cellCache, cell)
|
|
end
|
|
end
|
|
self.m_waitingCacheCells = {}
|
|
self.m_waitingTable = {}
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl._ClearTween = HL.Method() << function(self)
|
|
if self.m_tween then
|
|
self.m_tween:Kill()
|
|
end
|
|
self.m_tween = nil
|
|
end
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl._StartTween = HL.Method(HL.Boolean) << function(self, lastCell)
|
|
self:_ClearTween()
|
|
if lastCell then
|
|
for index, cell in pairs(self.m_waitingTable) do
|
|
cell.animationWrapper:ClearTween(false)
|
|
cell.animationWrapper:SampleToInAnimationEnd()
|
|
cell.animationWrapper:PlayOutAnimation(function()
|
|
if index == #self.m_waitingTable then
|
|
self:_CacheAllWaiting()
|
|
end
|
|
end)
|
|
end
|
|
else
|
|
local totalHeight = 0
|
|
for _, cell in pairs(self.m_waitingTable) do
|
|
cell.animationWrapper:ClearTween(false)
|
|
cell.animationWrapper:SampleToInAnimationEnd()
|
|
totalHeight = totalHeight + cell.transform.rect.height
|
|
end
|
|
|
|
self.m_tween = DOTween.To(function()
|
|
return self.view.content.transform.anchoredPosition.y
|
|
end, function(y)
|
|
self.view.content.transform.anchoredPosition = Vector2(0, y)
|
|
end, totalHeight, 0.2)
|
|
|
|
self.m_tween:SetEase(CS.DG.Tweening.Ease.OutSine)
|
|
self.m_tween:OnComplete(function()
|
|
self:_Reset()
|
|
end)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl._Reset = HL.Method() << function(self)
|
|
self:_ClearTween()
|
|
self:_CacheAllWaiting()
|
|
self.view.content.transform.anchoredPosition = Vector2.zero
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl._GenCell = HL.Method().Return(HL.Table) << function(self)
|
|
local cell
|
|
local cacheCount = #self.m_cellCache
|
|
local parent = self.view.content
|
|
if cacheCount > 0 then
|
|
cell = self.m_cellCache[cacheCount]
|
|
table.remove(self.m_cellCache, cacheCount)
|
|
cell.gameObject:SetActive(true)
|
|
cell.transform:SetParent(parent)
|
|
else
|
|
local go = UIUtils.addChild(parent, self.view.cell.gameObject)
|
|
cell = Utils.wrapLuaNode(go)
|
|
cell.gameObject:SetActive(true)
|
|
end
|
|
return cell
|
|
end
|
|
|
|
|
|
|
|
|
|
AIBarkCtrl.DoShowAIBark = HL.Method(CS.Beyond.Gameplay.AIBarkManager.AIBarkRuntimeData) << function(self, aiBarkData)
|
|
if not self:_CheckCanPlay() then
|
|
self:Hide()
|
|
return
|
|
end
|
|
|
|
self:_TryShowSingleBark(aiBarkData)
|
|
end
|
|
|
|
|
|
|
|
AIBarkCtrl._CheckCanPlay = HL.Method().Return(HL.Boolean) << function(self)
|
|
if Utils.isInNarrative() then
|
|
return false
|
|
end
|
|
|
|
if Utils.isRadioPlaying() then
|
|
return false
|
|
end
|
|
|
|
return AIBarkCtrl.s_inMainHud
|
|
end
|
|
|
|
HL.Commit(AIBarkCtrl)
|