CombatLogic.lua 59 KB

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