ServerCommerceActBattleGroundNS.lua 28 KB

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