400 lines
11 KiB
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 |