CombatLogic.lua 58 KB

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