DrillLogic.lua 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003
  1. ---------------------------------------------------
  2. -- 过关斩将/圣树试炼
  3. ---------------------------------------------------
  4. --[[
  5. db.drill = {
  6. time = 1, -- 这次数据的时间
  7. diff = 1, -- 选择的难度
  8. drillId = 1, -- 今日最大 通关关卡
  9. maxDiff = 1, -- 最大通关难度
  10. lastDiff = 1, -- 昨日选择的难度
  11. lastDrillId = 1, -- 昨日最大关卡
  12. myHelpIndex = 1, -- 我选择的援助出去英雄
  13. helpoutList = {}, -- 我选择的援助英雄
  14. dayGet = {}, -- 今日已获得奖励
  15. boxGet = {}, -- 今日宝箱 已领取
  16. }
  17. ]]--
  18. local Config = require("Config")
  19. local DrillExcel = require("excel.drill")
  20. local MailExcel = require("excel.mail")
  21. local MonsterExcel = require("excel.monster")
  22. local Util = require("common.Util")
  23. local Lang = require("common.Lang")
  24. local CommonDB = require("common.CommonDB")
  25. local Msg = require("core.Msg")
  26. local InnerMsg = require("core.InnerMsg")
  27. local ObjHuman = require("core.ObjHuman")
  28. local Timer = require("core.Timer")
  29. local Broadcast = require("broadcast.Broadcast")
  30. local Grid = require("bag.Grid")
  31. local BagLogic = require("bag.BagLogic")
  32. local CombatImpl = require("combat.CombatImpl")
  33. local CombatObj = require("combat.CombatObj")
  34. local CombatLogic = require("combat.CombatLogic")
  35. local CombatDefine = require("combat.CombatDefine")
  36. local CombatPosLogic = require("combat.CombatPosLogic")
  37. local CopyManage = require("copy.CopyManage")
  38. local ChatPaoMaLogic = require("chat.ChatPaoMaLogic")
  39. local DrillDB = require("drill.DrillDB")
  40. local DrillMiddleLogic = require("drill.DrillMiddleLogic")
  41. local DrillLogicAttribute = require("drill.DrillLogicAttribute")
  42. local HeroGrid = require("hero.HeroGrid")
  43. local HeroDefine = require("hero.HeroDefine")
  44. local RoleDefine = require("role.RoleDefine")
  45. local RoleLogic = require("role.RoleLogic")
  46. local RoleDBLogic = require("role.RoleDBLogic")
  47. local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
  48. local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
  49. local MailManager = require("mail.MailManager")
  50. local MiddleConnect = require("middle.MiddleConnect")
  51. local HeroExcel = require("excel.hero")
  52. local FriendDBLogic = require("friend.FriendDBLogic")
  53. local ChengjiuLogic = require("chengjiu.ChengjiuLogic")
  54. local ChengjiuDefine = require("chengjiu.ChengjiuDefine")
  55. local LiLianLogic = require("dailyTask.LiLianLogic")
  56. local BeSkill = require("combat.BeSkill")
  57. local SkinLogic = require("skin.SkinLogic")
  58. local DailyTaskLogic = require("dailyTask.DailyTaskLogic")
  59. local ItemDefine = require("bag.ItemDefine")
  60. local VipLogic = require("vip.VipLogic")
  61. local HeroLogic = require("hero.HeroLogic")
  62. local MailDefine = require("mail.MailIdDefine")
  63. local JibanLogic = require("combat.JibanLogic")
  64. local HeroLogLogic = require("absAct.HeroLogLogic")
  65. local HeroGrowUp = require("absAct.HeroGrowUp")
  66. local MengxinLogic = require("present.MengxinLogic")
  67. local YunYingLogic = require("yunying.YunYingLogic")
  68. local TalismanLogic = require("talisman.TalismanLogic")
  69. local WeekTaskLogic = require("dailyTask.WeekTaskLogic")
  70. local TriggerLogic = require("trigger.TriggerLogic")
  71. local TriggerDefine = require("trigger.TriggerDefine")
  72. local OverflowFundLogic = require("present.OverflowFundLogic")
  73. local Log = require("common.Log")
  74. local queryFields = {["uuid"] = 1}
  75. local queryFieldsList = {}
  76. local queryUuidFields = {["uuid"] = 1}
  77. local queryRawardFields = {["drillId"] = 1, ["rawardStatus"] = 1}
  78. local sortTable = {}
  79. SEASON_KEEP_DAY = 1 -- 1天一个流程
  80. STATE_NOOPEN = 0 -- 未开始
  81. STATE_OPEN = 1 -- 开始
  82. STATE_READY = 2 -- 准备期间
  83. -- 难度说明
  84. DIFF_NORMAL = 1 -- 普通难度
  85. DIFF_ELITE = 2 -- 精英难度
  86. DIFF_INCUBI = 3 -- 噩梦难度
  87. DRILL_BOX_STATE_0 = 0 -- 未领取
  88. DRILL_BOX_STATE_1 = 1 -- 可领取
  89. DRILL_BOX_STATE_2 = 2 -- 已领取
  90. DRILL_BOX_GOD_MAX = 3 -- 诸神怜悯 最大获奖次数
  91. local FRIEND_ITEM_CNT = 10 -- 每次助战获得x点友情点
  92. local MAX_HEROCOMBAT_MUL = 150 -- 助战英雄最大倍数百分比
  93. local INIT_HP_MAX = 100
  94. local SAODANG_COND_LEVEL = 90 --勇者试炼副本扫荡所需等级
  95. local CHALLENGE_DIAMONS = 500 -- 使用钻石通过当前关卡需要的钻石数量
  96. --秘宝加成
  97. local function getTalismanAdd(human)
  98. local heroExpMul = (TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.DRILL_HERO_EXP) or 0) / 100
  99. return heroExpMul
  100. end
  101. -- 获取剩余时间
  102. function getState()
  103. -- if MiddleConnect.IS_MIDDLE_CONNECT ~= true then
  104. -- return STATE_NOOPEN, Lang.MIDDLE_SVR_ERR_CONNECT
  105. -- end
  106. return STATE_OPEN
  107. end
  108. -- 判断
  109. function isOpen(human, sendTip)
  110. --[[
  111. local isok, tip = CopyManage.isOpen(CopyInfo, human)
  112. if not isok then
  113. if sendTip and tip then
  114. Broadcast.sendErr(human, tip)
  115. end
  116. return
  117. end
  118. local state, _, tip = getState()
  119. if state ~= STATE_OPEN then
  120. if sendTip and tip then
  121. Broadcast.sendErr(human, tip)
  122. end
  123. return
  124. end
  125. ]]
  126. return true
  127. end
  128. -- 活动开始倒计时
  129. function getStartLeftTime(human)
  130. local state, leftSec = getState()
  131. if state ~= STATE_NOOPEN then
  132. return leftSec
  133. end
  134. return 0
  135. end
  136. function getCopyState(human)
  137. local state = getState()
  138. return state
  139. end
  140. -- 最大通关难度
  141. function getMaxDiff(human)
  142. if not human.db.drill then
  143. return 0
  144. end
  145. return human.db.drill.maxDiff or 0
  146. end
  147. function setMaxDiff(human, diff)
  148. if not human.db.drill then return end
  149. human.db.drill = human.db.drill or {}
  150. human.db.drill.maxDiff = diff
  151. end
  152. -- 获取关卡奖励配置
  153. function getDrillItems(drillId, diff)
  154. local config = DrillExcel.drill[drillId]
  155. if not config then return end
  156. if diff == DIFF_NORMAL then
  157. return config.items
  158. end
  159. return config["items" .. diff]
  160. end
  161. -- 数据重置
  162. -- 重置关卡数据
  163. -- 重置关卡阵容
  164. -- 每天0点检测是否开启了试炼 进行清除
  165. function onHour()
  166. DrillDB.checkDrillReset()
  167. end
  168. function dayCheck()
  169. if _G.is_middle then return end
  170. DrillDB.reset()
  171. end
  172. -- 查询时间
  173. function querySec(human)
  174. if not isOpen(human, true) then return end
  175. local state, leftSec = getState()
  176. local msgRet = Msg.gc.GC_DRILL_SEC
  177. msgRet.leftSec = leftSec
  178. msgRet.isStart = (state == STATE_OPEN) and 1 or 0
  179. Msg.send(msgRet, human.fd)
  180. queryDrillId(human)
  181. end
  182. function inintDrill(human)
  183. if not human.db.drill then
  184. human.db.drill = {}
  185. local drill = human.db.drill
  186. drill.time = 0
  187. drill.diff = 0
  188. drill.drillId = nil
  189. drill.maxDiff = 0
  190. drill.lastDiff = 0
  191. drill.lastDrillId = 0
  192. drill.myHelpIndex = 0
  193. drill.dayGet = nil
  194. drill.boxGet = nil
  195. drill.myHelpHero = nil
  196. drill.helpoutList = nil
  197. end
  198. end
  199. function updateDaily(human)
  200. -- CombatPosLogic.cleanCombatHeros(human, CombatDefine.COMBAT_TYPE9)
  201. local drillDB = human.db.drill
  202. if not drillDB then return end
  203. if Util.isSameDay(drillDB.time) then
  204. return
  205. end
  206. local surDay = Util.diffDay(drillDB.time)
  207. if surDay == 1 then
  208. drillDB.lastDrillId = drillDB.drillId
  209. drillDB.lastDiff = drillDB.diff
  210. else
  211. drillDB.lastDrillId = 0
  212. drillDB.lastDiff = 0
  213. end
  214. drillDB.time = os.time()
  215. drillDB.drillId = nil
  216. drillDB.diff = 0
  217. drillDB.dayGet = nil
  218. drillDB.boxGet = nil
  219. drillDB.myHelpIndex = 0
  220. drillDB.myHelpHero = nil
  221. drillDB.helpoutList = nil
  222. drillDB.oneClickSaodangDone = nil -- 清除扫荡完成标记
  223. end
  224. -- 修正 玩家DB 玩家卡0点 选择难度挑战 DrilDB 后清 导致 玩家DB 和 DrillDB 对不上 后续修改为 以DrillDB 为准
  225. function fixDrillDB(human)
  226. if human.db.drill then
  227. human.db.drill.diff = 0
  228. end
  229. end
  230. -- 难度选择查询
  231. function diffChoseQuery(human)
  232. if not human.db.drill then
  233. inintDrill(human)
  234. end
  235. local drill = human.db.drill
  236. if not drill.diff or drill.diff == 0 then
  237. local msgRet = Msg.gc.GC_DRILL_DIFF
  238. msgRet.isGuide = drill.isGuide or 1
  239. drill.isGuide = 0
  240. for i = DIFF_NORMAL , DIFF_INCUBI do
  241. local config = DrillExcel.define[i]
  242. local net = msgRet.list[i]
  243. net.diff = i
  244. net.canChose = i == DIFF_NORMAL and 1 or 0
  245. net.reward[0] = 0
  246. net.needZhanli = config.needZhanli
  247. if drill.maxDiff >= i - 1 and human.db.zhandouli >= config.needZhanli then
  248. net.canChose = 1
  249. end
  250. end
  251. msgRet.list[0] = DIFF_INCUBI
  252. Msg.send(msgRet, human.fd)
  253. end
  254. end
  255. function checkSaoDang(human, diff, lastDiff, lastId)
  256. local diff = diff
  257. local id = 1
  258. local drillDB = human.db.drill
  259. if not drillDB then return diff, id end
  260. lastId = lastId and lastId or 0
  261. lastId = lastId <= #DrillExcel.drill and lastId or #DrillExcel.drill
  262. local double = RoleSystemLogic.isDouble(human, RoleSystemDefine.ROLE_SYS_ID_1204)
  263. local rewardCnt = double and 2 or 1
  264. --秘宝加成
  265. local heroExpMul = getTalismanAdd(human)
  266. if lastDiff and lastDiff == diff and lastId > 10 then
  267. id = lastId - 10
  268. local itemInfo = {}
  269. for i = 1 , id do
  270. local drillItems = getDrillItems( i, lastDiff)
  271. -- 关卡奖励
  272. for _, item in ipairs(drillItems) do
  273. local itemID = item[1]
  274. local itemCnt = item[2] * rewardCnt
  275. if itemID == ItemDefine.ITEM_GREEN_EXP_ID then
  276. itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul)
  277. end
  278. drillDB.dayGet = drillDB.dayGet or {}
  279. drillDB.dayGet[itemID] = (drillDB.dayGet[itemID] or 0) + itemCnt
  280. BagLogic.addItem(human, itemID, itemCnt, "drill")
  281. end
  282. end
  283. -- BagLogic.sendItemGetList(human, itemList, "drill")
  284. local msgRet = Msg.gc.GC_DRILL_SAODANG_ITEM
  285. msgRet.drillId = id
  286. local len = 0
  287. for k , v in pairs(drillDB.dayGet) do
  288. len = len + 1
  289. Grid.makeItem(msgRet.itemList[len], k, v)
  290. -- Grid.makeItem(msgRet.itemList[len], k, v, nil, nil, nil, nil, nil, nil, itemInfo[k])
  291. end
  292. msgRet.itemList[0] = len
  293. msgRet.double = double and 1 or 0
  294. Msg.send(msgRet, human.fd)
  295. id = id + 1
  296. end
  297. return diff, id
  298. end
  299. function saodangQuest(human, drillId)
  300. if drillId <= 1 then return end
  301. local drill = human.db.drill
  302. if not drill then return end
  303. local diff = drill.diff
  304. local dirllDefConfig = DrillExcel.define[drill.diff]
  305. if not dirllDefConfig then return end
  306. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  307. if not drillData then
  308. fristQust(human, drillId)
  309. return
  310. end
  311. local zhandouli = CombatPosLogic.getCombatHeroZDL(human, CombatDefine.COMBAT_TYPE1)
  312. if zhandouli <= 0 then return Broadcast.sendErr(human, Lang.COMBAT_ERR_NO_SET_FIGHT) end
  313. if human.maxZDL and human.maxZDL.zhandouli and human.maxZDL.zhandouli > zhandouli then
  314. -- 获取玩家真正的最高战力 防止玩家 战役上阵 战力低 去匹配 低战力对手
  315. zhandouli = human.maxZDL.zhandouli
  316. end
  317. local notTab = {}
  318. for i = 1 , drillId do
  319. local drillObj = pipei(human, i, diff, zhandouli, notTab)
  320. drillData.drillObjs[i] = Util.copyTable(drillObj)
  321. end
  322. DrillDB.updateDrillData(drillData)
  323. end
  324. -- 选择难度
  325. function choseDiff(human, diff)
  326. if not human.db.drill then
  327. inintDrill(human)
  328. end
  329. local drill = human.db.drill
  330. local now = os.time()
  331. if not drill.diff or drill.diff == 0 then
  332. drill.dayGet = {}
  333. drill.boxGet = {}
  334. drill.myHelpIndex = 0
  335. drill.myHelpHero = nil
  336. drill.helpoutList = nil
  337. drill.time = now
  338. drill.diff, drill.drillId = checkSaoDang(human, diff, drill.lastDiff, drill.lastDrillId)
  339. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  340. -- 临时处理
  341. if not drillData then
  342. quest(human, drill.drillId)
  343. else
  344. quest(human, drillData.drillId + 1)
  345. end
  346. saodangQuest(human, drill.drillId )
  347. queryDrillId(human)
  348. end
  349. end
  350. -- 获取宝箱状态
  351. function getBoxState(drill, index)
  352. local state = DRILL_BOX_STATE_0
  353. if not drill.drillId or drill.drillId <= 0 then
  354. return state
  355. end
  356. local config = DrillExcel.box[index]
  357. if drill.drillId > config.needDrill then
  358. state = DRILL_BOX_STATE_1
  359. end
  360. if drill.boxGet and drill.boxGet[index] and drill.boxGet[index].state then
  361. state = DRILL_BOX_STATE_2
  362. end
  363. return state
  364. end
  365. -- 查询关卡Id
  366. function queryDrillId(human, drillData, openPanel)
  367. -- openPanel: 是否打开界面,默认为true(打开界面)
  368. -- false-不打开界面,只刷新数据;true-打开界面
  369. if openPanel == nil then
  370. openPanel = true -- 默认打开界面
  371. end
  372. drillData = drillData or DrillDB.getDrillDataByUuid(human.db._id)
  373. if not drillData then -- 没有记录 请求第一关
  374. fixDrillDB(human)
  375. return diffChoseQuery(human) -- quest(human)
  376. end
  377. local drill = human.db.drill
  378. if not drill then
  379. -- drill 数据不存在,初始化
  380. fixDrillDB(human)
  381. drill = human.db.drill
  382. if not drill then
  383. return diffChoseQuery(human)
  384. end
  385. end
  386. local diff = drill.diff
  387. if not drill.diff or drill.diff == 0 then
  388. diff = drillData.diff
  389. end
  390. if diff == 0 then
  391. return diffChoseQuery(human)
  392. end
  393. local msgRet = Msg.gc.GC_DRILL_ID
  394. -- 按照协议定义的顺序赋值
  395. -- 1. drillId (byte类型,范围0-255,防止溢出)
  396. local drillIdValue = drillData.drillId or 1
  397. if drillIdValue > 255 or drillIdValue < 0 then
  398. --Log.write(Log.LOGID_DEBUG, "[queryDrillId] WARNING: drillId溢出,原始值="..drillIdValue..",限制后="..math.min(math.max(drillIdValue, 0), 255))
  399. end
  400. msgRet.drillId = math.min(math.max(drillIdValue, 0), 255)
  401. -- 2. diff (byte类型,范围0-255,防止溢出)
  402. local diffValue = diff or 1
  403. if diffValue > 255 or diffValue < 0 then
  404. --Log.write(Log.LOGID_DEBUG, "[queryDrillId] WARNING: diff溢出,原始值="..diffValue..",限制后="..math.min(math.max(diffValue, 0), 255))
  405. end
  406. msgRet.diff = math.min(math.max(diffValue, 0), 255)
  407. -- 3. box (数组) - 协议定义最大长度为5
  408. local boxCount = math.min(#DrillExcel.box, 5)
  409. msgRet.box[0] = boxCount
  410. --秘宝加成
  411. local heroExpMul = getTalismanAdd(human)
  412. for k = 1, boxCount do
  413. local config = DrillExcel.box[k]
  414. local net = msgRet.box[k]
  415. -- index 和 needId 都是 byte 类型,防止溢出
  416. if k > 255 or k < 0 then
  417. --Log.write(Log.LOGID_DEBUG, "[queryDrillId] WARNING: box index溢出,原始值="..k..",限制后="..math.min(math.max(k, 0), 255))
  418. end
  419. net.index = math.min(math.max(k, 0), 255)
  420. local needIdValue = config.needDrill or 0
  421. if needIdValue > 255 or needIdValue < 0 then
  422. --Log.write(Log.LOGID_DEBUG, "[queryDrillId] WARNING: box needId溢出,原始值="..needIdValue..",限制后="..math.min(math.max(needIdValue, 0), 255))
  423. end
  424. net.needId = math.min(math.max(needIdValue, 0), 255)
  425. net.state = getBoxState(drill, k)
  426. local itemID1 = config["items"..diff][1][1]
  427. local itemCnt1 = config["items"..diff][1][2]
  428. if itemID1 == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then
  429. itemCnt1 = itemCnt1 + math.ceil(itemCnt1 * heroExpMul)
  430. end
  431. local itemID2 = config["items"..diff][2][1]
  432. local itemCnt2 = config["items"..diff][2][2]
  433. if itemID2 == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then
  434. itemCnt2 = itemCnt1 + math.ceil(itemCnt2 * heroExpMul)
  435. end
  436. Grid.makeItem(net.reward[1], itemID1, itemCnt1 )
  437. Grid.makeItem(net.reward[2], itemID2, itemCnt2 )
  438. net.reward[0] = 2
  439. if config["items"..diff][3] then
  440. local itemID3 = config["items"..diff][3][1]
  441. local itemCnt3 = config["items"..diff][3][2]
  442. if itemID3 == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then
  443. itemCnt3 = itemCnt1 + math.ceil(itemCnt3 * heroExpMul)
  444. end
  445. Grid.makeItem(net.reward[3], itemID3, itemCnt3 )
  446. net.reward[0] = 3
  447. end
  448. end
  449. -- 4. dayGet (数组)
  450. msgRet.dayGet[0] = 2
  451. local dayJinbi = drill.dayGet and drill.dayGet[ItemDefine.ITEM_JINBI_ID] or 0
  452. local dayCoin = drill.dayGet and drill.dayGet[ItemDefine.ITEM_DRILL_COIN_ID] or 0
  453. Grid.makeItem(msgRet.dayGet[1], ItemDefine.ITEM_JINBI_ID, dayJinbi )
  454. Grid.makeItem(msgRet.dayGet[2], ItemDefine.ITEM_DRILL_COIN_ID, dayCoin )
  455. -- 5. maxDiff (byte类型,范围0-255,防止溢出)
  456. -- 注意:如果 maxDiff 为 0,应该视为未设置,使用默认值 1(因为 0 在 Lua 中是 truthy)
  457. local maxDiffValue = (drill.maxDiff == nil or drill.maxDiff == 0) and 1 or drill.maxDiff
  458. if maxDiffValue > 255 or maxDiffValue < 0 then
  459. --Log.write(Log.LOGID_DEBUG, "[queryDrillId] WARNING: maxDiff溢出,原始值="..maxDiffValue..",限制后="..math.min(math.max(maxDiffValue, 0), 255))
  460. end
  461. msgRet.maxDiff = math.min(math.max(maxDiffValue, 0), 255)
  462. -- 6. canOneClickSaodang
  463. -- 计算是否开启一键扫荡
  464. local canOneClickSaodang = 0
  465. -- 检查是否购买了基金
  466. local overflowState = human.db.overflow and human.db.overflow.state and human.db.overflow.state[OverflowFundLogic.OVERFLOW_TYPE_2]
  467. local hasFund = overflowState ~= nil
  468. --Log.write(Log.LOGID_DEBUG, "[queryDrillId] 检查基金状态: overflow="..tostring(human.db.overflow ~= nil)..", state="..tostring(human.db.overflow and human.db.overflow.state ~= nil)..", overflowState[2]="..tostring(overflowState)..", hasFund="..tostring(hasFund))
  469. if hasFund then
  470. -- 检查试炼是否开启
  471. local drillOpen = isOpen(human, false)
  472. if drillOpen then
  473. -- 检查是否有 drill 数据
  474. if drill then
  475. -- 检查是否有 drillData 数据
  476. if drillData then
  477. -- 检查 diff 不为 0
  478. if diff ~= 0 then
  479. -- 已购买基金且满足其他条件,开启一键扫荡(已去掉等级限制和关卡ID限制)
  480. -- 注意:即使 drillId=1,也显示按钮,实际扫荡时会检查是否有可扫荡的关卡
  481. canOneClickSaodang = 1
  482. else
  483. --Log.write(Log.LOGID_DEBUG, "[queryDrillId] canOneClickSaodang=0: diff="..diff.." == 0")
  484. end
  485. else
  486. --Log.write(Log.LOGID_DEBUG, "[queryDrillId] canOneClickSaodang=0: drillData为nil")
  487. end
  488. else
  489. --Log.write(Log.LOGID_DEBUG, "[queryDrillId] canOneClickSaodang=0: drill为nil")
  490. end
  491. else
  492. --Log.write(Log.LOGID_DEBUG, "[queryDrillId] canOneClickSaodang=0: 试炼未开启")
  493. end
  494. else
  495. --Log.write(Log.LOGID_DEBUG, "[queryDrillId] canOneClickSaodang=0: 未购买奢华基金(OVERFLOW_TYPE_2)")
  496. end
  497. msgRet.canOneClickSaodang = canOneClickSaodang
  498. -- 7. openPanel
  499. msgRet.openPanel = (openPanel == true) and 1 or 0
  500. -- Msg.trace(msgRet)
  501. Msg.send(msgRet, human.fd)
  502. end
  503. -- 是否被击杀
  504. function isObjKill(drillObj)
  505. if drillObj == nil then return end
  506. if drillObj.objStatus == nil then
  507. return
  508. end
  509. for _, hpRate in pairs(drillObj.objStatus) do
  510. if hpRate > 0 then
  511. return
  512. end
  513. end
  514. return true
  515. end
  516. -- 查询关卡状态
  517. function query(human, drillId)
  518. --if not isOpen(human, true) then return end
  519. local drill = human.db.drill
  520. if not drill then return end
  521. local drillCfg = DrillExcel.drill[drillId]
  522. if not drillCfg then return end
  523. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  524. if not drillData then return end
  525. local drillObj = drillData.drillObjs[drillId]
  526. if not drillObj then
  527. if drillId < 15 and drillData.drillId == drillId then
  528. quest(human, drillId)
  529. end
  530. return
  531. end
  532. --秘宝加成
  533. local heroExpMul = getTalismanAdd(human)
  534. local double = RoleSystemLogic.isDouble(human, RoleSystemDefine.ROLE_SYS_ID_1204)
  535. local rewardCnt = double and 2 or 1
  536. --require("common.Util").printTable(drillObj)
  537. local nowId = drillData.drillId
  538. local msgRet = Msg.gc.GC_DRILL_INFO
  539. msgRet.drillId = drillId
  540. msgRet.svrName = drillObj.svrName or Config.DB_NAME
  541. RoleLogic.makeRoleBase(drillObj, msgRet.roleBase)
  542. msgRet.reward[0] = 0
  543. msgRet.double = double and 1 or 0
  544. local itemConfig = drillCfg.items
  545. if drill.diff == DIFF_ELITE then
  546. itemConfig = drillCfg.items2
  547. elseif drill.diff == DIFF_INCUBI then
  548. itemConfig = drillCfg.items3
  549. end
  550. for _, item in pairs(itemConfig) do
  551. msgRet.reward[0] = msgRet.reward[0] + 1
  552. local itemCnt = item[2] * rewardCnt
  553. if item[1] == ItemDefine.ITEM_GREEN_EXP_ID then
  554. itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul)
  555. end
  556. Grid.makeItem(msgRet.reward[msgRet.reward[0]], item[1], itemCnt)
  557. --Grid.makeItem(msgRet.reward[msgRet.reward[0]], item[1], item[2] * rewardCnt)
  558. end
  559. msgRet.defence[0] = 0
  560. for i = 1, CombatDefine.COMBAT_HERO_CNT do
  561. local obj = drillObj.heroList[i]
  562. if obj and i ~= CombatDefine.BACKUP_POS[1] then
  563. local hpRate = DrillLogicAttribute.getObjHpRate(drillObj, obj.bagIndex)
  564. local hp = math.ceil(INIT_HP_MAX * hpRate)
  565. local hpMax = INIT_HP_MAX
  566. hp = nowId > drillId and 0 or hp
  567. local others = HeroGrid.createOthers(obj.lv, hp, hpMax, obj.star)
  568. msgRet.defence[0] = msgRet.defence[0] + 1
  569. if drillObj.monsterOutID and drillObj.monsterOutID > 0 then
  570. HeroGrid.makeHeroSimpleByMonsterID(msgRet.defence[msgRet.defence[0]], obj.id, others)
  571. else
  572. HeroGrid.makeHeroSimpleByID(msgRet.defence[msgRet.defence[0]], obj.id, i, others)
  573. end
  574. end
  575. end
  576. local quick = CombatLogic.getQuick(human, CombatDefine.COMBAT_TYPE9)
  577. local showNext = 1
  578. -- if getMaxDiff(human) >= drill.diff and human.db.lv >= SAODANG_COND_LEVEL then
  579. -- showNext = 1
  580. -- end
  581. --取消难度限制
  582. -- if human.db.lv >= SAODANG_COND_LEVEL then
  583. -- showNext = 1
  584. -- end
  585. msgRet.quick = quick or 0
  586. msgRet.showNext = showNext
  587. --Msg.trace(msgRet)
  588. Msg.send(msgRet, human.fd)
  589. -- 推送英雄的状态信息
  590. sendHeroList(human, drillData.heroStatus)
  591. end
  592. local FIX_LIST = {}
  593. function sendHeroList(human, heroStatus)
  594. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  595. if not drillData then return end
  596. local drill = human.db.drill
  597. if not drill then return end
  598. heroStatus = heroStatus and heroStatus or drillData.heroStatus
  599. local config = DrillExcel.define[drillData.diff]
  600. local msgRet = Msg.gc.GC_DRILL_HERO
  601. msgRet.isFirst = 1
  602. msgRet.isLast = 0
  603. msgRet.heroList[0] = 0
  604. msgRet.helpList[0] = 0
  605. local limit = human.drill or {}
  606. -- 雇佣英雄
  607. if drillData.helpUuids then
  608. for targetUuid, v in pairs(drillData.helpUuids) do
  609. msgRet.helpList[0] = msgRet.helpList[0] + 1
  610. local net = msgRet.helpList[msgRet.helpList[0]]
  611. if fontHelpNet(net, targetUuid, true) then
  612. -- 其它数据
  613. local hpRate = DrillLogicAttribute.getHelpHpRate(drillData, targetUuid)
  614. net.heroSimple.hp = math.ceil(INIT_HP_MAX * hpRate)
  615. net.heroSimple.hpMax = INIT_HP_MAX
  616. if limit.combatHelpUuid and limit.combatHelpUuid == targetUuid then
  617. net.pos = human.drill.combatHelpPos
  618. end
  619. if v.win or net.heroSimple.hp <= 0 then
  620. net.state = 1
  621. net.pos = 0
  622. end
  623. end
  624. end
  625. end
  626. local heroMinLevel = config and config.heroMinLevel or 0
  627. -- 背包的英雄
  628. for index,heroGrid in pairs(human.db.heroBag) do
  629. if index ~= 0 and heroGrid.lv >= heroMinLevel then
  630. if msgRet.heroList[0] >= #msgRet.heroList then
  631. Msg.send(msgRet, human.fd)
  632. msgRet.heroList[0] = 0
  633. msgRet.helpList[0] = 0
  634. msgRet.isFirst = 0
  635. end
  636. msgRet.heroList[0] = msgRet.heroList[0] + 1
  637. local heroNet = msgRet.heroList[msgRet.heroList[0]]
  638. HeroGrid.makeHeroSimple(heroNet, heroGrid, index)
  639. -- 其它数据
  640. local hpRate = DrillLogicAttribute.getHeroHpRate(drillData, heroGrid.uuid)
  641. heroNet.hp = math.ceil(INIT_HP_MAX * hpRate)
  642. heroNet.hpMax = INIT_HP_MAX
  643. end
  644. end
  645. if msgRet.heroList[0] > 0 or msgRet.isFirst == 1 then
  646. msgRet.isLast = 1
  647. -- Msg.trace(msgRet)
  648. Msg.send(msgRet, human.fd)
  649. end
  650. end
  651. function drillBoxGet(human, index)
  652. local drill = human.db.drill
  653. if not drill or not drill.diff or drill.diff == 0 then
  654. return
  655. end
  656. local config = DrillExcel.box[index]
  657. if not config then return end
  658. local state = getBoxState(drill, index)
  659. if state ~= 1 then
  660. return
  661. end
  662. drill.boxGet = drill.boxGet or {}
  663. drill.boxGet[index] = drill.boxGet[index] or {}
  664. drill.boxGet[index].cnt = drill.boxGet[index].cnt or 0
  665. drill.boxGet[index].cnt = drill.boxGet[index].cnt + 1
  666. local msgRet = Msg.gc.GC_DRILL_BOX_GET
  667. msgRet.type = 0
  668. msgRet.index = index
  669. local random = math.random(1, 100)
  670. if random <= 10 and drill.boxGet[index].cnt < DRILL_BOX_GOD_MAX then
  671. -- 诸神的怜悯
  672. msgRet.type = drill.boxGet[index].cnt >= DRILL_BOX_GOD_MAX - 1 and 2 or 1
  673. else
  674. drill.boxGet[index].state = 1
  675. end
  676. Msg.send(msgRet, human.fd)
  677. local itemConfig = config.items1
  678. if drill.diff == DIFF_ELITE then
  679. itemConfig = config.items2
  680. elseif drill.diff == DIFF_INCUBI then
  681. itemConfig = config.items3
  682. end
  683. --秘宝加成
  684. local heroExpMul = getTalismanAdd(human)
  685. local awardVec = {}
  686. for i, v in ipairs(itemConfig) do
  687. local itemID = v[1]
  688. local itemCnt = v[2]
  689. if itemID == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then
  690. itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul)
  691. end
  692. awardVec[i]= {itemID, itemCnt}
  693. end
  694. --BagLogic.addItemList(human, itemConfig, "drill")
  695. BagLogic.addItemList(human, awardVec, "drill")
  696. RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1204)
  697. RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1201)
  698. -- queryDrillId(human)
  699. end
  700. --奖励预览
  701. function rewardPreview(human)
  702. if not isOpen(human, true) then return end
  703. local msgRet = Msg.gc.GC_DRILL_REWARD_PREVIEW
  704. msgRet.list[0] = 0
  705. --秘宝加成
  706. local heroExpMul = getTalismanAdd(human)
  707. for drillId, cf in pairs(DrillExcel.drill) do
  708. msgRet.list[0] = msgRet.list[0] + 1
  709. local net = msgRet.list[msgRet.list[0]]
  710. net.drillId = drillId
  711. net.items[0] = #cf.items
  712. for i, item in ipairs(cf.items) do
  713. local itemID = item[1]
  714. local itemCnt = item[2]
  715. if itemID == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then
  716. itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul)
  717. end
  718. Grid.makeItem(net.items[i], itemID, itemCnt)
  719. end
  720. end
  721. Msg.send(msgRet, human.fd)
  722. end
  723. -- 邮件提醒
  724. function sendDrillTip(human)
  725. if human.db.mailtips[RoleSystemLogic.ROLE_MAILTIPS_ID1] == nil then
  726. human.db.mailtips[RoleSystemLogic.ROLE_MAILTIPS_ID1] = os.time()
  727. end
  728. local curTime = os.time()
  729. local daySec = 3600 * 24;
  730. if curTime - human.db.mailtips[RoleSystemLogic.ROLE_MAILTIPS_ID1] < daySec then
  731. return
  732. end
  733. human.db.mailtips[RoleSystemLogic.ROLE_MAILTIPS_ID1] = curTime
  734. if not isOpen(human) then return end
  735. end
  736. --------------------------------------------------------------------------------------
  737. --加入跨服试炼队列
  738. --检测是否有竞技场阵容
  739. --加入数据推送至中心服 [g->m]
  740. function onJjcPos(human)
  741. local heroList, helpList, rolebase , formation, elfList = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE3)
  742. if not heroList or not next(heroList) then return end -- 没有上阵
  743. local drillObj = DrillDB.createDrillObj(human)
  744. if not drillObj then return end
  745. DrillDB.updateDrillObj(drillObj)
  746. end
  747. --请求关卡记录
  748. ------------ 匹配规则 -----------------------
  749. function getDifficulty(quJian, diff,config)
  750. local str1 = ""
  751. local str2 = ""
  752. local stradd = ""
  753. if quJian == 2 then
  754. stradd = "1"
  755. end
  756. if diff == DIFF_NORMAL then
  757. str1 = "zdlMin"
  758. str2 = "zdlMax"
  759. elseif diff == DIFF_ELITE then
  760. str1 = "zdlMinElite"
  761. str2 = "zdlMaxElite"
  762. elseif diff == DIFF_INCUBI then
  763. str1 = "zdlMinIncubi"
  764. str2 = "zdlMaxIncubi"
  765. end
  766. if stradd == "" then
  767. return config[str1], config[str2]
  768. else
  769. return config[str1..stradd], config[str2..stradd]
  770. end
  771. end
  772. function getZhanLiByNpc(zhandouli)
  773. local DrillNpcExcel = DrillExcel.npc
  774. local maxCnt = #DrillNpcExcel
  775. if DrillNpcExcel[maxCnt].zhandouli[2] < zhandouli then
  776. return DrillNpcExcel[maxCnt].zhandouli[1], DrillNpcExcel[maxCnt].zhandouli[2]
  777. end
  778. for k, config in ipairs(DrillExcel.npc) do
  779. if config.zhandouli[1] <= zhandouli and config.zhandouli[2] >= zhandouli then
  780. return config.zhandouli[1], config.zhandouli[2]
  781. end
  782. end
  783. return DrillExcel.npc[1].zhandouli[1], DrillExcel.npc[1].zhandouli[2]
  784. end
  785. function findRandomObj(zdlMin, zdlMax, notTab, isRobot)
  786. local drillObj = DrillDB.randomDrillObj(zdlMin, zdlMax, notTab, isRobot)
  787. return drillObj
  788. end
  789. -- 请求关卡
  790. function pipei(human, drillId, diff, zhandouli, notTab)
  791. local drillCfg = DrillExcel.drill[drillId]
  792. if not drillCfg then return end
  793. local minPer, maxPer = getDifficulty(1, diff, drillCfg)
  794. local zdlMin = math.ceil(minPer / 10000 * zhandouli)
  795. local zdlMax = math.ceil(maxPer / 10000 * zhandouli)
  796. local drillObj
  797. if (diff == DIFF_NORMAL and drillId <= 10) or
  798. (diff == DIFF_ELITE and drillId <= 8) or
  799. (diff == DIFF_INCUBI and drillId <= 6) then
  800. drillObj = findRandomObj(zdlMin, zdlMax, notTab, true)
  801. if not drillObj then
  802. minPer, maxPer = getDifficulty(2, diff, drillCfg)
  803. zdlMin = math.ceil(minPer / 10000 * zhandouli)
  804. zdlMax = math.ceil(maxPer / 10000 * zhandouli)
  805. if zdlMin <= DrillExcel.npc[1].zhandouli[2] then
  806. zdlMin = DrillExcel.npc[1].zhandouli[1]
  807. zdlMax = DrillExcel.npc[1].zhandouli[2]
  808. end
  809. drillObj = findRandomObj(zdlMin, zdlMax, notTab, true)
  810. if not drillObj then
  811. zdlMin,zdlMax = getZhanLiByNpc(zhandouli)
  812. drillObj = findRandomObj(zdlMin, zdlMax, notTab, true)
  813. end
  814. end
  815. else
  816. drillObj = findRandomObj(zdlMin, zdlMax, notTab)
  817. if not drillObj then
  818. minPer, maxPer = getDifficulty(2, diff, drillCfg)
  819. zdlMin = math.ceil(minPer / 10000 * zhandouli)
  820. zdlMax = math.ceil(maxPer / 10000 * zhandouli)
  821. drillObj = findRandomObj(zdlMin, zdlMax, notTab)
  822. if not drillObj then
  823. minPer = minPer - 500
  824. maxPer = maxPer + 500
  825. zdlMin = math.ceil(minPer / 10000 * zhandouli)
  826. zdlMax = math.ceil(maxPer / 10000 * zhandouli)
  827. drillObj = findRandomObj(zdlMin, zdlMax, notTab)
  828. if not drillObj then
  829. if zdlMin <= DrillExcel.npc[1].zhandouli[2] then
  830. zdlMin = DrillExcel.npc[1].zhandouli[1]
  831. zdlMax = DrillExcel.npc[1].zhandouli[2]
  832. end
  833. drillObj = findRandomObj(zdlMin, zdlMax, notTab, true)
  834. if not drillObj then
  835. zdlMin = zhandouli - 50001
  836. zdlMax = zhandouli + 50001
  837. zdlMin = zdlMin > DrillExcel.npc[1].zhandouli[1] and zdlMin or DrillExcel.npc[1].zhandouli[1]
  838. zdlMax = zdlMax > DrillExcel.npc[1].zhandouli[2] and zdlMax or DrillExcel.npc[1].zhandouli[2]
  839. local maxID = #DrillExcel.npc
  840. zdlMin = zdlMin < DrillExcel.npc[maxID].zhandouli[1] and zdlMin or DrillExcel.npc[maxID].zhandouli[1]
  841. zdlMax = zdlMax < DrillExcel.npc[maxID].zhandouli[2] and zdlMax or DrillExcel.npc[maxID].zhandouli[2]
  842. drillObj = findRandomObj(zdlMin, zdlMax, notTab, true)
  843. end
  844. end
  845. end
  846. end
  847. end
  848. if not drillObj then
  849. return Broadcast.sendErr(human, Lang.DRILL_NOT_FING_DRILL)
  850. end
  851. return drillObj
  852. end
  853. -----------------------------------------------------------
  854. --计算战力区间
  855. function fristQust(human, drillId)
  856. local drill = human.db.drill
  857. if not drill then return end
  858. local diff = drill.diff
  859. local dirllDefConfig = DrillExcel.define[drill.diff]
  860. if not dirllDefConfig then return end
  861. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  862. if drillData then return end
  863. drillId = drillId and drillId or 1
  864. if drillId > dirllDefConfig.maxDrillID then return end
  865. local zhandouli = CombatPosLogic.getCombatHeroZDL(human, CombatDefine.COMBAT_TYPE1)
  866. if zhandouli <= 0 then
  867. drill.diff = 0
  868. return Broadcast.sendErr(human, Lang.COMBAT_ERR_NO_SET_FIGHT)
  869. end
  870. local notTab = {}
  871. if human.maxZDL and human.maxZDL.zhandouli and human.maxZDL.zhandouli > zhandouli then
  872. -- 获取玩家真正的最高战力 防止玩家 战役上阵 战力低 去匹配 低战力对手
  873. zhandouli = human.maxZDL.zhandouli
  874. end
  875. local drillObj = pipei(human, drillId, diff, zhandouli, notTab)
  876. if not drillObj then return end
  877. local drillData = DrillDB.createDrillData(human, drillId)
  878. drillData.diff = diff
  879. drillData.drillObjs[drillId] = Util.copyTable(drillObj)
  880. DrillDB.updateDrillData(drillData)
  881. queryDrillId(human, drillData)
  882. end
  883. function quest(human, drillId)
  884. local drill = human.db.drill
  885. if not drill then return end
  886. local diff = drill.diff
  887. local dirllDefConfig = DrillExcel.define[drill.diff]
  888. if not dirllDefConfig then return end
  889. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  890. if not drillData then
  891. fristQust(human, drillId)
  892. return
  893. end
  894. if drillId > dirllDefConfig.maxDrillID then return end
  895. local notTab = {}
  896. notTab[#notTab + 1] = human.db._id
  897. if drillData then
  898. for i = 1, dirllDefConfig.maxDrillID do
  899. local drillObj = drillData.drillObjs[i]
  900. if drillObj then
  901. notTab[#notTab + 1] = drillObj._id or drillObj.uuid
  902. end
  903. end
  904. end
  905. local zhandouli = CombatPosLogic.getCombatHeroZDL(human, CombatDefine.COMBAT_TYPE1)
  906. if zhandouli <= 0 then return Broadcast.sendErr(human, Lang.COMBAT_ERR_NO_SET_FIGHT) end
  907. if human.maxZDL and human.maxZDL.zhandouli and human.maxZDL.zhandouli > zhandouli then
  908. -- 获取玩家真正的最高战力 防止玩家 战役上阵 战力低 去匹配 低战力对手
  909. zhandouli = human.maxZDL.zhandouli
  910. end
  911. local drillObj = pipei(human, drillId, diff, zhandouli, notTab)
  912. drillData.drillObjs[drillId] = Util.copyTable(drillObj)
  913. DrillDB.updateDrillData(drillData)
  914. -- queryDrillId(human, drillData)
  915. end
  916. -- myHelpIndex = 1, -- 我选择的援助出去英雄
  917. -- helpoutList = {}, -- 我选择的援助英雄
  918. -- 选择自己的 出战 英雄
  919. function dispatchMyHelpHero(human, index)
  920. local drill = human.db.drill
  921. if not drill then return end
  922. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  923. if not drillData then return end
  924. -- if drillData.helpInfo then
  925. -- return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_MY_ERR_HAD)
  926. -- end
  927. -- 当日已经派遣过
  928. if drill.myHelpIndex and drill.myHelpIndex > 0 then
  929. return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_MY_ERR_HAD)
  930. end
  931. local heroGrid = human.db.heroBag[index]
  932. if type(heroGrid) ~= "table" then
  933. return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_MY_ERR_INDEX)
  934. end
  935. local combatObj = CombatLogic.createHumanObj(human, heroGrid.uuid)
  936. local rolebase = CombatLogic.createRoleBaseByDB(human.db)
  937. if not combatObj or not rolebase then
  938. return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_MY_ERR_INDEX)
  939. end
  940. combatObj.bagIndex = nil
  941. combatObj.friendUuid = human.db._id
  942. local helpInfo = {}
  943. helpInfo.heroGrid = heroGrid
  944. helpInfo.combatObj = combatObj
  945. helpInfo.rolebase = rolebase
  946. drillData.helpInfo = helpInfo
  947. drill.myHelpIndex = index
  948. DrillDB.updateDrillData(drillData)
  949. local heroID = heroGrid.id
  950. local heroConfig = HeroExcel.hero[heroID]
  951. if heroConfig == nil then return end
  952. drill.myHelpIndex = index
  953. drill.myHelpHero = helpInfo
  954. helpHeroFriendQuery(human)
  955. RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1204)
  956. RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1201)
  957. end
  958. -- 获取最大血量
  959. function getCombatObjHpMax(obj)
  960. if obj.hpMax then return obj.hpMax end
  961. local hpMax = obj.attrs[RoleDefine.HP]
  962. hpMax = math.ceil(hpMax * (1 + obj.attrs[RoleDefine.HP_RATE]/10000))
  963. return hpMax
  964. end
  965. -- 封装助战结构体
  966. function fontHelpNet(net, targetUuid)
  967. local tDrillData = DrillDB.getDrillDataByUuid(targetUuid)
  968. if not tDrillData then return end
  969. local tHelpInfo = tDrillData.helpInfo
  970. if not tHelpInfo then return end
  971. net.uuid = targetUuid
  972. net.name = tHelpInfo.rolebase.name
  973. net.state = 0
  974. net.pos = 0
  975. HeroGrid.makeHeroSimple(net.heroSimple, tHelpInfo.heroGrid)
  976. return true
  977. end
  978. local helpHeroFields = {lv = 1, name = 1, head = 1, technology=1, heroBag = 1, combatHero = 1, drill = 1}
  979. function helpHeroFriendQuery(human)
  980. local drill = human.db.drill
  981. if not drill then return end
  982. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  983. if not drillData then return end
  984. local now = os.time()
  985. local msgRet = Msg.gc.GC_DRILL_FRIEND_HELP_QUERY
  986. msgRet.myHelpIndex = drill.myHelpIndex and drill.myHelpIndex or 0
  987. msgRet.ownChose[0] = 0
  988. msgRet.herolist[0] = 0
  989. local len = 0
  990. -- 我已经选择了 部分 援助英雄
  991. if drill.helpoutList then
  992. for uuid, v in pairs(drill.helpoutList) do
  993. local net = msgRet.ownChose[msgRet.ownChose[0] + 1]
  994. if fontHelpNet(net, uuid, true) then
  995. msgRet.ownChose[0] = msgRet.ownChose[0] + 1
  996. end
  997. end
  998. end
  999. -- 玩家最多选择 三位好友援助英雄
  1000. if len < 3 then
  1001. len = 0
  1002. local cnt, list = FriendDBLogic.getFriendUuids(human.db._id)
  1003. for i = 1, cnt do
  1004. local targetUuid = list[i].uuid
  1005. if not drill.helpoutList or not drill.helpoutList[targetUuid] then
  1006. if msgRet.herolist[0] >= #msgRet.herolist then
  1007. break
  1008. end
  1009. local net = msgRet.herolist[msgRet.herolist[0] + 1]
  1010. if fontHelpNet(net, targetUuid) then
  1011. msgRet.herolist[0] = msgRet.herolist[0] + 1
  1012. end
  1013. end
  1014. end
  1015. end
  1016. -- Msg.trace(msgRet)
  1017. Msg.send(msgRet, human.fd)
  1018. end
  1019. -- 选择支援我的好友助战
  1020. local HELP_MAIL_ITEMS = {{}}
  1021. function choseHelpFriendHero(human, uuid)
  1022. if not uuid or uuid == "" then
  1023. return
  1024. end
  1025. local drill = human.db.drill
  1026. if not drill then return end
  1027. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  1028. if not drillData then return end
  1029. -- 今天 已经选择该玩家英雄援助了
  1030. if drill.helpoutList and drill.helpoutList[uuid] then
  1031. return
  1032. end
  1033. if not FriendDBLogic.isFriend(human.db._id, uuid) then
  1034. return
  1035. end
  1036. if drill.helpoutList then
  1037. local len = 0
  1038. for k, _ in pairs(drill.helpoutList) do
  1039. len = len + 1
  1040. end
  1041. if len >= 3 then
  1042. return
  1043. end
  1044. end
  1045. local friendHuman
  1046. friendHuman = ObjHuman.onlineUuid[uuid]
  1047. if not friendHuman then
  1048. local db = RoleDBLogic.getDb(uuid, helpHeroFields)
  1049. if db then
  1050. friendHuman = {db = db}
  1051. end
  1052. end
  1053. local drillFriend = friendHuman.db.drill
  1054. if not drillFriend or not drillFriend.myHelpHero then
  1055. return
  1056. end
  1057. -- 检查这个数据是否是当天设置的
  1058. if not Util.isSameDay(drillFriend.time) then
  1059. return
  1060. end
  1061. local tDrillData = DrillDB.getDrillDataByUuid(uuid)
  1062. local helpInfo = tDrillData and tDrillData.helpInfo
  1063. if not helpInfo then
  1064. return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_FRIEND_ERR_INFO)
  1065. end
  1066. local maxZhandouli = HeroLogic.getHeroMaxZDL(human)
  1067. if helpInfo.heroGrid.zhandouli > maxZhandouli * MAX_HEROCOMBAT_MUL / 100 then
  1068. return Broadcast.sendErr(human, Util.format(Lang.LIANYU_MY_SELECT_ERR_ZDL, MAX_HEROCOMBAT_MUL))
  1069. end
  1070. drill.helpoutList = drill.helpoutList or {}
  1071. drill.helpoutList[uuid] = {}
  1072. drill.helpoutList[uuid].time = os.time()
  1073. DrillLogicAttribute.setHelp(drillData ,uuid)
  1074. DrillDB.updateDrillData(drillData)
  1075. -- 给好友发送雇佣奖励
  1076. HELP_MAIL_ITEMS[1][1] = ItemDefine.ITEM_FRIEND_ID
  1077. HELP_MAIL_ITEMS[1][2] = FRIEND_ITEM_CNT
  1078. local mailConfig = MailExcel.mail[MailDefine.MAIL_ID_DRILL_HELP]
  1079. local title = mailConfig.title
  1080. local senderName = mailConfig.senderName
  1081. local content = Util.format(mailConfig.content, human.db.name)
  1082. MailManager.add(MailManager.SYSTEM, uuid, title, content, HELP_MAIL_ITEMS, senderName)
  1083. helpHeroFriendQuery(human)
  1084. RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1204)
  1085. RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1201)
  1086. end
  1087. function curFuhuoCnt(human, drillData)
  1088. local maxCnt = VipLogic.getPowerArgs(human, VipLogic.VIP_POWER5)
  1089. local oldCnt = DrillLogicAttribute.getOperCnt(drillData, DrillLogicAttribute.DRILL_OPER_1)
  1090. local curCnt = maxCnt - oldCnt
  1091. curCnt = curCnt > 0 and curCnt or 0
  1092. return maxCnt, curCnt
  1093. end
  1094. function getResetNeedZuanshi(drillData, maxCnt)
  1095. local oldCnt = DrillLogicAttribute.getOperCnt(drillData, DrillLogicAttribute.DRILL_OPER_1)
  1096. if oldCnt >= maxCnt then
  1097. return 0
  1098. end
  1099. local operConfig = DrillExcel.oper[oldCnt + 1]
  1100. return operConfig.zuanshi
  1101. end
  1102. function fuhuoQuery(human)
  1103. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  1104. if not drillData then return end
  1105. local msgRet = Msg.gc.GC_DRILL_FUHUO_QUERY
  1106. msgRet.maxCnt, msgRet.canCnt = curFuhuoCnt(human, drillData)
  1107. msgRet.needZuanshi = getResetNeedZuanshi(drillData, msgRet.maxCnt)
  1108. Msg.send(msgRet, human.fd)
  1109. end
  1110. function getHelpHeroState(human, args)
  1111. local choseUuid = args[1]
  1112. local drill = human.db.drill
  1113. if not drill then return false end
  1114. if drill.helpoutList and drill.helpoutList[choseUuid] then
  1115. local hero = drill.helpoutList[choseUuid]
  1116. -- 挑战胜利过的 不能作为出战英雄
  1117. if hero.winCnt and hero.winCnt > 0 then return false end
  1118. local hp = hero.helpObj.attrs[RoleDefine.HP]
  1119. if hp <= 0 then return false end
  1120. return true, hero.heroObj
  1121. end
  1122. return false
  1123. end
  1124. -- 助战英雄上阵
  1125. function setHelpCombatPos(human, uuid, pos)
  1126. if not isOpen(human, true) then return end
  1127. local drill = human.db.drill
  1128. if not drill then return false end
  1129. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  1130. if not drillData then return end
  1131. if drill.helpoutList and drill.helpoutList[uuid] then
  1132. human.drill = human.drill or {}
  1133. human.drill.combatHelpUuid = uuid
  1134. human.drill.combatHelpPos = pos
  1135. end
  1136. end
  1137. -- 防御方数据
  1138. function getDefender(drillObj)
  1139. local objList = {}
  1140. for index, obj in pairs(drillObj.heroList) do
  1141. if DrillLogicAttribute.getObjHpRate(drillObj, obj.bagIndex) > 0 and index ~= CombatDefine.BACKUP_POS[1] then -- 剔除死亡的
  1142. objList[index] = obj
  1143. end
  1144. end
  1145. local roleBase = {}
  1146. RoleLogic.makeRoleBase(drillObj, roleBase)
  1147. return objList, drillObj.helpList, roleBase, drillObj.formation, drillObj.jiban, drillObj.elfList
  1148. end
  1149. -- 攻击方数据
  1150. function getAttacker(human, drillData, pos2uuidAtk)
  1151. local drill = human.db.drill
  1152. if not drill then return end
  1153. local objList, helpList, rolebase, formation, jiban, elfList = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE9)
  1154. for pos, obj in pairs(objList) do
  1155. local heroGrid = human.db.heroBag[obj.bagIndex]
  1156. if heroGrid then
  1157. pos2uuidAtk[pos] = heroGrid.uuid
  1158. end
  1159. end
  1160. -- 助战英雄
  1161. local combatHelpUuid = human.drill and human.drill.combatHelpUuid
  1162. local combatHelpPos = human.drill and human.drill.combatHelpPos
  1163. if combatHelpUuid and combatHelpPos then
  1164. if drill.helpoutList and drill.helpoutList[combatHelpUuid] then
  1165. local tDrillData = DrillDB.getDrillDataByUuid(combatHelpUuid)
  1166. local combatHelp = tDrillData and tDrillData.helpInfo
  1167. if combatHelp and DrillLogicAttribute.getHelpHpRate(drillData, combatHelpUuid) > 0 and
  1168. CombatPosLogic.checkPos(formation, combatHelpPos) then
  1169. objList[combatHelpPos] = combatHelp.combatObj
  1170. pos2uuidAtk[combatHelpPos] = combatHelpUuid
  1171. end
  1172. end
  1173. end
  1174. return objList, helpList, rolebase, formation, jiban, elfList
  1175. end
  1176. -------------------------------------- combat -----------------------------------------
  1177. -- 判断是否合适上阵
  1178. local function isFixCombatPos(heroGrid, drillData, config)
  1179. if type(heroGrid) ~= "table" then return end
  1180. if not drillData then return end
  1181. if config and config.heroMinLevel and heroGrid.lv < config.heroMinLevel then return end -- 等级不满足
  1182. local hpRate = DrillLogicAttribute.getHeroHpRate(drillData, heroGrid.uuid)
  1183. if hpRate <= 0 then return end -- 死掉了
  1184. return true
  1185. end
  1186. -- 不合适的下阵
  1187. function updateCombatPosCheck(human, drillData)
  1188. local combatHero = CombatPosLogic.getCombatHeros(human, CombatDefine.COMBAT_TYPE9)
  1189. if not combatHero then return end
  1190. local drillDB = human.db.drill
  1191. local config = DrillExcel.define[drillData.diff]
  1192. for pos, uuid in pairs(combatHero) do
  1193. local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
  1194. if heroGrid and not isFixCombatPos(heroGrid, drillData, config) then
  1195. combatHero[pos] = nil
  1196. end
  1197. end
  1198. end
  1199. -- 战斗前加属性
  1200. function onFightBegin(human, cbParam)
  1201. for index = 1, CombatDefine.COMBAT_HERO_ALL_CNT do
  1202. local obj = CombatImpl.objList[index]
  1203. if obj then
  1204. if index <= CombatDefine.COMBAT_HERO_CNT then
  1205. calcAttrAtk(human, index, obj,cbParam )
  1206. else
  1207. calcAttrDef(human, index, obj, cbParam)
  1208. end
  1209. end
  1210. end
  1211. end
  1212. function getHelpGrid(human, uuid)
  1213. local drill = human.db.drill
  1214. if drill.helpoutList and drill.helpoutList[uuid] then
  1215. return drill.helpoutList[uuid].heroGrid
  1216. end
  1217. end
  1218. -- 所有属性计算完毕,重新设置血量(攻击)
  1219. function calcAttrAtk(human, pos, obj, cbParam)
  1220. local uuid = cbParam.pos2uuidAtk[pos]
  1221. if not uuid then return end
  1222. local hpRate = nil
  1223. if (obj.bagIndex or 0) > 0 then
  1224. hpRate = DrillLogicAttribute.getHeroHpRate(cbParam.drillData, uuid)
  1225. else
  1226. hpRate = DrillLogicAttribute.getHelpHpRate(cbParam.drillData, uuid)
  1227. end
  1228. local hpMax = CombatObj.getHpMax(obj)
  1229. obj.hp = math.ceil(hpRate * hpMax)
  1230. end
  1231. -- 所有属性计算完毕,重新设置血量(防守)
  1232. function calcAttrDef(human, pos, obj, cbParam)
  1233. local hpRate = DrillLogicAttribute.getObjHpRate(cbParam.drillObj, obj.bagIndex)
  1234. local hpMax = CombatObj.getHpMax(obj)
  1235. obj.hp = math.ceil(hpRate * hpMax)
  1236. end
  1237. -- 战斗
  1238. function fight(human, args)
  1239. if not isOpen(human, true) then return end
  1240. if human.db.combatQuick and human.db.combatQuick[CombatDefine.COMBAT_TYPE9] and human.db.combatQuick[CombatDefine.COMBAT_TYPE9] == 1 then
  1241. local combatHero = CombatPosLogic.getCombatHeros(human, CombatDefine.COMBAT_TYPE9 )
  1242. if CombatLogic.isCombatHeroEmpty(combatHero) then
  1243. queryDrillId(human)
  1244. return Broadcast.sendErr(human, Lang.DRILL_NOT_FIGHT_NOT_HERO)
  1245. end
  1246. end
  1247. local drill = human.db.drill
  1248. if not drill then return false end
  1249. local drillDB = human.db.drill
  1250. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  1251. if not drillData then
  1252. return Broadcast.sendErr(human, Lang.DRILL_IS_FINSH)
  1253. end
  1254. local drillId = tonumber(args[1] or 0)
  1255. if drillId ~= drillData.drillId then
  1256. return
  1257. end
  1258. local config = DrillExcel.drill[drillId]
  1259. if not config then return end
  1260. local drillObj = drillData.drillObjs[drillId]
  1261. if not drillObj then return end -- 不存在。。
  1262. updateCombatPosCheck(human, drillData)
  1263. local args = {}
  1264. local pos2uuidAtk = {}
  1265. args.defender, args.defHelp, args.defRBase, args.defFormation, args.defJiban, args.defElfList = getDefender(drillObj)
  1266. args.attacker, args.atkHelp, args.atkRBase, args.atkFormation, args.atkJiban, args.atkElfList = getAttacker(human, drillData, pos2uuidAtk)
  1267. args.drillId = drillData.drillId
  1268. local cbParam = {}
  1269. cbParam.pos2uuidAtk = pos2uuidAtk
  1270. cbParam.diff = drillData.diff
  1271. cbParam.drillId = drillData.drillId
  1272. cbParam.drillData = drillData
  1273. cbParam.drillObj = drillObj
  1274. cbParam.combatHelpPos = human.drill and human.drill.combatHelpPos
  1275. cbParam.combatHelpUuid = human.drill and human.drill.combatHelpUuid
  1276. CombatLogic.combatBegin(human, config.mapID, args, CombatDefine.COMBAT_TYPE9, cbParam)
  1277. end
  1278. -- 获取当前地图ID
  1279. function getMapID(human, args)
  1280. local drillDB = human.db.drill
  1281. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  1282. local drillId = tonumber(args[1] or args.drillId or 0)
  1283. if drillId ~= drillData.drillId then
  1284. return
  1285. end
  1286. local config = DrillExcel.drill[drillId]
  1287. if not config then return end
  1288. return config.mapID
  1289. end
  1290. -- 刷新drillData记录的血量
  1291. function combatOnUpdate(human, cbParam, combatInfo)
  1292. for index = 1, CombatDefine.COMBAT_HERO_CNT do
  1293. -- 更新攻击方血量
  1294. local atkPos = CombatLogic.getPos(CombatDefine.ATTACK_SIDE, index)
  1295. local atkObj = combatInfo.objList[atkPos]
  1296. if atkObj ~= nil then
  1297. local hp = atkObj.hp
  1298. local hpMax = CombatObj.getHpMax(atkObj)
  1299. local hpRate = hp / hpMax
  1300. local uuid = cbParam.pos2uuidAtk[index]
  1301. if (atkObj.bagIndex or 0) > 0 then
  1302. DrillLogicAttribute.setHeroHpRate(cbParam.drillData, uuid, hpRate)
  1303. else
  1304. DrillLogicAttribute.setHelpHpRate(cbParam.drillData, uuid, hpRate)
  1305. end
  1306. end
  1307. -- 更新防守方血量
  1308. local defPos = CombatLogic.getPos(CombatDefine.DEFEND_SIDE, index)
  1309. local defObj = combatInfo.objList[defPos]
  1310. if defObj ~= nil then
  1311. local hp = defObj.hp
  1312. local hpMax = CombatObj.getHpMax(defObj)
  1313. local hpRate = hp / hpMax
  1314. DrillLogicAttribute.setObjHpRate(cbParam.drillObj, defObj.bagIndex, hpRate)
  1315. end
  1316. end
  1317. updateCombatPosCheck(human, cbParam.drillData)
  1318. end
  1319. -- 战胜回调
  1320. function onFightWinCallback(human, result , diff,drillID)
  1321. LiLianLogic.onCallback(human,LiLianLogic.LILIAN_OUTID11,1,diff)
  1322. DailyTaskLogic.recordDailyTaskFinishCnt(human, DailyTaskLogic.DAILY_TASK_ID_11, 1)
  1323. HeroGrowUp.onCallback(human, HeroGrowUp.TASKTYPE16, 1)
  1324. MengxinLogic.onCallBack(human,MengxinLogic.MX_TASK_TYPE_8,drillID)
  1325. RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1204)
  1326. RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1201)
  1327. end
  1328. -- 援助英雄 添加胜利
  1329. function addHelpWin(human, drillData)
  1330. if human.drill and human.drill.combatHelpUuid then
  1331. DrillLogicAttribute.setHelpWin(drillData, human.drill.combatHelpUuid)
  1332. end
  1333. end
  1334. -- 通关回调
  1335. function tongGuan(human, diff)
  1336. if getMaxDiff(human) < diff then
  1337. setMaxDiff(human, diff)
  1338. end
  1339. end
  1340. -- 战斗结束
  1341. function onFightEnd(human, result, combatType, cbParam, combatInfo)
  1342. local isOtherDay = false
  1343. if not Util.isSameDay(combatInfo.time) then
  1344. isOtherDay = true
  1345. end
  1346. local drillDB = human.db.drill
  1347. if not drillDB then return end
  1348. combatOnUpdate(human, cbParam, combatInfo)
  1349. local drillData = cbParam.drillData
  1350. local isKill = true
  1351. if not isObjKill(cbParam.drillObj) then -- 未击杀对面
  1352. isKill = false
  1353. end
  1354. local diff = cbParam.diff or drillData.diff
  1355. if not isOtherDay then
  1356. if not isKill then
  1357. return DrillDB.updateDrillData(drillData)
  1358. end
  1359. -- 刷新最大通关难度
  1360. local dirllDefConfig = DrillExcel.define[diff]
  1361. if cbParam.drillId >= dirllDefConfig.maxDrillID then
  1362. tongGuan(human, diff)
  1363. ChengjiuLogic.onCallback(human,ChengjiuDefine.CJ_TASK_TYPE_17,1)
  1364. HeroLogLogic.finishTaskCB(human,HeroLogLogic.HERO_LOG_TYPE_5,1)
  1365. end
  1366. drillData.drillId = drillData.drillId + 1
  1367. drillDB.drillId = drillData.drillId
  1368. addHelpWin(human, drillData)
  1369. DrillDB.updateDrillData(drillData)
  1370. -- 手动通关后清除扫荡完成标记,允许再次扫荡
  1371. if drillDB then
  1372. drillDB.oneClickSaodangDone = nil
  1373. end
  1374. quest(human, cbParam.drillId + 1)
  1375. --[[if drillDB.drillId == cbParam.drillId and drillDB.diff == diff then
  1376. if cbParam.drillId <= dirllDefConfig.maxDrillID then
  1377. drillDB.drillId = drillDB.drillId + 1
  1378. drillData.drillId = drillData.drillId + 1
  1379. end
  1380. addHelpWin(human, drillData)
  1381. DrillDB.updateDrillData(drillData)
  1382. quest(human, cbParam.drillId + 1)
  1383. end]]
  1384. else
  1385. if not isKill then
  1386. updateDaily(human)
  1387. return
  1388. end
  1389. end
  1390. local drillItems = getDrillItems(cbParam.drillId, diff)
  1391. local double = RoleSystemLogic.isDouble(human, RoleSystemDefine.ROLE_SYS_ID_1204)
  1392. local rewardCnt = double and 2 or 1
  1393. combatInfo.double = double and 2 or 0
  1394. --秘宝加成
  1395. local heroExpMul = getTalismanAdd(human)
  1396. -- 关卡奖励
  1397. local itemList = {}
  1398. for k, item in ipairs(drillItems) do
  1399. local itemID = item[1]
  1400. local itemCnt = item[2] * rewardCnt
  1401. if itemID == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then
  1402. itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul)
  1403. end
  1404. itemList[k] = {}
  1405. itemList[k][1] = itemID
  1406. itemList[k][2] = itemCnt
  1407. -- itemList[k][4] = sourceId
  1408. BagLogic.addItem(human, itemID, itemCnt, "drill")
  1409. if not isOtherDay then
  1410. drillDB.dayGet = drillDB.dayGet or {}
  1411. drillDB.dayGet[itemID] = (drillDB.dayGet[itemID] or 0) + itemCnt
  1412. end
  1413. end
  1414. combatInfo.rewardItem = itemList
  1415. human.drill = nil
  1416. if isOtherDay then
  1417. updateDaily(human)
  1418. end
  1419. -- 回调
  1420. onFightWinCallback(human,result, diff,cbParam.drillId)
  1421. YunYingLogic.onCallBack(human, "onDrill",1)
  1422. --周任务 -8
  1423. WeekTaskLogic.recordWeekTaskFinishCnt(human, WeekTaskLogic.WEEK_TASK_ID_8, 1)
  1424. TriggerLogic.PublishEvent(TriggerDefine.DRILL_KILL_SHOUWEI, human.db._id, 1)
  1425. end
  1426. --[[
  1427. -- 增加关卡
  1428. function questMid(fd, msg)
  1429. local uuid = msg.uuid
  1430. local drillId = msg.drillId
  1431. local drillObj = msg.drillObj
  1432. if not RoleDBLogic.isUuidExistInDB(uuid) then
  1433. return
  1434. end
  1435. local drillData = DrillDB.getDrillDataByUuid(uuid)
  1436. if not drillData then
  1437. -- if drillId ~= 1 then return end -- 注意哦
  1438. drillData = DrillDB.createDrillData(uuid)
  1439. else
  1440. if drillData.drillId ~= drillId then return end
  1441. end
  1442. print("drillObj",drillObj._id, drillId)
  1443. drillData.drillObjs[drillId] = Util.copyTable(drillObj)
  1444. DrillDB.updateDrillData(drillData)
  1445. local human = ObjHuman.onlineUuid[uuid]
  1446. if human == nil then return end
  1447. queryDrillId(human, drillData)
  1448. end
  1449. ]]
  1450. function isDot(human)
  1451. local isOpen = RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_1204)
  1452. if not isOpen then return false end
  1453. if not human.db.drill then
  1454. return true
  1455. end
  1456. for k, _ in ipairs(DrillExcel.box) do
  1457. if getBoxState(human.db.drill, k) == DRILL_BOX_STATE_1 then
  1458. return true
  1459. end
  1460. end
  1461. if human.db.drill.myHelpIndex and human.db.drill.myHelpIndex > 0 then
  1462. return false
  1463. end
  1464. return true
  1465. end
  1466. function getQuick(human)
  1467. if getMaxDiff(human) > 0 then
  1468. return 1
  1469. end
  1470. return 0
  1471. end
  1472. -- 通关消耗钻石来通关当前关卡
  1473. function ChallengeLevelByDiamond(human, levelId)
  1474. local drill = human.db.drill
  1475. if not drill then
  1476. return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
  1477. end
  1478. local drillDB = human.db.drill
  1479. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  1480. if not drillData then
  1481. return Broadcast.sendErr(human, Lang.DRILL_IS_FINSH)
  1482. end
  1483. if levelId ~= drillData.drillId then
  1484. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  1485. end
  1486. local config = DrillExcel.drill[levelId]
  1487. if not config then
  1488. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  1489. end
  1490. local drillObj = drillData.drillObjs[levelId]
  1491. if not drillObj then
  1492. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  1493. end
  1494. if BagLogic.getItemCnt(human, ItemDefine.ITEM_ZUANSHI_ID) < CHALLENGE_DIAMONS then
  1495. return Broadcast.sendErr(human, Lang.COMMON_NO_ZUANSHI)
  1496. end
  1497. BagLogic.delItem(human, ItemDefine.ITEM_ZUANSHI_ID, CHALLENGE_DIAMONS, "drill")
  1498. local oldDrillID = drillData.drillId
  1499. local isOtherDay = false
  1500. local diff = drillData.diff
  1501. local dirllDefConfig = DrillExcel.define[diff]
  1502. if drillData.drillId >= dirllDefConfig.maxDrillID then
  1503. tongGuan(human, diff)
  1504. ChengjiuLogic.onCallback(human,ChengjiuDefine.CJ_TASK_TYPE_17,1)
  1505. HeroLogLogic.finishTaskCB(human,HeroLogLogic.HERO_LOG_TYPE_5,1)
  1506. end
  1507. drillData.drillId = drillData.drillId + 1
  1508. drillDB.drillId = drillData.drillId
  1509. -- addHelpWin(human, drillData)
  1510. DrillDB.updateDrillData(drillData)
  1511. -- 手动通关后清除扫荡完成标记,允许再次扫荡
  1512. if drillDB then
  1513. drillDB.oneClickSaodangDone = nil
  1514. end
  1515. quest(human, oldDrillID + 1)
  1516. local drillItems = getDrillItems(oldDrillID, diff)
  1517. local double = RoleSystemLogic.isDouble(human, RoleSystemDefine.ROLE_SYS_ID_1204)
  1518. local rewardCnt = double and 2 or 1
  1519. --秘宝加成
  1520. local heroExpMul = getTalismanAdd(human)
  1521. -- 关卡奖励
  1522. local itemArray = {}
  1523. for k, item in ipairs(drillItems) do
  1524. local itemID = item[1]
  1525. local itemCnt = item[2] * rewardCnt
  1526. if itemID == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then
  1527. itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul)
  1528. end
  1529. itemArray[k] = {itemID, itemCnt}
  1530. -- BagLogic.addItem(human, itemID, itemCnt, "drill")
  1531. if not isOtherDay then
  1532. drillDB.dayGet = drillDB.dayGet or {}
  1533. drillDB.dayGet[itemID] = (drillDB.dayGet[itemID] or 0) + itemCnt
  1534. end
  1535. end
  1536. -- 回调
  1537. onFightWinCallback(human,result, diff, oldDrillID)
  1538. YunYingLogic.onCallBack(human, "onDrill",1)
  1539. --周任务 -8
  1540. WeekTaskLogic.recordWeekTaskFinishCnt(human, WeekTaskLogic.WEEK_TASK_ID_8, 1)
  1541. TriggerLogic.PublishEvent(TriggerDefine.DRILL_KILL_SHOUWEI, human.db._id, 1)
  1542. -- 更新数据
  1543. queryDrillId(human)
  1544. -- 发放奖励
  1545. BagLogic.addItemList(human, itemArray, "drill")
  1546. end
  1547. -- 一键扫荡
  1548. function oneClickSaodang(human)
  1549. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 收到一键扫荡请求")
  1550. -- 检查是否购买了基金(购买项207)
  1551. if not human.db.overflow or not human.db.overflow.state or not human.db.overflow.state[OverflowFundLogic.OVERFLOW_TYPE_2] then
  1552. --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 未购买奢华基金(OVERFLOW_TYPE_2)")
  1553. return
  1554. end
  1555. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 已购买基金,继续执行")
  1556. -- 检查是否开启了试炼
  1557. if not isOpen(human, true) then
  1558. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 试炼未开启")
  1559. return
  1560. end
  1561. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 试炼已开启,继续执行")
  1562. local drill = human.db.drill
  1563. if not drill then
  1564. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] drill为nil")
  1565. return
  1566. end
  1567. local drillData = DrillDB.getDrillDataByUuid(human.db._id)
  1568. if not drillData then
  1569. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] drillData为nil")
  1570. return
  1571. end
  1572. local diff = drill.diff
  1573. if not drill.diff or drill.diff == 0 then
  1574. diff = drillData.diff
  1575. end
  1576. if diff == 0 then
  1577. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] diff="..diff..",需要!=0")
  1578. return
  1579. end
  1580. ---- 获取当前关卡ID
  1581. local currentDrillId = drillData.drillId or 1
  1582. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 当前关卡ID="..currentDrillId..", diff="..diff)
  1583. -- 获取总关卡数
  1584. local dirllDefConfig = DrillExcel.define[diff]
  1585. if not dirllDefConfig then
  1586. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 难度配置不存在,diff="..diff)
  1587. return
  1588. end
  1589. local maxDrillID = dirllDefConfig.maxDrillID
  1590. -- 如果已经通关所有关卡(drillId > maxDrillID),不允许再次扫荡
  1591. if currentDrillId > maxDrillID then
  1592. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 已通关所有关卡,不允许再次扫荡,currentDrillId="..currentDrillId..", maxDrillID="..maxDrillID)
  1593. Broadcast.sendErr(human, "已通关所有关卡,无法再次扫荡")
  1594. return
  1595. end
  1596. -- 计算可扫荡的关卡数
  1597. -- 一键扫荡应该扫荡所有关卡(1到maxDrillID),无论当前关卡ID是多少
  1598. local maxSaodangId = maxDrillID
  1599. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 一键扫荡:扫荡所有关卡,maxSaodangId="..maxSaodangId..", maxDrillID="..maxDrillID)
  1600. if maxSaodangId < 1 then
  1601. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 无可扫荡关卡,maxSaodangId="..maxSaodangId.." < 1")
  1602. return
  1603. end
  1604. -- 计算扫荡后的关卡ID
  1605. -- 一键扫荡后应该全部通关(newDrillId = maxDrillID + 1)
  1606. local newDrillId = maxDrillID + 1 -- 16表示已通关所有关卡
  1607. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 计算扫荡后关卡ID: 一键扫荡后全部通关, newDrillId="..newDrillId)
  1608. -- 检查是否已经扫荡过:
  1609. -- 由于 newDrillId 总是等于 maxDrillID + 1(全部通关),所以:
  1610. -- - 如果 currentDrillId <= maxDrillID,那么 newDrillId > currentDrillId,这是正常的,允许扫荡
  1611. -- - 如果 currentDrillId > maxDrillID,说明已经全部通关了,不允许再次扫荡(这个检查已经在前面做了)
  1612. -- 理论上 newDrillId 不会小于或等于 currentDrillId(除非已经全部通关),但为了安全起见,保留检查
  1613. if newDrillId < currentDrillId then
  1614. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 已扫荡过,不允许再次扫荡: currentDrillId="..currentDrillId..", newDrillId="..newDrillId..", maxSaodangId="..maxSaodangId)
  1615. Broadcast.sendErr(human, "已扫荡过,无法再次扫荡")
  1616. return
  1617. end
  1618. -- 如果 newDrillId == currentDrillId,理论上不会出现(因为 newDrillId 总是 maxDrillID + 1)
  1619. -- 但为了安全起见,保留检查(通过标记判断是否已经扫荡过)
  1620. if newDrillId == currentDrillId then
  1621. if drill.oneClickSaodangDone then
  1622. --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 已扫荡过(通过标记判断),不允许再次扫荡: currentDrillId="..currentDrillId..", newDrillId="..newDrillId..", maxSaodangId="..maxSaodangId)
  1623. Broadcast.sendErr(human, "已扫荡过,无法再次扫荡")
  1624. return
  1625. end
  1626. end
  1627. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 可扫荡关卡数: maxSaodangId="..maxSaodangId..", 总关卡数="..maxDrillID)
  1628. -- 双倍奖励
  1629. local double = RoleSystemLogic.isDouble(human, RoleSystemDefine.ROLE_SYS_ID_1204)
  1630. local rewardCnt = double and 2 or 1
  1631. -- 秘宝加成
  1632. local heroExpMul = getTalismanAdd(human)
  1633. -- 初始化今日奖励
  1634. drill.dayGet = drill.dayGet or {}
  1635. -- 收集所有奖励到列表中
  1636. local itemList = {}
  1637. -- 遍历所有可扫荡的关卡,收集奖励
  1638. for i = currentDrillId, maxSaodangId do
  1639. local drillItems = getDrillItems(i, diff)
  1640. if drillItems then
  1641. for _, item in ipairs(drillItems) do
  1642. local itemID = item[1]
  1643. local itemCnt = item[2] * rewardCnt
  1644. if itemID == ItemDefine.ITEM_GREEN_EXP_ID then
  1645. itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul)
  1646. end
  1647. -- 累加奖励到列表
  1648. itemList[itemID] = (itemList[itemID] or 0) + itemCnt
  1649. drill.dayGet[itemID] = (drill.dayGet[itemID] or 0) + itemCnt
  1650. end
  1651. end
  1652. end
  1653. -- 使用 addItemList 添加奖励,会自动显示奖励弹窗
  1654. if next(itemList) then
  1655. BagLogic.addItemList(human, itemList, "drill")
  1656. end
  1657. -- 发送奖励消息
  1658. local msgRet = Msg.gc.GC_DRILL_ONE_CLICK_SAODANG
  1659. msgRet.drillId = maxSaodangId
  1660. msgRet.double = double and 1 or 0
  1661. local len = 0
  1662. local itemInfo = ""
  1663. for k, v in pairs(drill.dayGet) do
  1664. len = len + 1
  1665. Grid.makeItem(msgRet.itemList[len], k, v)
  1666. if len > 1 then itemInfo = itemInfo .. ", " end
  1667. itemInfo = itemInfo .. "itemID="..k..", count="..v
  1668. end
  1669. msgRet.itemList[0] = len
  1670. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 发送协议数据: drillId="..msgRet.drillId..", double="..msgRet.double..", itemCount="..len..", items=["..itemInfo.."]")
  1671. Msg.send(msgRet, human.fd)
  1672. -- 更新关卡ID(已经在发放奖励前检查过了,这里直接更新)
  1673. local oldDrillId = drillData.drillId
  1674. drillData.drillId = newDrillId
  1675. drill.drillId = newDrillId
  1676. DrillDB.updateDrillData(drillData)
  1677. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 更新关卡ID: "..currentDrillId.." -> "..newDrillId.." (drillData.drillId: "..(oldDrillId or "nil").." -> "..newDrillId..")")
  1678. -- 检查是否全部通关
  1679. if newDrillId > maxDrillID then
  1680. --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 扫荡后已全部通关: newDrillId="..newDrillId.." > maxDrillID="..maxDrillID)
  1681. else
  1682. --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 扫荡后未全部通关: newDrillId="..newDrillId.." <= maxDrillID="..maxDrillID..", 可以手动挑战")
  1683. end
  1684. -- 设置扫荡完成标记(用于防止重复扫荡)
  1685. drill.oneClickSaodangDone = true
  1686. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 设置扫荡完成标记: oneClickSaodangDone=true")
  1687. -- 如果通关所有关卡,触发通关回调
  1688. if newDrillId > maxDrillID then
  1689. --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 触发通关回调: newDrillId="..newDrillId.." > maxDrillID="..maxDrillID)
  1690. tongGuan(human, diff)
  1691. ChengjiuLogic.onCallback(human, ChengjiuDefine.CJ_TASK_TYPE_17, 1)
  1692. HeroLogLogic.finishTaskCB(human, HeroLogLogic.HERO_LOG_TYPE_5, 1)
  1693. --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 通关回调执行完成")
  1694. else
  1695. --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 未触发通关回调: newDrillId="..newDrillId.." <= maxDrillID="..maxDrillID)
  1696. end
  1697. -- 更新数据
  1698. queryDrillId(human)
  1699. -- 触发相关回调
  1700. YunYingLogic.onCallBack(human, "onDrill", maxSaodangId)
  1701. RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1204)
  1702. -- 更新任务进度(扫荡了maxSaodangId个关卡,每个关卡胜利一次)
  1703. for i = 1, maxSaodangId do
  1704. LiLianLogic.onCallback(human, LiLianLogic.LILIAN_OUTID11, 1, diff)
  1705. DailyTaskLogic.recordDailyTaskFinishCnt(human, DailyTaskLogic.DAILY_TASK_ID_11, 1)
  1706. HeroGrowUp.onCallback(human, HeroGrowUp.TASKTYPE16, 1)
  1707. MengxinLogic.onCallBack(human, MengxinLogic.MX_TASK_TYPE_8, i)
  1708. WeekTaskLogic.recordWeekTaskFinishCnt(human, WeekTaskLogic.WEEK_TASK_ID_8, 1)
  1709. -- 触发勇者试炼击杀守卫事件(用于主线任务)
  1710. TriggerLogic.PublishEvent(TriggerDefine.DRILL_KILL_SHOUWEI, human.db._id, 1)
  1711. end
  1712. -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 任务进度已更新: 扫荡关卡数="..maxSaodangId)
  1713. end