CombatLogic.lua 58 KB

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