miduo_server/luafight/Modules/Battle/Logic/BattleLogic.lua

532 lines
15 KiB
Lua
Raw Normal View History

2019-03-12 14:05:45 +08:00
BattleLogic = {}
local floor = math.floor
2019-03-22 15:00:06 +08:00
local min = math.min
2019-03-21 14:33:56 +08:00
local objList = BattleDictionary.New()
2019-04-17 21:04:32 +08:00
local removeObjList = BattleList.New()
2019-03-21 14:33:56 +08:00
2019-03-12 14:05:45 +08:00
local curUid
local curBuffId
local curFrame
local playerMP
local enemyMP
local playerAggro
local enemyAggro
2019-03-21 14:33:56 +08:00
local playerSkillUsable
local enemySkillUsable
2019-04-17 21:04:32 +08:00
local isAuto
2019-03-21 14:33:56 +08:00
BattleLogic.IsEnd = false
BattleLogic.Result = -1
BattleLogic.Event = BattleEvent.New()
2019-04-16 14:32:11 +08:00
BattleLogic.BuffMgr = BuffManager.New()
2019-03-21 14:33:56 +08:00
2019-07-11 15:18:00 +08:00
local playerTeamDummyRole = {camp = 0, Event = BattleLogic.Event, isTeam = true, curSkill = nil}
local enemyTeamDummyRole = {camp = 1, Event = BattleLogic.Event, isTeam = true, curSkill = nil}
2019-03-21 14:33:56 +08:00
local playerTeamSkillList = {}
local enemyTeamSkillList = {}
local playerTeamSkillIndex
local enemyTeamSkillIndex
2019-03-12 14:05:45 +08:00
local fightData
local record
local optionRecord
--是否开启战斗日志
BattleLogic.IsOpenBattleRecord = false
--逻辑帧频
BattleLogic.GameFrameRate = 30
BattleLogic.GameDeltaTime = 1 / BattleLogic.GameFrameRate
--总波次
BattleLogic.TotalOrder = 0
--当前波次
BattleLogic.CurOrder = 0
2019-05-09 17:50:38 +08:00
local maxFrame --战斗最大用时,超时判负
2019-03-21 14:33:56 +08:00
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)
2019-05-09 17:50:38 +08:00
function BattleLogic.Init(maxTime, data, optionData)
2019-03-12 14:05:45 +08:00
if BattleLogic.IsOpenBattleRecord then
record = {}
end
2019-05-09 17:50:38 +08:00
maxFrame = BattleLogic.GameFrameRate * maxTime
2019-03-12 14:05:45 +08:00
fightData = data
if optionData then
optionRecord = optionData
else
optionRecord = {}
end
BattleLogic.CurOrder = 0
BattleLogic.TotalOrder = #data.enemyData
2019-03-21 14:33:56 +08:00
BattleLogic.Clear()
2019-03-12 14:05:45 +08:00
curUid = 0
curBuffId = 0
curFrame = 0
2019-03-21 14:33:56 +08:00
2019-03-12 14:05:45 +08:00
playerMP = 0
enemyMP = 0
2019-03-21 14:33:56 +08:00
playerTeamSkillIndex = 1
enemyTeamSkillIndex = 1
playerSkillUsable = true
enemySkillUsable = true
2019-04-17 21:04:32 +08:00
isAuto = true
2019-03-12 14:05:45 +08:00
BattleLogic.Event:ClearEvent()
2019-04-16 14:32:11 +08:00
BattleLogic.BuffMgr:Init()
2019-03-12 14:05:45 +08:00
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
2019-03-21 14:33:56 +08:00
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
2019-03-12 14:05:45 +08:00
else
BattleLogic.ClearOrder()
for i=1, #fightData.enemyData[BattleLogic.CurOrder] do
BattleLogic.AddRole(fightData.enemyData[BattleLogic.CurOrder][i])
end
2019-03-21 14:33:56 +08:00
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
2019-03-12 14:05:45 +08:00
end
BattleLogic.InitAggro()
end
function BattleLogic.AddMP(camp, mp)
if camp == 0 then
2019-04-17 21:04:32 +08:00
if #playerTeamSkillList > 0 then
playerMP = min(playerMP + mp, 100)
end
2019-03-12 14:05:45 +08:00
else
2019-04-17 21:04:32 +08:00
if #enemyTeamSkillList > 0 then
enemyMP = min(enemyMP + mp, 100)
end
2019-03-12 14:05:45 +08:00
end
end
function BattleLogic.GetMP(camp)
return camp == 0 and playerMP or enemyMP
end
2019-04-17 21:04:32 +08:00
function BattleLogic.GetAuto()
return isAuto
end
2019-03-12 14:05:45 +08:00
function BattleLogic.GenerateBuffId()
curBuffId = curBuffId + 1
return curBuffId
end
function BattleLogic.AddRole(roleData)
curUid = curUid + 1
2019-06-28 11:28:45 +08:00
local role = rolePool:Get()
role:Init(curUid, roleData)
objList:Add(curUid, role)
if not role.isDead then
BattleLogic.Event:DispatchEvent(BattleEventName.AddRole, role)
2019-03-27 15:47:27 +08:00
end
2019-03-12 14:05:45 +08:00
end
function BattleLogic.InitAggro()
2019-03-21 14:33:56 +08:00
for i=1, objList.size do
if objList.vList[i].camp == 1 then
playerAggro = objList.vList[i]
2019-03-12 14:05:45 +08:00
break
end
end
2019-03-21 14:33:56 +08:00
for i=1, objList.size do
if objList.vList[i].camp == 0 then
enemyAggro = objList.vList[i]
2019-03-12 14:05:45 +08:00
break
end
end
2019-04-17 21:04:32 +08:00
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, playerAggro, 1)
2019-03-12 14:05:45 +08:00
end
2019-04-17 21:04:32 +08:00
function BattleLogic.SetAggro(role)
2019-04-20 13:02:14 +08:00
if role.isTeam then
return
end
2019-03-12 14:05:45 +08:00
if role.camp == 1 then
2019-03-23 17:06:14 +08:00
playerAggro = role
2019-04-17 21:04:32 +08:00
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, role, 1)
2019-03-12 14:05:45 +08:00
else
2019-03-23 17:06:14 +08:00
enemyAggro = role
2019-03-12 14:05:45 +08:00
end
end
function BattleLogic.GetAggro(camp)
if camp == 0 then
if not playerAggro or playerAggro.isDead then
2019-03-21 14:33:56 +08:00
for i=1, objList.size do
if objList.vList[i].camp == 1 and not objList.vList[i].isDead then
playerAggro = objList.vList[i]
2019-04-17 21:04:32 +08:00
BattleLogic.SetAggro(playerAggro)
2019-03-12 14:05:45 +08:00
break
end
end
end
return playerAggro
else
if not enemyAggro or enemyAggro.isDead then
2019-03-21 14:33:56 +08:00
for i=1, objList.size do
if objList.vList[i].camp == 0 and not objList.vList[i].isDead then
enemyAggro = objList.vList[i]
2019-04-17 21:04:32 +08:00
BattleLogic.SetAggro(enemyAggro)
2019-03-12 14:05:45 +08:00
break
end
end
end
return enemyAggro
end
end
2019-03-21 14:33:56 +08:00
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
2019-03-12 14:05:45 +08:00
function BattleLogic.WaitForTrigger(delayTime, action)
2019-03-23 17:06:14 +08:00
delayTime = floor(delayTime * 100000 + 0.5) / 100000 --进行精度处理,避免前后端计算不一致
local delayFrame = floor(delayTime * BattleLogic.GameFrameRate + 0.5)
2019-04-18 13:25:01 +08:00
if delayFrame == 0 then --0延迟的回调直接调用
action()
return
end
2019-03-21 14:33:56 +08:00
local item = actionPool:Get()
2019-03-23 17:06:14 +08:00
item[1] = curFrame + delayFrame
2019-03-21 14:33:56 +08:00
item[2] = action
tbActionList:Add(item)
2019-03-23 13:18:16 +08:00
if BattleLogic.IsOpenBattleRecord then
2019-03-23 17:06:14 +08:00
BattleLogic.RecordDelayTrigger(delayTime, curFrame + delayFrame)
2019-03-23 13:18:16 +08:00
end
2019-03-12 14:05:45 +08:00
end
function BattleLogic.AddOption(opType, opArg)
table.insert(optionRecord, {curFrame + 1, opType, opArg})
end
function BattleLogic.GetOption()
return optionRecord
end
2019-05-10 19:31:20 +08:00
--执行操作逻辑
function BattleLogic.ExecuteOption(option)
local opType = option[2]
local opArg = option[3]
if opType == 1 then --全局自动手动
for i=1, objList.size do
local 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
elseif opType == 4 then --释放teamSkill
local teamSkill = playerTeamSkillList[playerTeamSkillIndex]
if teamSkill then
teamSkill:Cast()
playerTeamSkillIndex = playerTeamSkillIndex + 1
if playerTeamSkillIndex > #playerTeamSkillList then
playerTeamSkillIndex = 1
end
playerMP = 0
end
elseif opType == 4 then --释放teamSkill
local teamSkill = playerTeamSkillList[playerTeamSkillIndex]
if teamSkill then
teamSkill:Cast()
playerTeamSkillIndex = playerTeamSkillIndex + 1
if playerTeamSkillIndex > #playerTeamSkillList then
playerTeamSkillIndex = 1
end
playerMP = 0
end
elseif opType == 5 then --设置teamSkill自动手动
isAuto = opArg == 1
elseif opType == 6 then --切换单个角色自动手动 arg == uid * 10 + auto(0手动1自动)
local auto = opArg % 10
local uid = floor(opArg / 10)
if objList.kvList[uid] then
objList.kvList[uid].Auto = auto == 1
end
end
end
2019-03-12 14:05:45 +08:00
function BattleLogic.HasObj(obj)
2019-03-21 14:33:56 +08:00
return obj and objList.kvList[obj.uid]
2019-03-12 14:05:45 +08:00
end
function BattleLogic.CurFrame()
return curFrame
end
2019-04-20 17:21:45 +08:00
function BattleLogic.Query(func, inCludeDeadRole)
2019-03-22 18:36:24 +08:00
local list = {}
2019-03-12 14:05:45 +08:00
local index = 1
if func then
2019-03-21 14:33:56 +08:00
for i=1, objList.size do
local v = objList.vList[i]
2019-04-20 17:21:45 +08:00
if func(v) and (inCludeDeadRole or not v.isDead) then
2019-03-12 14:05:45 +08:00
list[index] = v
index = index + 1
end
end
end
return list
end
2019-03-21 14:33:56 +08:00
function BattleLogic.BattleEnd(result)
BattleLogic.IsEnd = true
BattleLogic.Result = result
BattleLogic.Event:DispatchEvent(BattleEventName.BattleEnd, result)
end
function BattleLogic.Clear()
2019-03-22 11:00:12 +08:00
while objList.size > 0 do
2019-04-17 21:04:32 +08:00
objList.vList[objList.size]:Dispose()
removeObjList:Add(objList.vList[objList.size])
objList:Remove(objList.vList[objList.size].uid)
end
while removeObjList.size > 0 do
rolePool:Put(removeObjList.buffer[removeObjList.size])
removeObjList:Remove(removeObjList.size)
2019-03-21 14:33:56 +08:00
end
2019-03-22 11:00:12 +08:00
while tbActionList.size > 0 do
actionPool:Put(tbActionList.buffer[tbActionList.size])
tbActionList:Remove(tbActionList.size)
2019-03-21 14:33:56 +08:00
end
end
2019-03-12 14:05:45 +08:00
function BattleLogic.ClearOrder()
local index = 1
2019-03-22 11:00:12 +08:00
while index <= objList.size do
2019-03-21 14:33:56 +08:00
if objList.vList[index].camp == 1 then
2019-04-17 21:04:32 +08:00
BattleLogic.Event:DispatchEvent(BattleEventName.RemoveRole, objList.vList[index])
objList.vList[index]:Dispose()
removeObjList:Add(objList.vList[index])
objList:Remove(objList.vList[index].uid)
2019-03-12 14:05:45 +08:00
else
index = index + 1
end
end
end
function BattleLogic.Update()
curFrame = curFrame + 1
2019-03-28 11:56:26 +08:00
if curFrame > maxFrame then
BattleLogic.BattleEnd(0)
return
end
2019-03-12 14:05:45 +08:00
for i=1, #optionRecord do
if optionRecord[i][1] == curFrame then
2019-05-10 19:31:20 +08:00
BattleLogic.ExecuteOption(optionRecord[i])
2019-03-12 14:05:45 +08:00
end
end
2019-04-17 21:04:32 +08:00
local index = 1
2019-03-21 14:33:56 +08:00
while index <= tbActionList.size do
2019-04-17 21:04:32 +08:00
local action = tbActionList.buffer[index]
if action[1] <= curFrame then
action[2]()
actionPool:Put(action)
2019-03-21 14:33:56 +08:00
tbActionList:Remove(index)
2019-03-12 14:05:45 +08:00
else
index = index + 1
end
end
2019-04-17 21:04:32 +08:00
if playerMP == 100 and playerSkillUsable and isAuto then
2019-03-21 14:33:56 +08:00
local teamSkill = playerTeamSkillList[playerTeamSkillIndex]
if teamSkill then
teamSkill:Cast()
playerTeamSkillIndex = playerTeamSkillIndex + 1
if playerTeamSkillIndex > #playerTeamSkillList then
playerTeamSkillIndex = 1
end
2019-04-17 21:04:32 +08:00
playerMP = 0
2019-03-12 14:05:45 +08:00
end
2019-03-21 14:33:56 +08:00
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
2019-04-17 21:04:32 +08:00
enemyMP = 0
2019-03-21 14:33:56 +08:00
end
2019-03-12 14:05:45 +08:00
end
2019-04-16 14:32:11 +08:00
BattleLogic.BuffMgr:Update()
2019-04-17 21:04:32 +08:00
local bMyAllDead = true
local bEnemyAllDead = true
2019-03-21 14:33:56 +08:00
for i=1, objList.size do
2019-04-17 21:04:32 +08:00
local tmpObj = objList.vList[i]
2019-03-12 14:05:45 +08:00
if not tmpObj.isDead then
tmpObj:Update()
if tmpObj.camp == 0 then
bMyAllDead = false
else
bEnemyAllDead = false
end
end
end
if bMyAllDead then
2019-03-21 14:33:56 +08:00
BattleLogic.BattleEnd(0)
2019-03-12 14:05:45 +08:00
end
if bEnemyAllDead then
if BattleLogic.CurOrder == BattleLogic.TotalOrder then
2019-03-21 14:33:56 +08:00
BattleLogic.BattleEnd(1)
2019-03-12 14:05:45 +08:00
else
2019-04-04 14:36:07 +08:00
BattleLogic.Event:DispatchEvent(BattleEventName.BattleOrderChange, BattleLogic.CurOrder + 1)
2019-03-12 14:05:45 +08:00
BattleLogic.StartOrder()
end
end
end
--Debug专用
function BattleLogic.SetDebug()
2019-03-21 14:33:56 +08:00
for i=1, objList.size do
2019-04-17 21:04:32 +08:00
local v = objList.vList[i]
2019-03-12 14:05:45 +08:00
v.IsDebug = not v.IsDebug
end
end
--Debug专用
function BattleLogic.SetRoleValue(uid, name, value)
2019-03-21 14:33:56 +08:00
if objList.kvList[uid] then
objList.kvList[uid].data:SetValue(name, value)
2019-03-12 14:05:45 +08:00
end
end
--Debug专用
function BattleLogic.SetRoleDebug(uid, isDebug)
2019-03-21 14:33:56 +08:00
if objList.kvList[uid] then
objList.kvList[uid].IsDebug = isDebug
2019-03-12 14:05:45 +08:00
end
end
2019-03-21 17:24:21 +08:00
--Record专用
function BattleLogic.GetRecord()
return record
end
2019-03-12 14:05:45 +08:00
--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
2019-03-22 18:36:24 +08:00
--Record专用
function BattleLogic.RecordEffect(caster, target, type, args, interval)
local cUid = tostring(caster.uid) or "cTeam"
local tUid = tostring(target.uid) or "tTeam"
local str = ""
for i=1, #args do
str = str..tostring(args[i]) .. (i == #args and "" or "#")
end
table.insert(record, string.format("frame:%d, caster:%s, target:%s, effectType:%d, args:%s, interval:%d", curFrame, cUid, tUid, type, str, interval))
end
2019-03-23 13:18:16 +08:00
--Record专用
function BattleLogic.RecordDelayTrigger(delayFrame, triggerFrame)
2019-03-23 17:06:14 +08:00
table.insert(record, string.format("frame:%d, delayTime:%f, triggerFrame:%d", curFrame, delayFrame, triggerFrame))
2019-03-23 13:18:16 +08:00
end
2019-03-12 14:05:45 +08:00
--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