BattleLogic = {} local floor = math.floor local tbObjList local tbActionList local tbActionListCount = 0 local curUid local curBuffId local curFrame local playerMP local enemyMP local playerAggro local enemyAggro local playerAggroChangable local enemyAggroChangable local fightData local record local optionRecord BattleLogic.IsEnd = false BattleLogic.Result = -1 BattleLogic.Event = BattleEvent:New() --是否开启战斗日志 BattleLogic.IsOpenBattleRecord = false --逻辑帧频 BattleLogic.GameFrameRate = 30 BattleLogic.GameDeltaTime = 1 / BattleLogic.GameFrameRate BattleLogic.SkillUsable = true --总波次 BattleLogic.TotalOrder = 0 --当前波次 BattleLogic.CurOrder = 0 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 tbObjList = BattleDictionary.New() tbActionList = {} tbActionListCount = 0 curUid = 0 curBuffId = 0 curFrame = 0 playerMP = 0 enemyMP = 0 playerAggroChangable = true enemyAggroChangable = true BattleLogic.Event:ClearEvent() BattleLogic.IsEnd = false BattleLogic.Result = -1 BattleLogic.SkillUsable = true 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 else BattleLogic.ClearOrder() for i=1, #fightData.enemyData[BattleLogic.CurOrder] do BattleLogic.AddRole(fightData.enemyData[BattleLogic.CurOrder][i]) 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 = RoleLogic.New(curUid, roleData) tbObjList:Add(curUid, data) BattleLogic.Event:DispatchEvent(BattleEventName.AddRole, data) end function BattleLogic.InitAggro() for i=1, tbObjList.size do if tbObjList.vList[i].camp == 1 then playerAggro = tbObjList.vList[i] break end end for i=1, tbObjList.size do if tbObjList.vList[i].camp == 0 then enemyAggro = tbObjList.vList[i] break end end end function BattleLogic.SetAggro(role, duration) if role.camp == 1 then if playerAggroChangable then playerAggro = role BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, role, math.max(duration, 0.3)) 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, tbObjList.size do if tbObjList.vList[i].camp == 1 and not tbObjList.vList[i].isDead then playerAggro = tbObjList.vList[i] BattleLogic.SetAggro(playerAggro, 0) break end end end return playerAggro else if not enemyAggro or enemyAggro.isDead then for i=1, tbObjList.size do if tbObjList.vList[i].camp == 0 and not tbObjList.vList[i].isDead then enemyAggro = tbObjList.vList[i] BattleLogic.SetAggro(enemyAggro, 0) break end end end return enemyAggro end end function BattleLogic.WaitForTrigger(delayTime, action) tbActionListCount = tbActionListCount + 1 tbActionList[tbActionListCount] = { curFrame + floor(delayTime * BattleLogic.GameFrameRate + 0.5), action } 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 tbObjList.kvList[obj.uid] end function BattleLogic.RemoveObj(uid) local role = tbObjList.kvList[uid] if role then BattleLogic.Event:DispatchEvent(BattleEventName.RemoveRole, role) tbObjList:Remove(uid) end end function BattleLogic.CurFrame() return curFrame end function BattleLogic.Query(func, inCludeDeadRole) local list = {} local index = 1 if func then for i=1, tbObjList.size do local v = tbObjList.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.ClearOrder() local index = 1 local count = tbObjList.size while index <= count do if tbObjList.vList[index].camp == 1 then BattleLogic.RemoveObj(tbObjList.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, tbObjList.size do tmpObj = tbObjList.vList[i] if tmpObj.camp == 0 then tmpObj.Auto = opArg == 1 end end elseif opType == 2 then --释放skill local role = tbObjList.kvList[opArg] if role and role.skill then role.skill:Cast() end elseif opType == 3 then --释放superSkill local role = tbObjList.kvList[opArg] if role and role.superSkill then role.superSkill:Cast() end end end end index = 1 while index <= tbActionListCount do if tbActionList[index][1] <= curFrame then if tbActionList[index][2] then tbActionList[index][2]() end table.remove(tbActionList, index) tbActionListCount = tbActionListCount - 1 else index = index + 1 end end if playerMP == 100 then if Random.Range01() < 0.5 then local roleArr = BattleLogic.Query(function (r) return r.camp == 0 end) BattleLogic.Event:DispatchEvent(BattleEventName.AOE, 0) --延迟1帧释放效果 BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function () for i = 1, #roleArr do local role = roleArr[i] BattleLogic.WaitForTrigger(0.3, function () BattleUtil.ApplyTreat(role, role, 50) end) end end) else local roleArr = BattleLogic.Query(function (r) return r.camp == 1 end) BattleLogic.Event:DispatchEvent(BattleEventName.AOE, 1) --延迟1帧释放效果 BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function () for i = 1, #roleArr do local role = roleArr[i] for j=1, 4 do BattleLogic.WaitForTrigger(0.1 * (j-1), function () BattleUtil.ApplyDamage(nil, role, 5) end) end end end) end playerMP = 0 BattleLogic.SkillUsable = false BattleLogic.WaitForTrigger(2, function () BattleLogic.SkillUsable = true end) end bMyAllDead = true bEnemyAllDead = true for i=1, tbObjList.size do tmpObj = tbObjList.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.IsEnd = true BattleLogic.Result = 0 BattleLogic.Event:DispatchEvent(BattleEventName.BattleEnd, 0) end if bEnemyAllDead then if BattleLogic.CurOrder == BattleLogic.TotalOrder then BattleLogic.IsEnd = true BattleLogic.Result = 1 BattleLogic.Event:DispatchEvent(BattleEventName.BattleEnd, 1) else BattleLogic.CurOrder = BattleLogic.CurOrder + 1 --for i=1, tbObjList.size do --切波次重置技能冷却时间 -- tmpObj = tbObjList.vList[i] -- if tmpObj.camp == 0 then -- if tmpObj.skill then -- tmpObj.skill.sp = 0 -- end -- if tmpObj.superSkill then -- tmpObj.superSkill.sp = 0 -- end -- end --end --playerMP = 0 --tbActionList = {} --tbActionListCount = 0 BattleLogic.SkillUsable = true BattleLogic.Event:DispatchEvent(BattleEventName.BattleOrderChange, BattleLogic.CurOrder) BattleLogic.StartOrder() end end end --Debug专用 function BattleLogic.SetDebug() local v for i=1, tbObjList.size do v = tbObjList.vList[i] v.IsDebug = not v.IsDebug end end --Debug专用 function BattleLogic.SetRoleValue(uid, name, value) if tbObjList.kvList[uid] then tbObjList.kvList[uid].data:SetValue(name, value) end end --Debug专用 function BattleLogic.SetRoleDebug(uid, isDebug) if tbObjList.kvList[uid] then tbObjList.kvList[uid].IsDebug = isDebug end 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