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

400 lines
11 KiB
Lua

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