local dialogCtrlBase = require_ex('UI/Panels/Dialog/DialogCtrlBase') local uiCtrl = require_ex('UI/Panels/Base/UICtrl') local PANEL_ID = PanelId.Dialog DialogCtrl = HL.Class('DialogCtrl', dialogCtrlBase.DialogCtrlBase) DialogCtrl.s_overrideMessages = HL.StaticField(HL.Table) << { [MessageConst.UI_DIALOG_TEXT_STOPPED] = 'OnDialogTextStopped', [MessageConst.ON_DIALOG_TRUNK_TEXT_FADE] = 'OnDialogTextFade', [MessageConst.ON_DIALOG_TRUNK_RADIO_FADE] = 'OnDialogRadioFade', [MessageConst.ON_DIALOG_CHANGE_CENTER_IMAGE] = 'OnDialogChangeCenterImage', [MessageConst.ON_DIALOG_DISABLE_CLICK_END] = 'OnDialogDisableClickEnd', [MessageConst.SWITCH_DIALOG_CAN_SKIP] = 'OnSwitchDialogCanSkip', [MessageConst.SWITCH_DIALOG_SHOW_LOG] = 'OnSwitchDialogShowLog', [MessageConst.DIALOG_SHOW_DEV_WATER_MARK] = 'ShowDevWaterMark', [MessageConst.DIALOG_REFRESH_AUTO_MODE] = 'OnRefreshAutoMode', } DialogCtrl.m_trunkNodeData = HL.Field(CS.Beyond.Gameplay.DTTrunkNodeData) DialogCtrl.m_canSkip = HL.Field(HL.Boolean) << true DialogCtrl.m_centerImageTween = HL.Field(HL.Userdata) DialogCtrl.m_radioName = HL.Field(HL.String) << "" DialogCtrl.m_curTrunkId = HL.Field(HL.String) << "" DialogCtrl.m_clickCount = HL.Field(HL.Number) << 0 DialogCtrl.OnPreloadDialogPanel = HL.StaticMethod(HL.Table) << function(arg) local preloadFinishCallback = unpack(arg) UIManager:PreloadPanelAsset(PANEL_ID, PhaseId.Dialog, function() if preloadFinishCallback ~= nil then preloadFinishCallback() end end) end DialogCtrl.OnShow = HL.Override() << function(self) self:OnDialogShow() self.view.debugNode.gameObject:SetActive(false) end DialogCtrl.RefreshDebugNode = HL.Method() << function(self) if NarrativeUtils.ShouldShowNarrativeDebugNode() then self.view.debugNode.gameObject:SetActive(true) local desc = "\nT2/T3" if GameWorld.dialogManager.dialogTree.dialogTreeData.qualityLevel == CS.Beyond.Gameplay.DialogEnums.DialogQualityLevel.High then desc = "\nTO/T1" end self.view.textDialogId.text = GameWorld.dialogManager.dialogId .. desc end end DialogCtrl.GetCurDialogId = HL.Override().Return(HL.String) << function(self) return GameWorld.dialogManager.dialogId end DialogCtrl.OnDialogShow = HL.Override() << function(self) DialogCtrl.Super.OnDialogShow(self) self:_RefreshAutoMode(GameWorld.dialogManager.autoMode) self:_RefreshCanSkip() if self.m_curTrunkId == "" then self:OnDialogTextFade({ 0, 0 }) end end DialogCtrl.OnBtnNextClick = HL.Override() << function(self) self.m_clickCount = self.m_clickCount + 1 if self:CheckTextPlaying() then self.view.textTalk:SeekToEnd() self.view.textTalkCenter:SeekToEnd() else self:_UpdateClickRecord() GameWorld.dialogManager:Next() end end DialogCtrl.OnDialogTextStopped = HL.Override() << function(self) self.view.optionList.gameObject:SetActive(true) local showWait = self.m_optionCells:GetCount() <= 0 self:_TrySetWaitNode(showWait) end DialogCtrl.OnDialogDisableClickEnd = HL.Method() << function(self) local showWait = self.m_optionCells:GetCount() <= 0 self:_TrySetWaitNode(showWait) end DialogCtrl.OnDialogTextFade = HL.Method(HL.Table) << function(self, arg) local duration, alpha = unpack(arg) self:_UpdateClickRecord() self.m_clickCount = 0 self.m_curTrunkId = GameWorld.dialogManager.trunkId self.view.bottomLayout:DOKill() self.view.bottomLayout:DOFade(alpha, duration) if self.view.textTalkCenterNode.gameObject.activeSelf then self.view.textTalkCenterNode:DOKill() self.view.textTalkCenterNode:DOFade(alpha, duration) end end DialogCtrl.OnDialogRadioFade = HL.Method(HL.Opt(HL.Any)) << function(self, _) local radioNode = self.view.radioNode if radioNode.gameObject.activeSelf then radioNode:PlayOutAnimation(function() radioNode.gameObject:SetActive(false) end) end end DialogCtrl._ClearCenterImageTween = HL.Method() << function(self) if self.m_centerImageTween then self.m_centerImageTween:Kill() self.m_centerImageTween = nil end end DialogCtrl.OnDialogChangeCenterImage = HL.Method(HL.Table) << function(self, data) local enable, sprite = unpack(data) self:_ClearCenterImageTween() if enable then self.view.bgBlack.gameObject:SetActive(true) self.view.bgBlack.alpha = 0 local finalSprite = self:_GetRealSprite("", sprite) self.view.itemImage:LoadSprite(finalSprite) self.m_centerImageTween = self.view.bgBlack:DOFade(1, 0.3) self.m_centerImageTween:OnComplete(function() self:_ClearCenterImageTween() end) else self.m_centerImageTween = self.view.bgBlack:DOFade(0, 0.3) self.m_centerImageTween:OnComplete(function() self:_ClearCenterImageTween() self.view.bgBlack.gameObject:SetActive(false) end) end end DialogCtrl.OnSwitchDialogCanSkip = HL.Method(HL.Table) << function(self, arg) self:_RefreshCanSkip() end DialogCtrl.OnSwitchDialogShowLog = HL.Method(HL.Table) << function(self, arg) local show = unpack(arg) self.view.buttonLog.gameObject:SetActive(show) end DialogCtrl._RefreshCanSkip = HL.Override() << function(self) self.m_canSkip = GameWorld.dialogManager.canSkip self.view.buttonSkip.gameObject:SetActive(self.m_canSkip) end DialogCtrl._TrySetWaitNode = HL.Override(HL.Boolean) << function(self, active) if active then local disableClick = GameWorld.dialogManager.disableClick local playing = self.view.textTalk.playing and self.view.textTalkCenter.playing local canShowWait = not disableClick and not playing self.view.waitNode.gameObject:SetActive(canShowWait) self.view.centerWaitNode.gameObject:SetActive(canShowWait) else self.view.waitNode.gameObject:SetActive(active) self.view.centerWaitNode.gameObject:SetActive(active) end end DialogCtrl.OnOptionClick = HL.Override(HL.Number, HL.Any) << function(self, index, _) GameWorld.dialogManager:SelectIndex(CSIndex(index)) end DialogCtrl.OnBtnSkipClick = HL.Override() << function(self) self:Notify(MessageConst.OPEN_DIALOG_SKIP_POP_UP) end DialogCtrl.OnBtnAutoClick = HL.Override() << function(self) local auto = not GameWorld.dialogManager.autoMode GameWorld.dialogManager:SetAutoMode(auto) end DialogCtrl.OnBtnBackClick = HL.Override() << function(self) self:Notify(MessageConst.ON_COMMON_BACK_CLICKED) end DialogCtrl.OnBtnStopClick = HL.Override() << function(self) self:Notify(MessageConst.SHOW_TOAST, Language.LUA_FEATURE_NOT_AVAILABLE) end DialogCtrl._CloseAutoMode = HL.Method(HL.Opt(HL.Any)) << function(self, _) self.view.textAuto.gameObject:SetActive(false) GameWorld.dialogManager:SetAutoMode(false) self:_SwitchControllerAutoPlayHint() end DialogCtrl.SetTrunk = HL.Method(HL.Userdata, HL.Opt(HL.Boolean, HL.Any, HL.Any)) << function(self, trunkNodeData, fastMode, npcId, npcGroupId) self.m_trunkNodeData = trunkNodeData local hideBg = trunkNodeData.hideBg local bgSprite = self:_GetRealSprite(UIConst.UI_SPRITE_DIALOG_BG, trunkNodeData.bgSprite or "") local trunkId = trunkNodeData.overrideTrunkId if string.isEmpty(trunkId) then trunkId = trunkNodeData.trunkId end self:_UpdateClickRecord() self.m_curTrunkId = trunkId local name = "" local dialogText = "" local res, trunkTbData = Tables.dialogTextTable:TryGetValue(trunkId) if res then if not string.isEmpty(trunkTbData.actorName) then name = trunkTbData.actorName end dialogText = trunkTbData.dialogText end local text = UIUtils.resolveTextCinematic(dialogText) local singleTrunk = string.isEmpty(name) self.view.bottomLayout:DOKill() self.view.bottomLayout.alpha = 1 self.view.textTalkCenterNode.alpha = 1 self.view.textTalkCenterNode.gameObject:SetActive(singleTrunk) self.view.bottomLayout.gameObject:SetActive(not singleTrunk) self.view.imageBG.gameObject:SetActive(not hideBg) if singleTrunk then self.view.textTalkCenter:SetText(text) if fastMode then self.view.textTalkCenter:SeekToEnd() else self.view.textTalkCenter:Play() end else local richName = UIUtils.resolveTextCinematic(name) richName = UIUtils.removePattern(richName, UIConst.NARRATIVE_ANONYMITY_PATTERN) self.view.textName:SetAndResolveTextStyle(richName) self.view.textName.gameObject:SetActive(true) self.view.textTalk:SetText(text) if fastMode then self.view.textTalk:SeekToEnd() else self.view.textTalk:Play() end end if not string.isEmpty(bgSprite) then self.view.bgSprite:LoadSprite(UIConst.UI_SPRITE_DIALOG_BG, bgSprite) self.view.bgSprite.gameObject:SetActive(true) else self.view.bgSprite.gameObject:SetActive(false) end local useRadio = trunkNodeData.useRadio local radioNode = self.view.radioNode if useRadio then radioNode.gameObject:SetActive(useRadio) local charSpriteName if not string.isEmpty(trunkNodeData.radioIcon) then charSpriteName = trunkNodeData.radioIcon else local entity = GameWorld.dialogManager:GetEntity(trunkNodeData.actorIndex) local charId = entity.templateData.id charSpriteName = UIConst.UI_CHAR_HEAD_SQUARE_PREFIX .. charId end self.view.charImage:LoadSprite(UIConst.UI_SPRITE_CHAR_HEAD_RECTANGLE, charSpriteName) self.view.blueMask:LoadSprite(UIConst.UI_SPRITE_CHAR_HEAD_RECTANGLE, charSpriteName) local radioName if not string.isEmpty(trunkNodeData.radioNameId) then radioName = Language.trunkNodeData.radioNameId else radioName = name end if radioName ~= self.m_radioName then radioNode:ClearTween(false) radioNode:PlayInAnimation() end self.m_radioName = radioName else if radioNode.gameObject.activeSelf then radioNode:ClearTween(false) radioNode:PlayOutAnimation(function() radioNode.gameObject:SetActive(useRadio) end) end self.m_radioName = "" end self.view.textDes.gameObject:SetActive(false) self:SetCtrlButtonVisible(true) self:_TrySetWaitNode(false) self:_RefreshCanSkip() self:RefreshDebugNode() end DialogCtrl._UpdateClickRecord = HL.Method() << function(self) GameWorld.dialogManager:UpdateClickRecord(self.m_curTrunkId, self.m_clickCount) self.m_clickCount = 0 end DialogCtrl.RefreshTrunk = HL.Method() << function(self) self.view.textTalk:Play() self.view.textTalkCenter:Play() end DialogCtrl.SetTrunkOption = HL.Override(HL.Userdata) << function(self, optionData) DialogCtrl.Super.SetTrunkOption(self, optionData) local count = optionData.Count if count == 0 then self:_SwitchFriendshipShow(false) else local workFriendship = GameWorld.dialogManager.showSpaceshipCharFriendship self:_SwitchFriendshipShow(workFriendship) end end DialogCtrl.GetTouchPanel = HL.Method().Return(CS.Beyond.UI.UITouchPanel) << function(self) return self.view.touchPanel end DialogCtrl._GetRealSprite = HL.Method(HL.String, HL.String).Return(HL.String) << function(self, folder, spriteName) local gender = Utils.getPlayerGender() local finalSprite = spriteName if gender == CS.Proto.GENDER.GenMale then local subName = finalSprite if string.endWith(spriteName, UIConst.DIALOG_IMAGE_FEMALE_SUFFIX) then subName = string.sub(spriteName, 0, string.len(spriteName) - 2) end local maleSpriteName = subName .. UIConst.DIALOG_IMAGE_MALE_SUFFIX local maleSpritePath = maleSpriteName if not string.isEmpty(folder) then maleSpritePath = UIUtils.getSpritePath(folder, maleSpriteName) else maleSpritePath = UIUtils.getSpritePath(maleSpriteName) end local res = ResourceManager.CheckExists(maleSpritePath) if res then finalSprite = maleSpriteName end end return finalSprite end DialogCtrl.SetFullBg = HL.Method(CS.Beyond.Gameplay.DialogFullBgActionData) << function(self, actionData) local bgSprite = self:_GetRealSprite(UIConst.UI_SPRITE_DIALOG_BG, actionData.bgSprite) local textId = actionData.textId local pos = actionData.pos local alpha = actionData.alpha local duration = actionData.duration local useCurve = actionData.useCurve local curve = actionData.curve local maskFadeTime = actionData.maskFadeTime local maskColor = actionData.maskColor self.view.bgSprite:DOKill() self.view.bgMask:DOKill() local function bgSpriteFade(onFadeComplete) if duration == 0 then UIUtils.changeAlpha(self.view.bgSprite, alpha) if onFadeComplete then onFadeComplete() end if alpha == 0 then self.view.bgSprite.gameObject:SetActive(false) end else local tween = self.view.bgSprite:DOFade(alpha, duration) tween:OnComplete(function() if onFadeComplete then onFadeComplete() end if alpha == 0 then self.view.bgSprite.gameObject:SetActive(false) end end) if useCurve and curve then tween:SetEase(curve) end end end local function maskFade(onFadeComplete) if maskFadeTime == 0 then UIUtils.changeAlpha(self.view.bgMask, alpha) if onFadeComplete then onFadeComplete() end if alpha == 0 then self.view.bgMask.gameObject:SetActive(false) end else local tween = self.view.bgMask:DOFade(alpha, maskFadeTime) tween:OnComplete(function() if onFadeComplete then onFadeComplete() end if alpha == 0 then self.view.bgMask.gameObject:SetActive(false) end end) end end if not string.isEmpty(bgSprite) then self.view.bgSprite:LoadSprite(UIConst.UI_SPRITE_DIALOG_BG, bgSprite) self.view.bgSprite.gameObject:SetActive(true) self.view.bgMask.gameObject:SetActive(true) self.view.bgMask.color = maskColor; UIUtils.changeAlpha(self.view.bgSprite, 1 - alpha) UIUtils.changeAlpha(self.view.bgMask, 1 - alpha) if alpha == 1 then maskFade(bgSpriteFade) else bgSpriteFade(maskFade) end else self.view.bgSprite.gameObject:SetActive(false) end if string.isEmpty(textId) then self.view.textDes.gameObject:SetActive(false) else self.view.textDes.gameObject:SetActive(true) self.view.textDes:SetAndResolveTextStyle(Language[textId]) self.view.textDes.transform.localPosition = pos self.view.textDes.transform.localPosition = pos end self.view.imageBG.gameObject:SetActive(false) self.view.optionList.gameObject:SetActive(false) self.view.bottomLayout.gameObject:SetActive(false) self.view.textTalkCenterNode.gameObject:SetActive(false) self.view.radioNode.gameObject:SetActive(false) self:SetCtrlButtonVisible(false) end DialogCtrl.SetPostProcessEffect = HL.Method(CS.Beyond.Gameplay.DialogUIPostProcessDesc) << function(self, postProcessDesc) local effectTexture = postProcessDesc.textureAsset local color = postProcessDesc.color local alpha = postProcessDesc.alpha local fadeTime = postProcessDesc.fadeTime self.view.postProcessEffect:DOKill() self.view.postProcessEffect.gameObject:SetActive(true) self.view.postProcessEffect.color = color if effectTexture ~= nil then self.view.postProcessEffect.texture = effectTexture end if fadeTime == 0 then UIUtils.changeAlpha(self.view.postProcessEffect, alpha) if alpha == 0 then self.view.postProcessEffect.gameObject:SetActive(false) end else UIUtils.changeAlpha(self.view.postProcessEffect, 1 - alpha) local tween = self.view.postProcessEffect:DOFade(alpha, fadeTime) tween:OnComplete(function() if alpha == 0 then self.view.postProcessEffect.gameObject:SetActive(false) end end) end end DialogCtrl.SetLeftSubtitle = HL.Method(CS.Beyond.Gameplay.DialogLeftSubtitleActionData) << function(self, actionData) self.view.leftSubtitlePanel:SetLeftSubTitle( (not actionData.text1.isEmpty) and actionData.text1:GetText() or nil, (not actionData.text2.isEmpty) and actionData.text2:GetText() or nil, (not actionData.text3.isEmpty) and actionData.text3:GetText() or nil, (not actionData.text4.isEmpty) and actionData.text4:GetText() or nil ) self.view.leftSubtitlePanel:StartAutoPlay(actionData.textStayTime) end DialogCtrl.ExitLeftSubtitle = HL.Method() << function(self) self.view.leftSubtitlePanel:Exit() end DialogCtrl.SetCtrlButtonVisible = HL.Method(HL.Boolean) << function(self, visible) self.view.topRight.gameObject:SetActive(visible) self.view.topLeft.gameObject:SetActive(visible) self.view.top.gameObject:SetActive(visible) end DialogCtrl._SwitchFriendshipShow = HL.Method(HL.Boolean) << function(self, visible) local charId = GameWorld.dialogManager.spaceshipCharId local realVisible = visible and not string.isEmpty(charId) local cellGO = self.view.friendshipRight.reliabilityCell.gameObject local lastVisible = cellGO.activeSelf if realVisible then self.view.friendshipRight.gameObject:SetActive(realVisible) if not lastVisible then cellGO:SetActive(realVisible) AudioAdapter.PostEvent("Au_UI_Popup_ReliabilithCell_Open") self.view.friendshipRight.animationWrapper:PlayInAnimation() self.view.friendshipRight.reliabilityCell:InitReliabilityCell(charId) end else self.view.friendshipRight.animationWrapper:PlayOutAnimation(function() cellGO:SetActive(realVisible) if lastVisible then AudioAdapter.PostEvent("Au_UI_Popup_ReliabilithCell_Close") end end) end end DialogCtrl.ShowPresentSuccess = HL.Method(HL.Boolean, HL.Number, HL.Table) << function(self, levelChanged, deltaFav, selectedItems) self.view.friendshipRight.reliabilityCell:ShowPresentSuccessTips(levelChanged, deltaFav, selectedItems) local workFriendship = GameWorld.dialogManager.showSpaceshipCharFriendship self:_SwitchFriendshipShow(workFriendship) end DialogCtrl._RefreshRestCell = HL.Method(HL.String) << function(self, charId) local restCell = self.view.friendshipRight.restCell local roomId, isWorking = CSPlayerDataUtil.GetCharRoomId(charId) local maxStamina = Tables.spaceshipConst.maxPhysicalStrength local curStamina = CSPlayerDataUtil.GetCharCharCurStamina(charId) local percent = curStamina / maxStamina if isWorking then restCell.textRest.text = Language.LUA_SPACESHIP_CHAR_WORKING elseif string.isEmpty(roomId) then if percent >= 1 then restCell.textRest.text = Language.LUA_SPACESHIP_CHAR_HANGING else restCell.textRest.text = Language.LUA_SPACESHIP_CHAR_RESTING end else restCell.textRest.text = Language.LUA_SPACESHIP_CHAR_RESTING end restCell.slider.value = percent restCell.textStamina.text = tostring(lume.round(percent * 100)) .. "%" if string.isEmpty(roomId) then restCell.textRoom.text = Language.LUA_SPACESHIP_HALL_NAME else local res, data = GameInstance.player.spaceship:TryGetRoom(roomId) restCell.textRoom.text = data.name end end HL.Commit(DialogCtrl)