--夺宝奇兵活动 --玩法: 从四条配置中各随机一个奖励, 然后把这4个奖励按照一定数量组成一个奖池给玩家抽奖, 奖励抽到后就减少 --注意事项:活动开启期间, 不能改4条配置中prizeData里各个奖励的顺序,因为服务器存储的是随机到的奖励的index --db --[=[ human.db.absAct[id] = { awardData = { [type] = {idx = 1, cnt = 1}, --key为奖池类型,idx为配置中随机到的奖励index,cnt表示当前奖励数量 }, isFreeReset = nil, --免费重置标识, 1-免费 posData = { --已经抽奖的位置, pos为位置 [pos] = {poolType = poolType, idx = idx} }, isStart = nil, --是否开始游戏 isTips = nil, --提示, 为0时不提示,其他情况都提示 dailyFreeState = nil, --每日单抽免费标识,为0时不免费,其他情况免费 } } ]=]-- local Msg = require("core.Msg") local Grid = require("bag.Grid") local Util = require("common.Util") local BagLogic = require("bag.BagLogic") local ItemDefine = require("bag.ItemDefine") local AbsActLogic = require("absAct.AbsActLogic") local Broadcast = require("broadcast.Broadcast") local Lang = require("common.Lang") local duobaoCfg = require("excel.absAct").DuoBaoQiBing local YunYingLogic = require("yunying.YunYingLogic") local AbsActExcel = require("excel.absAct") local TriggerDefine = require("trigger.TriggerDefine") local TriggerLogic = require("trigger.TriggerLogic") local CycleActivityLogic = require("yunying.CycleActivity") local LOGTYPE = "duobaoqibing" --日志标识 local POOL1CNT = 30 --从奖池1中抽取的奖励数量 local POOL2CNT = 12 --从奖池2中抽取的奖励数量 local POOL3CNT = 2 --从奖池3中抽取的奖励数量 local POOL4CNT = 1 --从奖池4中抽取的奖励数量 local LOTTERYCOSTCNT = 400 --单抽消耗数量 local RESETCOSTCNT = 1000 --重置消耗数量 local COSTITEMID = ItemDefine.ITEM_ZUANSHI_ID --单抽/重置消耗的道具id local function getAwardNumByType(poolType) local num = 0 if not poolType then return num end if poolType == 1 then num = POOL1CNT elseif poolType == 2 then num = POOL2CNT elseif poolType == 3 then num = POOL3CNT elseif poolType == 4 then num = POOL4CNT end return num end --从配置中随机一个奖励,并返回奖励的index local function getAwardIdx(awardCfg) local totalWeight = 0 for _, v in ipairs(awardCfg.prizeData) do totalWeight = totalWeight + v[3] end local randWeight = math.random(0, totalWeight) local weight, randIdx = 0, 0 for idx, data in ipairs(awardCfg.prizeData) do weight = weight + data[3] if randWeight <= weight then randIdx = idx break end end return randIdx end --生成奖励数据 local function generateAwardData(human, id) human.db.absAct[id] = human.db.absAct[id] or {} local actData = human.db.absAct[id] actData.awardData = actData.awardData or {} local awardData = actData.awardData for type, cfg in ipairs(duobaoCfg) do local awardIdx = getAwardIdx(cfg) awardData[type] = { idx = awardIdx, cnt = getAwardNumByType(type), --type = type } end end --填充协议数据 local function populateMsg(actData, msgTb) local awardData = actData.awardData local posData = actData.posData local awardNum, len = 0, 0 for i=1, 4 do awardNum = getAwardNumByType(i) local awardIdx = awardData[i].idx local awardInfo = duobaoCfg[i].prizeData[awardIdx] for j=1, awardNum do len = len + 1 msgTb[len].isGet = 0 msgTb[len].poolType = i msgTb[len].index = len Grid.makeItem(msgTb[len].item, awardInfo[1], awardInfo[2]) if posData and posData[len] then msgTb[len].isGet = 1 local poolType = posData[len].poolType --奖池类型不一样, 说明该位置抽到的是别的奖池的道具, 需要修改道具信息 if poolType ~= i then msgTb[len].poolType = poolType awardIdx = posData[len].idx local realAwardInfo = duobaoCfg[poolType].prizeData[awardIdx] Grid.makeItem(msgTb[len].item, realAwardInfo[1], realAwardInfo[2]) end end end end msgTb[0] = len end --生成抽奖数据 local function generateLotteryData(actData) local awardVec = {} local len, totalWeight = 0,0 local awardData = actData.awardData for type, data in ipairs(awardData) do if data.cnt > 0 then local awardInfo = duobaoCfg[type].prizeData[data.idx] local itemId = awardInfo[1] local itemNum = awardInfo[2] local weight = awardInfo[3] for i=1, data.cnt do len = len + 1 totalWeight = totalWeight + weight awardVec[len] = {itemId, itemNum, weight, type, data.idx} end end end return awardVec, totalWeight end --刷天处理 function updateDaily(human, id) -- local state = AbsActLogic.isStarted(human, id) local state = CycleActivityLogic.isStarted(human, id) if not state then return end local actData = human.db.absAct[id] if not actData then return end actData.isTips = 1 actData.dailyFreeState = 1 end function isRed(human, YYInfo, absActConfig) local id = absActConfig.funcID -- local state = AbsActLogic.isStarted(human, id) local state = CycleActivityLogic.isStarted(human, id) if not state then return false end local actData = human.db.absAct[id] if not actData then return false end if actData.dailyFreeState and actData.dailyFreeState == 0 then return false end return true end --查询 function Query(human, id) -- local state = AbsActLogic.isStarted(human, id) -- print("[DuoBaoQiBing_Query ] id = "..id.." name = "..human.db.name) local state = CycleActivityLogic.isStarted(human, id) if not state then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end local actData = human.db.absAct[id] if not actData then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end local msgRet = Msg.gc.GC_DBQB_QUERY msgRet.isFreeReset = actData.isFreeReset or 0 msgRet.isStart = actData.isStart or 0 msgRet.isTips = 1 if actData.isTips and actData.isTips == 0 then msgRet.isTips = 0 end msgRet.isFree = 0 if not actData.dailyFreeState or actData.dailyFreeState == 1 then msgRet.isFree = 1 end if not actData or not actData.awardData then generateAwardData(human, id) end Grid.makeItem(msgRet.lotteryCost, COSTITEMID, LOTTERYCOSTCNT) Grid.makeItem(msgRet.resetCost, COSTITEMID, RESETCOSTCNT) populateMsg(actData, msgRet.awardPoolData) Msg.send(msgRet, human.fd) end --奖池重置 function ResetAwardPool(human, id, resetType) if not id or not resetType then return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end -- local state = AbsActLogic.isStarted(human, id) local state = CycleActivityLogic.isStarted(human, id) if not state then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end local actData = human.db.absAct[id] if not actData then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end if resetType == 1 then if not actData.isFreeReset or actData.isFreeReset <= 0 then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end actData.isFreeReset = 0 elseif resetType == 2 then if BagLogic.getItemCnt(human, COSTITEMID) < RESETCOSTCNT then return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH) end BagLogic.delItem(human, COSTITEMID, RESETCOSTCNT, LOGTYPE) else return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end --重置数据 generateAwardData(human, id) actData.posData = nil actData.isStart = 0 --通知客户端 local msgRet = Msg.gc.GC_DBQB_RESET msgRet.isFreeReset = actData.isFreeReset or 0 msgRet.isStart = actData.isStart or 0 populateMsg(actData, msgRet.awardPoolData) Msg.send(msgRet, human.fd) end --抽奖 function Lottery(human, id, pos) if not id or not pos then return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end if 1 > pos or pos > (POOL1CNT + POOL2CNT + POOL3CNT + POOL4CNT) then return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end -- local state = AbsActLogic.isStarted(human, id) local state = CycleActivityLogic.isStarted(human, id) if not state then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end local actData = human.db.absAct[id] if not actData then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end local posData = actData.posData if posData and posData[pos] then return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end local itemCnt = LOTTERYCOSTCNT if not actData.dailyFreeState or actData.dailyFreeState == 1 then itemCnt = 0 actData.dailyFreeState = 0 end --扣消耗 if itemCnt > 0 then if BagLogic.getItemCnt(human, COSTITEMID) < itemCnt then return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH) end BagLogic.delItem(human, COSTITEMID, itemCnt, LOGTYPE) end --抽奖 local awardVec, totalWeight = generateLotteryData(actData) if #awardVec <= 0 then return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end local itemId, itemCnt, weight, poolType, awardIdx = 0,0,0,0,0 local randWeight = math.random(0, totalWeight) for _,v in ipairs(awardVec) do weight = weight + v[3] if randWeight <= weight then itemId = v[1] itemCnt = v[2] poolType = v[4] awardIdx = v[5] break end end --BagLogic.addItem(human, itemId, itemCnt, LOGTYPE) BagLogic.addItemList(human, { {itemId, itemCnt}}, LOGTYPE) --更新db actData.posData = actData.posData or {} actData.posData[pos] = { poolType = poolType, idx = awardIdx } actData.awardData[poolType].cnt = actData.awardData[poolType].cnt - 1 if poolType == 4 then --抽到特殊奖励, 获得免费刷新奖池一次 actData.isFreeReset = 1 TriggerLogic.PublishEvent(TriggerDefine.DRAGON_PEARL, human.db._id, 1) end --通知客户端 local msgRet = Msg.gc.GC_DBQB_LOTTERY msgRet.isFreeReset = actData.isFreeReset or 0 msgRet.isFree = 0 --有免费次数会优先使用免费次数, 所以抽奖后,免费次数就没有了 --populateMsg(actData, msgRet.awardPoolData) local posInfo = msgRet.posInfo posInfo.isGet = 1 posInfo.poolType = poolType posInfo.index = pos Grid.makeItem(posInfo.item, itemId, itemCnt) Msg.send(msgRet, human.fd) --红点刷新 if itemCnt == 0 then local config = AbsActExcel.absActivity[id] YunYingLogic.sendGroupUpdate(YYInfo[id], human, config.panelID) end end --点击开始游戏 function StartGame(human, id) if not id then return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end -- local state = AbsActLogic.isStarted(human, id) local state = CycleActivityLogic.isStarted(human, id) if not state then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end local actData = human.db.absAct[id] if not actData then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end --修改状态 actData.isStart = 1 --通知客户端 local msgRet = Msg.gc.GC_DBQB_START_GAME msgRet.isStart = actData.isStart or 0 Msg.send(msgRet, human.fd) end --关闭提示 function CloseTips(human, id) if not id then return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end -- local state = AbsActLogic.isStarted(human, id) local state = CycleActivityLogic.isStarted(human, id) if not state then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end local actData = human.db.absAct[id] if not actData then return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME) end --修改状态 actData.isTips = 0 --通知客户端 local msgRet = Msg.gc.GC_DBQB_TIPS msgRet.isTips = actData.isTips or 0 Msg.send(msgRet, human.fd) end