CombatLogic.lua 59 KB

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