BattleMain.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. -- windows
  2. package.path = package.path ..';luafight/?.lua';
  3. -- linux
  4. package.path = package.path ..';../luafight/?.lua';
  5. require("Modules.Battle.Logic.Misc.BattleDefine")
  6. require("Modules.Battle.Logic.Misc.BattleUtil")
  7. require("Modules.Battle.Logic.Misc.BattleQueue")
  8. require("Modules.Battle.Logic.Misc.BattleDictionary")
  9. require("Modules.Battle.Logic.Misc.BattleList")
  10. require("Modules.Battle.Logic.Misc.BattleObjectPool")
  11. require("Modules.Battle.Logic.Base.BattleEvent")
  12. require("Modules.Battle.Logic.Base.Random")
  13. require("Modules.Battle.Logic.Base.RoleData")
  14. require("Modules.Battle.Logic.Base.Buff")
  15. require("Modules.Battle.Logic.Base.Skill")
  16. require("Modules.Battle.Logic.Base.Passivity")
  17. require("Modules.Battle.Logic.BattleLogic")
  18. require("Modules.Battle.Logic.RoleLogic")
  19. require("Modules.Battle.Logic.SkillManager")
  20. require("Modules.Battle.Logic.RoleManager")
  21. require("Modules.Battle.Logic.OutDataManager")
  22. require("Modules.Battle.Logic.BattleLogManager")
  23. require("Modules.Battle.Logic.FightUnitLogic")
  24. require("Modules.Battle.Logic.FightUnitManager")
  25. require("Modules.Language")
  26. require("Modules.Debug")
  27. local BattleMain = {}
  28. local BattleLogic = BattleLogic
  29. local Random = Random
  30. local BattleRecord
  31. local _BattleErrorCache = {}
  32. local _BattleErrorIndex = 0
  33. local _seed
  34. local _type
  35. local _maxRound
  36. local _fightData
  37. local _optionData
  38. local function pairsByKeys(t)
  39. local a = {}
  40. for n in pairs(t) do
  41. if n then
  42. a[#a+1] = n
  43. end
  44. end
  45. table.sort(a, function( op1, op2 )
  46. local type1, type2 = type(op1), type(op2)
  47. local num1, num2 = tonumber(op1), tonumber(op2)
  48. if ( num1 ~= nil) and (num2 ~= nil) then
  49. return num1 < num2
  50. elseif type1 ~= type2 then
  51. return type1 < type2
  52. elseif type1 == "string" then
  53. return op1 < op2
  54. elseif type1 == "boolean" then
  55. return op1
  56. -- 以上处理: number, string, boolean
  57. else -- 处理剩下的: function, table, thread, userdata
  58. return tostring(op1) < tostring(op2) -- tostring后比较字符串
  59. end
  60. end)
  61. local i = 0
  62. return function()
  63. i = i + 1
  64. return a[i], t[a[i]]
  65. end
  66. end
  67. local function PrintTable(tb)
  68. local indent_str = "{"
  69. local count = 0
  70. for k,v in pairs(tb) do
  71. count = count + 1
  72. end
  73. for k=1, #tb do
  74. local v = tb[k]
  75. if type(v) == "table" then
  76. indent_str = indent_str .. PrintTable(v)
  77. else
  78. indent_str = indent_str .. tostring(v)
  79. end
  80. if k < count then
  81. indent_str = indent_str..","
  82. end
  83. end
  84. local index = 0
  85. for k,v in pairsByKeys(tb) do
  86. index = index + 1
  87. if type(k) ~= "number" then
  88. if type(v) == "table" then
  89. indent_str = string.format("%s%s=%s", indent_str, tostring(k), PrintTable(v))
  90. else
  91. indent_str = string.format("%s%s=%s", indent_str, tostring(k), tostring(v))
  92. end
  93. if index < count then
  94. indent_str = indent_str .. ","
  95. end
  96. end
  97. end
  98. indent_str = indent_str .. "}"
  99. return indent_str
  100. end
  101. local function generateRecordFile()
  102. local time = string.format("%d-%d-%d-%d-%d-%d",
  103. os.date("%Y"),
  104. os.date("%m"),
  105. os.date("%d"),
  106. os.date("%H"),
  107. os.date("%M"),
  108. os.date("%S"))
  109. -- local file = io.open("luafight/BattleRecord/"..time..".txt", "a")
  110. -- local record = BattleLogic.GetRecord()
  111. -- for i=1, #record do
  112. -- file:write(record[i].."\n")
  113. -- end
  114. -- io.close(file)
  115. end
  116. local function addBattleData()
  117. local str = ""
  118. str = str.."seed:\n"..tostring(_seed).."\n"
  119. str = str.."type:\n"..tostring(_type).."\n"
  120. str = str.."fightData:\n"..PrintTable(_fightData).."\n"
  121. str = str.."optionData:\n"..PrintTable(_optionData).."\n"
  122. _BattleErrorIndex = _BattleErrorIndex + 1
  123. if _BattleErrorIndex > 5 then
  124. _BattleErrorIndex = 1
  125. end
  126. _BattleErrorCache[_BattleErrorIndex] = str
  127. end
  128. local function AddRecord(fightData)
  129. BattleRecord = {}
  130. BattleLogic.Event:AddEvent(BattleEventName.AddRole, function (role)
  131. local record = {}
  132. record.uid = role.uid
  133. record.camp = role.camp
  134. record.damage = 0
  135. role.Event:AddEvent(BattleEventName.RoleDamage, function (defRole, damage, bCrit, finalDmg)
  136. record.damage = record.damage + finalDmg
  137. end)
  138. BattleRecord[role.uid] = record
  139. end)
  140. for i=1, #fightData.playerData.teamSkill do
  141. local teamCaster = BattleLogic.GetTeamSkillCaster(0)
  142. local teamSkill = fightData.playerData.teamSkill[i]
  143. local teamType = math.floor(teamSkill[1] / 100)
  144. local str = "order:1".."camp:"..teamCaster.camp.." team"..teamSkill[1]
  145. local record = {}
  146. record.uid = str
  147. record.camp = teamCaster.camp
  148. record.damage = 0
  149. record.order = 1
  150. local curSkill
  151. teamCaster.Event:AddEvent(BattleEventName.SkillCast, function (skill)
  152. if skill.owner.camp == record.camp then
  153. curSkill = skill
  154. end
  155. end)
  156. teamCaster.Event:AddEvent(BattleEventName.RoleDamage, function (defRole, damage, bCrit, finalDmg)
  157. if curSkill and curSkill.teamSkillType == teamType then
  158. record.damage = record.damage + finalDmg
  159. end
  160. end)
  161. BattleRecord[str] = record
  162. end
  163. for i=1, #fightData.enemyData do
  164. for j=1, #fightData.enemyData[i].teamSkill do
  165. local teamCaster = BattleLogic.GetTeamSkillCaster(1)
  166. local teamSkill = fightData.enemyData[i].teamSkill[j]
  167. local teamType = math.floor(teamSkill[1] / 100)
  168. local str = "order:"..i.."camp:"..teamCaster.camp.." team"..teamSkill[1]
  169. local record = {}
  170. record.uid = str
  171. record.camp = teamCaster.camp
  172. record.damage = 0
  173. record.order = i
  174. local curSkill
  175. teamCaster.Event:AddEvent(BattleEventName.SkillCast, function (skill)
  176. if skill.owner.camp == record.camp then
  177. curSkill = skill
  178. end
  179. end)
  180. teamCaster.Event:AddEvent(BattleEventName.RoleDamage, function (defRole, damage, bCrit, finalDmg)
  181. if curSkill and curSkill.teamSkillType == teamType and record.order == BattleLogic.CurOrder then
  182. record.damage = record.damage + finalDmg
  183. end
  184. end)
  185. BattleRecord[str] = record
  186. end
  187. end
  188. end
  189. function BattleMain.Execute(args, fightData, optionData)
  190. _seed = args.seed
  191. _type = args.type
  192. _maxRound = args.maxRound
  193. _fightData = fightData
  194. _optionData = optionData or {}
  195. --该开关用于输出战斗过程中的日志,用于验证前后端是否出现战斗不同步
  196. --BattleLogic.IsOpenBattleRecord = true
  197. local isError = false
  198. local errorCache
  199. if xpcall(function ()
  200. Random.SetSeed(args.seed)
  201. BattleLogic.Init(fightData, optionData, _maxRound)
  202. BattleLogic.Type = _type
  203. if _type == 9 or _type == 10 or _type == 11 or _type == 14 then
  204. AddRecord(fightData)
  205. end
  206. BattleLogic.StartOrder()
  207. while not BattleLogic.IsEnd do
  208. BattleLogic.Update()
  209. end
  210. end, function (err)
  211. isError = true
  212. errorCache = "error:\n"..debug.traceback(err).."\n"
  213. end) then
  214. BattleLogic.useTimes = 10
  215. local resultList = {0, 0, 0, 0, 0, 0, 0, 0, 0}
  216. if BattleLogic.Result == 1 then --胜利记录我方剩余血量
  217. local arr = RoleManager.Query(function (r) return r.camp == 0 end, true)
  218. for i=1, #arr do
  219. local pos = arr[i].position
  220. resultList[pos] = arr[i]:GetRoleData(RoleDataName.Hp)
  221. end
  222. elseif BattleLogic.Result == 0 then --失败记录敌方剩余血量
  223. local arr = RoleManager.Query(function (r) return r.camp == 1 end, true)
  224. for i=1, #arr do
  225. local pos = arr[i].position
  226. resultList[pos] = arr[i]:GetRoleData(RoleDataName.Hp)
  227. end
  228. end
  229. if BattleLogic.IsOpenBattleRecord then
  230. generateRecordFile()
  231. end
  232. -- print -----------------------------------------
  233. --for i=1, #resultList do
  234. -- print("hp:"..resultList[i])
  235. --end
  236. --print("最终运行帧数:"..BattleLogic.CurFrame())
  237. local curRound, maxRound = BattleLogic.GetCurRound()
  238. if curRound > maxRound and _type == 9 then
  239. local playerDamage=0
  240. local enemyDamage=0
  241. for k,v in pairs(BattleRecord)do
  242. if v.camp == 0 then
  243. playerDamage = playerDamage + v.damage
  244. else
  245. enemyDamage = enemyDamage + v.damage
  246. end
  247. end
  248. resultList.result = playerDamage > enemyDamage and 1 or 0
  249. else
  250. resultList.result = BattleLogic.Result
  251. end
  252. if _type == 10 or _type == 11 or _type == 14 then -- 公会boss和车迟斗法boss返回伤害值
  253. local playerDamage=0
  254. for k,v in pairs(BattleRecord)do
  255. if v.camp == 0 then
  256. playerDamage = playerDamage + v.damage
  257. end
  258. end
  259. resultList.duration = playerDamage --TODO:公会boss的持续时间传递的是我方总伤害值
  260. else
  261. resultList.duration = BattleLogic.CurFrame() / BattleLogic.GameFrameRate
  262. end
  263. resultList.useTimes = BattleLogic.useTimes
  264. addBattleData()
  265. return resultList
  266. end
  267. if isError then --捕获异常,并输出错误日志
  268. print("error")
  269. local time = string.format("%d-%d-%d-%d-%d-%d",
  270. os.date("%Y"),
  271. os.date("%m"),
  272. os.date("%d"),
  273. os.date("%H"),
  274. os.date("%M"),
  275. os.date("%S"))
  276. local file
  277. local platform
  278. -- linux
  279. if not file then
  280. file = io.open("../luafight/LogError/"..time..".txt", "a")
  281. platform = "Linux"
  282. end
  283. -- local window server
  284. if not file then
  285. file = io.open("luafight/LogError/"..time..".txt", "a")
  286. platform = "Local Windows Server"
  287. end
  288. -- local
  289. if not file then
  290. file = io.open("LogError/"..time..".txt", "a")
  291. platform = "Local"
  292. end
  293. file:write(platform..":\n\n\n")
  294. file:write(errorCache)
  295. file:write("seed:\n"..tostring(args.seed).."\n")
  296. file:write("type:\n"..tostring(args.type).."\n")
  297. file:write("fightData:\n"..PrintTable(_fightData).."\n")
  298. file:write("optionData:\n"..PrintTable(_optionData).."\n")
  299. file:write("\n\nlast com.ljsd.battle data:\n")
  300. for i=1, #_BattleErrorCache do
  301. file:write(string.format("\nindex:%d\n", i))
  302. file:write(_BattleErrorCache[i])
  303. end
  304. io.close(file)
  305. end
  306. return { result = -1 }
  307. end
  308. -- BattleMain.Execute({seed=1606726052, type=1, maxTime=300},{enemyData={{{ai={0},camp=1,element=0,monsterId=101011,passivity={},position=1,professionId=0,property={1,457,457,91,44,0,86,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},quality=0,roleId=10067,skillArray={{40901,0.3,{0},1,1200,0,1,{cd=1,release=1,slot=0},{400000,{1,1,2}}},{40911,0.2,{0},1,800,0,1,{cd=2,release=1,slot=1},{400000,{1,0.56,2},{3,0.2,1,2}}},{40931,0.2,{0},1,800,0,1,{cd=4,release=2,slot=3},{200000,{1,1.29,2},{3,0.2,1,2}}}},star=0,type=1},firstCamp=0,outData="",teamPassive={},teamSkill={}}},fightUnitData={},playerData={{camp=0,element=4,passivity={},position=1,professionId=2,property={1,592,592,122,53,3,0,0,0,1.0062,0,0,1.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},quality=0,roleId=10065,skillArray={{40701,0.3,{0},1,1200,0,1,{cd=1,release=1,slot=0},{400000,{1,1,2}}},{40711,0.2,{0},1,800,0,1,{cd=4,release=1,slot=1},{200000,{1,0.89,2},{254,0.3,1,5,3,0.1,3}}}},star=5,type=1},firstCamp=0,outData="",teamPassive={},teamSkill={}}})
  309. return BattleMain