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

482 lines
13 KiB
Lua

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