miduo_server/luafight/BattleMain.lua

337 lines
11 KiB
Lua
Raw Normal View History

2020-06-17 14:45:45 +08:00
-- windows
2019-03-21 15:32:29 +08:00
package.path = package.path ..';luafight/?.lua';
2019-06-24 11:21:25 +08:00
-- linux
2020-06-17 14:45:45 +08:00
package.path = package.path ..';../luafight/?.lua';
2019-03-12 14:05:45 +08:00
require("Modules.Battle.Logic.Misc.BattleDefine")
require("Modules.Battle.Logic.Misc.BattleUtil")
require("Modules.Battle.Logic.Misc.BattleQueue")
require("Modules.Battle.Logic.Misc.BattleDictionary")
2019-03-21 14:33:56 +08:00
require("Modules.Battle.Logic.Misc.BattleList")
require("Modules.Battle.Logic.Misc.BattleObjectPool")
2019-03-12 14:05:45 +08:00
require("Modules.Battle.Logic.Base.BattleEvent")
require("Modules.Battle.Logic.Base.Random")
2019-03-21 14:33:56 +08:00
2019-03-12 14:05:45 +08:00
require("Modules.Battle.Logic.Base.RoleData")
require("Modules.Battle.Logic.Base.Buff")
require("Modules.Battle.Logic.Base.Skill")
require("Modules.Battle.Logic.Base.Passivity")
2019-04-16 14:32:11 +08:00
require("Modules.Battle.Logic.BattleLogic")
require("Modules.Battle.Logic.RoleLogic")
2020-06-17 14:45:45 +08:00
require("Modules.Battle.Logic.SkillManager")
require("Modules.Battle.Logic.RoleManager")
require("Modules.Battle.Logic.OutDataManager")
require("Modules.Battle.Logic.BattleLogManager")
2019-03-21 15:01:27 +08:00
local BattleMain = {}
local BattleLogic = BattleLogic
local Random = Random
2019-12-12 11:42:56 +08:00
local BattleRecord
2019-03-21 14:33:56 +08:00
2019-08-20 15:38:33 +08:00
local _BattleErrorCache = {}
local _BattleErrorIndex = 0
local _seed
2019-08-31 13:45:45 +08:00
local _type
2020-05-07 16:31:28 +08:00
local _maxRound
2019-03-21 15:01:27 +08:00
local _fightData
local _optionData
2019-06-24 11:21:25 +08:00
local function pairsByKeys(t)
local a = {}
for n in pairs(t) do
if n then
a[#a+1] = n
end
end
table.sort(a, function( op1, op2 )
local type1, type2 = type(op1), type(op2)
local num1, num2 = tonumber(op1), tonumber(op2)
if ( num1 ~= nil) and (num2 ~= nil) then
return num1 < num2
elseif type1 ~= type2 then
return type1 < type2
elseif type1 == "string" then
return op1 < op2
elseif type1 == "boolean" then
return op1
-- 以上处理: number, string, boolean
else -- 处理剩下的: function, table, thread, userdata
return tostring(op1) < tostring(op2) -- tostring后比较字符串
end
end)
local i = 0
return function()
i = i + 1
return a[i], t[a[i]]
end
end
2019-03-22 15:00:06 +08:00
local function PrintTable(tb)
2019-03-21 15:01:27 +08:00
local indent_str = "{"
2019-05-15 12:05:54 +08:00
local count = 0
for k,v in pairs(tb) do
count = count + 1
end
2019-03-22 15:00:06 +08:00
for k=1, #tb do
local v = tb[k]
2019-03-21 15:01:27 +08:00
if type(v) == "table" then
indent_str = indent_str .. PrintTable(v)
2019-03-22 15:00:06 +08:00
else
2019-05-15 12:05:54 +08:00
indent_str = indent_str .. tostring(v)
end
if k < count then
indent_str = indent_str..","
2019-03-22 15:00:06 +08:00
end
end
2019-05-15 12:05:54 +08:00
local index = 0
2019-06-24 11:21:25 +08:00
for k,v in pairsByKeys(tb) do
2019-05-15 12:05:54 +08:00
index = index + 1
2019-03-22 15:00:06 +08:00
if type(k) ~= "number" then
if type(v) == "table" then
indent_str = string.format("%s%s=%s", indent_str, tostring(k), PrintTable(v))
else
2019-05-15 12:05:54 +08:00
indent_str = string.format("%s%s=%s", indent_str, tostring(k), tostring(v))
end
if index < count then
indent_str = indent_str .. ","
2019-03-22 15:00:06 +08:00
end
2019-03-21 15:01:27 +08:00
end
end
2019-05-15 12:05:54 +08:00
indent_str = indent_str .. "}"
2019-03-21 15:01:27 +08:00
return indent_str
end
2019-03-12 14:05:45 +08:00
2019-03-22 15:00:06 +08:00
local function 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("luafight/BattleRecord/"..time..".txt", "a")
local record = BattleLogic.GetRecord()
for i=1, #record do
file:write(record[i].."\n")
end
io.close(file)
end
2019-08-20 15:38:33 +08:00
local function addBattleData()
local str = ""
str = str.."seed:\n"..tostring(_seed).."\n"
2019-08-31 13:45:45 +08:00
str = str.."type:\n"..tostring(_type).."\n"
2019-08-20 15:38:33 +08:00
str = str.."fightData:\n"..PrintTable(_fightData).."\n"
str = str.."optionData:\n"..PrintTable(_optionData).."\n"
_BattleErrorIndex = _BattleErrorIndex + 1
if _BattleErrorIndex > 5 then
_BattleErrorIndex = 1
end
_BattleErrorCache[_BattleErrorIndex] = str
end
2019-12-26 17:39:02 +08:00
local function AddRecord(fightData)
2019-12-12 11:42:56 +08:00
BattleRecord = {}
BattleLogic.Event:AddEvent(BattleEventName.AddRole, function (role)
local record = {}
record.uid = role.uid
record.camp = role.camp
record.damage = 0
role.Event:AddEvent(BattleEventName.RoleDamage, function (defRole, damage, bCrit, finalDmg)
record.damage = record.damage + finalDmg
end)
BattleRecord[role.uid] = record
end)
2019-12-26 17:39:02 +08:00
for i=1, #fightData.playerData.teamSkill do
local teamCaster = BattleLogic.GetTeamSkillCaster(0)
local teamSkill = fightData.playerData.teamSkill[i]
local teamType = math.floor(teamSkill[1] / 100)
local str = "order:1".."camp:"..teamCaster.camp.." team"..teamSkill[1]
local record = {}
record.uid = str
record.camp = teamCaster.camp
record.damage = 0
record.order = 1
local curSkill
teamCaster.Event:AddEvent(BattleEventName.SkillCast, function (skill)
if skill.owner.camp == record.camp then
curSkill = skill
end
end)
teamCaster.Event:AddEvent(BattleEventName.RoleDamage, function (defRole, damage, bCrit, finalDmg)
if curSkill and curSkill.teamSkillType == teamType then
record.damage = record.damage + finalDmg
end
end)
BattleRecord[str] = record
end
for i=1, #fightData.enemyData do
for j=1, #fightData.enemyData[i].teamSkill do
local teamCaster = BattleLogic.GetTeamSkillCaster(1)
local teamSkill = fightData.enemyData[i].teamSkill[j]
local teamType = math.floor(teamSkill[1] / 100)
local str = "order:"..i.."camp:"..teamCaster.camp.." team"..teamSkill[1]
local record = {}
record.uid = str
record.camp = teamCaster.camp
record.damage = 0
record.order = i
local curSkill
teamCaster.Event:AddEvent(BattleEventName.SkillCast, function (skill)
if skill.owner.camp == record.camp then
curSkill = skill
end
end)
teamCaster.Event:AddEvent(BattleEventName.RoleDamage, function (defRole, damage, bCrit, finalDmg)
if curSkill and curSkill.teamSkillType == teamType and record.order == BattleLogic.CurOrder then
record.damage = record.damage + finalDmg
end
end)
BattleRecord[str] = record
end
end
2019-12-12 11:42:56 +08:00
end
2019-05-09 17:50:38 +08:00
function BattleMain.Execute(args, fightData, optionData)
2019-08-20 15:38:33 +08:00
_seed = args.seed
2019-08-31 13:45:45 +08:00
_type = args.type
2020-05-07 16:31:28 +08:00
_maxRound = args.maxRound
2019-03-21 15:01:27 +08:00
_fightData = fightData
2019-06-03 13:43:32 +08:00
_optionData = optionData or {}
2019-03-12 14:05:45 +08:00
2019-03-21 15:01:27 +08:00
--该开关用于输出战斗过程中的日志,用于验证前后端是否出现战斗不同步
2019-12-26 17:39:02 +08:00
BattleLogic.IsOpenBattleRecord = false
2019-03-21 14:33:56 +08:00
2019-06-03 13:43:32 +08:00
local isError = false
local errorCache
2019-03-21 15:01:27 +08:00
if xpcall(function ()
2019-05-09 17:50:38 +08:00
Random.SetSeed(args.seed)
2020-05-07 16:31:28 +08:00
BattleLogic.Init(fightData, optionData, _maxRound)
2019-08-31 13:45:45 +08:00
BattleLogic.Type = _type
2020-08-22 15:38:31 +08:00
if _type == 9 or _type == 10 or _type == 11 or _type == 14 then
2019-12-26 17:39:02 +08:00
AddRecord(fightData)
2019-12-12 11:42:56 +08:00
end
2019-03-21 15:01:27 +08:00
BattleLogic.StartOrder()
2019-03-21 14:33:56 +08:00
2019-03-21 15:01:27 +08:00
while not BattleLogic.IsEnd do
BattleLogic.Update()
end
2019-06-03 13:43:32 +08:00
end, function (err)
isError = true
errorCache = "error:\n"..debug.traceback(err).."\n"
end) then
2020-08-22 15:38:31 +08:00
local resultList = {0, 0, 0, 0, 0, 0}
2019-03-21 15:01:27 +08:00
if BattleLogic.Result == 1 then --胜利记录我方剩余血量
2020-05-07 16:31:28 +08:00
local arr = RoleManager.Query(function (r) return r.camp == 0 end, true)
2019-03-21 15:01:27 +08:00
for i=1, #arr do
2020-08-22 15:38:31 +08:00
local pos = arr[i].position
resultList[pos] = arr[i]:GetRoleData(RoleDataName.Hp)
2019-03-21 14:33:56 +08:00
end
2019-03-21 15:01:27 +08:00
elseif BattleLogic.Result == 0 then --失败记录敌方剩余血量
2020-05-07 16:31:28 +08:00
local arr = RoleManager.Query(function (r) return r.camp == 1 end, true)
2019-03-21 15:01:27 +08:00
for i=1, #arr do
2020-08-22 15:38:31 +08:00
local pos = arr[i].position
resultList[pos] = arr[i]:GetRoleData(RoleDataName.Hp)
2019-03-21 14:33:56 +08:00
end
end
2019-12-12 11:42:56 +08:00
2019-03-12 14:05:45 +08:00
2019-03-21 15:01:27 +08:00
if BattleLogic.IsOpenBattleRecord then
2019-03-22 15:00:06 +08:00
generateRecordFile()
2019-03-12 14:05:45 +08:00
end
2019-03-21 15:01:27 +08:00
-- print -----------------------------------------
2019-03-22 18:36:24 +08:00
--for i=1, #resultList do
-- print("hp:"..resultList[i])
--end
--print("最终运行帧数:"..BattleLogic.CurFrame())
2020-05-07 16:31:28 +08:00
local curRound, maxRound = BattleLogic.GetCurRound()
2020-04-10 18:04:21 +08:00
if curRound > maxRound and _type == 9 then
2019-12-12 11:42:56 +08:00
local playerDamage=0
local enemyDamage=0
for k,v in pairs(BattleRecord)do
if v.camp == 0 then
playerDamage = playerDamage + v.damage
else
enemyDamage = enemyDamage + v.damage
end
end
resultList.result = playerDamage > enemyDamage and 1 or 0
else
resultList.result = BattleLogic.Result
end
2020-01-07 19:24:55 +08:00
2020-08-22 15:38:31 +08:00
if _type == 10 or _type == 11 or _type == 14 then -- 公会boss和车迟斗法boss返回伤害值
2020-01-08 17:58:36 +08:00
local playerDamage=0
for k,v in pairs(BattleRecord)do
if v.camp == 0 then
playerDamage = playerDamage + v.damage
end
end
resultList.duration = playerDamage --TODO:公会boss的持续时间传递的是我方总伤害值
else
resultList.duration = BattleLogic.CurFrame() / BattleLogic.GameFrameRate
end
2020-01-07 19:24:55 +08:00
2019-03-22 15:00:06 +08:00
2019-08-20 15:38:33 +08:00
addBattleData()
2019-06-30 19:24:45 +08:00
return resultList
end
if isError then --捕获异常,并输出错误日志
2019-06-30 18:15:18 +08:00
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"))
2020-06-17 14:45:45 +08:00
local file
local platform
-- linux
if not file then
file = io.open("../luafight/LogError/"..time..".txt", "a")
platform = "Linux"
end
-- local window server
if not file then
file = io.open("luafight/LogError/"..time..".txt", "a")
platform = "Local Windows Server"
end
-- local
if not file then
file = io.open("LogError/"..time..".txt", "a")
platform = "Local"
end
file:write(platform..":\n\n\n")
2019-06-30 19:24:45 +08:00
file:write(errorCache)
2019-08-20 15:38:33 +08:00
file:write("seed:\n"..tostring(args.seed).."\n")
2019-08-31 13:45:45 +08:00
file:write("type:\n"..tostring(args.type).."\n")
2019-06-30 18:15:18 +08:00
file:write("fightData:\n"..PrintTable(_fightData).."\n")
file:write("optionData:\n"..PrintTable(_optionData).."\n")
file:write("\n\nlast com.ljsd.battle data:\n")
2019-08-20 15:38:33 +08:00
for i=1, #_BattleErrorCache do
file:write(string.format("\nindex:%d\n", i))
file:write(_BattleErrorCache[i])
end
2019-06-30 18:15:18 +08:00
io.close(file)
2019-06-03 13:43:32 +08:00
end
2019-03-21 15:01:27 +08:00
return { result = -1 }
2019-03-12 14:05:45 +08:00
end
2020-05-07 16:31:28 +08:00
2019-03-21 15:01:27 +08:00
return BattleMain