KunDun.lua 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  1. KunDun = {}
  2. local dataFunc = {}
  3. local this = {}
  4. --巨龙
  5. local FACTION_TYPE_JL = 1
  6. --猎鹰
  7. local FACTION_TYPE_LY = 2
  8. --苍狼
  9. local FACTION_TYPE_CL = 3
  10. local KUN_DUN_REP_TYPE = 21001
  11. --阵营人数数量存储
  12. local CROSS_FACTION_PLAYERS_TAG = "R$_CROSS_FACTIONS_PLAYERS"
  13. --昆顿副本状态
  14. local CROSS_STATE_TAG = "G$_CROSS_STATE"
  15. --昆顿副本玩家数据
  16. local KUNDUN_TAG = "R$_CROSS_KUNDUN_DUP"
  17. -- 昆顿副本心跳间隔记录
  18. local LAST_HEART_BEAT_TIME = "G$_KUN_DUN_LAST_HEART_MILLS"
  19. local HURT_INTEGRAL_ID = 21001001
  20. local KILL_INTEGRAL_ID = 21001002
  21. local REWARD_ID = 21001003
  22. local RANK_INTEGRAL_ID = 21001006;
  23. local RANK_FLUSH_SECONDS_ID = 21001007;
  24. -- 排行榜最小刷新间隔
  25. local RANK_FLUSH_MIN_SECONDS = 3
  26. KunDun.TaskStage = {
  27. DEFAULT = 0,
  28. DUP_FINISH = 1,
  29. ALL_FINISH = 2,
  30. }
  31. function dataFunc.getCrossGlobalData(key)
  32. local serverType = string.tonumber(getbaseinfo("servertype"))
  33. local isCross = serverType == 2 and 1 or nil
  34. return getsysvar(key, isCross) or {}
  35. end
  36. function dataFunc.setCrossGlobalData(key, value)
  37. setsysvar(key, value, 1)
  38. -- 同步数据到所有主机
  39. local hosts = gethosts()
  40. for _, host in ipairs(hosts) do
  41. setsysvar(host, key, value)
  42. end
  43. end
  44. function dataFunc.getAllKunDunData()
  45. return dataFunc.getCrossGlobalData(KUNDUN_TAG)
  46. end
  47. function dataFunc.setAllKunDunData(data)
  48. dataFunc.setCrossGlobalData(KUNDUN_TAG, data)
  49. end
  50. function dataFunc.getAllKunDunPlayerData()
  51. local data = dataFunc.getAllKunDunData()
  52. if data ~= nil then
  53. return data["players"] or {}
  54. else
  55. return {}
  56. end
  57. end
  58. function dataFunc.getKunDunTaskData()
  59. local data = dataFunc.getAllKunDunData()
  60. if data ~= nil then
  61. return data["task"] or {}
  62. else
  63. return {}
  64. end
  65. end
  66. function dataFunc.setKunDunTaskData(taskData)
  67. local data = dataFunc.getAllKunDunData()
  68. data["task"] = taskData
  69. dataFunc.setAllKunDunData(data)
  70. end
  71. function dataFunc.getKunDunPlayerData(actor)
  72. local id = actor:toString()
  73. local data = dataFunc.getAllKunDunPlayerData()
  74. local roleData = data[id]
  75. if roleData == nil then
  76. return {}
  77. else
  78. return roleData
  79. end
  80. end
  81. function dataFunc.setKunDunPlayerData(actor, roleData)
  82. local id = actor:toString()
  83. local data = dataFunc.getAllKunDunPlayerData()
  84. data[id] = roleData
  85. local allData = dataFunc.getAllKunDunData(data)
  86. allData["players"] = data
  87. dataFunc.setAllKunDunData(allData)
  88. end
  89. function dataFunc.getKunDunRankData()
  90. local data = dataFunc.getAllKunDunData()
  91. return data["rank"] or {}
  92. end
  93. function dataFunc.setKunDunRankData(rankList)
  94. local data = dataFunc.getAllKunDunData()
  95. data["rank"] = rankList
  96. dataFunc.setAllKunDunData(data)
  97. end
  98. function dataFunc.getAllKunDunFactionData()
  99. local data = dataFunc.getAllKunDunData()
  100. return data["faction"] or {}
  101. end
  102. function dataFunc.getKunDunFactionData(faction)
  103. local data = dataFunc.getAllKunDunData()
  104. local factionData = data["faction"] or {}
  105. return factionData[faction] or {}
  106. end
  107. function dataFunc.setKunDunFactionData(faction, data)
  108. local allData = dataFunc.getAllKunDunData()
  109. local factionData = allData["faction"] or {}
  110. factionData[faction] = data
  111. allData["faction"] = factionData
  112. dataFunc.setAllKunDunData(allData)
  113. end
  114. function dataFunc.getKunDunFactionRankData()
  115. local data = dataFunc.getAllKunDunData()
  116. return data["factionRank"] or {}
  117. end
  118. function dataFunc.setKunDunFactionRankData(rank)
  119. local allData = dataFunc.getAllKunDunData()
  120. allData["factionRank"] = rank
  121. dataFunc.setAllKunDunData(allData)
  122. end
  123. function dataFunc.setRankFlushInterval(data)
  124. setsysvar(LAST_HEART_BEAT_TIME, data)
  125. end
  126. function dataFunc.getRankFlushInterval()
  127. return getsysvar(LAST_HEART_BEAT_TIME) or 0
  128. end
  129. function dataFunc.addFactionPlayer(faction, rid)
  130. local data = dataFunc.getAllKunDunData()
  131. local factionData = data["factionPlayers"] or {}
  132. local ridList = factionData[faction] or {}
  133. table.insert(ridList, rid)
  134. factionData[faction] = ridList
  135. data["factionPlayers"] = factionData
  136. dataFunc.setAllKunDunData(data)
  137. end
  138. function dataFunc.getFactionPlayers(faction)
  139. local data = dataFunc.getAllKunDunData()
  140. local factionData = data["factionPlayers"] or {}
  141. return factionData[faction] or {}
  142. end
  143. function KunDun.getFactionData()
  144. return dataFunc.getCrossGlobalData(CROSS_FACTION_PLAYERS_TAG)
  145. end
  146. function KunDun.setFactionData(data)
  147. dataFunc.setCrossGlobalData(CROSS_FACTION_PLAYERS_TAG, data)
  148. end
  149. function KunDun.getKunDunState()
  150. return dataFunc.getCrossGlobalData(CROSS_STATE_TAG)
  151. end
  152. function KunDun.setKunDunState(start, mapId, x, y)
  153. local stateData = {
  154. start = start,
  155. mapId = mapId,
  156. x = x,
  157. y = y
  158. }
  159. dataFunc.setCrossGlobalData(CROSS_STATE_TAG, stateData)
  160. end
  161. -- ------------------------------------------------------------- --
  162. function KunDun.sendPanelData(actor, stage, nextTime)
  163. local resData = {}
  164. resData["stage"] = stage
  165. resData["nextStateStartTime"] = nextTime
  166. local taskData = dataFunc.getKunDunTaskData()
  167. resData["taskStage"] = taskData["stage"]
  168. local playerList = KunDun.calculateTop3RankList(actor)
  169. resData["playerRank"] = playerList
  170. local factionList = KunDun.calculateFactionRankList()
  171. resData["factionRank"] = factionList
  172. this.debug("KunDun.sendPanelData", resData)
  173. sendluamsg(actor, LuaMessageIdToClient.RES_KUN_DUN_PANEL_INFO, resData)
  174. end
  175. function KunDun.selectFaction()
  176. local factionData = KunDun.getFactionData()
  177. if table.isNullOrEmpty(factionData) then
  178. return math.random(FACTION_TYPE_JL, FACTION_TYPE_CL)
  179. else
  180. local minType
  181. local minCount
  182. for type, count in pairs(factionData) do
  183. if minType == nil then
  184. minType = type
  185. minCount = count
  186. else
  187. if count < minCount then
  188. minType = type
  189. minCount = count
  190. end
  191. end
  192. end
  193. return minType
  194. end
  195. end
  196. --function KunDun.addFactionPlayers(faction)
  197. -- local factionData = KunDun.getFactionData()
  198. -- local count = table.getValue(factionData, faction)
  199. -- if count == nil then
  200. -- count = 0
  201. -- end
  202. -- count = count + 1
  203. -- factionData[faction] = count
  204. -- KunDun.setFactionData(factionData)
  205. --end
  206. function KunDun.getHurtIntegralConfig()
  207. local integralConfigStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", HURT_INTEGRAL_ID)
  208. if string.isNullOrEmpty(integralConfigStr) then
  209. return nil, nil
  210. end
  211. local items = string.split(integralConfigStr, "#")
  212. local hurtHpPercent = tonumber(items[1])
  213. local integral = tonumber(items[2])
  214. return hurtHpPercent, integral
  215. end
  216. function KunDun.getKillIntegralConfig()
  217. local integralConfigStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", KILL_INTEGRAL_ID)
  218. if integralConfigStr == nil then
  219. return nil
  220. end
  221. return tonumber(integralConfigStr)
  222. end
  223. function KunDun.getRankIntegralLimit()
  224. local integral = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RANK_INTEGRAL_ID)
  225. if integral == nil then
  226. return nil
  227. end
  228. return tonumber(integral)
  229. end
  230. function KunDun.getRewardConfig(rank)
  231. local rewardString = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", REWARD_ID)
  232. if string.isNullOrEmpty(rewardString) then
  233. return
  234. end
  235. local rewardRanks = string.split(rewardString, "|")
  236. for _, rankRewardStr in pairs(rewardRanks) do
  237. local items = string.split(rankRewardStr, "#")
  238. if #items > 2 then
  239. local startRank = tonumber(items[1])
  240. local endRank = tonumber(items[2])
  241. if startRank <= rank and endRank >= rank then
  242. local index = 3
  243. local itemMap = {}
  244. while index <= #items do
  245. local itemId = tonumber(items[index])
  246. local itemCount = tonumber(items[index + 1])
  247. itemMap[itemId] = itemCount
  248. index = index + 2
  249. end
  250. return itemMap
  251. end
  252. end
  253. end
  254. return nil
  255. end
  256. function KunDun.isInKunDun(actor)
  257. local mapCfgId = getbaseinfo(actor, "mapid")
  258. local config = ConfigDataManager.getById("cfg_rep", KUN_DUN_REP_TYPE)
  259. if config == nil then
  260. return false
  261. end
  262. if tonumber(config["mapid"]) ~= mapCfgId then
  263. return false
  264. end
  265. local state = KunDun.getKunDunState()
  266. if state ~= nil and state.start then
  267. return true
  268. else
  269. return false
  270. end
  271. end
  272. function KunDun.addIntegralByHurt(actor, targetActor, totalHurt)
  273. local hurtHpPercent, integral = KunDun.getHurtIntegralConfig()
  274. local maxHP = getattrinfo(targetActor, "maxHP")
  275. local integralHurt = maxHP * hurtHpPercent / 10000
  276. if tonumber(totalHurt) >= integralHurt then
  277. local now = getbaseinfo("now")
  278. -- 个人记录
  279. local roleData = dataFunc.getKunDunPlayerData(actor)
  280. local integralTotal = roleData["integral"] or 0
  281. integralTotal = integralTotal + integral
  282. roleData["integral"] = integralTotal
  283. roleData["arrivalTime"] = tonumber(now)
  284. dataFunc.setKunDunPlayerData(actor, roleData)
  285. -- 阵营记录
  286. local faction = roleData["faction"]
  287. local factionData = dataFunc.getKunDunFactionData(faction)
  288. local factionTotal = factionData["integral"] or 0
  289. factionData["integral"] = factionTotal + integral
  290. factionData["arrivalTime"] = tonumber(now)
  291. dataFunc.setKunDunFactionData(faction, factionData)
  292. this.debug(" --- factionData --- ", dataFunc.getKunDunFactionData(faction))
  293. return true, roleData
  294. else
  295. return false
  296. end
  297. end
  298. function KunDun.addIntegralByKill(actor, dieActor)
  299. local addIntegralPercent = KunDun.getKillIntegralConfig() / 10000
  300. local dieRoleData = dataFunc.getKunDunPlayerData(dieActor)
  301. local dieRoleIntegral = dieRoleData["integral"] or 0
  302. if dieRoleIntegral <= 0 then
  303. return
  304. end
  305. local plunderIntegral = dieRoleIntegral * addIntegralPercent
  306. local now = getbaseinfo("now")
  307. -- 个人数据
  308. dieRoleData["integral"] = dieRoleIntegral - plunderIntegral
  309. dataFunc.setKunDunPlayerData(dieActor, dieRoleData)
  310. local selfRoleData = dataFunc.getKunDunPlayerData(actor)
  311. selfRoleData["integral"] = (selfRoleData["integral"] or 0) + dieRoleIntegral
  312. selfRoleData["arrivalTime"] = now
  313. dataFunc.setKunDunPlayerData(actor, selfRoleData)
  314. -- 阵营数据
  315. local dieFactionData = dataFunc.getKunDunFactionData(dieRoleData["faction"])
  316. dieFactionData["integral"] = dieFactionData["integral"] - plunderIntegral
  317. dataFunc.setKunDunFactionData(dieRoleData["faction"], dieFactionData)
  318. local selfFactionData = dataFunc.getKunDunFactionData(selfRoleData["faction"])
  319. selfFactionData["integral"] = selfFactionData["integral"] + dieRoleIntegral
  320. selfFactionData["arrivalTime"] = now
  321. dataFunc.setKunDunFactionData(selfRoleData["faction"], selfFactionData)
  322. end
  323. function KunDun.MonsterDie(mapId, _, monCfgId, monActor)
  324. if not KunDun.isInKunDun(monActor) then
  325. return
  326. end
  327. local config = ConfigDataManager.getById("cfg_rep", KUN_DUN_REP_TYPE)
  328. local kunDunMonsterCfgId = tonumber(config["monster"])
  329. if monCfgId ~= kunDunMonsterCfgId then
  330. return
  331. end
  332. -- 更新阶段 怪物已被击杀
  333. local taskData = dataFunc.getKunDunTaskData()
  334. taskData["stage"] = KunDun.TaskStage.DUP_FINISH
  335. dataFunc.setKunDunTaskData(taskData)
  336. -- this.debug("------ 更改交易行状态 -----", taskData, dataFunc.getKunDunTaskData(), dataFunc.getAllKunDunData())
  337. -- 个人积分重新排名
  338. local integralList = KunDun.calculatePlayerRankList()
  339. dataFunc.setKunDunRankData(integralList)
  340. -- 结算个人奖励
  341. for i = 1, #integralList do
  342. local integralItem = integralList[i]
  343. local id = integralItem["id"]
  344. local rewardMap = KunDun.getRewardConfig(i)
  345. this.debug(" --- integralItem --- ", integralItem, rewardMap, i)
  346. if not table.isNullOrEmpty(rewardMap) then
  347. local playerActor = getactor(id, mapId)
  348. local title = "昆顿入侵"
  349. local content = "恭喜您在" .. title .. "活动中排名第" .. i
  350. sendmailbyrid(playerActor, id, title, content, rewardMap)
  351. end
  352. end
  353. -- 阵营积分重新排名
  354. local factionList = KunDun.calculateFactionRankList()
  355. dataFunc.setKunDunFactionRankData(factionList)
  356. -- 结束活动
  357. setduplicatestate(mapId, SetDuplicateStateConst.TO_FINISH)
  358. -- 拍卖行上架道具
  359. KunDunAuction.Publish()
  360. end
  361. function KunDun.calculatePlayerRankList()
  362. local integralList = {}
  363. local allPlayerData = dataFunc.getAllKunDunPlayerData()
  364. local integralLimit = KunDun.getRankIntegralLimit()
  365. for id, playerData in pairs(allPlayerData) do
  366. local integral = playerData["integral"] or 0
  367. local arrivalTime = playerData["arrivalTime"] or 0
  368. if integral >= integralLimit then
  369. local actor = getactor(id)
  370. local name = getbaseinfo(actor, "rolename")
  371. table.insert(integralList,
  372. { ["id"] = id, ["name"] = name, ["integral"] = integral, ["arrivalTime"] = arrivalTime })
  373. end
  374. end
  375. table.sort(integralList, this.integralSortFunc)
  376. return integralList
  377. end
  378. function this.integralSortFunc(a, b)
  379. if a.integral ~= b.integral then
  380. return b.integral - a.integral
  381. else
  382. return a.arrivalTime - b.arrivalTime
  383. end
  384. end
  385. function KunDun.calculateFactionRankList()
  386. local integralList = {}
  387. local allData = dataFunc.getAllKunDunFactionData()
  388. for faction, factionData in pairs(allData) do
  389. local integral = factionData["integral"] or 0
  390. local arrivalTime = factionData["arrivalTime"] or 0
  391. table.insert(integralList, { ["faction"] = faction, ["integral"] = integral, ["arrivalTime"] = arrivalTime })
  392. end
  393. table.sort(integralList, this.integralSortFunc)
  394. return integralList
  395. end
  396. function KunDun.calculateTop3RankList(actor)
  397. local playerTopList = {}
  398. local rid = actor == nil and 0 or string.tonumber(actor:toString())
  399. local ridIndex
  400. local rankList = dataFunc.getKunDunRankData()
  401. for i, v in ipairs(rankList) do
  402. if v.id == rid then
  403. ridIndex = i
  404. break
  405. end
  406. end
  407. for i = 1, math.min(3, #rankList) do
  408. table.insert(playerTopList, rankList[i])
  409. end
  410. if ridIndex and ridIndex > 3 then
  411. table.insert(playerTopList, rankList[ridIndex])
  412. end
  413. return playerTopList
  414. end
  415. function KunDun.KillPlayer(actor, diePlayer)
  416. if not KunDun.isInKunDun(actor) then
  417. return
  418. end
  419. KunDun.addIntegralByKill(actor, diePlayer)
  420. end
  421. function KunDun.Attack(actor, fightData)
  422. if not KunDun.isInKunDun(actor) then
  423. return
  424. end
  425. local targetActor = fightData["target"]
  426. local targetType = fightData["targettype"]
  427. if tonumber(targetType) ~= MapObjectType.MONSTER then
  428. return
  429. end
  430. local hurt = fightData["targethurt"]
  431. local roleData = dataFunc.getKunDunPlayerData(actor)
  432. local totalHurt = roleData["hurt"] or 0
  433. totalHurt = totalHurt + hurt
  434. local ok, addResult = KunDun.addIntegralByHurt(actor, targetActor, totalHurt)
  435. if ok then
  436. totalHurt = 0
  437. roleData = addResult
  438. end
  439. roleData["hurt"] = totalHurt
  440. dataFunc.setKunDunPlayerData(actor, roleData)
  441. end
  442. function KunDun.EnterKunDun(actor, _)
  443. local stateData = KunDun.getKunDunState()
  444. jprint("昆顿副本,stateData", stateData)
  445. if stateData == nil then
  446. return
  447. end
  448. local start = stateData.start
  449. if start ~= 1 then
  450. return
  451. end
  452. local mapId = stateData.mapId
  453. local x = stateData.x
  454. local y = stateData.y
  455. local kunDunData = dataFunc.getKunDunPlayerData(actor)
  456. --处理阵营
  457. local faction = table.getValue(kunDunData, "faction")
  458. if faction == nil then
  459. faction = KunDun.selectFaction()
  460. kunDunData["faction"] = faction
  461. dataFunc.setKunDunPlayerData(actor, kunDunData)
  462. dataFunc.addFactionPlayer(faction, tonumber(actor:toString()))
  463. end
  464. --进入副本
  465. local configId = KUN_DUN_REP_TYPE
  466. local dupCheck = DuplicateCommon.CheckEnterConditonCommon(actor, configId)
  467. this.debug("----- dup check ------", configId, dupCheck)
  468. if dupCheck ~= EnterLimitResultConst.ALLOW then
  469. return
  470. end
  471. enterduplicate(actor, mapId, x, y)
  472. end
  473. function KunDun.DupStateUpdate(system, id, state, nextStateStartTime, configId)
  474. local now = getbaseinfo("now")
  475. local dupInfo = getduplicate(id)
  476. local players = table.getValue(dupInfo, "players")
  477. if state == DuplicateState.PREPARE then
  478. jprint("【昆顿】副本开始", configId, id, state)
  479. elseif state == DuplicateState.FIGHT then
  480. --战斗阶段,刷怪
  481. local monsterId = ConfigDataManager.getTableValue("cfg_rep", "monster", "id", configId)
  482. local monsterActors = DuplicateCommon.DupGenMonsterCommon(id, monsterId)
  483. jprint("【昆顿】战斗阶段开始刷怪", configId, id, state, monsterActors)
  484. -- 更新阶段 怪物已被创建
  485. local taskData = dataFunc.getKunDunTaskData()
  486. taskData["stage"] = KunDun.TaskStage.DEFAULT
  487. dataFunc.setKunDunTaskData(taskData)
  488. elseif state == DuplicateState.FINISH then
  489. jprint("【昆顿】副本结束", configId, id, state)
  490. closeactivity(DuplicateType.KUN_DUN)
  491. end
  492. end
  493. function KunDun.AfterEnterKunDun(actor, _, state, nextStateStartTime, _)
  494. KunDun.sendPanelData(actor, state, nextStateStartTime)
  495. local faction = KunDun.getKunDunViewData(actor)
  496. SceneMap.sendEnterViewInfoByType(actor, SceneMap.viewKey.KUN_DUN_FACTION, faction)
  497. end
  498. --function KunDun.getKunDunViewData(actor)
  499. -- local data = {}
  500. -- local rid = tonumber(actor:toString())
  501. -- local rank = 0;
  502. --
  503. -- local roleData = dataFunc.getKunDunPlayerData(actor)
  504. -- data['faction'] = roleData["faction"]
  505. --
  506. -- local playerList = KunDun.calculateTop3RankList(actor)
  507. -- for i, v in pairs(playerList) do
  508. -- if v.id == rid then
  509. -- rank = i
  510. -- break
  511. -- end
  512. -- end
  513. -- data['rank'] = rank
  514. -- return data
  515. --end
  516. function KunDun.getKunDunViewData(actor)
  517. local roleData = dataFunc.getKunDunPlayerData(actor)
  518. return roleData["faction"]
  519. end
  520. function KunDun.start()
  521. -- 清理上次昆顿副本内容
  522. dataFunc.setAllKunDunData(nil)
  523. local configId = KUN_DUN_REP_TYPE
  524. --寻找是否有可进入的副本,如果没有创建副本
  525. local nullActor = getactor(0, 0)
  526. local mapId = DuplicateCommon.CreateDupMapCommon(nullActor, configId, true)
  527. local x, y = DuplicateCommon.GetEnterPointXYCommon(configId)
  528. jprint("昆顿副本开始", mapId, x, y)
  529. KunDun.setKunDunState(1, mapId, x, y)
  530. end
  531. function KunDun.stop()
  532. KunDun.setKunDunState(0, 0, 0, 0)
  533. end
  534. function KunDun.Run(action)
  535. local serverType = getbaseinfo("servertype")
  536. if serverType ~= 2 then
  537. return
  538. end
  539. if tonumber(action) == 1 then
  540. KunDun.start()
  541. elseif tonumber(action) == 0 then
  542. KunDun.stop()
  543. end
  544. end
  545. function KunDun.DupSecondHeart(mapId, dupConfig, state)
  546. local stateData = KunDun.getKunDunState() or {}
  547. local start = stateData.start or 0
  548. if start ~= 1 then
  549. return
  550. end
  551. if state ~= DuplicateState.FIGHT then
  552. return
  553. end
  554. local now = tonumber(getbaseinfo("now"))
  555. local intervalData = dataFunc.getRankFlushInterval()
  556. if intervalData < 1 then
  557. local configLimit = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", 21001007)
  558. local interval = math.max(tonumber(configLimit), RANK_FLUSH_MIN_SECONDS)
  559. intervalData = interval
  560. dataFunc.setRankFlushInterval(intervalData)
  561. end
  562. -- X秒一次
  563. if math.floor((now / 1000) % intervalData) ~= 0 then
  564. return
  565. end
  566. -- 心跳刷新排行榜
  567. local rankList = KunDun.calculatePlayerRankList()
  568. dataFunc.setKunDunRankData(rankList)
  569. this.sendPanelRankData()
  570. end
  571. function this.sendPanelRankData()
  572. local resData = {}
  573. local factionList = KunDun.calculateFactionRankList()
  574. resData["factionRank"] = factionList
  575. local playerData = dataFunc.getAllKunDunPlayerData()
  576. for rid, _ in pairs(playerData) do
  577. local actor = getactor(rid)
  578. if KunDun.isInKunDun(actor) then
  579. local playerList = KunDun.calculateTop3RankList(actor)
  580. resData["playerRank"] = playerList
  581. sendluamsg(actor, LuaMessageIdToClient.RES_KUN_DUN_PANEL_INFO, resData)
  582. end
  583. end
  584. end
  585. -- ------------------------------------------------------------- --
  586. KunDunAuction = {}
  587. local aucDbFunc = {}
  588. local function __AuctionDbKey()
  589. return "R$_CROSS_GLOBAL_KUN_DUN_AUCTION_DATA"
  590. end
  591. local function _flushTime()
  592. return 5
  593. end
  594. local function _stallWay()
  595. return 1
  596. end
  597. function KunDunAuction.ontimer()
  598. this.onTimer()
  599. end
  600. function KunDunAuction.Publish()
  601. -- callonserial(l_kundun_auction_publish_goods)
  602. l_kundun_auction_publish_goods()
  603. this.sendOnLinePlayerPanel()
  604. end
  605. function KunDunAuction.PlayerBidding(actor, msgData)
  606. -- callonserial(l_kun_dun_auction_player_bidding, actor, msgData)
  607. l_kun_dun_auction_player_bidding(actor, msgData)
  608. end
  609. function KunDunAuction.login(actor)
  610. this.sendAuctionPanelData(actor)
  611. end
  612. function l_kundun_auction_publish_goods()
  613. if not this.auctionIsOpen() then
  614. return
  615. end
  616. local configList = ConfigDataManager.getTable("cfg_stall", 'way', _stallWay())
  617. if table.isEmpty(configList) then
  618. return
  619. end
  620. local now = getbaseinfo("now")
  621. local goodsMap = {}
  622. for _, config in pairs(configList) do
  623. local probability = string.tonumber(config["probability"])
  624. local cfgid = tonumber(config['id'])
  625. local count = tonumber(config['number'])
  626. if probability > 0 then
  627. local num = math.random(1, 10000)
  628. if probability < num then
  629. goto continue
  630. end
  631. end
  632. local goodsInfo = createitemsbymap({ [cfgid] = count })
  633. if table.isEmpty(goodsInfo) then
  634. goto continue
  635. end
  636. local endTime = now + tonumber(config['time']) * 60 * 1000
  637. for _, goods in pairs(goodsInfo) do
  638. goods['bidderId'] = 0
  639. goods['startTime'] = now
  640. goods['endTime'] = endTime
  641. goods['price'] = tonumber(config["startingprice"])
  642. goods['coinType'] = tonumber(config['money'])
  643. goods['fixedPrice'] = tonumber(config['fixedprice'])
  644. goods['auction'] = tonumber(config['auction'])
  645. goods['addTimes'] = tonumber(config['addTimes'])
  646. goodsMap[goods['id']] = goods
  647. end
  648. :: continue ::
  649. end
  650. this.debug("---- 拍卖行上架道具 -----", goodsMap)
  651. aucDbFunc.setPublishGoods(goodsMap)
  652. GlobalTimer.setontimerex(TimerIds.KUN_DUN_AUCTION, _flushTime())
  653. end
  654. function l_kun_dun_auction_player_bidding(actor, msgData)
  655. local goodsId = string.tonumber(msgData['goodsId'])
  656. if goodsId < 1 then
  657. return
  658. end
  659. if not this.auctionIsOpen() then
  660. this.info(actor, "拍卖未开启")
  661. return
  662. end
  663. if not this.isParticipate(actor) then
  664. this.info(actor, "您未参与昆顿活动")
  665. return
  666. end
  667. local goodsMap = aucDbFunc.getPublishGoods()
  668. local goods = goodsMap[goodsId]
  669. if table.isEmpty(goods) then
  670. this.info(actor, "该商品已被购买或已下架")
  671. return
  672. end
  673. local now = getbaseinfo("now")
  674. local endTime = goods['endTime']
  675. if endTime < now then
  676. this.info(actor, "该商品已下架")
  677. return
  678. end
  679. local buyNow = string.tonumber(msgData['type']) == 1
  680. local rid = tonumber(actor:toString())
  681. local lastBidder = goods['bidderId']
  682. if not buyNow and lastBidder == rid then
  683. this.info(actor, "您已参与竞拍, 请勿重复参与")
  684. return
  685. end
  686. local bidPrice = goods["price"]
  687. local fixedPrice = tonumber(goods['fixedprice'])
  688. local newPrice = buyNow and fixedPrice or this.calculateNewPrice(goods)
  689. local coinType = goods['coinType']
  690. local coinCount = getbagitemcountbyid(actor, coinType)
  691. if coinCount < newPrice then
  692. this.info(actor, "资源不足, 无法竞拍")
  693. return
  694. end
  695. removeitemfrombag(actor, coinType, newPrice, 0, 9999, "昆顿竞拍")
  696. goods['bidderId'] = rid
  697. goods['price'] = newPrice
  698. -- 一口价进入结算阶段
  699. if buyNow or newPrice == fixedPrice then
  700. this.toSettleAuction(goods)
  701. -- 结算并清理缓存
  702. goodsMap[goodsId] = nil
  703. else
  704. -- 增加时间 保存变动内容
  705. local finalTime = goods["addTimes"] * 1000 + endTime
  706. goods["endTime"] = finalTime
  707. goodsMap[goodsId] = goods
  708. end
  709. aucDbFunc.setPublishGoods(goodsMap)
  710. -- 返还上个竞拍玩家道具
  711. if lastBidder > 0 then
  712. this.bidFailMail(lastBidder, goodsId, coinType, bidPrice)
  713. end
  714. local result = { ["result"] = true, ["goods"] = goods }
  715. sendluamsg(actor, LuaMessageIdToClient.RES_KUN_DUN_AUCTION_BUY_RESULT, result)
  716. end
  717. -- ------------------------------------------------------------- --
  718. function l_kun_dun_test_main_2()
  719. this.sendOnLinePlayerPanel()
  720. end
  721. function this.sendOnLinePlayerPanel()
  722. local goods = aucDbFunc.getPublishGoods()
  723. local data = dataFunc.getAllKunDunPlayerData()
  724. this.debug("---- 获取所有玩家数据 -----", goods, data)
  725. for rid, _ in pairs(data) do
  726. local actor = getactor(rid)
  727. local onlineState = tonumber(getbaseinfo(actor, "onlinestate"))
  728. if onlineState == 1 then
  729. this.sendAuctionPanelData(actor, goods)
  730. end
  731. end
  732. end
  733. function this.sendAuctionPanelData(actor, goods)
  734. local data = {}
  735. if goods == nil then
  736. goods = aucDbFunc.getPublishGoods()
  737. end
  738. this.debug("---- 发送拍卖行面板数据 -----", goods, this.auctionIsOpen(), this.isParticipate(actor))
  739. if this.auctionIsOpen() and this.isParticipate(actor) and table.notEmpty(goods) then
  740. data['isOpen'] = true
  741. data['goods'] = goods
  742. else
  743. data['isOpen'] = false
  744. end
  745. sendluamsg(actor, LuaMessageIdToClient.RES_KUN_DUN_AUCTION_PANEL_INFO, data)
  746. end
  747. function this.bidFailMail(bidderId, goodsId, costType, costNum)
  748. local itemName = ConfigDataManager.getTableValue("cfg_item", "name", "id", goodsId)
  749. local costName = ConfigDataManager.getTableValue("cfg_item", "name", "id", costType)
  750. local param = itemName .. "#" .. costName
  751. local actor = getactor(bidderId)
  752. sendconfigmailbyrid(actor, bidderId, AuctionConst.AUCTION_FAIL_EMAIL, { [costType] = costNum }, param)
  753. end
  754. function this.calculateNewPrice(goods)
  755. local bidPrice = goods["price"]
  756. local auction = goods["auction"]
  757. local fixedPrice = goods["fixedPrice"]
  758. local newPrice = math.ceil(bidPrice * (1 + auction * 0.0001))
  759. this.debug("---- 拍卖行计算价格 -----", goods, bidPrice, auction, "|", "fixedPrice", fixedPrice, "newPrice", newPrice)
  760. return math.min(newPrice, fixedPrice)
  761. end
  762. function this.onTimer()
  763. local goodsData = aucDbFunc.getPublishGoods()
  764. -- this.debug("---- 拍卖行定时器 -----", goodsData)
  765. if table.notEmpty(goodsData) then
  766. local clearIdList = {}
  767. local now = string.tonumber(getbaseinfo("now"))
  768. for goodsId, goods in pairs(goodsData) do
  769. local endTime = goods["endTime"]
  770. if endTime < now then
  771. table.insert(clearIdList, goodsId)
  772. end
  773. end
  774. -- this.debug("---- 需要清理的拍卖行道具 -----", clearIdList)
  775. -- 结算到期竞拍道具
  776. for _, goodsId in pairs(clearIdList) do
  777. local goods = goodsData[goodsId]
  778. this.toSettleAuction(goods)
  779. goodsData[goodsId] = nil
  780. end
  781. aucDbFunc.setPublishGoods(goodsData)
  782. end
  783. -- 没有物品后关闭定时器
  784. if table.isEmpty(goodsData) then
  785. GlobalTimer.setofftimer(TimerIds.KUN_DUN_AUCTION)
  786. end
  787. end
  788. function this.toSettleAuction(goods)
  789. if table.isEmpty(goods) then
  790. return
  791. end
  792. local buyerId = goods['bidderId']
  793. if buyerId < 1 then
  794. return
  795. end
  796. -- 发放拍卖道具
  797. local buyer = getactor(buyerId)
  798. SendMailByCompleteItems(buyer, buyerId, "昆顿竞拍", "竞拍成功", goods)
  799. -- 分红名单
  800. local ridList = {}
  801. -- 是否为稀有道具
  802. local rareItem = false
  803. if rareItem then
  804. local rankData = dataFunc.getKunDunFactionRankData()
  805. local faction = rankData[1]['faction']
  806. ridList = dataFunc.getFactionPlayers(faction)
  807. else
  808. local allPlayer = dataFunc.getAllKunDunPlayerData()
  809. for rid, _ in pairs(allPlayer) do
  810. table.insert(ridList, rid)
  811. end
  812. end
  813. local buyerName = getbaseinfo(buyer, "rolename")
  814. this.debug("---- 拍卖结算 ----", goods, buyerId, buyerName, "-- 分红名单 --", ridList)
  815. local cfgId = goods['cfgid']
  816. local coinType = goods['coinType']
  817. local price = goods['price']
  818. local taxStr = ConfigDataManager.getTableValue("cfg_stall", "tax", "id", cfgId, "way", _stallWay())
  819. this.debug("config_data", cfgId, _stallWay(), taxStr)
  820. local aBonus = this.calculationTax(price, taxStr)
  821. aBonus = math.round(aBonus / #ridList)
  822. -- 发送邮件
  823. local reward = { [coinType] = aBonus }
  824. -- 解析文本配置
  825. local itemName = ConfigDataManager.getTableValue("cfg_item", "name", "id", cfgId)
  826. local priceTypeName = ConfigDataManager.getTableValue("cfg_item", "name", "id", coinType)
  827. local param = itemName .. "#" .. priceTypeName .. "#" .. 999 .. "#" .. aBonus
  828. for _, rid in pairs(ridList) do
  829. if rid ~= buyer then
  830. sendconfigmailbyrid(buyer, buyerId, AuctionConst.AUCTION_DIVIDE_EMAIL, reward, param)
  831. end
  832. end
  833. end
  834. -- 计算税率
  835. function this.calculationTax(price, taxStr)
  836. local tableTax = {}
  837. string.putIntIntMap(tableTax, taxStr)
  838. local deleteRate = tableTax[1]
  839. this.debug("---- 拍卖行税率 ----", price, taxStr, tableTax)
  840. local totalPrice = math.round(price * (100 - deleteRate) / 100)
  841. local deleteCount = tableTax[2]
  842. totalPrice = totalPrice - deleteCount
  843. return totalPrice
  844. end
  845. function this.auctionIsOpen()
  846. -- boss被击杀才开启
  847. local taskData = dataFunc.getKunDunTaskData()
  848. return taskData["stage"] == KunDun.TaskStage.DUP_FINISH
  849. end
  850. function this.isParticipate(actor)
  851. -- 参与了活动
  852. local data = dataFunc.getKunDunPlayerData(actor)
  853. return table.notEmpty(data)
  854. end
  855. function aucDbFunc.getAuctionData()
  856. return dataFunc.getCrossGlobalData(__AuctionDbKey())
  857. end
  858. function aucDbFunc.setAuctionData(data)
  859. dataFunc.setCrossGlobalData(__AuctionDbKey(), data)
  860. end
  861. function aucDbFunc.getPublishGoods()
  862. local data = aucDbFunc.getAuctionData()
  863. return data['publishgoods'] or {}
  864. end
  865. function aucDbFunc.setPublishGoods(goodsData)
  866. local data = aucDbFunc.getAuctionData()
  867. data['publishgoods'] = goodsData
  868. aucDbFunc.setAuctionData(data)
  869. end
  870. -- ------------------------------------------------------------- --
  871. this.log_open = false
  872. this.log_name = "[KunDun]"
  873. function this.debug(...)
  874. if not this.log_open then
  875. return
  876. end
  877. gameDebug.print(this.log_name, ...)
  878. end
  879. function this.print(...)
  880. if not this.log_open then
  881. return
  882. end
  883. if param == nil then
  884. param = "error! 输出内容为空. nil"
  885. end
  886. jprint(this.log_name, ...)
  887. end
  888. function this.info(actor, ...)
  889. info(actor, ...)
  890. this.print(...)
  891. end
  892. -- ------------------------------------------------------------- --
  893. function l_test_kundun_main_1(actor)
  894. local data = createitemsbymap({ [50030002] = 1 })
  895. data = data[1]
  896. data['bidderId'] = tonumber(actor:toString())
  897. data['coinType'] = 10020001
  898. data['price'] = 1000
  899. this.toSettleAuction(data)
  900. end
  901. -- 注册登录事件
  902. LoginEventListerTable:eventLister("0", "昆顿入侵", KunDunAuction.login)