PGRData/Script/matrix/xui/xuiplanet/fight/XUiPlanetRunningFight.lua
2024-09-01 22:49:41 +02:00

441 lines
No EOL
14 KiB
Lua

local STATUS = {
None = 0,
START = 1,
PROGRESS = 2, -- 在跑进度条
ACTION_CHECK = 3, --到达一次单位时间, 检查是否有角色行动
ACTION_START = 4, -- 角色行动开始
ACTION = 5,
ACTION_END = 6, -- 角色行动结束
END = 7
}
local XUiPlanetRunningSystemAction = require("XUi/XUiPlanet/Fight/System/XUiPlanetRunningSystemAction")
local XUiPlanetRunningActionAttack = require("XUi/XUiPlanet/Fight/Action/XUiPlanetRunningActionAttack")
---@class XUiPlanetRunningFight
local XUiPlanetRunningFight = XClass(nil, "XUiPlanetRunningFight")
function XUiPlanetRunningFight:Ctor()
self.ObjFight = false
---@type XUiPlanetRunningEntity[]
self.UiEntities = {}
self.TimelineHelper = false
self._Status = STATUS.None
self._ActionIndex = 0
self._DurationProgress = 0
self._DurationProgressMax = 0
self._BeginData = false
self._MaxTurn = 2000
---@type XUiPlanetRunningSystemAction
self._SystemAction = XUiPlanetRunningSystemAction.New()
---@type XUiPlanetRunningAction
self._Action = false
self._AnimationAttack = false
self._DurationEnd = 1
self._TimeScale = 1
self._Debug = false
local UnityRuntimePlatform = CS.UnityEngine.RuntimePlatform
local UnityApplication = CS.UnityEngine.Application
if UnityApplication.platform == UnityRuntimePlatform.WindowsEditor then
self._Debug = true
end
self._ResultLua = false
self._ResultCharacterHp = false
self._IsRequest = false
self._SkipCallback = false
self.IsEnd = false
self._IsSkip = false
end
function XUiPlanetRunningFight:SetScale(scale)
self._TimeScale = scale
end
function XUiPlanetRunningFight:GetScale()
return self._TimeScale
end
function XUiPlanetRunningFight:SetData(data)
self._BeginData = data
self:CreateFight(data)
end
function XUiPlanetRunningFight:CreateFight(data)
local fight = CS.XPlanetRunning.XPlanetRunningFight.XPlanetRunningFight()
if data then
fight:Init(data)
end
self.ObjFight = fight
self._Status = STATUS.START
end
function XUiPlanetRunningFight:Init()
local entities = self.ObjFight.Entities
for i = 0, entities.Count - 1 do
local entity = entities[i]
local entityId = entity.Id
self:UpdateHp(entityId)
end
end
function XUiPlanetRunningFight:Update(deltaTime)
deltaTime = deltaTime * self._TimeScale
if self._Status == STATUS.END then
if self._IsRequest then
return
end
self._DurationEnd = self._DurationEnd - deltaTime
if self._DurationEnd < 0 then
if not self.IsEnd then
self.IsEnd = true
end
XLuaUiManager.SafeClose("UiPlanetFightMain")
end
return
end
if self._Status == STATUS.START then
self._Status = STATUS.ACTION_CHECK
return
end
if self._Status == STATUS.PROGRESS then
-- wait to next action
self._DurationProgress = self._DurationProgress + deltaTime
local progress = self._DurationProgress / self._DurationProgressMax
progress = math.min(progress, 1)
local entities = self.ObjFight.Entities
for i = 0, entities.Count - 1 do
local entity = entities[i]
local entityId = entity.Id
local uiEntity = self.UiEntities[entityId]
if uiEntity then
uiEntity:UpdateProgressAction(progress)
end
end
if progress == 1 then
self._Status = STATUS.ACTION_CHECK
end
return
end
if self._Status == STATUS.ACTION_CHECK then
self.ObjFight:Run(1)
self._DurationProgress = 0
local entities = self.ObjFight.Entities
for i = 0, entities.Count - 1 do
local entity = entities[i]
local entityId = entity.Id
local uiEntity = self.UiEntities[entityId]
local actionPoint = entity.Action.ActionPoint
if entity.Attribute.Life <= 0 then
actionPoint = 0
end
if entity.Action.IsWaitingAction then
-- 等待行动时,显示满进度
if uiEntity then
uiEntity:SetMaxTargetActionPoint()
end
else
if uiEntity then
uiEntity:SetTargetActionPoint(actionPoint)
end
end
end
local actionIndexLast = self._ActionIndex
local actionIndexCurrent = self.ObjFight.RecordActionList.Count
if actionIndexCurrent > actionIndexLast then
self._ActionIndex = actionIndexCurrent
self._Status = STATUS.ACTION_START
else
if self.ObjFight.IsEnd then
self._Status = STATUS.END
self:GenerateResultAndEnd()
return
else
self._Status = STATUS.PROGRESS
end
end
return
end
if self._Status == STATUS.ACTION_START then
local actionIndexCurrent = self.ObjFight.RecordActionList.Count
if self._ActionIndex <= actionIndexCurrent then
local action = self.ObjFight.RecordActionList[self._ActionIndex - 1]
local entityId = action.LauncherId
local launcherUiEntity = self.UiEntities[entityId]
if launcherUiEntity then
launcherUiEntity:ResetProgressAction()
if self._Debug then
local entityAction = self.ObjFight:GetEntity(entityId)
local entityTarget = self.ObjFight:GetEntity(action.TargetId)
local strAction = ""
local strTarget = ""
local strCritical = "是否暴击: " .. tostring(action.IsCritical)
if entityAction and entityTarget then
local attrFormat = "生命值:%d/%d, 攻击:%d, 防御:%d, 暴击率:%d, 暴击率增益:%d, 暴击加成:%d, 速度:%d"
local attrAction = entityAction.Attribute
strAction = string.format(attrFormat, attrAction.Life, attrAction.MaxLife, attrAction.Attack, attrAction.Defense, attrAction.CriticalPercent, attrAction.CriticalPercentBonus, attrAction.CriticalDamageAdded, attrAction.Speed)
local attrTarget = entityTarget.Attribute
strTarget = string.format(attrFormat, attrTarget.Life, attrTarget.MaxLife, attrTarget.Attack, attrTarget.Defense, attrTarget.CriticalPercent, attrTarget.CriticalPercentBonus, attrTarget.CriticalDamageAdded, attrTarget.Speed)
end
print("当前回合:" .. actionIndexCurrent .. " 行动者" .. entityId .. "" .. action.TargetId .. " 造成伤害:" .. action.Value, strAction, strTarget, strCritical)
end
end
self._Action = XUiPlanetRunningActionAttack.New()
self._Action:Set(action)
self._Status = STATUS.ACTION
else
self._Status = STATUS.ACTION_END
end
return
end
if self._Status == STATUS.ACTION then
local action = self._Action
if not action then
self._Status = STATUS.ACTION_END
return
end
if not self._SystemAction:Update(deltaTime, action, self) then
self._Status = STATUS.ACTION_END
end
return
end
if self._Status == STATUS.ACTION_END then
self._Status = STATUS.ACTION_CHECK
return
end
end
function XUiPlanetRunningFight:UpdateHp(entityId)
local entity = self.ObjFight:GetEntity(entityId)
if not entity then
return
end
local uiEntity = self.UiEntities[entityId]
if not uiEntity then
return
end
uiEntity:SetHp(entity)
end
function XUiPlanetRunningFight:GetPlayerEntityArray()
return self:GetEntityArrayByCamp(CS.XPlanetRunning.XPlanetRunningFight.XPlanetRunningCampType.Player)
end
function XUiPlanetRunningFight:GetBossEntityArray()
return self:GetEntityArrayByCamp(CS.XPlanetRunning.XPlanetRunningFight.XPlanetRunningCampType.Boss)
end
function XUiPlanetRunningFight:GetEntityArrayByCamp(camp)
local entities = self.ObjFight.Entities
local array = {}
for i = 0, entities.Count - 1 do
local entity = entities[i];
if entity.Camp.CampType == camp then
array[#array + 1] = entity
end
end
return array
end
function XUiPlanetRunningFight:BindUiEntity(entityId, uiRole)
self.UiEntities[entityId] = uiRole
end
function XUiPlanetRunningFight:Destroy()
self.ObjFight = false
end
-- 将c#结构转成lua发送
function XUiPlanetRunningFight:GenerateResultAndEnd()
-- 隐藏特效
self:RestoreAllEffect()
local result = self.ObjFight:GetResult()
--region c#转lua
local characterHp = {}
local resultLua = {}
resultLua.Grid = result.Grid
resultLua.Seckill = {}
for i = 0, result.Seckill.Count - 1 do
local entityId = result.Seckill[i]
table.insert(resultLua.Seckill, entityId)
end
resultLua.IsWin = result.IsWin
resultLua.StageId = result.StageId
resultLua.ResultCharacterInfos = {}
for i = 0, result.ResultCharacterInfos.Count - 1 do
local attributeLua = {}
local dataLua = {
FightingAttribute = {},
BaseAttribute = {
Attribute = attributeLua
}
}
local info = result.ResultCharacterInfos[i]
local objAttribute = info.BaseAttribute.Attribute
for j = 0, objAttribute.Count - 1 do
table.insert(attributeLua, objAttribute[j])
end
local characterId = info.CharacterInfo.Id
dataLua.CharacterInfo = {
Id = characterId,
}
table.insert(resultLua.ResultCharacterInfos, dataLua)
characterHp[characterId] = attributeLua[XPlanetCharacterConfigs.ATTR.Life]
end
self._ResultLua = resultLua
self._ResultCharacterHp = characterHp
--endregion c#转lua
-- 血量靠客户端自己更新 失败时不更新 否则角色们会被移除
if resultLua.IsWin then
local stageData = XDataCenter.PlanetManager.GetStageData()
local stageCharacterData = stageData:GetCharacterData()
for i = 1, #stageCharacterData do
local characterData = stageCharacterData[i]
local hp = characterHp[characterData.Id]
if hp then
characterData.Life = hp
end
end
stageData:SetCharacterData(stageCharacterData)
end
if self._BeginData._IsRequest then
self:OnRequestEnd()
else
self._BeginData._IsRequest = true
self._IsRequest = true
XDataCenter.FunctionEventManager.LockFunctionEvent()
XDataCenter.PlanetExploreManager.RequestCheckFight(resultLua, function()
self._IsRequest = false
local resultFromServer = XDataCenter.PlanetExploreManager.GetResult()
if (not resultFromServer) or (not resultFromServer:IsStageFinish()) or (resultFromServer:IsPlayed()) then
self:OnRequestEnd()
return
end
local settleType = resultFromServer:GetSettleType()
local condition = nil
if settleType == XPlanetExploreConfigs.SETTLE_TYPE.Lose then
condition = XPlanetExploreConfigs.MOVIE_CONDITION.SETTLE_FAIL
elseif settleType == XPlanetExploreConfigs.SETTLE_TYPE.StageFinish then
condition = XPlanetExploreConfigs.MOVIE_CONDITION.SETTLE_WIN
end
local stageId = XDataCenter.PlanetManager.GetStageData():GetStageId()
local movieId = XPlanetExploreConfigs.GetMovieIdByCheckControllerStage(condition, stageId)
-- 结算剧情
local explore = XDataCenter.PlanetExploreManager.GetExplore()
if not movieId then
explore:Pause(XPlanetExploreConfigs.PAUSE_REASON.RESULT)
self:OnRequestEnd()
return
end
XLuaUiManager.SafeClose("UiPlanetFightMain")
explore:PlayMovie(movieId, function()
explore:Pause(XPlanetExploreConfigs.PAUSE_REASON.RESULT)
self:OnRequestEnd()
end)
end)
end
end
function XUiPlanetRunningFight:RestoreAllEffect()
for id, entity in pairs(self.UiEntities) do
entity:HideEffectMove()
entity:HideEffectBeAttack()
end
end
function XUiPlanetRunningFight:OnRequestEnd()
local resultLua = self._ResultLua
-- 跳过战斗时, 播放气泡
if resultLua.IsWin and self._IsSkip then
local bubbleId
if #(resultLua.Seckill) > 0 then
bubbleId = XPlanetConfigs.GetSkipFightBubbleSeckill()
else
bubbleId = XPlanetConfigs.GetSkipFightBubble()
end
XEventManager.DispatchEvent(XEventId.EVENT_PLANET_PLAY_BUBBLE_ID, bubbleId)
end
if resultLua.IsWin then
XDataCenter.PlanetExploreManager.OpenUiPlanetEncounter(function()
XDataCenter.PlanetExploreManager.HandleResult()
XEventManager.DispatchEvent(XEventId.EVENT_PLANET_RESUME_RUNNING, XPlanetExploreConfigs.PAUSE_REASON.FIGHT)
if self._SkipCallback then
self._SkipCallback()
end
end, XPlanetConfigs.TipType.GameWin)
else
XDataCenter.PlanetExploreManager.OpenUiPlanetEncounter(function()
XDataCenter.PlanetExploreManager.HandleResult()
XEventManager.DispatchEvent(XEventId.EVENT_PLANET_RESUME_RUNNING, XPlanetExploreConfigs.PAUSE_REASON.FIGHT)
if self._SkipCallback then
self._SkipCallback()
end
end, XPlanetConfigs.TipType.GameOver)
end
XDataCenter.PlanetExploreManager.OnFightComplete(self._BeginData)
end
function XUiPlanetRunningFight:BindAnimationAttack(timelineHelper)
self.TimelineHelper = timelineHelper
--if timelineHelper.Mute then
-- timelineHelper:Mute("LauncherMove")
--end
end
function XUiPlanetRunningFight:Skip(callback, isSkip)
self._IsSkip = isSkip
self._SkipCallback = callback
local deltaTime = 1 / 60
for i = 1, self._MaxTurn do
if self._Status == STATUS.END then
break
end
self:Update(deltaTime)
-- 把每个回合产生的action都置空
self._Action = false
end
if self._Status ~= STATUS.END then
self:GenerateResultAndEnd()
XLog.Error("[XUiPlanetRunningFight] 这场战斗没有结果")
end
end
return XUiPlanetRunningFight