miduo_server/luafight/BattleMain.lua

299 lines
9.8 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

-- windows
package.path = package.path ..';luafight/?.lua';
-- linux
package.path = package.path ..';../luafight/?.lua';
require("Modules.Battle.Logic.Misc.BattleDefine")
require("Modules.Battle.Logic.Misc.BattleUtil")
require("Modules.Battle.Logic.Misc.BattleQueue")
require("Modules.Battle.Logic.Misc.BattleDictionary")
require("Modules.Battle.Logic.Misc.BattleList")
require("Modules.Battle.Logic.Misc.BattleObjectPool")
require("Modules.Battle.Logic.Base.BattleEvent")
require("Modules.Battle.Logic.Base.Random")
require("Modules.Battle.Logic.Base.Buff")
require("Modules.Battle.Logic.Base.Passivity")
require("Modules.Battle.Logic.Role.RoleLogic")
require("Modules.Battle.Logic.Role.RoleData")
require("Modules.Battle.Logic.Role.RoleManager")
require("Modules.Battle.Logic.Role.Skill")
require("Modules.Battle.Logic.BattleLogic")
require("Modules.Battle.Logic.SkillManager")
require("Modules.Battle.Logic.OutDataManager")
require("Modules.Battle.Logic.BattleLogManager")
require("Modules.Battle.Logic.Monster.MonsterManager")
require("Modules.Battle.Logic.Weapon.FightWeaponManager")
require("Modules.Battle.Logic.HardStageCondition")
require("Modules.Battle.Logic.HardStageEventManager")
require "Modules/Battle/Data/ConfigData"
local BattleMain = {}
local BattleLogic = BattleLogic
local Random = Random
local _BattleErrorCache = {}
local _BattleErrorIndex = 0
local _seed
local _type
local _maxRound
local _fightData
local _optionData
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
local function PrintTable(tb)
local indent_str = "{"
local count = 0
for k,v in pairs(tb) do
count = count + 1
end
for k=1, #tb do
local v = tb[k]
if type(v) == "table" then
indent_str = indent_str .. PrintTable(v)
else
indent_str = indent_str .. tostring(v)
end
if k < count then
indent_str = indent_str..","
end
end
local index = 0
for k,v in pairsByKeys(tb) do
index = index + 1
if type(k) ~= "number" then
if type(v) == "table" then
indent_str = string.format("%s%s=%s", indent_str, tostring(k), PrintTable(v))
else
indent_str = string.format("%s%s=%s", indent_str, tostring(k), tostring(v))
end
if index < count then
indent_str = indent_str .. ","
end
end
end
indent_str = indent_str .. "}"
return indent_str
end
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
local function addBattleData()
local str = ""
str = str.."seed:\n"..tostring(_seed).."\n"
str = str.."type:\n"..tostring(_type).."\n"
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
function BattleMain.Execute(args, fightData, optionData)
_seed = args.seed
_type = args.type
_maxRound = args.maxRound
_fightData = fightData
_optionData = optionData or {}
--该开关用于输出战斗过程中的日志,用于验证前后端是否出现战斗不同步
BattleLogic.IsOpenBattleRecord = false
local isError = false
local errorCache
if xpcall(function ()
Random.SetSeed(args.seed)
BattleLogic.Init(fightData, optionData, _maxRound)
BattleLogic.Type = _type
BattleLogic.StartOrder()
-- local startTime = os.clock()
-- local cor = coroutine.create(function()
-- while not BattleLogic.IsEnd do
-- print(os.clock())
-- if os.clock() - startTime > 3 then
-- assert(false, "fight time out!!!")
-- break
-- end
-- end
-- end)
-- coroutine.resume(cor)
--debug.sethook(
-- function (event, line)
-- BattleLogManager.Log(debug.getinfo(2).short_src .. ":" .. line)
-- end
--, "l")
while not BattleLogic.IsEnd do
BattleLogic.Update()
end
end, function (err)
isError = true
errorCache = "error:\n"..debug.traceback(err).."\n"
end) then
local resultList = {0, 0, 0, 0, 0, 0}
if BattleLogic.Result == 1 then --胜利记录我方剩余血量
local arr = RoleManager.QueryIncludeExile(function (r) return r.camp == 0 end, true)
for i=1, #arr do
local pos = arr[i].position
resultList[pos] = arr[i]:GetRoleData(RoleDataName.Hp)
end
elseif BattleLogic.Result == 0 then --失败记录敌方剩余血量
local arr = RoleManager.QueryIncludeExile(function (r) return r.camp == 1 end, true)
for i=1, #arr do
local pos = arr[i].position
resultList[pos] = arr[i]:GetRoleData(RoleDataName.Hp)
end
end
if BattleLogic.IsOpenBattleRecord then
generateRecordFile()
end
-- print -----------------------------------------
--for i=1, #resultList do
-- print("hp:"..resultList[i])
--end
--print("最终运行帧数:"..BattleLogic.CurFrame())
local curRound, maxRound = BattleLogic.GetCurRound()
if curRound > maxRound and _type == BATTLE_SERVER_TYPE.SenLuoHuanJing then -- 森罗幻境超时返回两边血量战斗结果为2
resultList = {0, 0, 0, 0, 0, 0}
-- 第一位保存我方血量
local arr = RoleManager.QueryIncludeExile(function (r) return r.camp == 0 end, true)
if arr[1] then
resultList[1] = arr[1]:GetRoleData(RoleDataName.Hp)
end
-- 第二位保存地方血量
local arr = RoleManager.QueryIncludeExile(function (r) return r.camp == 1 end, true)
if arr[1] then
resultList[2] = arr[1]:GetRoleData(RoleDataName.Hp)
end
-- 结果为2
resultList.result = 2
else
resultList.result = BattleLogic.Result
end
resultList.curRound=curRound
local allHeroDamage, allEnemyDamage = BattleLogic.GetAllDamage()
-- print(allHeroDamage, allEnemyDamage)
if _type == BATTLE_SERVER_TYPE.GuildBossFight -- 公会boss
or _type == BATTLE_SERVER_TYPE.CarBossFight -- 车迟boss
or _type == BATTLE_SERVER_TYPE.GuildChallenge
or _type == BATTLE_SERVER_TYPE.CarPersonFight
then -- 公会副本 -- 返回伤害值
resultList.duration = allHeroDamage --TODO:公会boss的持续时间传递的是我方总伤害值
else
resultList.duration = BattleLogic.CurFrame() / BattleLogic.GameFrameRate
end
resultList.starRecord=BattleLogic.GetHardLevelStarRecord()
addBattleData()
return resultList
end
if isError then --捕获异常,并输出错误日志
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
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")
file:write(errorCache)
file:write("seed:\n"..tostring(args.seed).."\n")
file:write("type:\n"..tostring(args.type).."\n")
file:write("fightData:\n"..PrintTable(_fightData).."\n")
file:write("optionData:\n"..PrintTable(_optionData).."\n")
file:write("\n\nlast com.ljsd.battle data:\n")
for i=1, #_BattleErrorCache do
file:write(string.format("\nindex:%d\n", i))
file:write(_BattleErrorCache[i])
end
io.close(file)
end
return { result = -1 }
end
function BattleMain.TestExcute(data, seed, battleType, round, uid)
if type(data) == "string" then
data = loadstring("return "..data)()
end
local resultList = BattleMain.Execute({seed = seed, type = battleType, maxRound = round}, data, {uid = uid})
print(PrintTable(resultList))
end
return BattleMain