ServerCommerceActBattleGroundNS.lua 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  1. -- 跨服商业活动-巅峰战场
  2. -- db
  3. -- human.db.ServerCommerce.battleGround = {
  4. -- heroBag = {}, -- 英雄背包
  5. -- isHaveNewHero = false, -- 是否获得新英雄
  6. -- unLockIdx = 0, -- 英雄解锁层数
  7. -- freeChallengeCnt = 5, -- 免费挑战次数
  8. -- lastResetTime = 1123156, -- 上一次重置免费挑战次数的时间戳
  9. -- lineUp = { -- 战斗阵容数据
  10. -- formation = 1,
  11. -- heroList = {},
  12. -- },
  13. -- matchList = {rank1, rank2, rank3, rank4, rank5}, -- 对手列表
  14. -- }
  15. local Msg = require("core.Msg")
  16. local Timer = require("core.Timer")
  17. local Config = require("Config")
  18. local Grid = require("bag.Grid")
  19. local BagLogic = require("bag.BagLogic")
  20. local ObjHuman = require("core.ObjHuman")
  21. local MailExcel = require("excel.mail")
  22. local MailManager = require("mail.MailManager")
  23. local Util = require("common.Util")
  24. local Lang = require("common.Lang")
  25. local Broadcast = require("broadcast.Broadcast")
  26. local InnerMsg = require("core.InnerMsg")
  27. local RoleHeadLogic = require("role.RoleHeadLogic")
  28. local ServerCommerceManager = require("serverCommerce.ServerCommerceManager")
  29. local ServerCommerceActDefine = require("serverCommerce.ServerCommerceActDefine")
  30. local battleGroundConfig = require("excel.ServerCommerceBattleGround")
  31. local MonsterExcel = require("excel.monster")
  32. local HeroConfig = require("excel.hero").hero
  33. local HeroDefine = require("hero.HeroDefine")
  34. local CombatDefine = require("combat.CombatDefine")
  35. local CombatLogic = require("combat.CombatLogic")
  36. local CombatPosLogic = require("combat.CombatPosLogic")
  37. local MiddleCommonLogic = require("middle.MiddleCommonLogic")
  38. local RoleDBLogic = require("role.RoleDBLogic")
  39. local Log = require("common.Log")
  40. local lua_mongo = _G.lua_mongo
  41. local rankListCache = {}
  42. local lastGetRankListTime = 0
  43. local LOGTYPE = "ServerCommerceActBattleGround"
  44. local function writeLog(logStr)
  45. Log.write(Log.LOGID_OSS_COMMON_ACT, logStr)
  46. end
  47. -- 玩家排名下降, 通过邮件通知
  48. local function rankReduceMail(mailId, receiverUuid, arg)
  49. if not mailId or not receiverUuid then
  50. return
  51. end
  52. local mailCfg = MailExcel.mail[mailId]
  53. local content = mailCfg.content
  54. if arg then
  55. content = Util.format(content, arg[1], arg[2], arg[3])
  56. end
  57. MailManager.add(MailManager.SYSTEM, receiverUuid, mailCfg.title, content, nil, mailCfg.senderName or "GM")
  58. end
  59. -- 排行奖励邮件
  60. local function sendAwardMail(mailId, receiverUuid, rank, itemArray)
  61. local mailCfg = MailExcel.mail[mailId]
  62. local content = mailCfg.content
  63. content = Util.format(content, rank or ServerCommerceActDefine.COMMERCEACT_NPC_CNT)
  64. MailManager.add(MailManager.SYSTEM, receiverUuid, mailCfg.title, content, itemArray, mailCfg.senderName or "GM")
  65. end
  66. -- 创建一个发奖queue
  67. local function createRewardQueue()
  68. local issueRewardQueue = {
  69. playerArray = {},
  70. insertMaxNum = 100, -- 一次最多插入数据库的邮件数量
  71. repeatMaxTimes = 3, -- 重试次数
  72. repeatTb = {},
  73. extraInfo = {},
  74. }
  75. function issueRewardQueue:add(playerInfo)
  76. table.insert(self.playerArray, playerInfo)
  77. end
  78. function issueRewardQueue:insertDB()
  79. local maxNum = math.min(self.insertMaxNum, #self.playerArray)
  80. local mailId = battleGroundConfig.var[1].rankAwardMailId
  81. for i=1, maxNum do
  82. local resTag = ServerCommerceActDefine.BG_MAIL_SUCC_TAG
  83. local playerInfo = table.remove(self.playerArray)
  84. local playerUuid = playerInfo[2]
  85. local ok, err = pcall(sendAwardMail, mailId, playerUuid, playerInfo[1], playerInfo[3])
  86. if not ok then
  87. if not self.repeatTb[playerUuid] or self.repeatTb[playerUuid] < self.repeatMaxTimes then
  88. issueRewardQueue:add(playerInfo)
  89. self.repeatTb[playerUuid] = (self.repeatTb[playerUuid] or 0) + 1
  90. end
  91. resTag = ServerCommerceActDefine.BG_MAIL_FAIL_TAG
  92. end
  93. -- 写入日志
  94. local str = string.format("ServerCommerceActBattleGround PrizeAward result: %s, playerUuid: %s, insertErrTimes: %d, errInfo: %s",
  95. resTag, playerUuid, self.repeatTb[playerUuid] or 0, err)
  96. writeLog(str)
  97. end
  98. if #self.playerArray > 0 then
  99. Timer.addLater(2, self.insertDB, self)
  100. end
  101. end
  102. return issueRewardQueue
  103. end
  104. -- 是否处于活动中
  105. local function isRunning()
  106. return true == ServerCommerceManager.CommerceAct_IsRun()
  107. end
  108. -- 生成对手算法
  109. local function matchListAlgorithm(rank)
  110. -- 输入验证
  111. if not rank or type(rank) ~= "number" or rank < 1 or rank > (ServerCommerceActDefine.COMMERCEACT_NPC_CNT + 1) then
  112. return {} -- 返回空列表或根据需求处理错误
  113. end
  114. local matchList = {}
  115. local usedRanks = {}
  116. -- 确保玩家自己不会被选为对手
  117. usedRanks[rank] = true
  118. -- 计算抽取范围
  119. local minRank = math.max(1, rank - 50)
  120. local maxRank = math.min(ServerCommerceActDefine.COMMERCEACT_NPC_CNT, rank + 10)
  121. -- 生成所有可能的对手排名
  122. local possibleRanks = {}
  123. for i = minRank, maxRank do
  124. if not usedRanks[i] then
  125. table.insert(possibleRanks, i)
  126. end
  127. end
  128. -- 如果可用对手不足5个,则返回所有可能的对手
  129. local numToSelect = math.min(5, #possibleRanks)
  130. if numToSelect == 0 then
  131. return {}
  132. end
  133. -- 随机抽取指定数量的对手
  134. for i = 1, numToSelect do
  135. -- 从剩余可选排名中随机选择一个
  136. local randomIndex = math.random(#possibleRanks)
  137. local selectedRank = possibleRanks[randomIndex]
  138. -- 添加到匹配列表
  139. table.insert(matchList, selectedRank)
  140. -- 从可选列表中移除已选中的排名
  141. table.remove(possibleRanks, randomIndex)
  142. -- 标记为已使用
  143. usedRanks[selectedRank] = true
  144. end
  145. table.sort( matchList, function (a, b)
  146. return a > b
  147. end)
  148. return matchList
  149. end
  150. -- 生成一个英雄模板数据
  151. local function genHeroGrid(heroId)
  152. local obj = {}
  153. obj[1] = heroId
  154. obj[2] = lua_mongo.id()
  155. return obj
  156. end
  157. -- 遍历
  158. local function findVal(list, val)
  159. for k, info in pairs(list or {}) do
  160. if info[1] == val then
  161. return k
  162. end
  163. end
  164. end
  165. -- 填充协议英雄数据
  166. local function populateHeroMsg(net, heroInfo, heroConfig, heroLv, heroStar, heroBagIdx)
  167. net.heroHeadId = heroConfig.head
  168. net.heroName = heroConfig.name
  169. net.heroCamp = heroConfig.camp
  170. net.heroLv = heroLv
  171. net.heroStar = heroStar
  172. net.heroGrade = heroConfig.grade or 0
  173. net.heroBodyId = heroConfig.body
  174. net.heroId = heroInfo[1] or 0
  175. net.heroUuid = heroInfo[2] or ""
  176. net.heroBagIdx = heroBagIdx or 0
  177. net.heroJob = heroConfig.job or 1
  178. end
  179. -- 获取可以解锁的英雄信息
  180. local function getUnlockHeroInfoByRank(rank)
  181. local unLockHero = battleGroundConfig.unLockHero
  182. for idx, cfg in ipairs(unLockHero) do
  183. if rank >= cfg.unLockRankArea[1] and rank <= cfg.unLockRankArea[2] then
  184. return idx, cfg.unLockHeroInfo
  185. end
  186. end
  187. end
  188. -- 解锁英雄
  189. local function unlockHero(human, unlockHeroInfo, isInit)
  190. human.db.ServerCommerce.battleGround = human.db.ServerCommerce.battleGround or {}
  191. local battleGroundData = human.db.ServerCommerce.battleGround
  192. battleGroundData.heroBag = battleGroundData.heroBag or {}
  193. local heroBagData = battleGroundData.heroBag
  194. if #unlockHeroInfo == 0 then
  195. for heroId, heroCfg in pairs(HeroConfig) do
  196. if heroCfg.grade >= HeroDefine.HERO_SSR_GRADE and not findVal(heroBagData, heroId) then
  197. heroBagData[#heroBagData+1] = genHeroGrid(heroId)
  198. end
  199. end
  200. battleGroundData.isHaveNewHero = true
  201. return
  202. end
  203. -- local heroList = {}
  204. local heroArr = {}
  205. for heroId, heroCfg in pairs(HeroConfig) do
  206. if heroCfg.grade >= HeroDefine.HERO_SSR_GRADE and not findVal(heroBagData, heroId) then
  207. -- heroList[heroId] = heroCfg
  208. heroArr[#heroArr+1] = {heroId, heroCfg}
  209. end
  210. end
  211. table.shuffle(heroArr)
  212. for _, heroCond in ipairs(unlockHeroInfo) do
  213. local campCond = heroCond[1] or 0
  214. local numCond = heroCond[2] or 0
  215. for i=1, numCond do
  216. for _, heroData in ipairs(heroArr) do
  217. local heroId = heroData[1]
  218. local heroCfg = heroData[2]
  219. if heroCfg.camp == campCond and not findVal(heroBagData, heroId) then
  220. heroBagData[#heroBagData+1] = genHeroGrid(heroId)
  221. break
  222. end
  223. end
  224. end
  225. end
  226. battleGroundData.isHaveNewHero = true
  227. if isInit then
  228. battleGroundData.isHaveNewHero = false
  229. end
  230. end
  231. -- 获取上阵英雄
  232. local function getLineupHeroArr(human)
  233. local heroArr
  234. local heroList = CombatPosLogic.getCombatHeros(human, CombatDefine.COMBAT_TYPE37)
  235. for _, heroUuid in ipairs(heroList) do
  236. if heroUuid and heroUuid ~= "" and heroUuid ~= "0" then
  237. local heroGrid = getHeroGridByUuid(human, heroUuid)
  238. if heroGrid then
  239. heroArr = heroArr or {}
  240. heroArr[#heroArr+1] = heroGrid.id
  241. end
  242. end
  243. end
  244. return heroArr
  245. end
  246. -- 生成玩家的展示数据
  247. local function populatePlayerShowData(human, showData, rank)
  248. showData.rank = rank
  249. showData.serverId = Config.SVR_INDEX
  250. showData.playerUuid = human.db._id
  251. showData.name = human.db.name
  252. showData.bodyId = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_3) or 0
  253. showData.headId = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_1) or 0
  254. showData.headFrameId = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_2) or 0
  255. showData.heroArr = {}
  256. showData.heroArr = getLineupHeroArr(human)
  257. end
  258. -- 战斗结束处理
  259. local function fightEndHanle(human, result)
  260. local msgData = InnerMsg.lw.LW_BATTLEGROUND_CHALLENGE_END
  261. msgData.sourceServerId = Config.SVR_INDEX
  262. msgData.playerUuid = human.db._id
  263. msgData.atkRank = human.battleGroundRank
  264. msgData.defRank = human.battleGroundCache.defRank
  265. msgData.challengeRes = CombatDefine.RESULT_WIN
  266. msgData.playerShowData = {}
  267. local varCfg = battleGroundConfig.var[1]
  268. local challengeAward = varCfg.defeatAward
  269. if result == CombatDefine.RESULT_WIN then
  270. human.battleGroundRank = human.battleGroundCache.defRank
  271. local newMatchList = matchListAlgorithm(human.battleGroundRank)
  272. -- 更新对手列表
  273. local battleGroundData = human.db.ServerCommerce.battleGround
  274. battleGroundData.matchList = newMatchList
  275. -- 检查是否能解锁新英雄
  276. local idx, unlockHeroInfo = getUnlockHeroInfoByRank(human.battleGroundRank)
  277. if idx ~= battleGroundData.unLockIdx then
  278. unlockHero(human, unlockHeroInfo)
  279. battleGroundData.unLockIdx = idx
  280. end
  281. -- 展示数据
  282. populatePlayerShowData(human, msgData.playerShowData, human.battleGroundCache.defRank)
  283. -- 挑战奖励
  284. challengeAward = varCfg.winAward
  285. end
  286. -- 发放挑战奖励
  287. local finalAwardArr = {}
  288. for i, itemInfo in ipairs(challengeAward) do
  289. finalAwardArr[i] = {itemInfo[1], itemInfo[2]}
  290. end
  291. BagLogic.addItemList(human, finalAwardArr, LOGTYPE)
  292. -- 通知跨服更新数据
  293. InnerMsg.sendMsg(0, msgData)
  294. end
  295. -- 获取排名奖励
  296. local function getRankAward(rank)
  297. local itemArr
  298. for i, cfg in ipairs(battleGroundConfig.rankAward) do
  299. if rank >= cfg.rankArea[1] and rank <= cfg.rankArea[2] then
  300. itemArr = {}
  301. for k, itemInfo in ipairs(cfg.rankAward) do
  302. itemArr[k] = {itemInfo[1], itemInfo[2]}
  303. end
  304. break
  305. end
  306. end
  307. return itemArr
  308. end
  309. function updateDaily(human)
  310. if not isRunning() then
  311. return
  312. end
  313. local battleGroundData = human.db.ServerCommerce and human.db.ServerCommerce.battleGround
  314. if not battleGroundData then
  315. return
  316. end
  317. local lastResetTime = battleGroundData.lastResetTime
  318. if not Util.isSameDay(lastResetTime) then
  319. battleGroundData.freeChallengeCnt = ServerCommerceActDefine.COMMERCEACT_DAILY_FREECHALLENGETIMES
  320. battleGroundData.lastResetTime = os.time()
  321. end
  322. end
  323. -- 根据英雄uuid获取英雄信息
  324. function getHeroGridByUuid(human, heroUuid)
  325. if not isRunning() then
  326. return
  327. end
  328. if not human.db.ServerCommerce then
  329. return
  330. end
  331. local battleGroundData = human.db.ServerCommerce.battleGround
  332. if not battleGroundData.heroBag then
  333. return
  334. end
  335. local heroGrid
  336. local heroBagData = battleGroundData.heroBag
  337. for bagIdx, heroInfo in ipairs(heroBagData) do
  338. if heroInfo[2] == heroUuid then
  339. heroGrid = {
  340. id = heroInfo[1],
  341. bagIndex = bagIdx,
  342. uuid = heroInfo[2],
  343. zhandouli = 0
  344. }
  345. break
  346. end
  347. end
  348. return heroGrid
  349. end
  350. -- 根据英雄id获取英雄信息
  351. function getHeroGridByheroId(human, heroId)
  352. if not isRunning() then
  353. return
  354. end
  355. if not human.db.ServerCommerce then
  356. return
  357. end
  358. local battleGroundData = human.db.ServerCommerce.battleGround
  359. if not battleGroundData.heroBag then
  360. return
  361. end
  362. local heroGrid
  363. local heroBagData = battleGroundData.heroBag
  364. for bagIdx, heroInfo in ipairs(heroBagData) do
  365. if heroInfo[1] == heroId then
  366. heroGrid = {
  367. id = heroInfo[1],
  368. bagIndex = bagIdx,
  369. uuid = heroInfo[2]
  370. }
  371. break
  372. end
  373. end
  374. return heroGrid
  375. end
  376. -- 是否获得英雄
  377. function isGetHero(human, heroId)
  378. return getHeroGridByheroId(human, heroId)
  379. end
  380. -- 阵容有更新
  381. function onUpdatePos(human)
  382. BattleGround_Lineup_Update(human)
  383. end
  384. -- 推送主界面信息
  385. local function sendMainPageData(human)
  386. local msgRet = Msg.gc.GC_SERVEERCOMMERCE_ACT_BATTLEGROUND_MAINPAGE_QUERY
  387. msgRet.myRank = human.battleGroundRank or (ServerCommerceActDefine.COMMERCEACT_NPC_CNT + 1)
  388. msgRet.freeChallengeCnt = 0
  389. msgRet.showBodyId = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_3) or 0
  390. local battleGroundData = human.db.ServerCommerce and human.db.ServerCommerce.battleGround
  391. msgRet.freeChallengeCnt = battleGroundData and battleGroundData.freeChallengeCnt or ServerCommerceActDefine.COMMERCEACT_DAILY_FREECHALLENGETIMES
  392. Msg.send(msgRet, human.fd)
  393. end
  394. -- 推送排行榜数据
  395. local function sendRankListData(human)
  396. local msgRet = Msg.gc.GC_SERVEERCOMMERCE_ACT_BATTLEGROUND_RANK_QUERY
  397. msgRet.rankList[0] = 0
  398. msgRet.isEnd = 0
  399. msgRet.myRankInfo.rank = human.battleGroundRank
  400. msgRet.myRankInfo.serverId = Config.SVR_INDEX - ServerCommerceActDefine.BG_SERVERID_START
  401. msgRet.myRankInfo.name = human.db.name
  402. msgRet.myRankInfo.heroHeadId = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_1) or 0
  403. msgRet.myRankInfo.heroHeadFrameId = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_2) or 0
  404. local msgMaxLen = 20
  405. local len = 0
  406. local rankNum = #rankListCache
  407. for rank, rankInfo in ipairs(rankListCache) do
  408. len = len + 1
  409. msgRet.rankList[0] = len
  410. msgRet.rankList[len].rank = rank
  411. msgRet.rankList[len].serverId = rankInfo.serverId and (rankInfo.serverId - ServerCommerceActDefine.BG_SERVERID_START) or 1
  412. msgRet.rankList[len].name = rankInfo.name
  413. msgRet.rankList[len].heroHeadId = rankInfo.heroHeadId
  414. msgRet.rankList[len].heroHeadFrameId = rankInfo.heroHeadFrameId
  415. if len >= msgMaxLen then
  416. rankNum = rankNum - len
  417. if rankNum <= 0 then
  418. msgRet.isEnd = 1
  419. return Msg.send(msgRet, human.fd)
  420. end
  421. Msg.send(msgRet, human.fd)
  422. len = 0
  423. end
  424. end
  425. if len > 0 then
  426. msgRet.isEnd = 1
  427. Msg.send(msgRet, human.fd)
  428. end
  429. end
  430. -- 主界面信息查询
  431. function BattleGround_MainPage_Query(human)
  432. if not isRunning() then
  433. return Broadcast.sendErr(human, Lang.ACT_NOT_START)
  434. end
  435. if not human.battleGroundRank then
  436. local msgData = InnerMsg.lw.LW_BATTLEGROUND_PLAYER_RANK_QUERY
  437. msgData.sourceServerId = Config.SVR_INDEX
  438. msgData.playerUuid = human.db._id
  439. return InnerMsg.sendMsg(0, msgData)
  440. end
  441. sendMainPageData(human)
  442. end
  443. -- 匹配界面信息查询
  444. function BattleGround_MatchPage_Query(human)
  445. if not isRunning() then
  446. return Broadcast.sendErr(human, Lang.ACT_NOT_START)
  447. end
  448. local battleGroundData = human.db.ServerCommerce.battleGround
  449. if not battleGroundData.matchList or not next(battleGroundData.matchList) then
  450. battleGroundData.matchList = matchListAlgorithm(human.battleGroundRank)
  451. end
  452. local msgData = InnerMsg.lw.LW_BATTLEGROUND_MATCHLIST_QUERY
  453. msgData.sourceServerId = Config.SVR_INDEX
  454. msgData.playerUuid = human.db._id
  455. msgData.matchList = {}
  456. for _, rank in ipairs(battleGroundData.matchList) do
  457. msgData.matchList[#msgData.matchList+1] = rank
  458. end
  459. InnerMsg.sendMsg(0, msgData)
  460. end
  461. -- 匹配对手查询
  462. function BattleGround_Player_Query(human, targetRank)
  463. if not isRunning() then
  464. return Broadcast.sendErr(human, Lang.ACT_NOT_START)
  465. end
  466. local battleGroundData = human.db.ServerCommerce.battleGround
  467. if not table.find(battleGroundData.matchList, targetRank) then
  468. return Broadcast.sendErr(human, Lang.BG_MATCHLIST_ERR)
  469. end
  470. local msgData = InnerMsg.lw.LW_BATTLEGROUND_PLAYER_DATA_QUERY
  471. msgData.sourceServerId = Config.SVR_INDEX
  472. msgData.playerUuid = human.db._id
  473. msgData.playerRank = targetRank
  474. InnerMsg.sendMsg(0, msgData)
  475. end
  476. -- 请求挑战某个排名玩家
  477. function BattleGround_Try_Challenge(human, targetRank)
  478. local msgData = InnerMsg.lw.LW_BATTLEGROUND_CHALLENGE_QUERY
  479. msgData.sourceServerId = Config.SVR_INDEX
  480. msgData.playerUuid = human.db._id
  481. msgData.rank = targetRank
  482. InnerMsg.sendMsg(0, msgData)
  483. end
  484. -- 英雄背包查询
  485. function BattleGround_HeroBag_Query(human)
  486. if not isRunning() then
  487. return Broadcast.sendErr(human, Lang.ACT_NOT_START)
  488. end
  489. local battleGroundData = human.db.ServerCommerce.battleGround
  490. if not battleGroundData.heroBag then
  491. local idx, unlockHeroInfo = getUnlockHeroInfoByRank(human.battleGroundRank)
  492. if unlockHeroInfo then
  493. unlockHero(human, unlockHeroInfo, true)
  494. battleGroundData.unLockIdx = idx
  495. end
  496. end
  497. local msgRet = Msg.gc.GC_SERVEERCOMMERCE_ACT_BATTLEGROUND_HEROBAG_QUERY
  498. msgRet.heroArr[0] = 0
  499. msgRet.isEnd = 0
  500. local len, msgMaxLen = 0, 0
  501. local heroNum = #battleGroundData.heroBag
  502. for heroBagIdx, heroInfo in ipairs(battleGroundData.heroBag) do
  503. len = len + 1
  504. msgRet.heroArr[0] = len
  505. local heroConfig = HeroConfig[heroInfo[1]]
  506. populateHeroMsg(msgRet.heroArr[len], heroInfo, heroConfig, ServerCommerceActDefine.COMMERCEACT_HERO_LV, ServerCommerceActDefine.COMMERCEACT_HERO_STAR, heroBagIdx)
  507. if len >= msgMaxLen then
  508. heroNum = heroNum - len
  509. if heroNum <= 0 then
  510. msgRet.isEnd = 1
  511. return Msg.send(msgRet, human.fd)
  512. end
  513. Msg.send(msgRet, human.fd)
  514. len = 0
  515. end
  516. end
  517. if len > 0 then
  518. msgRet.isEnd = 1
  519. Msg.send(msgRet, human.fd)
  520. end
  521. end
  522. -- 排行榜查询
  523. function BattleGround_RankList_Query(human)
  524. if not isRunning() then
  525. return Broadcast.sendErr(human, Lang.ACT_NOT_START)
  526. end
  527. local now = os.time()
  528. if #rankListCache == 0 or now - lastGetRankListTime >= ServerCommerceActDefine.COMMERCEACT_RANKUPDATE then
  529. local msgData = InnerMsg.lw.LW_BATTLEGROUND_RANKLIST_QUERY
  530. msgData.sourceServerId = Config.SVR_INDEX
  531. msgData.playerUuid = human.db._id
  532. return InnerMsg.sendMsg(0, msgData)
  533. end
  534. sendRankListData(human)
  535. end
  536. -- 排行奖励查询
  537. function BattleGround_RankAward_Query(human)
  538. if not isRunning() then
  539. return Broadcast.sendErr(human, Lang.ACT_NOT_START)
  540. end
  541. local msgRet = Msg.gc.GC_SERVEERCOMMERCE_ACT_BATTLEGROUND_RANKAWARD_QUERY
  542. msgRet.rankAwardList[0] = 0
  543. msgRet.rankAwardList[0] = #battleGroundConfig.rankAward
  544. for i, cfg in ipairs(battleGroundConfig.rankAward) do
  545. msgRet.rankAwardList[i].minRank = cfg.rankArea[1]
  546. msgRet.rankAwardList[i].maxRank = cfg.rankArea[2]
  547. msgRet.rankAwardList[i].rankAward[0] = #cfg.rankAward
  548. for k, itemInfo in ipairs(cfg.rankAward) do
  549. Grid.makeItem(msgRet.rankAwardList[i].rankAward[k], itemInfo[1], itemInfo[2])
  550. end
  551. end
  552. Msg.send(msgRet, human.fd)
  553. end
  554. -- 更新阵容数据
  555. function BattleGround_Lineup_Update(human, msg)
  556. if not isRunning() then
  557. return
  558. end
  559. -- local battleGroundData = human.db.ServerCommerce.battleGround
  560. -- local formation = msg.formation
  561. -- local posList = CombatPosLogic.getPosList(formation)
  562. -- local heroList = Util.split(msg.heroList, ",", true)
  563. -- local reapetTb = {}
  564. -- for i = 1, CombatDefine.COMBAT_HERO_CNT do
  565. -- local heroId = heroList[i]
  566. -- if heroId > 0 then
  567. -- -- 英雄Id检测
  568. -- if HeroConfig[heroId] then
  569. -- return Broadcast.sendErr(human, Lang.FUWEN_HERO_GRID_ERR)
  570. -- end
  571. -- -- 英雄背包检测
  572. -- if not battleGroundData.heroBag or not table.find(battleGroundData.heroBag, heroId) then
  573. -- return Broadcast.sendErr(human, Lang.FUWEN_HERO_GRID_ERR)
  574. -- end
  575. -- -- 相同英雄检测
  576. -- if reapetTb[heroId] then
  577. -- return Broadcast.sendErr(human, Lang.HERO_SAME)
  578. -- end
  579. -- -- 位置检测
  580. -- if posList[i] == nil and i ~= CombatDefine.COMBAT_HERO_CNT then
  581. -- return Broadcast.sendErr(human, Lang.POS_ERROR)
  582. -- end
  583. -- reapetTb[heroId] = true
  584. -- end
  585. -- end
  586. -- battleGroundData.lineUp = battleGroundData.lineUp or {}
  587. -- battleGroundData.lineUp.formation = formation
  588. -- battleGroundData.lineUp.heroList = heroList
  589. -- 通知跨服更新
  590. if human.battleGroundRank and human.battleGroundRank <= ServerCommerceActDefine.COMMERCEACT_NPC_CNT then
  591. local msgData = InnerMsg.lw.LW_BATTLEGROUND_LINEUP_UPDATE
  592. msgData.sourceServerId = Config.SVR_INDEX
  593. msgData.playerUuid = human.db._id
  594. msgData.heroArr = getLineupHeroArr(human)
  595. InnerMsg.sendMsg(0, msgData)
  596. end
  597. end
  598. -- 活动结束
  599. function Act_End()
  600. local msgData = InnerMsg.lw.LW_BATTLEGROUND_ACT_END
  601. msgData.sourceServerId = Config.SVR_INDEX
  602. InnerMsg.sendMsg(0, msgData)
  603. end
  604. -----------------------------------------------C2N-------------------------------------------------------
  605. -- 跨服返回玩家排名数据
  606. function BG_C2N_PlayerRank_Res(msg)
  607. local human = ObjHuman.onlineUuid[msg.playerUuid]
  608. if not human then
  609. return
  610. end
  611. human.battleGroundRank = msg.playerRank
  612. sendMainPageData(human)
  613. end
  614. -- 跨服返回对手列表数据
  615. function BG_C2N_MatchList_Res(msg)
  616. local human = ObjHuman.onlineUuid[msg.playerUuid]
  617. if not human then
  618. return
  619. end
  620. local msgRet = Msg.gc.GC_SERVEERCOMMERCE_ACT_BATTLEGROUND_MATCHLIST_QUERY
  621. msgRet.myRank = human.battleGroundRank or (ServerCommerceActDefine.COMMERCEACT_NPC_CNT + 1)
  622. msgRet.freeChallengeCnt = 0
  623. msgRet.isGetNew = 0
  624. msgRet.matchList[0] = 0
  625. local battleGroundData = human.db.ServerCommerce and human.db.ServerCommerce.battleGround
  626. local costItem = battleGroundConfig.var[1].cost
  627. Grid.makeItem(msgRet.exchangeCost, costItem[1], costItem[2])
  628. msgRet.freeChallengeCnt = battleGroundData and battleGroundData.freeChallengeCnt or ServerCommerceActDefine.COMMERCEACT_DAILY_FREECHALLENGETIMES
  629. msgRet.isGetNew = battleGroundData and battleGroundData.isHaveNewHero and 1 or 0
  630. msgRet.matchList[0] = #msg.playerInfoList
  631. for i, rankInfo in ipairs(msg.playerInfoList) do
  632. msgRet.matchList[i].rank = rankInfo.rank
  633. msgRet.matchList[i].serverId = rankInfo.serverId and (rankInfo.serverId - ServerCommerceActDefine.BG_SERVERID_START) or 1
  634. msgRet.matchList[i].name = rankInfo.name
  635. msgRet.matchList[i].showBodyId = rankInfo.showBodyId
  636. end
  637. Msg.send(msgRet, human.fd)
  638. end
  639. -- 跨服返回单个对手数据
  640. function BG_C2N_PlayerData_Res(msg)
  641. local human = ObjHuman.onlineUuid[msg.playerUuid]
  642. if not human then
  643. return
  644. end
  645. local playerInfo = msg.playerInfo
  646. local msgRet = Msg.gc.GC_SERVEERCOMMERCE_ACT_BATTLEGROUND_PLAYER_QUERY
  647. msgRet.serverId = playerInfo.serverId and (playerInfo.serverId - ServerCommerceActDefine.BG_SERVERID_START) or 1
  648. msgRet.name = playerInfo.name
  649. msgRet.heroHeadId = playerInfo.heroHeadId
  650. msgRet.heroHeadFrameId = playerInfo.heroHeadFrameId
  651. msgRet.heroArr[0] = 0
  652. msgRet.isQuick = human.db.combatQuick and human.db.combatQuick[CombatDefine.COMBAT_TYPE37] or 0
  653. local heroInfo = {0}
  654. if playerInfo.monsteroutId == 0 then -- 真实玩家
  655. msgRet.heroArr[0] = #playerInfo.heroArr
  656. for i, heroId in ipairs(playerInfo.heroArr) do
  657. local heroConfig = HeroConfig[heroId]
  658. heroInfo[1] = heroId
  659. populateHeroMsg(msgRet.heroArr[i], heroInfo, heroConfig, ServerCommerceActDefine.COMMERCEACT_HERO_LV, ServerCommerceActDefine.COMMERCEACT_HERO_STAR)
  660. end
  661. else
  662. local monsterOutConfig = MonsterExcel.monsterOut[playerInfo.monsteroutId]
  663. msgRet.heroArr[0] = #monsterOutConfig.member
  664. for i, monsterInfo in ipairs(monsterOutConfig.member) do
  665. local monsterID = monsterInfo[1]
  666. local mcf = MonsterExcel.monster[monsterID]
  667. heroInfo[1] = monsterID
  668. populateHeroMsg(msgRet.heroArr[i], heroInfo, mcf, monsterInfo[2], mcf.star)
  669. end
  670. end
  671. Msg.send(msgRet, human.fd)
  672. end
  673. -- 跨服返回排行榜数据
  674. function BG_C2N_RankList_Res(msg)
  675. rankListCache = msg.rankList
  676. lastGetRankListTime = os.time()
  677. local human = ObjHuman.onlineUuid[msg.playerUuid]
  678. if not human then
  679. return
  680. end
  681. sendRankListData(human)
  682. end
  683. -- 跨服返回请求战斗结果
  684. function BG_C2N_Challenge_Res(msg)
  685. local human = ObjHuman.onlineUuid[msg.playerUuid]
  686. if not human then
  687. return
  688. end
  689. if msg.errCode ~= 0 then
  690. return Broadcast.sendErr(human, Lang.BG_MATCHLIST_ERR)
  691. end
  692. local playerUuid = msg.playerInfo.playerUuid
  693. local defServerId = msg.playerInfo.defServerId
  694. human.battleGroundCache = {
  695. defRank = msg.playerInfo.rank
  696. }
  697. if defServerId ~= 0 then -- 真实玩家
  698. local args = {
  699. combatType = CombatDefine.COMBAT_TYPE37,
  700. nServerIndex = defServerId,
  701. param = playerUuid
  702. }
  703. MiddleCommonLogic.MiddleCommonLogic_CombatBegin_LW(human, args)
  704. else
  705. CombatLogic.combatBegin(human, nil, {playerUuid}, CombatDefine.COMBAT_TYPE37)
  706. end
  707. end
  708. -- 跨服通知玩家排名下降
  709. function BG_C2N_RankReduce(msg)
  710. local human = ObjHuman.onlineUuid[msg.playerUuid]
  711. if not human then
  712. local db = RoleDBLogic.getDb(msg.playerUuid)
  713. if not db then
  714. return
  715. end
  716. human = {}
  717. human.db = db
  718. end
  719. -- 更新对手列表
  720. local battleGroundData = human.db.ServerCommerce.battleGround
  721. battleGroundData.matchList = matchListAlgorithm(msg.newRank)
  722. -- 邮件通知
  723. local varCfg = battleGroundConfig.var[1]
  724. local arg = {msg.atkeServerId - 810537, msg.atkName, msg.newRank}
  725. rankReduceMail(varCfg.defeatMailId, human.db._id, arg)
  726. -- 玩家在线
  727. if human.fd then
  728. human.battleGroundRank = msg.newRank
  729. return
  730. end
  731. -- 玩家不在线,则保存数据
  732. ObjHuman.save(human)
  733. end
  734. -- 跨服通知发奖
  735. function BG_C2N_PrizeAward(msg)
  736. local playerArr = msg.playerArr
  737. if not next(playerArr) then
  738. return
  739. end
  740. local issueRewardQueue = createRewardQueue()
  741. for _, playerInfo in ipairs(playerArr) do
  742. local itemArr = getRankAward(playerInfo[1])
  743. if itemArr then
  744. playerInfo[3] = itemArr
  745. issueRewardQueue:add(playerInfo)
  746. end
  747. end
  748. issueRewardQueue:insertDB()
  749. end
  750. ----------------------------------战斗-----------------------------------
  751. function fight(human, args, combatType)
  752. if combatType ~= CombatDefine.COMBAT_TYPE37 then
  753. return Broadcast.sendErr(human, Lang.BG_COMBAT_TYPE_ERR)
  754. end
  755. local targetRank = tonumber(args[1])
  756. local battleGroundData = human.db.ServerCommerce.battleGround
  757. if not targetRank or not table.find(battleGroundData.matchList, targetRank) then
  758. return Broadcast.sendErr(human, Lang.BG_MATCHLIST_ERR)
  759. end
  760. -- if not battleGroundData.lineUp then
  761. -- return Broadcast.sendErr(human, Lang.SEAL_GROUND_COMBAT_HERO_ERR)
  762. -- end
  763. local heroList = CombatPosLogic.getCombatHeros(human, combatType)
  764. if not next(heroList) then
  765. return Broadcast.sendErr(human, Lang.SEAL_GROUND_COMBAT_HERO_ERR)
  766. end
  767. if battleGroundData.freeChallengeCnt <= 0 then
  768. local costItem = battleGroundConfig.var[1].cost
  769. local itemId, itemNum = costItem[1], costItem[2]
  770. if BagLogic.getItemCnt(human, itemId) < itemNum then
  771. return Broadcast.sendErr(human, Lang.BG_CONDITION_ERR)
  772. end
  773. BagLogic.delItem(human, itemId, itemNum, LOGTYPE)
  774. else
  775. battleGroundData.freeChallengeCnt = battleGroundData.freeChallengeCnt - 1
  776. end
  777. BattleGround_Try_Challenge(human, targetRank)
  778. end
  779. function getCombatMonsterOutID(human, side, args)
  780. if side ~= CombatDefine.DEFEND_SIDE then return end
  781. return args[1]
  782. end
  783. function getCombatObjList(human, side, args, combatType)
  784. if side == CombatDefine.ATTACK_SIDE and not human then return end
  785. if side == CombatDefine.DEFEND_SIDE and human then
  786. return
  787. end
  788. if not human then
  789. local uuid = args[1]
  790. local db = RoleDBLogic.getDb(uuid)
  791. if not db then
  792. return
  793. end
  794. human = {}
  795. human.db = db
  796. end
  797. -- local battleGroundData = human.db.ServerCommerce.battleGround
  798. -- local lineUpData = battleGroundData.lineUp
  799. -- if not lineUpData.heroList or not lineUpData.formation then
  800. -- return
  801. -- end
  802. local heroList, _, formation = CombatPosLogic.getCombatHeros(human, combatType)
  803. if not next(heroList) then
  804. return Broadcast.sendErr(human, Lang.SEAL_GROUND_COMBAT_HERO_ERR)
  805. end
  806. local fakeHuman = { db = {} }
  807. local objList = {}
  808. for i = 1, CombatDefine.COMBAT_HERO_CNT do
  809. local heroUuid = heroList[i]
  810. if heroUuid and heroUuid ~= "" and heroUuid ~= "0" then
  811. local heroInfo = getHeroGridByUuid(human, heroUuid)
  812. if not heroInfo then
  813. return Broadcast.sendErr(human, Lang.SEAL_GROUND_COMBAT_HERO_ERR)
  814. end
  815. objList[i] = CombatLogic.createHeroObj(fakeHuman, heroInfo.id, ServerCommerceActDefine.COMMERCEACT_HERO_LV, ServerCommerceActDefine.COMMERCEACT_HERO_STAR, i)
  816. end
  817. end
  818. local rolebase = CombatLogic.createRoleBaseByDB(human.db)
  819. return objList, nil, rolebase, formation
  820. end
  821. function onFightEnd(human, result, type, cbParam, combatInfo)
  822. local battleGroundCache = human.battleGroundCache
  823. if not battleGroundCache then
  824. return Broadcast.sendErr(human, Lang.DATA_ERR)
  825. end
  826. fightEndHanle(human, result)
  827. end