WorldBoss = {} local this = {} -- 报名过的玩家 local SIGNIN_ALL_PLAYER = "G$SignInWorldBossPlayers" local MonLowHp = "G$_WorldBossMonsterLowHP" local CurBossRepId = "R$_WorldBoss_Cur_Activity_ID" local Activity_ID = 23001 -- 世界BOSS活动ID local Activity_TYPE = 30001 -- 世界BOSS活动类型 local AucMailConst = { SUCCESS = 102061, FAIL = 102062, A_BONUS = 102063 } function WorldBoss.start() local curRepId = WorldBoss.UpDataCurRepId() local nullActor = getactor(0, 0) local mapId = DuplicateCommon.CreateDupMapCommon(nullActor, curRepId, true) local x, y = DuplicateCommon.GetEnterPointXYCommon(curRepId) jprint("世界BOSS副本开始", mapId, x, y) end function WorldBoss.UpDataCurRepId() local openDay = getbaseinfo("serveropendays") local cfgDay = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", 23001002)) if openDay < cfgDay then return 0 end local repId = getsysvar(CurBossRepId) or 0 local id = Activity_ID if repId > 0 then id = repId + 1 local monsterId = ConfigDataManager.getTableValue("cfg_rep", "monster", "id", id) if monsterId == nil or monsterId == "" then id = Activity_ID end end setsysvar(CurBossRepId,id) return id end function WorldBoss.stop() local existDupList = getduplicatelist(Activity_TYPE) if table.isEmpty(existDupList) then return end local mapId = existDupList[1].id setduplicatestate(mapId, SetDuplicateStateConst.TO_FINISH) setduplicatestate(mapId, SetDuplicateStateConst.TO_CLOSED) closeactivity(DuplicateType.WORLD_BOSS) end function WorldBoss.Run(action) -- local serverType = getbaseinfo("servertype") if tonumber(action) == 1 then WorldBoss.start() elseif tonumber(action) == 0 then WorldBoss.stop() -- elseif tonumber(action) == 2 then -- -- 调试:查看排行榜 -- local existDupList = getduplicatelist(Activity_TYPE) -- if not table.isEmpty(existDupList) then -- local mapId = existDupList[1].id -- WorldBoss.DebugRankList(mapId) -- end -- elseif tonumber(action) == 3 then -- -- 调试:手动分配奖励(仅测试用) -- local existDupList = getduplicatelist(Activity_TYPE) -- if not table.isEmpty(existDupList) then -- local mapId = existDupList[1].id -- WorldBoss.DistributeRewards(mapId, 10000) -- end end end function WorldBoss.DupStateUpdate(system, mapId, state, nextStateStartTime, configId) if state == DuplicateState.PREPARE then -- info("WorldBoss副本进入准备阶段, mapId:", mapId, " state:", state, " nextStateStartTime:", nextStateStartTime, " configId:", configId) -- 准备阶段 elseif state == DuplicateState.FIGHT then -- info("WorldBoss副本进入战斗阶段, mapId:", mapId, " state:", state, " nextStateStartTime:", nextStateStartTime, " configId:", configId) -- 战斗阶段 local monsterId = ConfigDataManager.getTableValue("cfg_rep", "monster", "id", configId) DuplicateCommon.DupGenMonsterCommon(mapId, monsterId) --刷怪 WorldBoss.upDataState(mapId) elseif state == DuplicateState.FINISH then -- info("WorldBoss副本进入结算阶段, mapId:", mapId, " state:", state, " nextStateStartTime:", nextStateStartTime, " configId:", configId) -- 结束阶段 elseif state == DuplicateState.CLOSED then -- info("WorldBoss副本进入销毁阶段, mapId:", mapId, " state:", state, " nextStateStartTime:", nextStateStartTime, " configId:", configId) end end -- 更新当前状态 function WorldBoss.upDataState(mapId) local players = getenvirvar(mapId, SIGNIN_ALL_PLAYER) or {} for k, v in pairs(players) do local actor = getactor(k) if actor then WorldBoss.SendWorldBossInfo(actor) end end end function WorldBoss.ReqWorldBossMsg(actor, msgData) local reqType = msgData["type"] if reqType == 1 then WorldBoss.SendWorldBossInfo(actor) elseif reqType == 2 then WorldBoss.ReqSignInWorldBoss(actor) end end -- 活动报名 function WorldBoss.ReqSignInWorldBoss(actor) -- 检查是否拥有战盟 local guildid = getbaseinfo(actor, "guildid") if guildid == 0 then tipinfo(actor, "不在战盟中") return end local existDupList = getduplicatelist(Activity_TYPE) if table.isEmpty(existDupList) then tipinfo(actor, "活动未开启,无法报名") return end local state = existDupList[1].state if state ~= DuplicateState.PREPARE then tipinfo(actor, "非报名时间,无法报名") return end local mapId = existDupList[1].id local players = getenvirvar(mapId, SIGNIN_ALL_PLAYER) or {} local rid = getbaseinfo(actor, "rid") if players[rid] then tipinfo(actor, "已报名,无需重复操作") return end players[rid] = 0 setenvirvar(mapId, SIGNIN_ALL_PLAYER, players) WorldBoss.SendWorldBossInfo(actor) tipinfo(actor, "世界boss活动报名成功") end -- 发送当前状态信息 function WorldBoss.SendWorldBossInfo(actor) local resData = {} local existDupList = getduplicatelist(Activity_TYPE) if table.isEmpty(existDupList) then return end -- id:副本地图唯一ID -- dupcfgid:配置表id,cfg_rep表的ID -- activityid:活动id -- players:玩家actor列表 -- state:当前阶段 -- nextstatetime:下一阶段开始时间戳(毫秒), -- type:副本类型 local mapId = existDupList[1].id resData["signin"] = WorldBoss.GetSignInNUm(mapId) resData["mapid"] = mapId resData["dupcfgid"] = existDupList[1].dupcfgid resData["activityid"] = existDupList[1].activityid resData["state"] = existDupList[1].state resData["type"] = existDupList[1].type resData["nextstatetime"] = existDupList[1].nextstatetime sendluamsg(actor, LuaMessageIdToClient.RES_WORLD_BOSS_INFO, resData) end function WorldBoss.isWorldBoss(actor) local mapId = getbaseinfo(actor, "unimapid") local dupInfo = getduplicate(mapId) if not dupInfo then return false end local type = dupInfo["type"] if type ~= DuplicateType.WORLD_BOSS then return false end return true end -- 获取报名人数 function WorldBoss.GetSignInNUm(mapId) local players = getenvirvar(mapId, SIGNIN_ALL_PLAYER) or {} return table.count(players) end -- @description 请求进入世界boss活动 function WorldBoss.ReqEnterWorldBoss(actor) local activityInfo = getactivityinfo(Activity_TYPE) if not activityInfo["open"] then tipinfo(actor, "活动未开启") return end -- 检查是否拥有战盟 local guildid = getbaseinfo(actor, "guildid") if guildid == 0 then tipinfo(actor, "不在战盟中") return end if WorldBoss.isWorldBoss(actor) then WbAuction.Publish() tipinfo(actor, "您已经在世界boss挑战中") return end -- 寻找是否有可进入的副本,如果没有创建副本 local existDupList = getduplicatelist(Activity_TYPE) if table.isEmpty(existDupList) then tipinfo(actor, "活动副本未开启") return -- mapId = DuplicateCommon.CreateDupMapCommon(actor, Activity_ID, true) end local mapId = existDupList[1].id local curRepId = existDupList[1].dupcfgid local curState = existDupList[1].state if curState ~= DuplicateState.FIGHT then tipinfo(actor, "非战斗时间,无法进入") return end local players = getenvirvar(mapId, SIGNIN_ALL_PLAYER) or {} if not players[getbaseinfo(actor, "rid")] then tipinfo(actor, "未报名,无法进入") return end local LowNum = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", 23001001)) if LowNum > 0 then local num = WorldBoss.GetSignInNUm(mapId) if num < LowNum then tipinfo(actor, "当前报名人数不足,无法进入") return end end if mapId ~= 0 and curRepId ~= 0 then local x, y = DuplicateCommon.GetEnterPointXYCommon(curRepId) enterduplicate(actor, mapId, x, y) end -- 设置pk状态 setplayersetting(actor, 1, 1) --1 和平 5战盟 end function WorldBoss.afterenterduplicate(actor, mapId, dupType, state, nextStateStartTime, configId) sendluamsg(actor, LuaMessageIdToClient.RES_WORLD_BOSS_RANK, {}) end function WorldBoss.OnMonsterDie( mapId, killer, monCfgId) local timer = setenvirontimer(mapId,60000,1000,1,"closeworldboss",mapId) local exit = hasenvirtimer(mapId,timer) WbAuction.Publish() end -- 关闭世界boss副本 function closeworldboss(_, mapId) -- info("boss死亡,关闭世界boss副本mapId:", mapId) end function WorldBoss.calculatePlayerRankList(mapId) local playerList = {} local guildList = {} local guildDamage = {} local guildName = {} local players = getenvirvar(mapId, SIGNIN_ALL_PLAYER) if players ~= nil then for id, damage in pairs(players) do local actor = getactor(id) local guildid = getbaseinfo(actor, "guildid") or 0 guildName[guildid] = getbaseinfo(actor, "guildname") or "" -- playerList[id] = { damage = damage ,name = tostring(getbaseinfo(actor, "rolename")) } table.insert(playerList, {id = id, damage = damage ,name = tostring(getbaseinfo(actor, "rolename")) }) -- local curDamage = guildList[guildid] and guildList[guildid].damage or 0 -- guildList[guildid] = { damage = curDamage + damage ,name = getbaseinfo(actor, "guildname") } guildDamage[guildid] = (guildDamage[guildid] or 0) + damage end for k,v in pairs(guildDamage) do table.insert(guildList, {id = k, damage = v ,name = guildName[k] or "" }) end end table.sort(playerList, this.SortFunc) table.sort(guildList, this.SortFunc) local topPlayerList = {} for i = 1, math.min(50, #playerList) do table.insert(topPlayerList, playerList[i]) end local topGuildList = {} for i = 1, math.min(50, #guildList) do table.insert(topGuildList, guildList[i]) end return topPlayerList,topGuildList end function this.SortFunc(a, b) if a.damage ~= b.damage then return b.damage < a.damage end end -- 世界BOSS奖励分配 -- 总奖励:10000钻石 -- 战盟分配:第1名50%,第2名30%,第3名20% -- 玩家分配:第1名30%,第2名25%,第3名20%,第4名10%,第5名5%,剩余平均分配 function WorldBoss.DistributeRewards(totalReward) local existDupList = getduplicatelist(Activity_TYPE) if table.isEmpty(existDupList) then -- tipinfo(actor, "活动副本未开启") return end local mapId = existDupList[1].id if not totalReward or totalReward <= 0 then -- jprint("世界BOSS奖励分配失败:奖励金额无效", totalReward) return end local playerList, guildList = WorldBoss.calculatePlayerRankList(mapId) if table.isEmpty(playerList) or table.isEmpty(guildList) then -- jprint("世界BOSS奖励分配失败:没有玩家或战盟数据") return end -- jprint(string.format("=== 世界BOSS奖励分配开始,总奖励:%d钻石 ===", totalReward)) -- 获取前3名战盟 local top3Guilds = {} for i = 1, math.min(3, #guildList) do table.insert(top3Guilds, guildList[i]) end -- 战盟分配比例 local guildRewardRatios = {0.5, 0.3, 0.2} -- 50%, 30%, 20% -- 为每个前3名战盟计算奖励 local guildRewards = {} local totalDistributedReward = 0 for i, guild in ipairs(top3Guilds) do local guildTotalReward = totalReward * guildRewardRatios[i] totalDistributedReward = totalDistributedReward + guildTotalReward guildRewards[guild.id] = { totalReward = guildTotalReward, guildName = guild.name, guildRank = i, players = {} } -- jprint(string.format("第%d名战盟:%s,获得%.0f钻石(%.0f%%)", -- i, guild.name, guildTotalReward, guildRewardRatios[i] * 100)) end -- 玩家分配比例(前5名) local playerRewardRatios = {0.3, 0.25, 0.2, 0.1, 0.05} -- 30%, 25%, 20%, 10%, 5% -- 为每个战盟的玩家分配奖励 for guildId, guildData in pairs(guildRewards) do local guildPlayers = {} -- 获取该战盟的所有玩家(按照伤害排名) for _, player in ipairs(playerList) do local actor = getactor(player.id) local playerGuildId = getbaseinfo(actor, "guildid") or 0 if playerGuildId == guildId then table.insert(guildPlayers, player) end end -- jprint(string.format(" 战盟%s共有%d名玩家参与", guildData.guildName, #guildPlayers)) if #guildPlayers > 0 then -- 前5名玩家按比例分配 local distributedReward = 0 local top5Count = math.min(5, #guildPlayers) for i = 1, top5Count do local player = guildPlayers[i] local playerReward = guildData.totalReward * playerRewardRatios[i] distributedReward = distributedReward + playerReward table.insert(guildData.players, { playerId = player.id, playerName = player.name, damage = player.damage, rank = i, reward = playerReward, rewardType = i <= 5 and "排名奖励" or "参与奖励" }) -- jprint(string.format(" 第%d名:%s,%.0f钻石(%.0f%%),伤害:%d", -- i, player.name, playerReward, playerRewardRatios[i] * 100, player.damage)) end -- 剩余玩家平均分配 if #guildPlayers > 5 then local remainingCount = #guildPlayers - 5 local remainingReward = guildData.totalReward - distributedReward local avgReward = remainingReward / remainingCount -- jprint(string.format(" 剩余%d名玩家,每人平均获得%.0f钻石", remainingCount, avgReward)) for i = 6, #guildPlayers do local player = guildPlayers[i] table.insert(guildData.players, { playerId = player.id, playerName = player.name, damage = player.damage, rank = i, reward = avgReward, rewardType = "参与奖励" }) end end end end -- jprint(string.format("=== 奖励分配完成,总计分配%.0f钻石 ===", totalDistributedReward)) -- 发送奖励 WorldBoss.SendWorldBossRewards(guildRewards) return guildRewards end -- 发送世界BOSS奖励 function WorldBoss.SendWorldBossRewards(guildRewards) -- jprint("=== 世界BOSS奖励分配开始 ===") for guildId, guildData in pairs(guildRewards) do -- jprint(string.format("战盟:%s,总奖励:%.0f钻石", guildData.guildName, guildData.totalReward)) for _, playerData in ipairs(guildData.players) do local actor = getactor(playerData.playerId) if actor then -- 发送钻石奖励 local rewardItems = { [10040001] = math.floor(playerData.reward) } -- 钻石ID和数量 -- 发送奖励邮件 -- local title = "世界BOSS奖励" -- local content = string.format("恭喜您在世界BOSS活动中获得排名奖励!\n战盟:%s\n个人排名:第%d名\n伤害值:%d\n获得钻石:%.0f", guildData.guildName, guildData.guildName, playerData.damage, playerData.reward) -- sendmailbycompleteitems(actor, playerData.playerId, title, content, rewardItems)--getbaseinfo(actor, "rid") local param = guildData.guildName .. "#" ..guildData.guildRank.. "#" .. math.floor(guildData.totalReward).. "#" .. playerData.rank sendconfigmailbyrid(actor, playerData.playerId, AucMailConst.A_BONUS, rewardItems, param) -- 记录日志 -- jprint(string.format(" 玩家:%s,排名:%d,伤害:%d,奖励:%.0f钻石", -- playerData.playerName, playerData.rank, playerData.damage, playerData.reward)) end end end -- jprint("=== 世界BOSS奖励分配结束 ===") end -- 调试函数:查看排行榜详情 -- function WorldBoss.DebugRankList(mapId) -- local playerList, guildList = WorldBoss.calculatePlayerRankList(mapId) -- jprint("=== 世界BOSS战盟排行榜 ===") -- for i = 1, math.min(3, #guildList) do -- local guild = guildList[i] -- jprint(string.format("第%d名战盟:%s,伤害:%d", i, guild.name, guild.damage)) -- end -- jprint("=== 世界BOSS玩家排行榜 ===") -- for i = 1, math.min(10, #playerList) do -- local player = playerList[i] -- local actor = getactor(player.id) -- local guildName = "" -- if actor then -- guildName = getbaseinfo(actor, "guildname") or "无战盟" -- end -- jprint(string.format("第%d名:%s(%s),伤害:%d", i, player.name, guildName, player.damage)) -- end -- end -- 攻击事件 function WorldBoss.Attack(actor, fightData) local mapId = getbaseinfo(actor, "unimapid") local dupInfo = getduplicate(mapId) if dupInfo == nil then return end local type = dupInfo["type"] if type ~= DuplicateType.WORLD_BOSS then return end local casterType = fightData.castertype local targetType = fightData.targettype if casterType ~= MapObjectType.PLAYER or targetType ~= MapObjectType.MONSTER then return end -- 累计伤害 local players = getenvirvar(mapId, SIGNIN_ALL_PLAYER) or {} local rid = getbaseinfo(actor, "rid") players[rid] = (players[rid] or 0) + fightData.targethurt setenvirvar(mapId, SIGNIN_ALL_PLAYER, players) WorldBoss.CheckMonsterHp(actor,mapId,fightData.target) end -- 检查怪当前血量是否低于30% function WorldBoss.CheckMonsterHp(actor,mapId,Monste) local tip = getenvirvar(mapId, MonLowHp) if tonumber(tip) == 1 then return end local mInfo = getmonsterinfo(Monste) if mInfo == nil then return end local hp = mInfo["hp"] local maxhp = mInfo["maxhp"] local bossName = mInfo["name"] if (hp / maxhp) <= 0.3 then setenvirvar(mapId, MonLowHp, 1) -- 本地通广播提示 noticeTip.noticeinfo(Monste, StringIdConst.text35010, bossName) setplayersetting(actor, 1, 5) --1 和平 5战盟 end end function WorldBoss.DupSecondHeart(mapId, dupConfig, state) if state == DuplicateState.PREPARE then elseif state == DuplicateState.FIGHT then -- 刷新排行榜 this.sendPanelRankData(mapId) return end end function this.sendPanelRankData(mapId) local resData = {} local rankList,guildList = WorldBoss.calculatePlayerRankList(mapId) resData["playerRank"] = rankList resData["guildRank"] = guildList local existDupList = getduplicatelist(Activity_TYPE) if table.isEmpty(existDupList) then return end local playerData = existDupList[1].players or {} for _, actor in pairs(playerData) do -- local actor = getactor(rid) sendluamsg(actor, LuaMessageIdToClient.RES_WORLD_BOSS_RANK, resData) end end -- ------------------------------------------------------------- -- WbAuction = {} local aucDbFunc = {} local function __AuctionDbKey() return "R$_WORLD_BOSS_AUCTION_DATA" end local function _flushTime() return 5 end local function _stallWay() return 11 end function WbAuction.ontimer() this.onTimer() end function WbAuction.Publish() callonserial("_wb_auction_publish_goods") end function WbAuction.PlayerBidding(actor, msgData) callonserial(actor,"_wb_auction_player_bidding", msgData) end function WbAuction.login(actor) this.sendAuctionPanelData(actor) end -- 拍卖行上架道具 function _wb_auction_publish_goods() if not this.auctionIsOpen() then return end local configList = ConfigDataManager.getTable("cfg_stall", 'way', _stallWay()) if table.isEmpty(configList) then return end local repId = getsysvar(CurBossRepId) or Activity_ID local UIreward = ConfigDataManager.getTableValue("cfg_rep", "UIreward", "id", repId) local rewardMap = string.split(UIreward, "|") if table.isNullOrEmpty(rewardMap) then return end local now = getbaseinfo("now") local goodsMap = {} for _, config in pairs(configList) do local probability = string.tonumber(config["probability"]) local cfgid = tonumber(config['id']) local count = tonumber(config['number']) local isup = false for _, uiId in pairs(rewardMap) do if tonumber(uiId) == cfgid then isup = true break end end if not isup then -- goto continue end if probability > 0 then local num = math.random(1, 10000) if probability < num then goto continue end end local goodsInfo = createitemsbymap({ [cfgid] = count }) if table.isEmpty(goodsInfo) then goto continue end local endTime = now + tonumber(config['time']) * 60 * 1000 for _, goods in pairs(goodsInfo) do goods['bidderId'] = 0 goods['startTime'] = now goods['endTime'] = endTime goods['price'] = tonumber(config["startingprice"]) goods['coinType'] = tonumber(config['money']) goods['fixedPrice'] = tonumber(config['fixedprice']) goods['auction'] = tonumber(config['auction']) goods['addTimes'] = tonumber(config['addtime']) goodsMap[goods['id']] = goods end :: continue :: end this.debug("---- 拍卖行上架道具 -----", goodsMap) aucDbFunc.setPublishGoods(goodsMap) GlobalTimer.setontimerex(TimerIds.WORLD_BOSS_AUCTION, _flushTime()) -- local goods = aucDbFunc.getPublishGoods() -- this.sendOnLinePlayerPanel(this.sendAuctionPanelData, goods) end function _wb_auction_player_bidding(actor, msgData) local goodsId = string.tonumber(msgData['goodsId']) if goodsId < 1 then return end if not this.auctionIsOpen() then this.info(actor, "拍卖未开启") return end if not this.isParticipate(actor) then this.info(actor, "您未参与活动") return end local goodsMap = aucDbFunc.getPublishGoods() local goods = goodsMap[goodsId] if table.isEmpty(goods) then this.info(actor, "该商品已被购买或已下架") return end local now = getbaseinfo("now") local endTime = goods['endTime'] if endTime < now then this.info(actor, "该商品已下架") return end local buyNow = string.tonumber(msgData['type']) == 1 local rid = tonumber(actor:toString()) local lastBidder = goods['bidderId'] if not buyNow and lastBidder == rid then this.info(actor, "您已参与竞拍, 请勿重复参与") return end local bidPrice = goods["price"] local fixedPrice = tonumber(goods['fixedPrice']) local newPrice = buyNow and fixedPrice or this.calculateNewPrice(goods) local coinType = goods['coinType'] local coinCount = getbagitemcountbyid(actor, coinType) if coinCount < newPrice then this.info(actor, "资源不足, 无法竞拍") return end removeitemfrombag(actor, coinType, newPrice, 0, 9999, "世界BOSS竞拍") goods['bidderId'] = rid goods['price'] = newPrice -- 一口价进入结算阶段 if buyNow or newPrice == fixedPrice then this.toSettleAuction(goods) -- 结算并清理缓存 goodsMap[goodsId] = nil goods['endTime'] = 0 else -- 增加时间 保存变动内容 local finalTime = (goods["addTimes"] or 0) * 1000 + endTime goods["endTime"] = finalTime goodsMap[goodsId] = goods end aucDbFunc.setPublishGoods(goodsMap) -- 返还上个竞拍玩家道具 if lastBidder > 0 then this.bidFailMail(lastBidder, goodsId, coinType, bidPrice) end local result = { ["result"] = true, ["goods"] = goods } -- this.sendOnLinePlayerPanel(this.sendAuctionResult, result) this.sendAuctionResult(actor, result) end function this.sendAuctionResult(actor, result) sendluamsg(actor, LuaMessageIdToClient.RES_KUN_DUN_AUCTION_BUY_RESULT, result) end -- ------------------------------------------------------------- -- function this.sendAuctionPanelData(actor, goods) local data = {} if goods == nil then goods = aucDbFunc.getPublishGoods() end -- this.debug("---- 发送拍卖行面板数据 -----", goods, this.auctionIsOpen(), this.isParticipate(actor)) if this.auctionIsOpen() and this.isParticipate(actor) and table.notEmpty(goods) then data['isOpen'] = true data['goods'] = goods else data['isOpen'] = false end sendluamsg(actor, LuaMessageIdToClient.RES_WORLD_BOSS_AUCTION_GOODS, data) end function this.sendOnLinePlayerPanel(func, resData) local data = dataFunc.getAllKunDunPlayerData() this.debug("---- 获取所有玩家数据 -----", resData, data) for rid, _ in pairs(data) do local actor = getactor(rid) local onlineState = tonumber(getbaseinfo(actor, "onlinestate")) if onlineState == 1 then func(actor, resData) end end end function this.bidFailMail(bidderId, goodsId, costType, costNum) local itemName = ConfigDataManager.getTableValue("cfg_item", "name", "id", goodsId) local costName = ConfigDataManager.getTableValue("cfg_item", "name", "id", costType) local param = itemName .. "#" .. costName local actor = getactor(bidderId) sendconfigmailbyrid(actor, bidderId, AucMailConst.FAIL, { [costType] = costNum }, param) end function this.calculateNewPrice(goods) local bidPrice = goods["price"] local auction = goods["auction"] or 1 local fixedPrice = goods["fixedPrice"] -- local newPrice = math.ceil(bidPrice * (1 + auction * 0.0001)) local newPrice = bidPrice + auction this.debug("---- 拍卖行计算价格 -----", goods, bidPrice, auction, "|", "fixedPrice", fixedPrice, "newPrice", newPrice) return math.min(newPrice, fixedPrice) end function this.onTimer() local goodsData = aucDbFunc.getPublishGoods() -- this.debug("---- 拍卖行定时器 -----", goodsData) if table.notEmpty(goodsData) then local clearIdList = {} local now = string.tonumber(getbaseinfo("now")) for goodsId, goods in pairs(goodsData) do local endTime = goods["endTime"] if endTime < now then table.insert(clearIdList, goodsId) end end -- this.debug("---- 需要清理的拍卖行道具 -----", clearIdList) -- 结算到期竞拍道具 for _, goodsId in pairs(clearIdList) do local goods = goodsData[goodsId] this.toSettleAuction(goods) goodsData[goodsId] = nil end aucDbFunc.setPublishGoods(goodsData) end -- 没有物品后关闭定时器 if table.isEmpty(goodsData) then GlobalTimer.setofftimer(TimerIds.WORLD_BOSS_AUCTION) end end function this.toSettleAuction(goods) if table.isEmpty(goods) then return end local buyerId = goods['bidderId'] if buyerId < 1 then return end -- 发放拍卖道具 local buyer = getactor(buyerId) local mailConfig = ConfigDataManager.getById("cfg_mail", AucMailConst.SUCCESS) if table.notEmpty(mailConfig) then local title = mailConfig['title'] local content = mailConfig['content'] local itemName = ConfigDataManager.getTableValue("cfg_item", "name", "id", goods['cfgid']) content = string.format(content, itemName) sendmailbycompleteitems(buyer, buyerId, title, content, { goods }) end -- 分红名单 local ridList = {} -- -- 是否为稀有道具 -- local rareItem = false -- if rareItem then -- local rankData = dataFunc.getKunDunFactionRankData() -- local faction = rankData[1]['faction'] -- ridList = dataFunc.getFactionPlayers(faction) -- else -- local allPlayer = dataFunc.getAllKunDunPlayerData() -- for rid, _ in pairs(allPlayer) do -- table.insert(ridList, rid) -- end -- end local buyerName = getbaseinfo(buyer, "rolename") this.debug("---- 拍卖结算 ----", goods, buyerId, buyerName, "-- 分红名单 --", ridList) local cfgId = goods['cfgid'] local coinType = goods['coinType'] local price = goods['price'] local taxStr = ConfigDataManager.getTableValue("cfg_stall", "tax", "id", cfgId, "way", _stallWay()) this.debug("config_data", cfgId, _stallWay(), taxStr) local aBonus = this.calculationTax(price, taxStr) local getABonus = math.round(aBonus / #ridList) -- -- 发送邮件 -- 分配世界BOSS奖励 (10000钻石) WorldBoss.DistributeRewards( aBonus) -- local reward = { [coinType] = aBonus } -- -- 解析文本配置 -- local itemName = ConfigDataManager.getTableValue("cfg_item", "name", "id", cfgId) -- local priceTypeName = ConfigDataManager.getTableValue("cfg_item", "name", "id", coinType) -- local param = itemName .. "#" .. priceTypeName .. "#" .. aBonus .. "#" .. getABonus -- for _, rid in pairs(ridList) do -- if tonumber(rid) ~= buyerId then -- local player = getactor(rid) -- sendconfigmailbyrid(player, rid, AucMailConst.A_BONUS, reward, param) -- end -- end end -- 计算税率 function this.calculationTax(price, taxStr) local tableTax = {} string.putIntIntMap(tableTax, taxStr) local deleteRate = tableTax[1] this.debug("---- 拍卖行税率 ----", price, taxStr, tableTax) local totalPrice = math.round(price * (100 - deleteRate) / 100) local deleteCount = tableTax[2] totalPrice = totalPrice - deleteCount return totalPrice end function this.auctionIsOpen() -- boss被击杀才开启 -- local taskData = dataFunc.getKunDunTaskData() -- return taskData["stage"] == KunDun.TaskStage.DUP_FINISH return true end function this.isParticipate(actor) -- 参与了活动 -- local data = dataFunc.getKunDunPlayerData(actor) -- return table.notEmpty(data) return true end function aucDbFunc.getAuctionData() -- return dataFunc.getCrossGlobalData(__AuctionDbKey()) return getsysvar(__AuctionDbKey()) or {} end function aucDbFunc.setAuctionData(data) -- dataFunc.setCrossGlobalData(__AuctionDbKey(), data) setsysvar(__AuctionDbKey(), data) end function aucDbFunc.getPublishGoods() local data = aucDbFunc.getAuctionData() return data['publishgoods'] or {} end function aucDbFunc.setPublishGoods(goodsData) local data = aucDbFunc.getAuctionData() data['publishgoods'] = goodsData aucDbFunc.setAuctionData(data) end -- ------------------------------------------------------------- -- this.log_open = true this.log_name = "[WorldBossAuction]" function this.debug(...) if not this.log_open then return end gameDebug.print(this.log_name, ...) end function this.print(...) if not this.log_open then return end if param == nil then param = "error! 输出内容为空. nil" end jprint(this.log_name, ...) end function this.info(actor, ...) tipinfo(actor, ...) this.print(...) end -- ------------------------------------------------------------- --