KunDun.lua 33 KB

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