BattleLogic = {} local floor = math.floor local objList = BattleDictionary.New() local skillList local curUid local curBuffId local curFrame local playerMP local enemyMP local playerAggro local enemyAggro local playerAggroChangable local enemyAggroChangable local playerSkillUsable local enemySkillUsable BattleLogic.IsEnd = false BattleLogic.Result = -1 BattleLogic.Event = BattleEvent.New() local playerTeamDummyRole = {camp = 0, Event = BattleLogic.Event, isTeam = true} local enemyTeamDummyRole = {camp = 0, Event = BattleLogic.Event, isTeam = true} local playerTeamSkillList = {} local enemyTeamSkillList = {} local playerTeamSkillIndex local enemyTeamSkillIndex local fightData local record local optionRecord --是否开启战斗日志 BattleLogic.IsOpenBattleRecord = false --逻辑帧频 BattleLogic.GameFrameRate = 30 BattleLogic.GameDeltaTime = 1 / BattleLogic.GameFrameRate --总波次 BattleLogic.TotalOrder = 0 --当前波次 BattleLogic.CurOrder = 0 local actionPool = BattleObjectPool.New(function () return { 0, 0 } end) local skillPool = BattleObjectPool.New(function () return Skill:New() end) local tbActionList = BattleList.New() local rolePool = BattleObjectPool.New(function () return RoleLogic.New() end) function BattleLogic.Init(data, optionData) if BattleLogic.IsOpenBattleRecord then record = {} end fightData = data if optionData then optionRecord = optionData else optionRecord = {} end BattleLogic.CurOrder = 0 BattleLogic.TotalOrder = #data.enemyData BattleLogic.Clear() skillList = {} curUid = 0 curBuffId = 0 curFrame = 0 playerMP = 0 enemyMP = 0 playerTeamSkillIndex = 1 enemyTeamSkillIndex = 1 playerAggroChangable = true enemyAggroChangable = true playerSkillUsable = true enemySkillUsable = true BattleLogic.Event:ClearEvent() BattleLogic.IsEnd = false BattleLogic.Result = -1 end function BattleLogic.StartOrder() BattleLogic.CurOrder = BattleLogic.CurOrder + 1 if BattleLogic.CurOrder == 1 then for i=1, #fightData.playerData do BattleLogic.AddRole(fightData.playerData[i]) end for i=1, #fightData.enemyData[BattleLogic.CurOrder] do BattleLogic.AddRole(fightData.enemyData[BattleLogic.CurOrder][i]) end for i=1, #playerTeamSkillList do skillPool:Put(playerTeamSkillList[i]) playerTeamSkillList[i]=nil end for i=1, #fightData.playerData.teamSkill do playerTeamSkillList[i] = skillPool:Get() playerTeamSkillList[i]:Init(playerTeamDummyRole, fightData.playerData.teamSkill[i]) playerTeamSkillList[i].isTeamSkill = true end for i=1, #enemyTeamSkillList do skillPool:Put(enemyTeamSkillList[i]) enemyTeamSkillList[i]=nil end for i=1, #fightData.enemyData[BattleLogic.CurOrder].teamSkill do enemyTeamSkillList[i] = skillPool:Get() enemyTeamSkillList[i]:Init(enemyTeamDummyRole, fightData.enemyData[BattleLogic.CurOrder].teamSkill[i]) enemyTeamSkillList[i].isTeamSkill = true end else BattleLogic.ClearOrder() for i=1, #fightData.enemyData[BattleLogic.CurOrder] do BattleLogic.AddRole(fightData.enemyData[BattleLogic.CurOrder][i]) end for i=1, #enemyTeamSkillList do skillPool:Put(enemyTeamSkillList[i]) enemyTeamSkillList[i]=nil end for i=1, #fightData.enemyData[BattleLogic.CurOrder].teamSkill do enemyTeamSkillList[i] = skillPool:Get() enemyTeamSkillList[i]:Init(enemyTeamDummyRole, fightData.enemyData[BattleLogic.CurOrder].teamSkill[i]) enemyTeamSkillList[i].isTeamSkill = true end end BattleLogic.InitAggro() end function BattleLogic.AddMP(camp, mp) if camp == 0 then playerMP = math.min(playerMP + mp, 100) else enemyMP = math.min(playerMP + mp, 100) end end function BattleLogic.GetMP(camp) return camp == 0 and playerMP or enemyMP end function BattleLogic.GenerateBuffId() curBuffId = curBuffId + 1 return curBuffId end function BattleLogic.AddRole(roleData) curUid = curUid + 1 local data = rolePool:Get() --rolePool:Get(curUid, roleData) data:Init(curUid, roleData) objList:Add(curUid, data) BattleLogic.Event:DispatchEvent(BattleEventName.AddRole, data) end function BattleLogic.InitAggro() for i=1, objList.size do if objList.vList[i].camp == 1 then playerAggro = objList.vList[i] break end end for i=1, objList.size do if objList.vList[i].camp == 0 then enemyAggro = objList.vList[i] break end end end function BattleLogic.SetAggro(role, duration) if role.camp == 1 then if playerAggroChangable then playerAggro = role if enemySkillUsable then BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, role, math.max(duration/2, 0.3)) end playerAggroChangable = false BattleLogic.WaitForTrigger(duration-BattleLogic.GameDeltaTime, function () --减去一帧避免卡点 playerAggroChangable = true end) end else if enemyAggroChangable then enemyAggro = role enemyAggroChangable = false BattleLogic.WaitForTrigger(duration-BattleLogic.GameDeltaTime, function () --减去一帧避免卡点 enemyAggroChangable = true end) end end end function BattleLogic.GetAggro(camp) if camp == 0 then if not playerAggro or playerAggro.isDead then for i=1, objList.size do if objList.vList[i].camp == 1 and not objList.vList[i].isDead then playerAggro = objList.vList[i] BattleLogic.SetAggro(playerAggro, 0) break end end end return playerAggro else if not enemyAggro or enemyAggro.isDead then for i=1, objList.size do if objList.vList[i].camp == 0 and not objList.vList[i].isDead then enemyAggro = objList.vList[i] BattleLogic.SetAggro(enemyAggro, 0) break end end end return enemyAggro end end function BattleLogic.SetSkillUsable(camp, value) if camp == 0 then playerSkillUsable = value else enemySkillUsable = value end end function BattleLogic.GetSkillUsable(camp) if camp == 0 then return playerSkillUsable else return enemySkillUsable end end function BattleLogic.WaitForTrigger(delayTime, action) local item = actionPool:Get() item[1] = curFrame + floor(delayTime * BattleLogic.GameFrameRate + 0.5) item[2] = action tbActionList:Add(item) end function BattleLogic.AddOption(opType, opArg) table.insert(optionRecord, {curFrame + 1, opType, opArg}) end function BattleLogic.GetOption() return optionRecord end function BattleLogic.HasObj(obj) return obj and objList.kvList[obj.uid] end function BattleLogic.RemoveObj(uid) local role = objList.kvList[uid] if role then BattleLogic.Event:DispatchEvent(BattleEventName.RemoveRole, role) role:Dispose() rolePool:Put(role) objList:Remove(uid) end end function BattleLogic.CurFrame() return curFrame end local list = {} function BattleLogic.Query(func, inCludeDeadRole) for i=1, #list do list[i] = nil end --local list = {} local index = 1 if func then for i=1, objList.size do local v = objList.vList[i] if func(v) and (inCludeDeadRole or not v.isDead) then list[index] = v index = index + 1 end end end return list end function BattleLogic.BattleEnd(result) BattleLogic.IsEnd = true BattleLogic.Result = result BattleLogic.Event:DispatchEvent(BattleEventName.BattleEnd, result) end function BattleLogic.Clear() local index = 1 while index <= objList.size do BattleLogic.RemoveObj(objList.vList[index].uid) end index = 1 while index <= tbActionList.size do actionPool:Put(tbActionList.buffer[index]) tbActionList:Remove(index) end end function BattleLogic.ClearOrder() local index = 1 local count = objList.size while index <= count do if objList.vList[index].camp == 1 then BattleLogic.RemoveObj(objList.vList[index].uid) count = count - 1 else index = index + 1 end end end local tmpObj, index, bMyAllDead, bEnemyAllDead function BattleLogic.Update() curFrame = curFrame + 1 for i=1, #optionRecord do if optionRecord[i][1] == curFrame then local opType = optionRecord[i][2] local opArg = optionRecord[i][3] if opType == 1 then --自动手动 for i=1, objList.size do tmpObj = objList.vList[i] if tmpObj.camp == 0 then tmpObj.Auto = opArg == 1 end end elseif opType == 2 then --释放skill local role = objList.kvList[opArg] if role and role.skill then role.skill:Cast() end elseif opType == 3 then --释放superSkill local role = objList.kvList[opArg] if role and role.superSkill then role.superSkill:Cast() end end end end index = 1 while index <= tbActionList.size do if tbActionList.buffer[index][1] <= curFrame then if tbActionList.buffer[index][2] then tbActionList.buffer[index][2]() end actionPool:Put(tbActionList.buffer[index]) tbActionList:Remove(index) else index = index + 1 end end if playerMP == 100 and playerSkillUsable then local teamSkill = playerTeamSkillList[playerTeamSkillIndex] if teamSkill then teamSkill:Cast() playerTeamSkillIndex = playerTeamSkillIndex + 1 if playerTeamSkillIndex > #playerTeamSkillList then playerTeamSkillIndex = 1 end end playerMP = 0 end if enemyMP == 100 and enemySkillUsable then local teamSkill = enemyTeamSkillList[enemyTeamSkillIndex] if teamSkill then teamSkill:Cast() enemyTeamSkillIndex = enemyTeamSkillIndex + 1 if enemyTeamSkillIndex > #enemyTeamSkillList then enemyTeamSkillIndex = 1 end end enemyMP = 0 end bMyAllDead = true bEnemyAllDead = true for i=1, objList.size do tmpObj = objList.vList[i] if not tmpObj.isDead then tmpObj:Update() if tmpObj.camp == 0 then bMyAllDead = false else bEnemyAllDead = false end end end if bMyAllDead then BattleLogic.BattleEnd(0) end if bEnemyAllDead then if BattleLogic.CurOrder == BattleLogic.TotalOrder then BattleLogic.BattleEnd(1) else BattleLogic.CurOrder = BattleLogic.CurOrder + 1 BattleLogic.Event:DispatchEvent(BattleEventName.BattleOrderChange, BattleLogic.CurOrder) BattleLogic.StartOrder() end end end --Debug专用 function BattleLogic.SetDebug() local v for i=1, objList.size do v = objList.vList[i] v.IsDebug = not v.IsDebug end end --Debug专用 function BattleLogic.SetRoleValue(uid, name, value) if objList.kvList[uid] then objList.kvList[uid].data:SetValue(name, value) end end --Debug专用 function BattleLogic.SetRoleDebug(uid, isDebug) if objList.kvList[uid] then objList.kvList[uid].IsDebug = isDebug end end --Record专用 function BattleLogic.GetRecord() return record end --Record专用 function BattleLogic.RecordSeed(seed) table.insert(record, string.format("frame:%d, seed:%d", curFrame, seed)) end --Record专用 function BattleLogic.RecordRoleProperty(uid, camp, name, value, delta) table.insert(record, string.format("frame:%d, uid:%d, camp:%d, name:%s, value:%d, delta:%d", curFrame, uid, camp, name, value, delta)) end --Record专用 function BattleLogic.GenerateRecordFile() local time = string.format("%d-%d-%d-%d-%d-%d", os.date("%Y"), os.date("%m"), os.date("%d"), os.date("%H"), os.date("%M"), os.date("%S")) local file = io.open("BattleRecord/"..time..".txt", "a") for i=1, #record do file:write(record[i].."\n") end io.close(file) end