CombatLogic.lua 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791
  1. ----------------------------------
  2. -- 战斗逻辑
  3. -- combatBegin 开始战斗
  4. -- createCombatFakeHuman 根据uuid创角战斗human
  5. -- fight 战斗开始前各模块自己的判断函数,成功调用CombatLogic.combatBegin()
  6. -- onFightBegin 战斗帧计算前的属性重新计算
  7. -- onFightEnd 战斗结束回调,发送GC_COMBAT_FINISH前
  8. -- checkCombatPos 可否打开上阵界面(默认可打开)
  9. -- 获取双方上阵对象信息
  10. -- getCombatMonsterOutID 获取上阵怪物组id
  11. -- getCombatTarget 获取上阵human信息
  12. -- getCombatObjList 获取上阵队伍列表
  13. ----------------------------------
  14. local CombatExcel = require("excel.combat")
  15. local MonsterExcel = require("excel.monster")
  16. local HeroExcel = require("excel.hero")
  17. local SkillExcel = require("excel.skill")
  18. local BufferExcel = require("excel.buffer")
  19. local Config = require("Config")
  20. local Util = require("common.Util")
  21. local Lang = require("common.Lang")
  22. local Log = require("common.Log")
  23. local Msg = require("core.Msg")
  24. local ObjHuman = require("core.ObjHuman")
  25. local Grid = require("bag.Grid")
  26. local Broadcast = require("broadcast.Broadcast")
  27. local BeSkill = require("combat.BeSkill")
  28. local CombatObj = require("combat.CombatObj")
  29. local CombatImpl = require("combat.CombatImpl")
  30. local CombatDefine = require("combat.CombatDefine")
  31. local CombatPosLogic = require("combat.CombatPosLogic")
  32. local CombatPetCalc = require("combat.CombatPetCalc")
  33. local MoshouLogic = require("moshou.MoshouLogic")
  34. local RoleDBLogic = require("role.RoleDBLogic")
  35. local RoleAttr = require("role.RoleAttr")
  36. local RoleDefine = require("role.RoleDefine")
  37. local RoleLogic = require("role.RoleLogic")
  38. local HeroGrid = require("hero.HeroGrid")
  39. local DrillLogic = require("drill.DrillLogic")
  40. local SkinLogic = require("skin.SkinLogic")
  41. local BeginStory = require("scene.BeginStory")
  42. local Skill = require("combat.Skill")
  43. local CombatPosExcel = require("excel.combatPos")
  44. local ValleyLogic = require("valley.ValleyLogic")
  45. local LianyuLogic = require("lianyu.LianyuLogic")
  46. local TheStarsLogic = require("theStars.TheStarsLogic")
  47. local HeroDefine = require("hero.HeroDefine")
  48. local JibanLogic = require("combat.JibanLogic")
  49. local EquipLogic = require("equip.EquipLogic")
  50. local ItemDefine = require("bag.ItemDefine")
  51. local HeroLogic = require("hero.HeroLogic")
  52. local XingYaoGongMing = require("xingYaoMen.XingYaoGongMing")
  53. local MoshouLogic = require("moshou.MoshouLogic")
  54. local LostTempleCombatLogic = require("lostTemple.lostTempleCombatLogic")
  55. FieldsCombat = {
  56. lv = 1, name = 1, head = 1, headFrame = 1, unionUuid = 1, lastLogoutTime = 1,
  57. combatHero = 1, heroBag = 1, moshou = 1, technology=1, chengjiu=1,
  58. }
  59. COMBAT_CACHE = COMBAT_CACHE or {}
  60. ------------------------------------------- 模块相关 start -------------------------------------------------
  61. -- 初始
  62. COMBATTYPE_2_MODULE = COMBATTYPE_2_MODULE or {}
  63. function init()
  64. for combatType, cf in pairs(CombatExcel.combat) do
  65. if cf.moduleFn ~= "" then
  66. local moduleFn = load("return require(\""..cf.moduleFn.."\")")()
  67. COMBATTYPE_2_MODULE[combatType] = moduleFn
  68. end
  69. end
  70. end
  71. -- 获取模块
  72. function getModule(combatType)
  73. if not combatType then return end
  74. return COMBATTYPE_2_MODULE[combatType]
  75. end
  76. -- 获取攻/守方怪物组id
  77. local function getCombatMonsterOutID(human, side, combatType, args)
  78. local moduleFn = getModule(combatType)
  79. if moduleFn and moduleFn.getCombatMonsterOutID then
  80. return moduleFn.getCombatMonsterOutID(human, side, args, combatType)
  81. end
  82. end
  83. -- 获取攻/守方怪物组id
  84. function getMapID(human, combatType, param)
  85. local moduleFn = getModule(combatType)
  86. local mapID = nil
  87. if moduleFn and moduleFn.getMapID then
  88. mapID = moduleFn.getMapID(human, param)
  89. end
  90. if not mapID then
  91. local config = CombatExcel.combat[combatType]
  92. mapID = config.mapID == 0 and 1001 or config.mapID
  93. end
  94. return mapID
  95. end
  96. -- 获取是否跳过
  97. function getQuick(human, combatType)
  98. local config = CombatExcel.combat[combatType]
  99. local moduleFn = getModule(combatType)
  100. local quick = nil
  101. if moduleFn and moduleFn.getQuick then
  102. quick = moduleFn.getQuick(human, combatType)
  103. end
  104. if quick ~= nil and quick >= 0 then
  105. return quick
  106. end
  107. if human.db.combatQuick[combatType] and human.db.combatQuick[combatType] ~= 0 then
  108. if config.isQuick == 0 then
  109. human.db.combatQuick[combatType] = 0
  110. end
  111. end
  112. return config.isQuick
  113. end
  114. -- 获取攻/守方对象
  115. local function getCombatTarget(human, side, combatType, args)
  116. local moduleFn = getModule(combatType)
  117. if moduleFn and moduleFn.getCombatTarget then
  118. return moduleFn.getCombatTarget(human, side, args, combatType)
  119. end
  120. end
  121. --更新上阵信息回调
  122. function onUpdatePos(human,combatType)
  123. local moduleFn = getModule(combatType)
  124. if moduleFn and moduleFn.onUpdatePos then
  125. return moduleFn.onUpdatePos(human)
  126. end
  127. end
  128. -- 获取攻/守方上阵信息
  129. function getCombatObjList(human, side, combatType, args)
  130. if type(args) == "table" then
  131. if side == CombatDefine.ATTACK_SIDE then
  132. if args.attacker then
  133. return args.attacker, args.atkHelp, args.atkRBase, args.atkFormation,args.atkJiban
  134. end
  135. else
  136. if args.defender then
  137. return args.defender, args.defHelp, args.defRBase, args.defFormation,args.defJiban
  138. end
  139. end
  140. end
  141. local moduleFn = getModule(combatType)
  142. if not moduleFn then return end
  143. if moduleFn.getCombatObjList then
  144. local objList, helpList, rolebase, formation,jiban = moduleFn.getCombatObjList(human, side, args, combatType)
  145. if objList then
  146. return objList, helpList, rolebase ,formation,jiban
  147. end
  148. end
  149. local monsterOutID, zhandouli = getCombatMonsterOutID(human, side, combatType, args)
  150. if monsterOutID then
  151. local objList, helpList, rolebase, formation, jiban = getMonsterObjList(monsterOutID, nil, args)
  152. if zhandouli then
  153. rolebase.zhandouli = zhandouli
  154. end
  155. return objList, helpList, rolebase,formation,jiban
  156. end
  157. if moduleFn.getHumanObjList then
  158. return moduleFn.getHumanObjList(human, combatType)
  159. end
  160. local target = getCombatTarget(human, side, combatType, args)
  161. if target then
  162. return getHumanObjList(target, combatType)
  163. end
  164. if side == CombatDefine.ATTACK_SIDE then -- 没有模块没有特写,攻防默认取自身上阵信息
  165. return getHumanObjList(human, combatType)
  166. end
  167. end
  168. --获取战斗最大回合数
  169. local function getMaxRound(human,combatType)
  170. local config = CombatExcel.combat[combatType]
  171. if config and config.maxRound and config.maxRound > 0 then
  172. return config.maxRound
  173. end
  174. return CombatDefine.COMBAT_ROUND_MAX
  175. end
  176. --获取战斗模式
  177. local function getFightMode(combatType)
  178. local config = CombatExcel.combat[combatType]
  179. if config.fightMode[1] == CombatDefine.FIGHT_MODE1 or config.fightMode[1] == CombatDefine.FIGHT_MODE3 then
  180. return config.fightMode
  181. end
  182. end
  183. -- 尝试战斗
  184. function tryCombatBegin(human, combatType, param)
  185. local moduleFn = getModule(combatType)
  186. if moduleFn and moduleFn.fight then
  187. local args = Util.split(param, "|")
  188. return moduleFn.fight(human, args, combatType)
  189. end
  190. end
  191. -- 可否打开上阵界面
  192. function checkCombatPos(human, combatType, args)
  193. local moduleFn = getModule(combatType)
  194. if moduleFn and moduleFn.checkCombatPos then
  195. return moduleFn.checkCombatPos(human, args, combatType)
  196. end
  197. return true
  198. end
  199. -- 战斗结束回调 在发送GC_COMBAT_FINISH前
  200. local function onFightEnd(human, result, combatType, cbParam, combatInfo, isSaodang,param)
  201. local moduleFn = getModule(combatType)
  202. if not moduleFn then return end
  203. if not moduleFn.onFightEnd then return end
  204. moduleFn.onFightEnd(human, result, combatType, cbParam, combatInfo, isSaodang,param)
  205. end
  206. -- 战斗名称
  207. function getCombatName(human, combatType, args)
  208. local moduleFn = getModule(combatType)
  209. if not moduleFn then return "" end
  210. if not moduleFn.getCombatName then return "" end
  211. return moduleFn.getCombatName(human, args, combatType) or ""
  212. end
  213. ------------------------------------------- 模块相关 end -------------------------------------------------
  214. -- 判断阵容是不是为空
  215. function isCombatHeroEmpty(combatHero)
  216. if not combatHero then return true end
  217. local isEmpty = true
  218. for _, heroUuid in pairs(combatHero) do
  219. if heroUuid and heroUuid ~= "" and heroUuid ~= "0" then
  220. isEmpty = nil
  221. break
  222. end
  223. end
  224. return isEmpty
  225. end
  226. -- 根据阵营和下标获取对战位置
  227. function getPos(side, index)
  228. if side == CombatDefine.ATTACK_SIDE then
  229. return index
  230. elseif side == CombatDefine.DEFEND_SIDE then
  231. return index + CombatDefine.COMBAT_HERO_CNT
  232. else
  233. assert()
  234. end
  235. end
  236. function getIndexByPos(side, pos)
  237. if side == CombatDefine.ATTACK_SIDE then
  238. return pos
  239. elseif side == CombatDefine.DEFEND_SIDE then
  240. return pos - CombatDefine.COMBAT_HERO_CNT
  241. end
  242. end
  243. -- 获取对象配置
  244. function getConfigByObj(obj)
  245. if not obj then return end
  246. local id = obj.id or obj.heroID
  247. if obj.type == CombatDefine.COMBAT_OBJ_TYPE1 then
  248. return HeroExcel.hero[id]
  249. end
  250. return MonsterExcel.monster[id]
  251. end
  252. -- 创建战斗Human
  253. function createCombatFakeHuman(uuid)
  254. if not uuid then return end
  255. local db = RoleDBLogic.getDb(uuid, FieldsCombat)
  256. if not db then return end
  257. local fakeHuman = {}
  258. fakeHuman.db = db
  259. return fakeHuman
  260. end
  261. -- 创建初始角色信息
  262. function createRoleBaseDefault()
  263. local rolebase = {}
  264. RoleLogic.makeRoleBase(nil, rolebase, nil, true)
  265. rolebase.name = Lang.COMBAT_DEFEND_NAME
  266. return rolebase
  267. end
  268. -- 根据怪物信息创建角色信息
  269. function createRoleBaseByMOutID(monsterOutID, zhandouli, args)
  270. local _, monsterConfig, monsterLv = getMonsterIDByOutID(monsterOutID, args)
  271. local rolebase = createRoleBaseDefault()
  272. if monsterConfig then
  273. rolebase.name = monsterConfig.name
  274. rolebase.lv = monsterLv or 1
  275. rolebase.head = monsterConfig.head
  276. rolebase.zhandouli = zhandouli or 0
  277. end
  278. return rolebase
  279. end
  280. -- 创建角色信息
  281. function createRoleBaseByDB(db, zhandouli)
  282. local rolebase = {}
  283. RoleLogic.makeRoleBase(db, rolebase, nil, true)
  284. rolebase.zhandouli = zhandouli or 0
  285. return rolebase
  286. end
  287. -- 根据怪物表信息创建临时对象
  288. function createMonsterObj(id, lv, attrID, index, objType, monsterOutConfig, attrInput)
  289. local monsterConfig = MonsterExcel.monster[id]
  290. if not monsterConfig then return end
  291. local obj = {}
  292. obj.type = objType or CombatDefine.COMBAT_OBJ_TYPE2
  293. obj.bagIndex = index
  294. obj.id = id
  295. obj.lv = lv
  296. obj.job = monsterConfig.job
  297. obj.quality = 6
  298. obj.star = monsterConfig.star
  299. obj.head = monsterConfig.head
  300. obj.body = monsterConfig.body
  301. obj.camp = monsterConfig.camp
  302. obj.sex = monsterConfig.sex
  303. BeSkill.initBeSkill(obj)
  304. BeSkill.setBeSkill(obj, monsterConfig, nil, monsterOutConfig)
  305. Skill.setSkill(obj, monsterConfig)
  306. obj.attrs = RoleAttr.calcMonsterConf(id, attrID, attrInput)
  307. return obj
  308. end
  309. -- 根据英雄ID信息创建临时对象
  310. function createHeroObjByID(heroId, lv, star, quality, index)
  311. local heroConfig = HeroExcel.hero[heroId]
  312. if not heroConfig then return end
  313. local obj = {}
  314. obj.type = CombatDefine.COMBAT_OBJ_TYPE1
  315. obj.bagIndex = index
  316. obj.id = heroId
  317. obj.lv = lv
  318. obj.job = heroConfig.job
  319. obj.quality = quality and quality or HeroGrid.getMaxQuality(star)
  320. obj.star = star
  321. obj.body = heroConfig.body
  322. obj.head = heroConfig.head
  323. local attrConfig = HeroDefine.getAttrConfig(obj.id, obj.star)
  324. BeSkill.initBeSkill(obj)
  325. Skill.setSkill(obj, attrConfig)
  326. BeSkill.setBeSkill(obj, attrConfig)
  327. obj.attrs = Util.copyTable(RoleAttr.calcHeroGrid(obj, index))
  328. obj.zhandouli = obj.attrs[RoleDefine.ZHANDOULI]
  329. return obj
  330. end
  331. -- 根据英雄表信息创建临时对象
  332. function createHeroObj(human, heroId, lv, star, index)
  333. local heroConfig = HeroExcel.hero[heroId]
  334. if not heroConfig then return end
  335. local obj = {}
  336. obj.type = CombatDefine.COMBAT_OBJ_TYPE1
  337. obj.bagIndex = index
  338. obj.id = heroId
  339. obj.lv = lv
  340. obj.job = heroConfig.job
  341. obj.quality = HeroGrid.getMaxQuality(star)
  342. obj.star = star
  343. obj.body = heroConfig.body
  344. obj.head = heroConfig.head
  345. local attrConfig = HeroDefine.getAttrConfig(obj.id, obj.star)
  346. BeSkill.initBeSkill(obj)
  347. if not SkinLogic.setSkill(human,index,attrConfig,obj) then
  348. Skill.setSkill(obj, attrConfig)
  349. BeSkill.setBeSkill(obj, attrConfig)
  350. end
  351. obj.attrs = Util.copyTable(RoleAttr.calcHeroGrid(obj, index, human))
  352. obj.zhandouli = obj.attrs[RoleDefine.ZHANDOULI]
  353. return obj
  354. end
  355. function createHeroObjByHeroGrid(human, heroGrid)
  356. local heroConfig = HeroExcel.hero[heroGrid.id]
  357. if not heroConfig then return end
  358. local obj = {}
  359. obj.type = CombatDefine.COMBAT_OBJ_TYPE1
  360. obj.bagIndex = heroGrid.bagIndex
  361. obj.uuid = heroGrid.uuid
  362. obj.id = heroGrid.id
  363. obj.lv = heroGrid.lv
  364. obj.job = heroConfig.job
  365. obj.quality = heroGrid.quality
  366. obj.star = heroGrid.star -- dxzeng 取db star
  367. obj.fuwen = Util.copyTable(heroGrid.fuwen)
  368. obj.bingshu = Util.copyTable(heroGrid.bingshu)
  369. obj.body, obj.head = SkinLogic.getBody(human, obj.bagIndex)
  370. obj.camp = heroConfig.camp
  371. obj.isGongMing = XingYaoGongMing.isGongMing(human, heroGrid.bagIndex)
  372. obj.sex = heroConfig.sex
  373. local attrConfig = HeroDefine.getAttrConfig(obj.id, obj.star)
  374. BeSkill.initBeSkill(obj)
  375. if not SkinLogic.setSkill(human,obj.bagIndex,attrConfig,obj) then
  376. Skill.setSkill(obj, attrConfig)
  377. BeSkill.setBeSkill(obj, attrConfig)
  378. end
  379. if heroGrid.isLostTemple then
  380. obj.attrs = Util.copyTable(LostTempleCombatLogic.getHeroAttrs(human, heroGrid.bagIndex))
  381. else
  382. obj.attrs = Util.copyTable(ObjHuman.getHeroAttrs(human, obj.bagIndex))
  383. end
  384. obj.zhandouli = obj.attrs[RoleDefine.ZHANDOULI]
  385. return obj
  386. end
  387. -- 根据英雄背包创建临时对象
  388. function createHumanObj(human, uuid)
  389. if not uuid then return end
  390. local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
  391. if not heroGrid or type(heroGrid) ~= "table" then return end
  392. return createHeroObjByHeroGrid(human, heroGrid)
  393. end
  394. -- 根据怪物组id获取出战英雄列表
  395. function getMonsterObjList(monsterOutID, objType, args)
  396. if not monsterOutID then return end
  397. local monsterOutConfig = MonsterExcel.monsterOut[monsterOutID]
  398. if not monsterOutConfig then return end
  399. local formation = monsterOutConfig.formation
  400. if formation == 0 then
  401. formation = 1
  402. end
  403. local mationConfig = CombatPosExcel.formation[formation]
  404. local posList = mationConfig.pos
  405. if not posList then return end
  406. local objList = nil
  407. local zhandouli = 0
  408. for i, member in ipairs(monsterOutConfig.member) do
  409. local monsterID = member[1]
  410. local monsterConfig = MonsterExcel.monster[monsterID]
  411. if posList[i] then
  412. local monsterLv = member[2]
  413. local attrID = monsterOutConfig.attrID[i]
  414. local attrInput = nil
  415. if monsterOutConfig.combatType == CombatDefine.COMBAT_TYPE5 then
  416. if args then
  417. local throneID = args[1]
  418. local evolveCnt = args[2]
  419. monsterLv, attrInput = TheStarsLogic.getMonsterLvAttr(i, throneID, evolveCnt)
  420. end
  421. end
  422. local obj = createMonsterObj(monsterID, monsterLv, attrID, i, objType, monsterOutConfig.beSkill[i], attrInput)
  423. if obj then
  424. zhandouli = zhandouli + obj.attrs[RoleDefine.ZHANDOULI]
  425. objList = objList or {}
  426. local pos = posList[i]
  427. if monsterOutConfig.combatType == CombatDefine.COMBAT_TYPE10 then
  428. pos = 5
  429. end
  430. objList[pos] = obj
  431. end
  432. end
  433. end
  434. if not objList then
  435. assert(nil, "getMonsterObjList is nil, monsterOutID = " .. monsterOutID)
  436. end
  437. local rolebase = createRoleBaseByMOutID(monsterOutID, zhandouli, args)
  438. local jiban = nil -- todo 怪物的羁绊
  439. return objList, nil, rolebase,formation,jiban
  440. end
  441. -- 获取human出战英雄列表 objList, helpList, rolebase, formation
  442. function getHumanObjList(human, combatType)
  443. local teamType = CombatPosLogic.getTeamType(combatType)
  444. if not teamType then return end
  445. local combatHero, _, formation,combatHeroDB = CombatPosLogic.getCombatHeros(human, combatType)
  446. if not combatHero then return end
  447. if formation == 0 then
  448. formation = 1
  449. end
  450. local jiban = JibanLogic.getJibanHero(human,combatHeroDB)
  451. local objList = {}
  452. local zhandouli = 0
  453. for i = 1, CombatDefine.COMBAT_HERO_CNT do
  454. local uuid = combatHero[i]
  455. local obj = createHumanObj(human, uuid)
  456. if obj then
  457. zhandouli = zhandouli + obj.attrs[RoleDefine.ZHANDOULI]
  458. objList[i] = obj
  459. end
  460. end
  461. local helpList = {}
  462. local pet = MoshouLogic.createCombatMoshow(human,combatType)
  463. helpList[CombatDefine.HELP_TYPE1] = pet
  464. local rolebase = createRoleBaseByDB(human.db, zhandouli)
  465. return objList, helpList, rolebase,formation,jiban
  466. end
  467. ---------------------------------------------- msg -----------------------------------------------
  468. -- 封装对战英雄信息
  469. local function fontCombatHeroNet(net, obj)
  470. local config = getConfigByObj(obj)
  471. if not config then return end
  472. net.pos = obj.pos
  473. net.heroID = obj.id
  474. net.star = obj.star
  475. net.lv = obj.lv or 0
  476. net.body = obj.body or config.body
  477. net.hpMax = CombatObj.getHpMax(obj)
  478. net.hpNow = obj.initHp
  479. net.icon = config.head
  480. net.width = config.width
  481. net.height = config.height
  482. net.camp = config.camp
  483. net.name = config.name
  484. net.posX = CombatDefine.DEFAULT_POS_SIZE[obj.pos][1]
  485. net.posY = CombatDefine.DEFAULT_POS_SIZE[obj.pos][2]
  486. net.size = CombatDefine.DEFAULT_POS_SIZE[obj.pos][3]
  487. net.isBoss = 0
  488. net.isGongMing = obj.isGongMing or 0
  489. net.grade = config.grade or 0
  490. local len = 0
  491. for _,v in pairs(obj.skillList) do
  492. if SkillExcel.skill[v[1]].contentType == 3 then
  493. len = len + 1
  494. net.sayList[len] = v[1]
  495. end
  496. end
  497. for _,v in pairs(obj.beSkillList) do
  498. for _,v1 in ipairs(v) do
  499. if SkillExcel.skill[v1[1]].contentType == 3 then
  500. len = len + 1
  501. net.sayList[len] = v1[1]
  502. end
  503. end
  504. end
  505. net.sayList[0] = len
  506. return true
  507. end
  508. -- 封装辅助对象
  509. function fontCombatHelpNet(net, help)
  510. net.pos = help.pos
  511. net.id = help.id or 0
  512. net.head = help.head or 0
  513. net.body = help.body or 0
  514. net.skill[0] = 0
  515. local skillConfig = SkillExcel.skill[help.icon]
  516. if skillConfig then
  517. net.skill[1].id = help.icon
  518. net.skill[1].icon = skillConfig.icon
  519. net.skill[1].name = skillConfig.name
  520. net.skill[1].desc = skillConfig.desc
  521. net.skill[1].lv = help.skillLV or 0
  522. net.skill[1].index = 0
  523. net.skill[1].state = 2
  524. net.skill[0] = 1
  525. end
  526. net.args[0] = 0
  527. if help.clientArgs then
  528. local len = 0
  529. for k,v in ipairs(help.clientArgs) do
  530. len = len + 1
  531. net.args[len] = v
  532. end
  533. net.args[0] = len
  534. end
  535. return true
  536. end
  537. -- 封装战斗技能信息
  538. function fontCombatSkillNet(skillNet, skillID)
  539. local skillConfig = SkillExcel.skill[skillID]
  540. if not skillConfig then return end
  541. skillNet.skillID = skillID
  542. skillNet.fireType = skillConfig.fireType
  543. skillNet.readyAction = skillConfig.readyAction
  544. skillNet.attackPart = skillConfig.attackPart
  545. skillNet.attackAction = skillConfig.attackAction
  546. skillNet.readyEffect = skillConfig.readyEffect
  547. skillNet.attackEffect = skillConfig.attackEffect
  548. skillNet.hitEffect = skillConfig.hitEffect
  549. skillNet.flyEffect = skillConfig.flyEffect
  550. skillNet.flyCoords = skillConfig.flyCoords
  551. skillNet.hitBack = skillConfig.hitBack
  552. skillNet.effectTime = skillConfig.effectTime
  553. skillNet.contentType = skillConfig.contentType
  554. skillNet.content = skillConfig.content
  555. skillNet.movieEffect = skillConfig.movieEffect
  556. skillNet.quake = skillConfig.quake
  557. skillNet.flySound = skillConfig.flySound
  558. skillNet.fireSound = skillConfig.fireSound
  559. skillNet.hitSound = skillConfig.hitSound
  560. skillNet.cvSound = skillConfig.cvSound
  561. skillNet.screenMask = skillConfig.screenMask
  562. skillNet.screenCam = skillConfig.screenCam
  563. skillNet.largeEffect = skillConfig.largeEffect
  564. skillNet.lie = skillConfig.lie
  565. skillNet.cuoZhen = skillConfig.cuoZhen
  566. skillNet.skillDelay = skillConfig.skillDelay
  567. skillNet.isFraming = skillConfig.isFraming
  568. return true
  569. end
  570. -- 封装技能cmd
  571. local function fontSkillCmd(cmdNet, cmd)
  572. local cmdConfig = SkillExcel.cmd[cmd]
  573. if not cmdConfig then return end
  574. cmdNet.cmd = cmd
  575. cmdNet.hitEffect = cmdConfig.hitEffect
  576. cmdNet.hitSound = cmdConfig.hitSound
  577. return true
  578. end
  579. -- 封装buff
  580. local function fontBufferNet(bufferNet, bufferID)
  581. local bufferConf = BufferExcel.buffer[bufferID]
  582. if not bufferConf then return end
  583. bufferNet.bufferID = bufferID
  584. bufferNet.name = bufferConf.name
  585. bufferNet.desc = bufferConf.desc
  586. bufferNet.icon = bufferConf.icon
  587. bufferNet.keepEffect = bufferConf.keepEffect
  588. bufferNet.hitEffect = bufferConf.hitEffect
  589. bufferNet.validateEffect = bufferConf.validateEffect
  590. bufferNet.dieEffect = bufferConf.dieEffect
  591. bufferNet.cmd = bufferConf.cmd
  592. bufferNet.hitSound = bufferConf.hitSound
  593. bufferNet.holdOnDie = bufferConf.holdOnDie
  594. bufferNet.effectOffset = bufferConf.effectOffset
  595. bufferNet.canAppend = bufferConf.canAppend
  596. bufferNet.appendCnt = bufferConf.appendCnt
  597. return true
  598. end
  599. -- 封装阵法属性
  600. local function fontCombatPosAttr(attrNets, attrs)
  601. attrNets[0] = 0
  602. if type(attrs) ~= "table" then return end
  603. for key, value in pairs(attrs) do
  604. attrNets[0] = attrNets[0] + 1
  605. local attrNet = attrNets[attrNets[0]]
  606. attrNet.key = key
  607. attrNet.value = value
  608. end
  609. end
  610. -- 发送战斗开始
  611. local function sendCombatBegin(human, combatInfo, isLogin)
  612. combatInfo = combatInfo or human.combat
  613. if not combatInfo then return end
  614. local msgRet = Msg.gc.GC_COMBAT_BEGIN
  615. msgRet.isLogin = isLogin == true and 1 or 0
  616. msgRet.combatType = combatInfo.type
  617. local keepTime = os.time() - combatInfo.time
  618. if combatInfo.passTime < keepTime then
  619. combatInfo.passTime = keepTime
  620. end
  621. msgRet.keepTime = combatInfo.passTime
  622. if combatInfo.isVideo then -- 录像回放
  623. msgRet.keepTime = 0
  624. end
  625. local isCanQuick = getQuick(human, combatInfo.type)
  626. msgRet.isQuick = isCanQuick or 0
  627. msgRet.isVideo = combatInfo.isVideo == true and 1 or 0
  628. msgRet.mapID = combatInfo.mapID
  629. msgRet.speed = human.db and human.db.combatSpeed or 1
  630. msgRet.atkName = combatInfo.attacker and combatInfo.attacker.name or ""
  631. msgRet.defName = combatInfo.defender and combatInfo.defender.name or ""
  632. msgRet.atkUuid = combatInfo.attacker and combatInfo.attacker.uuid or ""
  633. msgRet.defUuid = combatInfo.defender and combatInfo.defender.uuid or ""
  634. msgRet.maxRound = combatInfo.maxRound
  635. msgRet.petCD = CombatDefine.PET_CD
  636. msgRet.heros[0] = 0
  637. msgRet.atkFormation = combatInfo.atkFormation
  638. msgRet.defFormation = combatInfo.defFormation
  639. msgRet.backup[0] = 2
  640. for i = 1, CombatDefine.COMBAT_HERO_ALL_CNT do
  641. local obj = combatInfo.objList[i]
  642. if fontCombatHeroNet(msgRet.heros[msgRet.heros[0] + 1], obj) then
  643. msgRet.heros[0] = msgRet.heros[0] + 1
  644. end
  645. if i % CombatDefine.COMBAT_HERO_CNT == 0 then
  646. msgRet.backup[i/CombatDefine.COMBAT_HERO_CNT] = obj and obj.backupPos or 0
  647. end
  648. end
  649. msgRet.helps[0] = 0
  650. for _, help in pairs(combatInfo.helpList) do
  651. if fontCombatHelpNet(msgRet.helps[msgRet.helps[0] + 1], help) then
  652. msgRet.helps[0] = msgRet.helps[0] + 1
  653. end
  654. end
  655. msgRet.skillList[0] = 0
  656. for skillID in pairs(combatInfo.skillUseList) do
  657. if fontCombatSkillNet(msgRet.skillList[msgRet.skillList[0] + 1], skillID) then
  658. msgRet.skillList[0] = msgRet.skillList[0] + 1
  659. end
  660. end
  661. msgRet.cmdList[0] = 0
  662. if combatInfo.cmdUseList then
  663. for cmd in pairs(combatInfo.cmdUseList) do
  664. if fontSkillCmd(msgRet.cmdList[msgRet.cmdList[0] + 1], cmd) then
  665. msgRet.cmdList[0] = msgRet.cmdList[0] + 1
  666. end
  667. end
  668. end
  669. msgRet.bufferList[0] = 0
  670. for bufferID in pairs(combatInfo.bufferUseList) do
  671. if fontBufferNet(msgRet.bufferList[msgRet.bufferList[0] + 1], bufferID) then
  672. msgRet.bufferList[0] = msgRet.bufferList[0] + 1
  673. end
  674. end
  675. fontCombatPosAttr(msgRet.attrsAtk, combatInfo.posAttr[1])
  676. fontCombatPosAttr(msgRet.attrsDef, combatInfo.posAttr[2])
  677. msgRet.atkJibanDesc = JibanLogic.getDesc(combatInfo.jiban[CombatDefine.ATTACK_SIDE])
  678. msgRet.defJibanDesc = JibanLogic.getDesc(combatInfo.jiban[CombatDefine.DEFEND_SIDE])
  679. Msg.send(msgRet, human.fd)
  680. end
  681. -- 封装战斗帧技能信息
  682. local function fontFrameSkillNet(skillNet, skillData)
  683. skillNet.attackPos = skillData.attackPos
  684. skillNet.skillID = skillData.skillID
  685. skillNet.hitList[0] = 0
  686. for i = 1, CombatDefine.COMBAT_HERO_ALL_CNT do
  687. local skillHitData = skillData.hitList[i]
  688. if skillHitData then
  689. skillNet.hitList[0] = skillNet.hitList[0] + 1
  690. local skillHitNet = skillNet.hitList[skillNet.hitList[0]]
  691. skillHitNet.pos = i
  692. skillHitNet.flag = skillHitData.flag
  693. skillHitNet.cmd = 0
  694. skillHitNet.hpNow = skillHitData.hpNow
  695. local frameAttrs = skillHitData.attrs
  696. skillHitNet.attrs[0] = frameAttrs and #frameAttrs or 0
  697. for j = 1, #frameAttrs do
  698. skillHitNet.attrs[j].key = frameAttrs[j][1]
  699. skillHitNet.attrs[j].value = frameAttrs[j][2]
  700. end
  701. end
  702. end
  703. skillNet.helpList[0] = 0
  704. --for i = CombatDefine.PET_POS_ATTACK, CombatDefine.PET_POS_DEFEND do
  705. -- local helpHitData = skillData.helpList and skillData.helpList[i]
  706. -- if helpHitData then
  707. -- skillNet.helpList[0] = skillNet.helpList[0] + 1
  708. -- local helpHitNet = skillNet.helpList[skillNet.helpList[0]]
  709. -- helpHitNet.pos = i
  710. -- end
  711. --end
  712. skillNet.extraList[0] = 0
  713. for i = 1, CombatDefine.COMBAT_HERO_ALL_CNT do
  714. local extraHitData = skillData.extraList[i]
  715. if extraHitData then
  716. skillNet.extraList[0] = skillNet.extraList[0] + 1
  717. local extraHitNet = skillNet.extraList[skillNet.extraList[0]]
  718. extraHitNet.pos = i
  719. extraHitNet.flag = extraHitData.flag
  720. extraHitNet.cmd = extraHitData.cmd
  721. extraHitNet.hpNow = extraHitData.hpNow
  722. local frameAttrs = extraHitData.attrs
  723. local attrsLen = math.min(frameAttrs and #frameAttrs or 0, #extraHitNet.attrs)
  724. extraHitNet.attrs[0] = attrsLen
  725. for j = 1, attrsLen do
  726. extraHitNet.attrs[j].key = frameAttrs[j][1]
  727. extraHitNet.attrs[j].value = frameAttrs[j][2]
  728. end
  729. end
  730. end
  731. end
  732. -- 封装战斗帧buff信息
  733. local function fontFrameBuff(net, buffers)
  734. net[0] = #buffers
  735. for i = 1, net[0] do
  736. local bufferNet = net[i]
  737. local bufferData = buffers[i]
  738. bufferNet.bufferID = bufferData.id
  739. bufferNet.op = bufferData.op
  740. bufferNet.cnt = bufferData.cnt
  741. bufferNet.round = bufferData.round or -1
  742. bufferNet.hpNow = bufferData.hpNow
  743. bufferNet.attrs[0] = bufferData.attrs and #bufferData.attrs or 0
  744. for j = 1, bufferNet.attrs[0] do
  745. bufferNet.attrs[j].key = bufferData.attrs[j][1]
  746. bufferNet.attrs[j].value = bufferData.attrs[j][2]
  747. end
  748. end
  749. end
  750. -- 封装战斗帧
  751. local function fontFrameNet(net, frame)
  752. net.round = frame.round
  753. net.petCD = frame.petCD
  754. net.skillList[0] = #frame.skillList
  755. for i = 1, net.skillList[0] do
  756. local skillNet = net.skillList[i]
  757. local skillData = frame.skillList[i]
  758. fontFrameSkillNet(skillNet, skillData)
  759. end
  760. net.bufferList[0] = 0
  761. for i = 1, CombatDefine.COMBAT_HERO_ALL_CNT do
  762. local bufferData = frame.bufferList[i]
  763. if bufferData then
  764. net.bufferList[0] = net.bufferList[0] + 1
  765. local bufferNet = net.bufferList[net.bufferList[0]]
  766. bufferNet.pos = i
  767. fontFrameBuff(bufferNet.list, bufferData)
  768. end
  769. end
  770. net.sayList[0] = 0
  771. for i = 1, CombatDefine.COMBAT_HERO_ALL_CNT do
  772. if frame.sayList[i] then
  773. for _,saySkillID in ipairs(frame.sayList[i]) do
  774. net.sayList[0] = net.sayList[0] + 1
  775. local sayNet = net.sayList[net.sayList[0]]
  776. sayNet.pos = i
  777. sayNet.skillID = saySkillID
  778. end
  779. end
  780. end
  781. return net.skillList[0] > 0 or net.bufferList[0] > 0 or net.sayList[0] > 0
  782. end
  783. -- 发送战斗帧
  784. local function sendCombatFrame(human, combatInfo, isLogin)
  785. combatInfo = combatInfo or human.combat
  786. if not combatInfo then return end
  787. local result = combatInfo.result
  788. local msgFrame = Msg.gc.GC_COMBAT_FRAME
  789. msgFrame.isLogin = isLogin == true and 1 or 0
  790. msgFrame.isEnd = 0
  791. msgFrame.combatType = combatInfo.type
  792. msgFrame.frames[0] = 0
  793. local frameCnt = result.frames and #result.frames or 0
  794. local len = 1
  795. for i = 1, frameCnt do
  796. local frame = result.frames[i]
  797. msgFrame.frames[0] = len
  798. local frameNet = msgFrame.frames[msgFrame.frames[0]]
  799. if fontFrameNet(frameNet, frame) then
  800. if len >= CombatDefine.COMBAT_FRAME_MAXCNT then
  801. msgFrame.isEnd = (i == frameCnt) and 1 or 0
  802. Msg.send(msgFrame, human.fd)
  803. msgFrame.frames[0] = 0
  804. len = 1
  805. else
  806. len = len + 1
  807. end
  808. end
  809. end
  810. if msgFrame.isEnd == 0 or msgFrame.frames[0] > 0 then
  811. msgFrame.isEnd = 1
  812. Msg.send(msgFrame, human.fd)
  813. end
  814. end
  815. -- 发送战斗开始
  816. function sendCombatData(human, combatInfo, isLogin)
  817. sendCombatBegin(human, combatInfo, isLogin)
  818. sendCombatFrame(human, combatInfo, isLogin)
  819. end
  820. -- 封装战斗统计
  821. function fontFinishResultNet(net, obj)
  822. net.pos = obj.pos
  823. net.hurt = obj.result[1]
  824. net.hp = obj.result[2]
  825. net.beHurt = obj.result[3]
  826. net.bout = obj.result[4]
  827. net.isDie = obj.hp == 0 and 1 or 0
  828. net.heroID = obj.id or 0
  829. net.head = obj.head or 0
  830. net.lv = obj.lv or 0
  831. net.star = obj.star or 0
  832. local heroConfig = HeroExcel.hero[net.heroID]
  833. local monsterConfig = MonsterExcel.monster[net.heroID]
  834. if obj.type == CombatDefine.COMBAT_OBJ_TYPE1 then
  835. net.name = heroConfig and heroConfig.name or ""
  836. net.body = heroConfig and heroConfig.body.."" or ""
  837. net.head = heroConfig and heroConfig.head or 0
  838. net.grade = heroConfig and heroConfig.grade or 0
  839. else
  840. net.name = monsterConfig and monsterConfig.name or ""
  841. net.body = monsterConfig and monsterConfig.body.."" or ""
  842. net.head = monsterConfig and monsterConfig.head or 0
  843. net.grade = monsterConfig and monsterConfig.grade or 0
  844. end
  845. net.camp = heroConfig and heroConfig.camp or 0
  846. end
  847. -- 封装战斗结束魔兽信息
  848. local function fontFinishPetNet(net, pet)
  849. net.pos = pet.pos
  850. net.side = pet.side
  851. net.lv = pet.lv or 0
  852. net.head = pet.head
  853. end
  854. function fontCombatFinish(dataNet, combatInfo, isQuick)
  855. if not combatInfo then return end
  856. local combatConfig = CombatExcel.combat[combatInfo.type]
  857. if not combatConfig then return end
  858. dataNet.ret = combatInfo.isWin and 1 or 2
  859. dataNet.type = combatInfo.type
  860. dataNet.param = combatInfo.endParam or "0"
  861. dataNet.isVideo = (combatInfo.isVideo == true) and 1 or 0
  862. dataNet.lookType = combatInfo.lookType or 0
  863. dataNet.isQuick = isQuick or 0
  864. dataNet.combatTime = getCombatUseTime(combatInfo)
  865. dataNet.double = combatInfo.double or 0
  866. dataNet.oldLv = combatInfo.attacker.oldLv or 0
  867. dataNet.panelIDs[0] = #combatConfig.panelIDs
  868. for i, panelID in ipairs(combatConfig.panelIDs) do
  869. dataNet.panelIDs[i] = tonumber(panelID)
  870. end
  871. if combatInfo.panelID then
  872. dataNet.panelIDs[0] = dataNet.panelIDs[0] + 1
  873. dataNet.panelIDs[dataNet.panelIDs[0]] = tonumber(combatInfo.panelID)
  874. end
  875. -- 攻守方基本信息
  876. RoleLogic.makeRoleBase(combatInfo.defender, dataNet.target)
  877. RoleLogic.makeRoleBase(combatInfo.attacker, dataNet.self)
  878. -- 每个出战单位的战斗统计
  879. dataNet.result[0] = 0
  880. for pos = 1, CombatDefine.COMBAT_HERO_ALL_CNT do
  881. local obj = combatInfo.objList and combatInfo.objList[pos]
  882. if obj then
  883. dataNet.result[0] = dataNet.result[0] + 1
  884. local net = dataNet.result[dataNet.result[0]]
  885. fontFinishResultNet(net, obj)
  886. end
  887. end
  888. -- 出战魔兽
  889. for _,pos in ipairs(CombatDefine.SIDE2HELPPOS[0]) do
  890. local pet = combatInfo.helpList and combatInfo.helpList[pos]
  891. if pet and pet.isPet then
  892. dataNet.result[0] = dataNet.result[0] + 1
  893. local net = dataNet.result[dataNet.result[0]]
  894. fontFinishResultNet(net, pet)
  895. end
  896. end
  897. -- 奖励
  898. local rewardItem = combatInfo.rewardItem
  899. local len = 0
  900. for k, v in pairs(rewardItem) do
  901. if not ItemDefine.isEquip(v[1]) then
  902. len = len + 1
  903. Grid.makeItem(dataNet.items[len], v[1], v[2])
  904. end
  905. end
  906. dataNet.items[0] = EquipLogic.makeEquipItem(combatInfo, dataNet.items, len)
  907. return true
  908. end
  909. -- 发送战斗结束
  910. function sendCombatFinish(human, combatInfo)
  911. local msgRet = Msg.gc.GC_COMBAT_FINISH
  912. local dataNet = msgRet.data
  913. local isQuick = human.db.combatQuick[combatInfo.type] or 0
  914. if not fontCombatFinish(dataNet, combatInfo, isQuick) then
  915. return
  916. end
  917. BeginStory.handleBattleFail(human, combatInfo.isWin, combatInfo.type, combatInfo.isVideo, msgRet)
  918. BeginStory.handleBattle8End(human, combatInfo.isWin, combatInfo.isVideo, combatInfo.type, msgRet)
  919. BeginStory.handleBattle12End(human, combatInfo.isWin, combatInfo.isVideo, combatInfo.type, msgRet)
  920. Msg.send(msgRet,human.fd)
  921. end
  922. ---------------------------------------- 下面是战斗各种设置逻辑 ------------------------------------------------
  923. local function getMonsterBossName(param)
  924. local monsterOutID = param.monsterOutID
  925. local posList = param.posList
  926. for i,member in ipairs(MonsterExcel.monsterOut[monsterOutID].member) do
  927. local monsterID = member[1]
  928. local monsterConfig = MonsterExcel.monster[monsterID]
  929. if monsterConfig and posList[monsterID] ~= nil then
  930. return monsterConfig.name
  931. end
  932. end
  933. end
  934. -- 在各种战前加成后,重新设置血量
  935. function recalcHpFightBegin(human, combatType, cbParam)
  936. for i = 1,CombatDefine.COMBAT_HERO_CNT do
  937. local atkPos = getPos(CombatDefine.ATTACK_SIDE, i)
  938. local atkObj = CombatImpl.objList[atkPos]
  939. if atkObj then
  940. if atkObj.isSysAttrChange then
  941. CombatObj.calcAttr(atkObj)
  942. -- 重新计算血量
  943. if combatType == CombatDefine.COMBAT_TYPE9 then
  944. DrillLogic.calcAttrAtk(human, i, atkObj, cbParam)
  945. elseif combatType == CombatDefine.COMBAT_TYPE17 then
  946. ValleyLogic.calcAttr(CombatDefine.ATTACK_SIDE, i, atkObj, cbParam)
  947. elseif combatType == CombatDefine.COMBAT_TYPE8 then
  948. LianyuLogic.recalcHpFightBegin(human, i, atkObj)
  949. end
  950. end
  951. atkObj.hp = atkObj.hp or CombatObj.getHpMax(atkObj)
  952. atkObj.mp = atkObj.mp or atkObj.attr[RoleDefine.INIT_MP]
  953. atkObj.initHp = atkObj.hp
  954. atkObj.initMp = atkObj.mp
  955. end
  956. local defPos = getPos(CombatDefine.DEFEND_SIDE, i)
  957. local defObj = CombatImpl.objList[defPos]
  958. if defObj then
  959. if defObj.isSysAttrChange then
  960. CombatObj.calcAttr(defObj)
  961. if combatType == CombatDefine.COMBAT_TYPE9 then
  962. DrillLogic.calcAttrDef(human, i, defObj, cbParam)
  963. elseif combatType == CombatDefine.COMBAT_TYPE17 then
  964. ValleyLogic.calcAttr(CombatDefine.DEFEND_SIDE, i, defObj, cbParam)
  965. end
  966. end
  967. defObj.hp = defObj.hp or CombatObj.getHpMax(defObj)
  968. defObj.mp = defObj.mp or defObj.attr[RoleDefine.INIT_MP]
  969. defObj.initHp = defObj.hp
  970. defObj.initMp = defObj.mp
  971. end
  972. end
  973. end
  974. --战前加属性(包括各系统,被动技能,阵营光环)
  975. function onFightBegin(human, combatType, cbParam, param)
  976. local moduleFn = getModule(combatType)
  977. if moduleFn and moduleFn.onFightBegin then
  978. moduleFn.onFightBegin(human, cbParam, combatType, param)
  979. end
  980. BeSkill.onFightBegin(human)
  981. CombatPosLogic.onFightBegin(human)
  982. recalcHpFightBegin(human, combatType, cbParam)
  983. end
  984. function getHumanHeroList(human,combatType, cbParam)
  985. return getHumanObjList(human, combatType)
  986. end
  987. -- 设置英雄出战
  988. local function setCombatInfo(formation,objList, side)
  989. for index = 1, CombatDefine.COMBAT_HERO_CNT do
  990. local obj = objList[index]
  991. if obj then
  992. -- 出战英雄站位
  993. if CombatPosLogic.checkPos(formation,index, side) then
  994. local pos = CombatDefine.SIDE2POS[side][index]
  995. CombatImpl.setData(pos, obj) --初始化对象数据
  996. end
  997. end
  998. end
  999. end
  1000. -- 设置辅助对象出战
  1001. local function setHelp(helpList, side)
  1002. if not helpList then return end
  1003. for k,v in pairs(helpList) do
  1004. if k == CombatDefine.HELP_TYPE1 then
  1005. CombatPetCalc.calcGrowArgs(v)
  1006. CombatPetCalc.clacBuffArgs(v)
  1007. end
  1008. CombatImpl.setHelp(side,k,v)
  1009. end
  1010. end
  1011. -- 初始combatInfo
  1012. local function initCombatInfo(human, combatType, mapID)
  1013. local combatInfo = {}
  1014. combatInfo.time = os.time() -- 战斗时间
  1015. combatInfo.passTime = 0 -- 客户端经过的时间
  1016. combatInfo.type = combatType -- 战斗类型
  1017. combatInfo.mapID = mapID -- 地图
  1018. combatInfo.posAttr = {} -- 阵法属性
  1019. combatInfo.jiban = {} -- 阵法属性
  1020. combatInfo.attacker = nil -- 攻方基础角色信息 roleBase
  1021. combatInfo.defender = nil -- 守方基础角色信息 roleBase
  1022. combatInfo.atkJiban = nil -- 攻方羁绊英雄
  1023. combatInfo.defJiban = nil -- 守方羁绊英雄
  1024. combatInfo.isWin = nil -- 战斗结果
  1025. combatInfo.result = nil -- 战斗帧
  1026. combatInfo.skillUseList = nil -- 战斗技能
  1027. combatInfo.cmdUseList = nil -- 战斗技能命令
  1028. combatInfo.bufferUseList = nil -- 战斗buff
  1029. combatInfo.objList = nil -- 战斗英雄列表
  1030. combatInfo.helpList = nil -- 战斗魔兽列表
  1031. combatInfo.rewardItem = {} -- 奖励
  1032. combatInfo.endParam = nil -- 额外参数
  1033. combatInfo.isVideo = nil -- 是否录像
  1034. combatInfo.videoUuid = nil -- 录像uuid
  1035. combatInfo.panelID = nil -- 返回界面(特殊)
  1036. combatInfo.maxRound = nil -- 最大会合数
  1037. combatInfo.fightMode = nil -- 战斗模式
  1038. human.combat = combatInfo
  1039. return combatInfo
  1040. end
  1041. -- 为了战斗回放,某些数据需要保存
  1042. local function copyToCombatInfo(combatInfo)
  1043. combatInfo.isWin = CombatImpl.result.isWin
  1044. combatInfo.result = Util.copyTable(CombatImpl.result)
  1045. combatInfo.result.round = CombatImpl.round
  1046. combatInfo.skillUseList = Util.copyTable(CombatImpl.skillUseList)
  1047. combatInfo.cmdUseList = Util.copyTable(CombatImpl.cmdUseList)
  1048. combatInfo.bufferUseList = Util.copyTable(CombatImpl.bufferUseList)
  1049. combatInfo.objList = Util.copyTable(CombatImpl.objList)
  1050. combatInfo.helpList = Util.copyTable(CombatImpl.helpList)
  1051. combatInfo.totalAtkCnt = CombatImpl.totalAtkCnt
  1052. end
  1053. function setSkillAndBeskill(human,combatInfo)
  1054. local combatType = combatInfo.type
  1055. local moduleFn = getModule(combatType)
  1056. if moduleFn and moduleFn.setSkillAndBeskill then
  1057. moduleFn.setSkillAndBeskill(human,combatInfo)
  1058. end
  1059. end
  1060. --[[
  1061. @param1 : agent
  1062. @param2 : mapID //地图ID
  1063. @oaram3 : 对应参数
  1064. @param4 : 战斗类型
  1065. ]]
  1066. function combatBegin(human, mapID, param, combatType, cbParam, isSaodang)
  1067. if COMBAT_CACHE[human.db._id] and COMBAT_CACHE[human.db._id][combatType] then
  1068. --assert(nil, "has combat cache "..combatType .. " " .. human.db.account) -- reyes test
  1069. human.combat = COMBAT_CACHE[human.db._id][combatType].combatInfo
  1070. sendCombatData(human, human.combat)
  1071. return
  1072. end
  1073. -- 获得地图ID
  1074. CombatImpl.init(combatType)
  1075. mapID = getMapID(human, combatType, param)
  1076. local defender, defHelp, defRBase,defFormation,defJiban = getCombatObjList(human, CombatDefine.DEFEND_SIDE, combatType, param)
  1077. local attacker, atkHelp, atkRBase, atkFormation,atkJiban
  1078. if defender then
  1079. attacker, atkHelp, atkRBase, atkFormation,atkJiban = getCombatObjList(human, CombatDefine.ATTACK_SIDE, combatType, param)
  1080. end
  1081. if not (attacker and next(attacker)) then
  1082. return
  1083. end
  1084. if not defender then
  1085. return
  1086. end
  1087. local combatInfo = initCombatInfo(human, combatType, mapID)
  1088. combatInfo.attacker = atkRBase or {}
  1089. combatInfo.atkHelp = atkHelp or {}
  1090. combatInfo.atkFormation = atkFormation
  1091. combatInfo.atkJiban = atkJiban
  1092. combatInfo.defender = defRBase or {}
  1093. combatInfo.defHelp = defHelp or {}
  1094. combatInfo.defFormation = defFormation
  1095. combatInfo.defJiban = defJiban
  1096. combatInfo.posAttr[CombatDefine.ATTACK_SIDE] = CombatPosLogic.getPosAttr(attacker)
  1097. combatInfo.posAttr[CombatDefine.DEFEND_SIDE] = CombatPosLogic.getPosAttr(defender)
  1098. combatInfo.jiban[CombatDefine.ATTACK_SIDE] = JibanLogic.getJiban(attacker,atkJiban)
  1099. combatInfo.jiban[CombatDefine.DEFEND_SIDE] = JibanLogic.getJiban(defender,defJiban)
  1100. combatInfo.maxRound = getMaxRound(human,combatType)
  1101. combatInfo.fightMode = getFightMode(combatType)
  1102. --战役第五关特殊处理
  1103. BeginStory.handleBattle5(human, combatType, defender)
  1104. JibanLogic.setBeSkill(attacker,combatInfo.jiban[CombatDefine.ATTACK_SIDE])
  1105. JibanLogic.setBeSkill(defender,combatInfo.jiban[CombatDefine.DEFEND_SIDE])
  1106. local changePos = nil
  1107. if combatType == CombatDefine.COMBAT_TYPE10 then
  1108. for k,v in pairs(attacker) do
  1109. changePos = k
  1110. attacker[k] = nil
  1111. attacker[5] = v
  1112. break
  1113. end
  1114. end
  1115. setCombatInfo(atkFormation, attacker, CombatDefine.ATTACK_SIDE)
  1116. setCombatInfo(defFormation, defender, CombatDefine.DEFEND_SIDE)
  1117. setHelp(atkHelp, CombatDefine.ATTACK_SIDE)
  1118. setHelp(defHelp, CombatDefine.DEFEND_SIDE)
  1119. CombatImpl.setMaxRound(combatInfo.maxRound)
  1120. CombatImpl.setFightMode(combatInfo.fightMode)
  1121. --需要对技能特殊处理的(比如不重置cd)
  1122. setSkillAndBeskill(human,combatInfo)
  1123. -- 战前属性/血量重算
  1124. local tempParam = cbParam
  1125. if combatType == CombatDefine.COMBAT_TYPE10 then
  1126. tempParam = {}
  1127. tempParam.cbParam = cbParam
  1128. tempParam.changePos = changePos
  1129. end
  1130. onFightBegin(human, combatType, tempParam, param)
  1131. makeAttrLogStr(human)
  1132. while CombatImpl.calcFrame() do end
  1133. copyToCombatInfo(combatInfo)
  1134. combatInfo.changePos = changePos
  1135. local result = combatInfo.isWin and CombatDefine.RESULT_WIN or CombatDefine.RESULT_FAIL
  1136. local isQuick = human.db.combatQuick[combatType] == 1-- 是否跳过战斗
  1137. if isSaodang or isQuick then
  1138. -- 扫荡/跳过战斗需要立刻出结果
  1139. onFightEnd(human, result, combatType, cbParam, combatInfo, isSaodang,param)
  1140. sendCombatFinish(human, combatInfo)
  1141. else
  1142. -- 发送战斗开始+战斗帧
  1143. sendCombatData(human, combatInfo)
  1144. addCombatCache(human.db._id, combatInfo, cbParam,param)
  1145. end
  1146. makeLogStr(human) -- 写战斗日志
  1147. end
  1148. function getCombatUseTime(combatInfo)
  1149. local combatUseTime = CombatDefine.COMBAT_ATK_TIME * (combatInfo.totalAtkCnt or 0) -- 1.2秒1次行动
  1150. combatUseTime = combatUseTime + 10 --带上出场时间
  1151. return combatUseTime
  1152. end
  1153. function combatGm(human,mapID,atkFormation,attacker,defFormation,defender,atkPet,defPet,rewardItem)
  1154. local combatType = 0
  1155. local config = CombatExcel.combat[combatType]
  1156. local combatInfo = initCombatInfo(human, combatType, mapID)
  1157. combatInfo.attacker = {}
  1158. combatInfo.defender = {}
  1159. combatInfo.posAttr[CombatDefine.ATTACK_SIDE] = CombatPosLogic.getPosAttr(attacker)
  1160. combatInfo.posAttr[CombatDefine.DEFEND_SIDE] = CombatPosLogic.getPosAttr(defender)
  1161. combatInfo.jiban[CombatDefine.ATTACK_SIDE] = JibanLogic.getJiban(attacker)
  1162. combatInfo.jiban[CombatDefine.DEFEND_SIDE] = JibanLogic.getJiban(defender)
  1163. combatInfo.rewardItem = rewardItem or combatInfo.rewardItem
  1164. combatInfo.atkFormation = atkFormation
  1165. combatInfo.defFormation = defFormation
  1166. combatInfo.fightMode = config.fightMode
  1167. CombatImpl.init(combatType)
  1168. setCombatInfo(atkFormation,attacker, CombatDefine.ATTACK_SIDE)
  1169. setCombatInfo(defFormation,defender, CombatDefine.DEFEND_SIDE)
  1170. setHelp({atkPet}, CombatDefine.ATTACK_SIDE)
  1171. setHelp({defPet}, CombatDefine.DEFEND_SIDE)
  1172. combatInfo.maxRound = getMaxRound(human,combatType)
  1173. CombatImpl.setMaxRound(combatInfo.maxRound)
  1174. CombatImpl.setFightMode(combatInfo.fightMode)
  1175. -- 战前属性/血量重算
  1176. onFightBegin(human, combatType, nil, {}, {})
  1177. makeAttrLogStr(human)
  1178. while CombatImpl.calcFrame() do end
  1179. copyToCombatInfo(combatInfo)
  1180. sendCombatData(human, combatInfo)
  1181. -- 方便调试不做缓存
  1182. addCombatCache(human.db._id, combatInfo)
  1183. makeLogStr(human) -- 写战斗日志
  1184. end
  1185. function combatGuide(human, atkFormation,attacker,defFormation,defender,atkPet,defPet)
  1186. local combatType = CombatDefine.COMBAT_TYPE18
  1187. local config = CombatExcel.combat[combatType]
  1188. local combatInfo = initCombatInfo(human, combatType, config.mapID)
  1189. combatInfo.attacker = {}
  1190. combatInfo.defender = {}
  1191. combatInfo.posAttr[CombatDefine.ATTACK_SIDE] = CombatPosLogic.getPosAttr(attacker)
  1192. combatInfo.posAttr[CombatDefine.DEFEND_SIDE] = CombatPosLogic.getPosAttr(defender)
  1193. combatInfo.jiban[CombatDefine.ATTACK_SIDE] = JibanLogic.getJiban(attacker)
  1194. combatInfo.jiban[CombatDefine.DEFEND_SIDE] = JibanLogic.getJiban(defender)
  1195. combatInfo.rewardItem = rewardItem or combatInfo.rewardItem
  1196. combatInfo.atkFormation = atkFormation
  1197. combatInfo.defFormation = defFormation
  1198. combatInfo.fightMode = config.fightMode
  1199. CombatImpl.init(combatType)
  1200. setCombatInfo(atkFormation,attacker, CombatDefine.ATTACK_SIDE)
  1201. setCombatInfo(defFormation,defender, CombatDefine.DEFEND_SIDE)
  1202. setHelp({atkPet}, CombatDefine.ATTACK_SIDE)
  1203. setHelp({defPet}, CombatDefine.DEFEND_SIDE)
  1204. combatInfo.maxRound = getMaxRound(human, combatType)
  1205. CombatImpl.setMaxRound(combatInfo.maxRound)
  1206. CombatImpl.setFightMode(combatInfo.fightMode)
  1207. JibanLogic.setBeSkill(attacker,combatInfo.jiban[CombatDefine.ATTACK_SIDE])
  1208. JibanLogic.setBeSkill(defender,combatInfo.jiban[CombatDefine.DEFEND_SIDE])
  1209. -- 战前属性/血量重算
  1210. onFightBegin(human, combatType, nil, {}, {})
  1211. human.combat = combatInfo
  1212. while CombatImpl.calcFrame() do end
  1213. copyToCombatInfo(human.combat)
  1214. end
  1215. --
  1216. function combatVedio(human, atkFormation, attacker,defFormation,defender,atkPet,defPet, fakeHuman)
  1217. local combatType = CombatDefine.COMBAT_TYPE22
  1218. local config = CombatExcel.combat[combatType]
  1219. local combatInfo = initCombatInfo(human, combatType, config.mapID)
  1220. combatInfo.attacker = {}
  1221. combatInfo.defender = {}
  1222. combatInfo.posAttr[CombatDefine.ATTACK_SIDE] = CombatPosLogic.getPosAttr(attacker)
  1223. combatInfo.posAttr[CombatDefine.DEFEND_SIDE] = CombatPosLogic.getPosAttr(defender)
  1224. combatInfo.jiban[CombatDefine.ATTACK_SIDE] = JibanLogic.getJiban(attacker)
  1225. combatInfo.jiban[CombatDefine.DEFEND_SIDE] = JibanLogic.getJiban(defender)
  1226. combatInfo.rewardItem = rewardItem or combatInfo.rewardItem
  1227. combatInfo.atkFormation = atkFormation
  1228. combatInfo.defFormation = defFormation
  1229. combatInfo.fightMode = config.fightMode
  1230. CombatImpl.init(combatType)
  1231. setCombatInfo(atkFormation,attacker, CombatDefine.ATTACK_SIDE)
  1232. setCombatInfo(defFormation,defender, CombatDefine.DEFEND_SIDE)
  1233. setHelp({atkPet}, CombatDefine.ATTACK_SIDE)
  1234. setHelp({defPet}, CombatDefine.DEFEND_SIDE)
  1235. combatInfo.maxRound = getMaxRound(human, combatType)
  1236. CombatImpl.setMaxRound(combatInfo.maxRound)
  1237. CombatImpl.setFightMode(combatInfo.fightMode)
  1238. JibanLogic.setBeSkill(attacker,combatInfo.jiban[CombatDefine.ATTACK_SIDE])
  1239. JibanLogic.setBeSkill(defender,combatInfo.jiban[CombatDefine.DEFEND_SIDE])
  1240. -- 战前属性/血量重算
  1241. onFightBegin(human, combatType, nil, {}, {})
  1242. human.combat = combatInfo
  1243. while CombatImpl.calcFrame() do end
  1244. copyToCombatInfo(human.combat)
  1245. sendCombatData(fakeHuman, combatInfo)
  1246. end
  1247. -- 战斗录像
  1248. local VEDIO_COMBAT_INFO = VEDIO_COMBAT_INFO or { db = {} }
  1249. function combatFightVedio(human, heroID)
  1250. local heroConfig = HeroExcel.hero[heroID]
  1251. if not heroConfig then return end
  1252. local combatConf = CombatExcel.gm[heroConfig.gm]
  1253. if not combatConf then return end
  1254. VEDIO_COMBAT_INFO.attacker = {}
  1255. VEDIO_COMBAT_INFO.defender = {}
  1256. VEDIO_COMBAT_INFO.atkFormation = combatConf.atkF
  1257. VEDIO_COMBAT_INFO.defFormation = combatConf.defF
  1258. local atkConf = nil
  1259. for i = 1, CombatDefine.COMBAT_HERO_CNT do
  1260. atkConf = nil
  1261. for k, v in ipairs(combatConf.atk) do
  1262. if i == v[2] then
  1263. atkConf = v
  1264. break
  1265. end
  1266. end
  1267. if atkConf then
  1268. VEDIO_COMBAT_INFO.attacker[i] = createHeroObj(VEDIO_COMBAT_INFO, atkConf[1], atkConf[3], atkConf[4], i)
  1269. end
  1270. atkConf = nil
  1271. for k, v in ipairs(combatConf.def) do
  1272. if i == v[2] then
  1273. atkConf = v
  1274. break
  1275. end
  1276. end
  1277. if atkConf then
  1278. VEDIO_COMBAT_INFO.defender[i] = createHeroObj(VEDIO_COMBAT_INFO, atkConf[1], atkConf[3], atkConf[4], i)
  1279. end
  1280. end
  1281. combatVedio(VEDIO_COMBAT_INFO, VEDIO_COMBAT_INFO.atkFormation, VEDIO_COMBAT_INFO.attacker,
  1282. VEDIO_COMBAT_INFO.defFormation, VEDIO_COMBAT_INFO.defender, nil, nil, human)
  1283. end
  1284. function repeatCombat(human, combatInfo)
  1285. if not combatInfo then
  1286. return
  1287. end
  1288. if isCombating(human) then
  1289. return Broadcast.sendErr(human, Lang.COMBAT_VIDEO_LOOK_ERR_ING)
  1290. end
  1291. combatInfo.isVideo = true
  1292. human.combat = combatInfo
  1293. sendCombatData(human, combatInfo)
  1294. sendCombatFinish(human, combatInfo)
  1295. end
  1296. -- 初始属性数据写日志
  1297. function makeAttrLogStr(human)
  1298. if not Config.IS_DEBUG then
  1299. return
  1300. end
  1301. local logStr = "\n初始属性数据:\n"
  1302. for i = 1, CombatDefine.COMBAT_HERO_ALL_CNT do
  1303. data = CombatImpl.objList[i]
  1304. if data then
  1305. logStr = logStr .. "\n\t" .. "{pos:"..data.pos.." heroID:"..data.id.."}\n\t"
  1306. for k,v in pairs(data.attr) do
  1307. if v ~= 0 then
  1308. logStr = logStr .."{key:"..k..",value:"..v.."},"
  1309. end
  1310. end
  1311. end
  1312. end
  1313. logStr = logStr .."\n"
  1314. local f = io.open("./log/fight_log.log", "w+")
  1315. f:write(logStr)
  1316. assert(io.close(f))
  1317. end
  1318. function makeLogStr(human)
  1319. if not Config.IS_DEBUG then
  1320. return
  1321. end
  1322. local logStr = "\n战斗开始数据:\n"
  1323. for i = 1, CombatDefine.COMBAT_HERO_ALL_CNT do
  1324. data = CombatImpl.objList[i]
  1325. if data then
  1326. logStr = logStr .. "\t" .. "{pos:"..data.pos.." heroID:"..data.id.."}"
  1327. end
  1328. end
  1329. logStr = logStr .. "\n"
  1330. logStr = logStr .. "战斗帧数据:\n"
  1331. local result = CombatImpl.result
  1332. local frameCnt = result.frames and #result.frames or 0
  1333. for i = 1,frameCnt do
  1334. local data = result.frames[i]
  1335. logStr = logStr .. "\t" .. i .."帧\n"
  1336. for j = 1,#data.skillList do
  1337. local skillData = data.skillList[j]
  1338. logStr = logStr .. "\t\t技能释放 attackPos:"..skillData.attackPos.." skillID:"..skillData.skillID.."\n"
  1339. local hitLen = 0
  1340. for k = 1,CombatDefine.COMBAT_HERO_ALL_CNT do
  1341. if skillData.hitList[k] then
  1342. hitLen = hitLen + 1
  1343. local skillHitData = skillData.hitList[k]
  1344. logStr = logStr .. "\t\t\t技能对象"..hitLen.." pos:"..k.." hpNow:"..skillHitData.hpNow.." attrs:"
  1345. local frameAttrs = skillHitData.attrs
  1346. local attrsLen = 0
  1347. if frameAttrs then
  1348. for m = 1,#frameAttrs do
  1349. logStr = logStr .. " {key:"..frameAttrs[m][1].." value:"..frameAttrs[m][2].."}"
  1350. end
  1351. end
  1352. logStr = logStr .. "\n"
  1353. end
  1354. end
  1355. local extraLen = 0
  1356. for k = 1,CombatDefine.COMBAT_HERO_ALL_CNT do
  1357. if skillData.extraList[k] then
  1358. extraLen = extraLen + 1
  1359. local extraHitData = skillData.extraList[k]
  1360. logStr = logStr .. "\t\t\t额外作用对象"..extraLen.." pos:"..k.." cmd:"..extraHitData.cmd.." hpNow:"..extraHitData.hpNow.." attrs:"
  1361. local frameAttrs = extraHitData.attrs
  1362. if frameAttrs then
  1363. for m = 1,#frameAttrs do
  1364. logStr = logStr .. " {key:"..frameAttrs[m][1].." value:"..frameAttrs[m][2].."}"
  1365. end
  1366. end
  1367. logStr = logStr .. "\n"
  1368. end
  1369. end
  1370. end
  1371. local bufferLen = 0
  1372. for j = 1,CombatDefine.COMBAT_HERO_ALL_CNT do
  1373. if data.bufferList[j] then
  1374. bufferLen = bufferLen + 1
  1375. logStr = logStr .. "\t\tbuffer更新 pos:"..j.."\n"
  1376. local bufferDataList = data.bufferList[j]
  1377. for i = 1,#bufferDataList do
  1378. local bufferData = bufferDataList[i]
  1379. logStr = logStr .. "\t\t\t bufferID:"..bufferData.id.." op:"..bufferData.op.." cnt:"..bufferData.cnt.." round:"..(bufferData.round or -1).." hpNow:"..bufferData.hpNow.." attrs:"
  1380. local attrsLen = 0
  1381. if bufferData.attrs then
  1382. for k,v in ipairs(bufferData.attrs) do
  1383. logStr = logStr .. " {key:"..v[1].." value:"..v[2].."}"
  1384. end
  1385. end
  1386. end
  1387. logStr = logStr .. "\n"
  1388. end
  1389. end
  1390. end
  1391. local f = io.open("./log/fight_log.log", "a+")
  1392. f:write(logStr)
  1393. assert(io.close(f))
  1394. end
  1395. -- 获取角色上阵的形象
  1396. function getRoleBody(human, combatType)
  1397. local teamType = CombatPosLogic.getTeamType(combatType)
  1398. local combatHero = teamType and human.db.combatHero[teamType]
  1399. if not combatHero then return end
  1400. local zhandouli = 0
  1401. local maxGrid = nil
  1402. for i = 1, CombatDefine.COMBAT_HERO_CNT do
  1403. local uuid = combatHero.list[i]
  1404. local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
  1405. if heroGrid and type(heroGrid) == "table" and
  1406. zhandouli < heroGrid.zhandouli then
  1407. zhandouli = heroGrid.zhandouli
  1408. maxGrid = heroGrid
  1409. end
  1410. end
  1411. if not maxGrid then return end
  1412. return HeroGrid.getHeroBodyById(maxGrid.id)
  1413. end
  1414. -- 根据怪物组id获取外显
  1415. function getMonsterIDByOutID(monsterOutID, args)
  1416. local mocf = MonsterExcel.monsterOut[monsterOutID]
  1417. if not mocf then return end
  1418. local memberCnt = #mocf.member
  1419. local index = (monsterOutID % 1000) % memberCnt
  1420. if index == 0 then index = memberCnt - 1 end
  1421. local minfo = mocf.member[index]
  1422. if not minfo then
  1423. for _, minfo0 in ipairs(mocf.member) do
  1424. if minfo0[1] > 0 then
  1425. minfo = minfo0
  1426. break
  1427. end
  1428. end
  1429. end
  1430. if not minfo then return end
  1431. local monsterID = minfo[1]
  1432. local monsterLv = minfo[2]
  1433. local mcf = monsterID and MonsterExcel.monster[monsterID]
  1434. if not mcf then return end
  1435. if mocf.combatType == CombatDefine.COMBAT_TYPE5 then
  1436. if args then
  1437. local throneID = args[1]
  1438. local evolveCnt = args[2]
  1439. monsterLv = TheStarsLogic.getMonsterLvAttr(1, throneID, evolveCnt)
  1440. end
  1441. end
  1442. return monsterID, mcf, monsterLv
  1443. end
  1444. -- 根据伤害计算胜负
  1445. function calcWinByHurt(combatInfo)
  1446. if not combatInfo.isWin then return end
  1447. if not combatInfo.objList then return end
  1448. local atkHurt = 0
  1449. local defHurt = 0
  1450. local atkLive = 0
  1451. local defLive = 0
  1452. for i = 1,CombatDefine.COMBAT_HERO_CNT do
  1453. local atkPos = getPos(CombatDefine.ATTACK_SIDE, i)
  1454. local atkObj = combatInfo.objList[atkPos]
  1455. if atkObj then
  1456. atkHurt = atkHurt + atkObj.result[1]
  1457. if atkObj.hp > 0 and not atkLive then
  1458. atkLive = 1
  1459. end
  1460. end
  1461. local defPos = getPos(CombatDefine.DEFEND_SIDE, i)
  1462. local defObj = combatInfo.objList[defPos]
  1463. if defObj then
  1464. defHurt = defHurt + defObj.result[1]
  1465. if atkObj.hp > 0 and not defLive then
  1466. defLive = 1
  1467. end
  1468. end
  1469. end
  1470. if atkLive == 0 then
  1471. atkHurt = 0
  1472. elseif defLive == 0 then
  1473. defLive = 0
  1474. end
  1475. combatInfo.isWin = atkHurt > defHurt and true or false
  1476. return combatInfo.isWin
  1477. end
  1478. ------------- reyes test ---------------------
  1479. function isCombating(human)
  1480. local list = COMBAT_CACHE[human.db._id]
  1481. if not list then return end
  1482. for combatType, combatCache in pairs(list) do
  1483. if not combatCache.combatInfo.isVideo then
  1484. return true
  1485. end
  1486. end
  1487. end
  1488. function getCombatCache(uuid, type)
  1489. return COMBAT_CACHE[uuid] and COMBAT_CACHE[uuid][type]
  1490. end
  1491. function addCombatCache(uuid, combatInfo, cbParam,param)
  1492. COMBAT_CACHE[uuid] = COMBAT_CACHE[uuid] or {} -- reyes test
  1493. local tempCache = {}
  1494. local result = combatInfo.isWin and CombatDefine.RESULT_WIN or CombatDefine.RESULT_FAIL
  1495. tempCache.result = result
  1496. tempCache.combatType = combatInfo.type
  1497. tempCache.cbParam = cbParam
  1498. tempCache.combatInfo = combatInfo
  1499. tempCache.param = param
  1500. tempCache.ts = os.time() + getCombatUseTime(combatInfo)
  1501. COMBAT_CACHE[uuid][combatInfo.type] = tempCache
  1502. end
  1503. function cleanCombatCache(uuid, type)
  1504. if not COMBAT_CACHE[uuid] then return end
  1505. COMBAT_CACHE[uuid][type] = nil
  1506. if Util.getTableCount(COMBAT_CACHE[uuid]) == 0 then
  1507. COMBAT_CACHE[uuid] = nil
  1508. end
  1509. end
  1510. function clientFinish(human, type, noSend)
  1511. if COMBAT_CACHE[human.db._id] == nil or COMBAT_CACHE[human.db._id][type] == nil then
  1512. return
  1513. end
  1514. local combatCache = COMBAT_CACHE[human.db._id][type]
  1515. cleanCombatCache(human.db._id, type)
  1516. --print("onend-=----------------------")
  1517. if not combatCache.combatInfo.isVideo then
  1518. onFightEnd(human, combatCache.result, combatCache.combatType, combatCache.cbParam, combatCache.combatInfo,combatCache.param)
  1519. end
  1520. -- 绝望深渊 非失败 不发
  1521. -- 冰龙 次元魔珠 失落神庙 不走默认结算协议
  1522. if type ~= CombatDefine.COMBAT_TYPE8 and
  1523. type ~= CombatDefine.COMABT_TYPE23 and
  1524. type ~= CombatDefine.COMBAT_TYPE20 and
  1525. type ~= CombatDefine.COMBAT_TYPE24
  1526. and not noSend then
  1527. sendCombatFinish(human, combatCache.combatInfo)
  1528. end
  1529. end
  1530. function clientPassTime(human, type, passTime)
  1531. if COMBAT_CACHE[human.db._id] == nil or COMBAT_CACHE[human.db._id][type] == nil then
  1532. return
  1533. end
  1534. local combatInfo = COMBAT_CACHE[human.db._id][type].combatInfo
  1535. combatInfo.passTime = passTime
  1536. end
  1537. function onLogin(human)
  1538. checkFinish(human)
  1539. -- 这里要先check才判断cache 因为check完cache可能就空了
  1540. if COMBAT_CACHE[human.db._id] == nil then
  1541. return
  1542. end
  1543. for k, v in pairs(COMBAT_CACHE[human.db._id]) do
  1544. --assert(nil, "has combat cache "..combatType .. " " .. human.db.account) -- reyes test
  1545. human.combat = v.combatInfo
  1546. sendCombatData(human, human.combat, true)
  1547. end
  1548. end
  1549. function checkFinish(human)
  1550. if COMBAT_CACHE[human.db._id] == nil then
  1551. return
  1552. end
  1553. local now = os.time()
  1554. for k, v in pairs(COMBAT_CACHE[human.db._id]) do
  1555. if now >= v.ts then
  1556. clientFinish(human, k)
  1557. if COMBAT_CACHE[human.db._id] == nil then
  1558. return
  1559. end
  1560. end
  1561. end
  1562. end
  1563. -- 不管时间立刻结算 目前只有踢人等非正常下线会用到
  1564. function forceFinish(human)
  1565. if COMBAT_CACHE[human.db._id] == nil then
  1566. return
  1567. end
  1568. local now = os.time()
  1569. for k, v in pairs(COMBAT_CACHE[human.db._id]) do
  1570. clientFinish(human, k)
  1571. if COMBAT_CACHE[human.db._id] == nil then
  1572. return
  1573. end
  1574. end
  1575. end
  1576. function killFrames(combatInfo)
  1577. --60帧2倍速情况下大概1分半。限制录像时长再3-5分钟。节省包量
  1578. if combatInfo.result.frames and #combatInfo.result.frames > 200 then
  1579. for i = 201,#combatInfo.result.frames do
  1580. combatInfo.result.frames[i] = nil
  1581. end
  1582. end
  1583. end