CombatLogic.lua 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793
  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. CombatPosLogic.onFightBegin(human)
  990. recalcHpFightBegin(human, combatType, cbParam)
  991. end
  992. function getHumanHeroList(human,combatType, cbParam)
  993. return getHumanObjList(human, combatType)
  994. end
  995. -- 设置英雄出战
  996. local function setCombatInfo(formation,objList, side)
  997. for index = 1, CombatDefine.COMBAT_HERO_CNT do
  998. local obj = objList[index]
  999. if obj then
  1000. -- 出战英雄站位
  1001. if CombatPosLogic.checkPos(formation,index, side) then
  1002. local pos = CombatDefine.SIDE2POS[side][index]
  1003. CombatImpl.setData(pos, obj)
  1004. end
  1005. end
  1006. end
  1007. end
  1008. -- 设置辅助对象出战
  1009. local function setHelp(helpList, side)
  1010. if not helpList then return end
  1011. for k,v in pairs(helpList) do
  1012. if k == CombatDefine.HELP_TYPE1 then
  1013. CombatPetCalc.calcGrowArgs(v)
  1014. CombatPetCalc.clacBuffArgs(v)
  1015. end
  1016. CombatImpl.setHelp(side,k,v)
  1017. end
  1018. end
  1019. -- 初始combatInfo
  1020. local function initCombatInfo(human, combatType, mapID)
  1021. local combatInfo = {}
  1022. combatInfo.time = os.time() -- 战斗时间
  1023. combatInfo.passTime = 0 -- 客户端经过的时间
  1024. combatInfo.type = combatType -- 战斗类型
  1025. combatInfo.mapID = mapID -- 地图
  1026. combatInfo.posAttr = {} -- 阵法属性
  1027. combatInfo.jiban = {} -- 阵法属性
  1028. combatInfo.attacker = nil -- 攻方基础角色信息 roleBase
  1029. combatInfo.defender = nil -- 守方基础角色信息 roleBase
  1030. combatInfo.atkJiban = nil -- 攻方羁绊英雄
  1031. combatInfo.defJiban = nil -- 守方羁绊英雄
  1032. combatInfo.isWin = nil -- 战斗结果
  1033. combatInfo.result = nil -- 战斗帧
  1034. combatInfo.skillUseList = nil -- 战斗技能
  1035. combatInfo.cmdUseList = nil -- 战斗技能命令
  1036. combatInfo.bufferUseList = nil -- 战斗buff
  1037. combatInfo.objList = nil -- 战斗英雄列表
  1038. combatInfo.helpList = nil -- 战斗魔兽列表
  1039. combatInfo.rewardItem = {} -- 奖励
  1040. combatInfo.endParam = nil -- 额外参数
  1041. combatInfo.isVideo = nil -- 是否录像
  1042. combatInfo.videoUuid = nil -- 录像uuid
  1043. combatInfo.panelID = nil -- 返回界面(特殊)
  1044. combatInfo.maxRound = nil -- 最大会合数
  1045. combatInfo.fightMode = nil -- 战斗模式
  1046. human.combat = combatInfo
  1047. return combatInfo
  1048. end
  1049. -- 为了战斗回放,某些数据需要保存
  1050. local function copyToCombatInfo(combatInfo)
  1051. combatInfo.isWin = CombatImpl.result.isWin
  1052. combatInfo.result = Util.copyTable(CombatImpl.result)
  1053. combatInfo.result.round = CombatImpl.round
  1054. combatInfo.skillUseList = Util.copyTable(CombatImpl.skillUseList)
  1055. combatInfo.cmdUseList = Util.copyTable(CombatImpl.cmdUseList)
  1056. combatInfo.bufferUseList = Util.copyTable(CombatImpl.bufferUseList)
  1057. combatInfo.objList = Util.copyTable(CombatImpl.objList)
  1058. combatInfo.helpList = Util.copyTable(CombatImpl.helpList)
  1059. combatInfo.totalAtkCnt = CombatImpl.totalAtkCnt
  1060. end
  1061. function setSkillAndBeskill(human,combatInfo)
  1062. local combatType = combatInfo.type
  1063. local moduleFn = getModule(combatType)
  1064. if moduleFn and moduleFn.setSkillAndBeskill then
  1065. moduleFn.setSkillAndBeskill(human,combatInfo)
  1066. end
  1067. end
  1068. function combatBegin(human, mapID, param, combatType, cbParam, isSaodang)
  1069. if COMBAT_CACHE[human.db._id] and COMBAT_CACHE[human.db._id][combatType] then
  1070. --assert(nil, "has combat cache "..combatType .. " " .. human.db.account) -- reyes test
  1071. human.combat = COMBAT_CACHE[human.db._id][combatType].combatInfo
  1072. sendCombatData(human, human.combat)
  1073. return
  1074. end
  1075. -- 获得地图ID
  1076. CombatImpl.init(combatType)
  1077. mapID = getMapID(human, combatType, param)
  1078. local defender, defHelp, defRBase,defFormation,defJiban = getCombatObjList(human, CombatDefine.DEFEND_SIDE, combatType, param)
  1079. local attacker, atkHelp, atkRBase, atkFormation,atkJiban
  1080. if defender then
  1081. attacker, atkHelp, atkRBase, atkFormation,atkJiban = getCombatObjList(human, CombatDefine.ATTACK_SIDE, combatType, param)
  1082. end
  1083. if not (attacker and next(attacker)) then
  1084. return
  1085. end
  1086. if not defender then
  1087. return
  1088. end
  1089. local combatInfo = initCombatInfo(human, combatType, mapID)
  1090. combatInfo.attacker = atkRBase or {}
  1091. combatInfo.atkHelp = atkHelp or {}
  1092. combatInfo.atkFormation = atkFormation
  1093. combatInfo.atkJiban = atkJiban
  1094. combatInfo.defender = defRBase or {}
  1095. combatInfo.defHelp = defHelp or {}
  1096. combatInfo.defFormation = defFormation
  1097. combatInfo.defJiban = defJiban
  1098. combatInfo.posAttr[CombatDefine.ATTACK_SIDE] = CombatPosLogic.getPosAttr(attacker)
  1099. combatInfo.posAttr[CombatDefine.DEFEND_SIDE] = CombatPosLogic.getPosAttr(defender)
  1100. combatInfo.jiban[CombatDefine.ATTACK_SIDE] = JibanLogic.getJiban(attacker,atkJiban)
  1101. combatInfo.jiban[CombatDefine.DEFEND_SIDE] = JibanLogic.getJiban(defender,defJiban)
  1102. combatInfo.maxRound = getMaxRound(human,combatType)
  1103. combatInfo.fightMode = getFightMode(combatType)
  1104. --战役第五关特殊处理
  1105. BeginStory.handleBattle5(human, combatType, defender)
  1106. JibanLogic.setBeSkill(attacker,combatInfo.jiban[CombatDefine.ATTACK_SIDE])
  1107. JibanLogic.setBeSkill(defender,combatInfo.jiban[CombatDefine.DEFEND_SIDE])
  1108. local changePos = nil
  1109. if combatType == CombatDefine.COMBAT_TYPE10 then
  1110. for k,v in pairs(attacker) do
  1111. changePos = k
  1112. attacker[k] = nil
  1113. attacker[5] = v
  1114. break
  1115. end
  1116. end
  1117. setCombatInfo(atkFormation, attacker, CombatDefine.ATTACK_SIDE)
  1118. setCombatInfo(defFormation, defender, CombatDefine.DEFEND_SIDE)
  1119. setHelp(atkHelp, CombatDefine.ATTACK_SIDE)
  1120. setHelp(defHelp, CombatDefine.DEFEND_SIDE)
  1121. CombatImpl.setMaxRound(combatInfo.maxRound)
  1122. CombatImpl.setFightMode(combatInfo.fightMode)
  1123. --需要对技能特殊处理的(比如不重置cd)
  1124. setSkillAndBeskill(human,combatInfo)
  1125. -- 战前属性/血量重算
  1126. local tempParam = cbParam
  1127. if combatType == CombatDefine.COMBAT_TYPE10 then
  1128. tempParam = {}
  1129. tempParam.cbParam = cbParam
  1130. tempParam.changePos = changePos
  1131. end
  1132. onFightBegin(human, combatType, tempParam, param)
  1133. makeAttrLogStr(human)
  1134. while CombatImpl.calcFrame() do end
  1135. copyToCombatInfo(combatInfo)
  1136. combatInfo.changePos = changePos
  1137. local result = combatInfo.isWin and CombatDefine.RESULT_WIN or CombatDefine.RESULT_FAIL
  1138. local isQuick = human.db.combatQuick[combatType] == 1-- 是否跳过战斗
  1139. if isSaodang or isQuick then
  1140. -- 扫荡/跳过战斗需要立刻出结果
  1141. onFightEnd(human, result, combatType, cbParam, combatInfo, isSaodang,param)
  1142. sendCombatFinish(human, combatInfo)
  1143. else
  1144. -- 发送战斗开始+战斗帧
  1145. sendCombatData(human, combatInfo)
  1146. addCombatCache(human.db._id, combatInfo, cbParam,param)
  1147. end
  1148. makeLogStr(human) -- 写战斗日志
  1149. end
  1150. function getCombatUseTime(combatInfo)
  1151. local combatUseTime = CombatDefine.COMBAT_ATK_TIME * (combatInfo.totalAtkCnt or 0) -- 1.2秒1次行动
  1152. combatUseTime = combatUseTime + 10 --带上出场时间
  1153. return combatUseTime
  1154. end
  1155. function combatGm(human,mapID,atkFormation,attacker,defFormation,defender,atkPet,defPet,rewardItem)
  1156. local combatType = 0
  1157. local config = CombatExcel.combat[combatType]
  1158. local combatInfo = initCombatInfo(human, combatType, mapID)
  1159. combatInfo.attacker = {}
  1160. combatInfo.defender = {}
  1161. combatInfo.posAttr[CombatDefine.ATTACK_SIDE] = CombatPosLogic.getPosAttr(attacker)
  1162. combatInfo.posAttr[CombatDefine.DEFEND_SIDE] = CombatPosLogic.getPosAttr(defender)
  1163. combatInfo.jiban[CombatDefine.ATTACK_SIDE] = JibanLogic.getJiban(attacker)
  1164. combatInfo.jiban[CombatDefine.DEFEND_SIDE] = JibanLogic.getJiban(defender)
  1165. combatInfo.rewardItem = rewardItem or combatInfo.rewardItem
  1166. combatInfo.atkFormation = atkFormation
  1167. combatInfo.defFormation = defFormation
  1168. combatInfo.fightMode = config.fightMode
  1169. CombatImpl.init(combatType)
  1170. setCombatInfo(atkFormation,attacker, CombatDefine.ATTACK_SIDE)
  1171. setCombatInfo(defFormation,defender, CombatDefine.DEFEND_SIDE)
  1172. setHelp({atkPet}, CombatDefine.ATTACK_SIDE)
  1173. setHelp({defPet}, CombatDefine.DEFEND_SIDE)
  1174. combatInfo.maxRound = getMaxRound(human,combatType)
  1175. CombatImpl.setMaxRound(combatInfo.maxRound)
  1176. CombatImpl.setFightMode(combatInfo.fightMode)
  1177. -- 战前属性/血量重算
  1178. onFightBegin(human, combatType, nil, {}, {})
  1179. makeAttrLogStr(human)
  1180. while CombatImpl.calcFrame() do end
  1181. copyToCombatInfo(combatInfo)
  1182. sendCombatData(human, combatInfo)
  1183. -- 方便调试不做缓存
  1184. addCombatCache(human.db._id, combatInfo)
  1185. makeLogStr(human) -- 写战斗日志
  1186. end
  1187. function combatGuide(human, atkFormation,attacker,defFormation,defender,atkPet,defPet)
  1188. local combatType = CombatDefine.COMBAT_TYPE18
  1189. local config = CombatExcel.combat[combatType]
  1190. local combatInfo = initCombatInfo(human, combatType, config.mapID)
  1191. combatInfo.attacker = {}
  1192. combatInfo.defender = {}
  1193. combatInfo.posAttr[CombatDefine.ATTACK_SIDE] = CombatPosLogic.getPosAttr(attacker)
  1194. combatInfo.posAttr[CombatDefine.DEFEND_SIDE] = CombatPosLogic.getPosAttr(defender)
  1195. combatInfo.jiban[CombatDefine.ATTACK_SIDE] = JibanLogic.getJiban(attacker)
  1196. combatInfo.jiban[CombatDefine.DEFEND_SIDE] = JibanLogic.getJiban(defender)
  1197. combatInfo.rewardItem = rewardItem or combatInfo.rewardItem
  1198. combatInfo.atkFormation = atkFormation
  1199. combatInfo.defFormation = defFormation
  1200. combatInfo.fightMode = config.fightMode
  1201. CombatImpl.init(combatType)
  1202. setCombatInfo(atkFormation,attacker, CombatDefine.ATTACK_SIDE)
  1203. setCombatInfo(defFormation,defender, CombatDefine.DEFEND_SIDE)
  1204. setHelp({atkPet}, CombatDefine.ATTACK_SIDE)
  1205. setHelp({defPet}, CombatDefine.DEFEND_SIDE)
  1206. combatInfo.maxRound = getMaxRound(human, combatType)
  1207. CombatImpl.setMaxRound(combatInfo.maxRound)
  1208. CombatImpl.setFightMode(combatInfo.fightMode)
  1209. JibanLogic.setBeSkill(attacker,combatInfo.jiban[CombatDefine.ATTACK_SIDE])
  1210. JibanLogic.setBeSkill(defender,combatInfo.jiban[CombatDefine.DEFEND_SIDE])
  1211. -- 战前属性/血量重算
  1212. onFightBegin(human, combatType, nil, {}, {})
  1213. human.combat = combatInfo
  1214. while CombatImpl.calcFrame() do end
  1215. copyToCombatInfo(human.combat)
  1216. end
  1217. --
  1218. function combatVedio(human, atkFormation, attacker,defFormation,defender,atkPet,defPet, fakeHuman)
  1219. local combatType = CombatDefine.COMBAT_TYPE22
  1220. local config = CombatExcel.combat[combatType]
  1221. local combatInfo = initCombatInfo(human, combatType, config.mapID)
  1222. combatInfo.attacker = {}
  1223. combatInfo.defender = {}
  1224. combatInfo.posAttr[CombatDefine.ATTACK_SIDE] = CombatPosLogic.getPosAttr(attacker)
  1225. combatInfo.posAttr[CombatDefine.DEFEND_SIDE] = CombatPosLogic.getPosAttr(defender)
  1226. combatInfo.jiban[CombatDefine.ATTACK_SIDE] = JibanLogic.getJiban(attacker)
  1227. combatInfo.jiban[CombatDefine.DEFEND_SIDE] = JibanLogic.getJiban(defender)
  1228. combatInfo.rewardItem = rewardItem or combatInfo.rewardItem
  1229. combatInfo.atkFormation = atkFormation
  1230. combatInfo.defFormation = defFormation
  1231. combatInfo.fightMode = config.fightMode
  1232. CombatImpl.init(combatType)
  1233. setCombatInfo(atkFormation,attacker, CombatDefine.ATTACK_SIDE)
  1234. setCombatInfo(defFormation,defender, CombatDefine.DEFEND_SIDE)
  1235. setHelp({atkPet}, CombatDefine.ATTACK_SIDE)
  1236. setHelp({defPet}, CombatDefine.DEFEND_SIDE)
  1237. combatInfo.maxRound = getMaxRound(human, combatType)
  1238. CombatImpl.setMaxRound(combatInfo.maxRound)
  1239. CombatImpl.setFightMode(combatInfo.fightMode)
  1240. JibanLogic.setBeSkill(attacker,combatInfo.jiban[CombatDefine.ATTACK_SIDE])
  1241. JibanLogic.setBeSkill(defender,combatInfo.jiban[CombatDefine.DEFEND_SIDE])
  1242. -- 战前属性/血量重算
  1243. onFightBegin(human, combatType, nil, {}, {})
  1244. human.combat = combatInfo
  1245. while CombatImpl.calcFrame() do end
  1246. copyToCombatInfo(human.combat)
  1247. sendCombatData(fakeHuman, combatInfo)
  1248. end
  1249. -- 战斗录像
  1250. local VEDIO_COMBAT_INFO = VEDIO_COMBAT_INFO or { db = {} }
  1251. function combatFightVedio(human, heroID)
  1252. local heroConfig = HeroExcel.hero[heroID]
  1253. if not heroConfig then return end
  1254. local combatConf = CombatExcel.gm[heroConfig.gm]
  1255. if not combatConf then return end
  1256. VEDIO_COMBAT_INFO.attacker = {}
  1257. VEDIO_COMBAT_INFO.defender = {}
  1258. VEDIO_COMBAT_INFO.atkFormation = combatConf.atkF
  1259. VEDIO_COMBAT_INFO.defFormation = combatConf.defF
  1260. local atkConf = nil
  1261. for i = 1, CombatDefine.COMBAT_HERO_CNT do
  1262. atkConf = nil
  1263. for k, v in ipairs(combatConf.atk) do
  1264. if i == v[2] then
  1265. atkConf = v
  1266. break
  1267. end
  1268. end
  1269. if atkConf then
  1270. VEDIO_COMBAT_INFO.attacker[i] = createHeroObj(VEDIO_COMBAT_INFO, atkConf[1], atkConf[3], atkConf[4], i,atkConf[5])
  1271. end
  1272. atkConf = nil
  1273. for k, v in ipairs(combatConf.def) do
  1274. if i == v[2] then
  1275. atkConf = v
  1276. break
  1277. end
  1278. end
  1279. if atkConf then
  1280. VEDIO_COMBAT_INFO.defender[i] = createHeroObj(VEDIO_COMBAT_INFO, atkConf[1], atkConf[3], atkConf[4], i,atkConf[5])
  1281. end
  1282. end
  1283. combatVedio(VEDIO_COMBAT_INFO, VEDIO_COMBAT_INFO.atkFormation, VEDIO_COMBAT_INFO.attacker,
  1284. VEDIO_COMBAT_INFO.defFormation, VEDIO_COMBAT_INFO.defender, nil, nil, human)
  1285. end
  1286. function repeatCombat(human, combatInfo)
  1287. if not combatInfo then
  1288. return
  1289. end
  1290. if isCombating(human) then
  1291. return Broadcast.sendErr(human, Lang.COMBAT_VIDEO_LOOK_ERR_ING)
  1292. end
  1293. combatInfo.isVideo = true
  1294. human.combat = combatInfo
  1295. sendCombatData(human, combatInfo)
  1296. sendCombatFinish(human, combatInfo)
  1297. end
  1298. -- 初始属性数据写日志
  1299. function makeAttrLogStr(human)
  1300. if not Config.IS_DEBUG then
  1301. return
  1302. end
  1303. local logStr = "\n初始属性数据:\n"
  1304. for i = 1, CombatDefine.COMBAT_HERO_ALL_CNT do
  1305. data = CombatImpl.objList[i]
  1306. if data then
  1307. logStr = logStr .. "\n\t" .. "{pos:"..data.pos.." heroID:"..data.id.."}\n\t"
  1308. for k,v in pairs(data.attr) do
  1309. if v ~= 0 then
  1310. logStr = logStr .."{key:"..k..",value:"..v.."},"
  1311. end
  1312. end
  1313. end
  1314. end
  1315. logStr = logStr .."\n"
  1316. local f = io.open("./log/fight_log.log", "w+")
  1317. f:write(logStr)
  1318. assert(io.close(f))
  1319. end
  1320. function makeLogStr(human)
  1321. if not Config.IS_DEBUG then
  1322. return
  1323. end
  1324. local logStr = "\n战斗开始数据:\n"
  1325. for i = 1, CombatDefine.COMBAT_HERO_ALL_CNT do
  1326. data = CombatImpl.objList[i]
  1327. if data then
  1328. logStr = logStr .. "\t" .. "{pos:"..data.pos.." heroID:"..data.id.."}"
  1329. end
  1330. end
  1331. logStr = logStr .. "\n"
  1332. logStr = logStr .. "战斗帧数据:\n"
  1333. local result = CombatImpl.result
  1334. local frameCnt = result.frames and #result.frames or 0
  1335. for i = 1,frameCnt do
  1336. local data = result.frames[i]
  1337. logStr = logStr .. "\t" .. i .."帧\n"
  1338. for j = 1,#data.skillList do
  1339. local skillData = data.skillList[j]
  1340. logStr = logStr .. "\t\t技能释放 attackPos:"..skillData.attackPos.." skillID:"..skillData.skillID.."\n"
  1341. local hitLen = 0
  1342. for k = 1,CombatDefine.COMBAT_HERO_ALL_CNT do
  1343. if skillData.hitList[k] then
  1344. hitLen = hitLen + 1
  1345. local skillHitData = skillData.hitList[k]
  1346. logStr = logStr .. "\t\t\t技能对象"..hitLen.." pos:"..k.." hpNow:"..skillHitData.hpNow.." attrs:"
  1347. local frameAttrs = skillHitData.attrs
  1348. local attrsLen = 0
  1349. if frameAttrs then
  1350. for m = 1,#frameAttrs do
  1351. logStr = logStr .. " {key:"..frameAttrs[m][1].." value:"..frameAttrs[m][2].."}"
  1352. end
  1353. end
  1354. logStr = logStr .. "\n"
  1355. end
  1356. end
  1357. local extraLen = 0
  1358. for k = 1,CombatDefine.COMBAT_HERO_ALL_CNT do
  1359. if skillData.extraList[k] then
  1360. extraLen = extraLen + 1
  1361. local extraHitData = skillData.extraList[k]
  1362. logStr = logStr .. "\t\t\t额外作用对象"..extraLen.." pos:"..k.." cmd:"..extraHitData.cmd.." hpNow:"..extraHitData.hpNow.." attrs:"
  1363. local frameAttrs = extraHitData.attrs
  1364. if frameAttrs then
  1365. for m = 1,#frameAttrs do
  1366. logStr = logStr .. " {key:"..frameAttrs[m][1].." value:"..frameAttrs[m][2].."}"
  1367. end
  1368. end
  1369. logStr = logStr .. "\n"
  1370. end
  1371. end
  1372. end
  1373. local bufferLen = 0
  1374. for j = 1,CombatDefine.COMBAT_HERO_ALL_CNT do
  1375. if data.bufferList[j] then
  1376. bufferLen = bufferLen + 1
  1377. logStr = logStr .. "\t\tbuffer更新 pos:"..j.."\n"
  1378. local bufferDataList = data.bufferList[j]
  1379. for i = 1,#bufferDataList do
  1380. local bufferData = bufferDataList[i]
  1381. logStr = logStr .. "\t\t\t bufferID:"..bufferData.id.." op:"..bufferData.op.." cnt:"..bufferData.cnt.." round:"..(bufferData.round or -1).." hpNow:"..bufferData.hpNow.." attrs:"
  1382. local attrsLen = 0
  1383. if bufferData.attrs then
  1384. for k,v in ipairs(bufferData.attrs) do
  1385. logStr = logStr .. " {key:"..v[1].." value:"..v[2].."}"
  1386. end
  1387. end
  1388. end
  1389. logStr = logStr .. "\n"
  1390. end
  1391. end
  1392. end
  1393. local f = io.open("./log/fight_log.log", "a+")
  1394. f:write(logStr)
  1395. assert(io.close(f))
  1396. end
  1397. -- 获取角色上阵的形象
  1398. function getRoleBody(human, combatType)
  1399. local teamType = CombatPosLogic.getTeamType(combatType)
  1400. local combatHero = teamType and human.db.combatHero[teamType]
  1401. if not combatHero then return end
  1402. local zhandouli = 0
  1403. local maxGrid = nil
  1404. for i = 1, CombatDefine.COMBAT_HERO_CNT do
  1405. local uuid = combatHero.list[i]
  1406. local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
  1407. if heroGrid and type(heroGrid) == "table" and
  1408. zhandouli < heroGrid.zhandouli then
  1409. zhandouli = heroGrid.zhandouli
  1410. maxGrid = heroGrid
  1411. end
  1412. end
  1413. if not maxGrid then return end
  1414. return HeroGrid.getHeroBodyById(maxGrid.id)
  1415. end
  1416. -- 根据怪物组id获取外显
  1417. function getMonsterIDByOutID(monsterOutID, args)
  1418. local mocf = MonsterExcel.monsterOut[monsterOutID]
  1419. if not mocf then return end
  1420. local memberCnt = #mocf.member
  1421. local index = (monsterOutID % 1000) % memberCnt
  1422. if index == 0 then index = memberCnt - 1 end
  1423. local minfo = mocf.member[index]
  1424. if not minfo then
  1425. for _, minfo0 in ipairs(mocf.member) do
  1426. if minfo0[1] > 0 then
  1427. minfo = minfo0
  1428. break
  1429. end
  1430. end
  1431. end
  1432. if not minfo then return end
  1433. local monsterID = minfo[1]
  1434. local monsterLv = minfo[2]
  1435. local mcf = monsterID and MonsterExcel.monster[monsterID]
  1436. if not mcf then return end
  1437. if mocf.combatType == CombatDefine.COMBAT_TYPE5 then
  1438. if args then
  1439. local throneID = args[1]
  1440. local evolveCnt = args[2]
  1441. monsterLv = TheStarsLogic.getMonsterLvAttr(1, throneID, evolveCnt)
  1442. end
  1443. end
  1444. return monsterID, mcf, monsterLv
  1445. end
  1446. -- 根据伤害计算胜负
  1447. function calcWinByHurt(combatInfo)
  1448. if not combatInfo.isWin then return end
  1449. if not combatInfo.objList then return end
  1450. local atkHurt = 0
  1451. local defHurt = 0
  1452. local atkLive = 0
  1453. local defLive = 0
  1454. for i = 1,CombatDefine.COMBAT_HERO_CNT do
  1455. local atkPos = getPos(CombatDefine.ATTACK_SIDE, i)
  1456. local atkObj = combatInfo.objList[atkPos]
  1457. if atkObj then
  1458. atkHurt = atkHurt + atkObj.result[1]
  1459. if atkObj.hp > 0 and not atkLive then
  1460. atkLive = 1
  1461. end
  1462. end
  1463. local defPos = getPos(CombatDefine.DEFEND_SIDE, i)
  1464. local defObj = combatInfo.objList[defPos]
  1465. if defObj then
  1466. defHurt = defHurt + defObj.result[1]
  1467. if atkObj.hp > 0 and not defLive then
  1468. defLive = 1
  1469. end
  1470. end
  1471. end
  1472. if atkLive == 0 then
  1473. atkHurt = 0
  1474. elseif defLive == 0 then
  1475. defLive = 0
  1476. end
  1477. combatInfo.isWin = atkHurt > defHurt and true or false
  1478. return combatInfo.isWin
  1479. end
  1480. ------------- reyes test ---------------------
  1481. function isCombating(human)
  1482. local list = COMBAT_CACHE[human.db._id]
  1483. if not list then return end
  1484. for combatType, combatCache in pairs(list) do
  1485. if not combatCache.combatInfo.isVideo then
  1486. return true
  1487. end
  1488. end
  1489. end
  1490. function getCombatCache(uuid, type)
  1491. return COMBAT_CACHE[uuid] and COMBAT_CACHE[uuid][type]
  1492. end
  1493. function addCombatCache(uuid, combatInfo, cbParam,param)
  1494. COMBAT_CACHE[uuid] = COMBAT_CACHE[uuid] or {} -- reyes test
  1495. local tempCache = {}
  1496. local result = combatInfo.isWin and CombatDefine.RESULT_WIN or CombatDefine.RESULT_FAIL
  1497. tempCache.result = result
  1498. tempCache.combatType = combatInfo.type
  1499. tempCache.cbParam = cbParam
  1500. tempCache.combatInfo = combatInfo
  1501. tempCache.param = param
  1502. tempCache.ts = os.time() + getCombatUseTime(combatInfo)
  1503. COMBAT_CACHE[uuid][combatInfo.type] = tempCache
  1504. end
  1505. function cleanCombatCache(uuid, type)
  1506. if not COMBAT_CACHE[uuid] then return end
  1507. COMBAT_CACHE[uuid][type] = nil
  1508. if Util.getTableCount(COMBAT_CACHE[uuid]) == 0 then
  1509. COMBAT_CACHE[uuid] = nil
  1510. end
  1511. end
  1512. function clientFinish(human, type, noSend)
  1513. if COMBAT_CACHE[human.db._id] == nil or COMBAT_CACHE[human.db._id][type] == nil then
  1514. return
  1515. end
  1516. local combatCache = COMBAT_CACHE[human.db._id][type]
  1517. cleanCombatCache(human.db._id, type)
  1518. --print("onend-=----------------------")
  1519. if not combatCache.combatInfo.isVideo then
  1520. onFightEnd(human, combatCache.result, combatCache.combatType, combatCache.cbParam, combatCache.combatInfo,combatCache.param)
  1521. end
  1522. -- 绝望深渊 非失败 不发
  1523. -- 冰龙 次元魔珠 失落神庙 不走默认结算协议
  1524. if type ~= CombatDefine.COMBAT_TYPE8 and
  1525. type ~= CombatDefine.COMABT_TYPE23 and
  1526. type ~= CombatDefine.COMBAT_TYPE20 and
  1527. type ~= CombatDefine.COMBAT_TYPE24
  1528. and not noSend then
  1529. sendCombatFinish(human, combatCache.combatInfo)
  1530. end
  1531. end
  1532. function clientPassTime(human, type, passTime)
  1533. if COMBAT_CACHE[human.db._id] == nil or COMBAT_CACHE[human.db._id][type] == nil then
  1534. return
  1535. end
  1536. local combatInfo = COMBAT_CACHE[human.db._id][type].combatInfo
  1537. combatInfo.passTime = passTime
  1538. end
  1539. function onLogin(human)
  1540. checkFinish(human)
  1541. -- 这里要先check才判断cache 因为check完cache可能就空了
  1542. if COMBAT_CACHE[human.db._id] == nil then
  1543. return
  1544. end
  1545. for k, v in pairs(COMBAT_CACHE[human.db._id]) do
  1546. --assert(nil, "has combat cache "..combatType .. " " .. human.db.account) -- reyes test
  1547. human.combat = v.combatInfo
  1548. sendCombatData(human, human.combat, true)
  1549. end
  1550. end
  1551. function checkFinish(human)
  1552. if COMBAT_CACHE[human.db._id] == nil then
  1553. return
  1554. end
  1555. local now = os.time()
  1556. for k, v in pairs(COMBAT_CACHE[human.db._id]) do
  1557. if now >= v.ts then
  1558. clientFinish(human, k)
  1559. if COMBAT_CACHE[human.db._id] == nil then
  1560. return
  1561. end
  1562. end
  1563. end
  1564. end
  1565. -- 不管时间立刻结算 目前只有踢人等非正常下线会用到
  1566. function forceFinish(human)
  1567. if COMBAT_CACHE[human.db._id] == nil then
  1568. return
  1569. end
  1570. local now = os.time()
  1571. for k, v in pairs(COMBAT_CACHE[human.db._id]) do
  1572. clientFinish(human, k)
  1573. if COMBAT_CACHE[human.db._id] == nil then
  1574. return
  1575. end
  1576. end
  1577. end
  1578. function killFrames(combatInfo)
  1579. --60帧2倍速情况下大概1分半。限制录像时长再3-5分钟。节省包量
  1580. if combatInfo.result.frames and #combatInfo.result.frames > 200 then
  1581. for i = 201,#combatInfo.result.frames do
  1582. combatInfo.result.frames[i] = nil
  1583. end
  1584. end
  1585. end