| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541 |
- --新商业化活动——秘境翻牌
- --db
- --[=[
- human.db.absAct[id] = {
- freeCnt = nil, 当日免费抽取次数,为0时表示没有,为其他表示可以免费抽取一次
- normalAwardIdxTbl --普通奖励,value为配置表的Index
- normalAwardRecord = { --普通奖励获得记录,key为 normalAwardIdxTbl 中的索引,有值则表示获得了
- [1] = '1',
- [3] = '1',
- },
- lineAwardIdxTbl= = nil, --当前横排(上方)大奖Index列表, value为配置表的Index
- lineAwardRecord = { --横排大奖(上方)获得记录,key为 lineAwardRecord 中的索引,有值则表示获得了
- [1] = '1',
- [3] = '1',
- },
- rowAwardIdxTbl = nil, --当前竖排(右边)大奖Index列表, value为配置表的Index
- rowAwardRecord = { --竖排大奖(右边)获得记录,key为 rowAwardIdxTbl 中的索引,有值则表示获得了
- [1] = '1',
- [3] = '1',
- }
- }
- ]=]--
- local Msg = require("core.Msg")
- local Grid = require("bag.Grid")
- local BagLogic = require("bag.BagLogic")
- local AbsActLogic = require("absAct.AbsActLogic")
- local Broadcast = require("broadcast.Broadcast")
- local Lang = require("common.Lang")
- local AbsActExcel = require("excel.absAct")
- local YunYingLogic = require("yunying.YunYingLogic")
- local ItemDefine = require("bag.ItemDefine")
- local TriggerDefine = require("trigger.TriggerDefine")
- local TriggerLogic = require("trigger.TriggerLogic")
- local CycleActivityLogic = require("yunying.CycleActivity")
- local LOGTAG = "AbsLotteryCardLogic" --日志标识
- local LOTTERYCOSTTYPE = ItemDefine.ITEM_ZUANSHI_ID --抽奖消耗道具ID
- local LOTTERY1COSTCNT = 400 --单抽消耗的数量
- local LOTTERY10COSTCNT = 4000 --十连消耗的数量
- local RESETCOSTCNT = 1000 --重置需要消耗的数量
- local FOUR = 4
- --是否是GM模式, 为true时, 每次抽取只会获得没有抽到的奖励, 抽够一定次数, 则一定会获得所有奖励
- local isGmMode = false
- --生成奖励
- local function generateAwardByWeight(awardConfig, awardNum)
- local totalWeight = 0
- for _, v in pairs(awardConfig) do
- totalWeight = totalWeight + v[3]
- end
- local weight, randWeight = 0, 0
- local awardIdxTbl = {}
- for i=1, awardNum do
- weight = 0
- randWeight = math.random(0, totalWeight)
- for idx, cfg in ipairs(awardConfig) do
- weight = weight + cfg[3]
- if randWeight <= weight then
- awardIdxTbl[i] = idx
- break
- end
- end
- end
- return awardIdxTbl
- end
- --封装奖励协议数据结构
- local function populateAwardMsg(net, awardCfg, awardRecordData, indexTbl)
- net[0] = #indexTbl
- for k, awardIdx in ipairs(indexTbl) do
- net[k].idx = k
- net[k].getState = 0
- if awardRecordData and awardRecordData[k] then
- net[k].getState = 1
- end
- local itemInfo = awardCfg[awardIdx]
- Grid.makeItem(net[k].item, itemInfo[1], itemInfo[2])
- end
- end
- --封装协议数据结构
- local function populateMsg(msgRet, actData)
- msgRet.freeCnt = 0
- local freeCnt = actData.freeCnt
- if not freeCnt or freeCnt ~= 0 then
- msgRet.freeCnt = 1
- end
- local config = AbsActExcel.AbsLotteryCardLogic
- --普通奖励
- populateAwardMsg(msgRet.normalAwardInfo, config[1].award, actData.normalAwardRecord, actData.normalAwardIdxTbl)
- --横排大奖
- populateAwardMsg(msgRet.lineAwardInfo, config[2].award, actData.lineAwardRecord, actData.lineAwardIdxTbl)
- --竖排大奖
- populateAwardMsg(msgRet.rowAwardInfo, config[3].award, actData.rowAwardRecord, actData.rowAwardIdxTbl)
- end
- --计算一个值在4 x 4 矩阵中 横排和竖排的位置
- local function calcLineRowPos(num)
- local linePos, rowPos = 0, 0
- rowPos = num % FOUR
- if rowPos == 0 then
- rowPos = FOUR
- end
- linePos = math.ceil(num / FOUR)
- return linePos, rowPos
- end
- --判断是否获得横排(上方)大奖
- local function isGetLineAward(pos, awardRecordData)
- -- if pos % FOUR == 0 then
- -- pos = FOUR
- -- end
- local isGet = true
- for i=1, FOUR do
- if not awardRecordData[pos] then
- isGet = false
- break
- end
- pos = pos + FOUR
- end
- return isGet
- end
- --判断是否获得竖排(右边)大奖
- local function isGetRowAward(pos, awardRecordData)
- local isGet = true
- local startPos = (pos- 1) * FOUR + 1
- for i=1, FOUR do
- if not awardRecordData[startPos] then
- isGet = false
- break
- end
- startPos = startPos + 1
- end
- return isGet
- end
- --是否需要重置奖励
- local function isReset(lineTbl, rowTbl)
- local lineNum, rowNum = 0,0
- for _,_ in pairs(lineTbl or {}) do
- lineNum = lineNum + 1
- end
- if lineNum < FOUR then
- return false
- end
- for _,_ in pairs(rowTbl or {}) do
- rowNum = rowNum + 1
- end
- if rowNum < FOUR then
- return false
- end
- return true
- end
- --随机普通奖励,返回的是normalAwardIdxTbl的key
- local function randAwardIdx(normalAwardIdxTbl, normalAwardRecord, normalAwardCfg)
- local weight, randIdx, randWeight, totalWeight = 0,0,0,0
- local len = 0
- local subAwardIdxVec = {}
- for i, cfgIndex in ipairs(normalAwardIdxTbl) do
- if isGmMode and normalAwardRecord then --GM模式随机,剔除掉已经获得的奖励, 在剩下奖励中随机
- if not normalAwardRecord[i] then
- len = len + 1
- totalWeight = totalWeight + normalAwardCfg[cfgIndex][3]
- subAwardIdxVec[len] = {normalAwardCfg[cfgIndex][3], i}
- end
- else
- len = len + 1
- totalWeight = totalWeight + normalAwardCfg[cfgIndex][3]
- subAwardIdxVec[len] = {normalAwardCfg[cfgIndex][3], i}
- end
- end
- randWeight = math.random(0, totalWeight)
- for _, data in ipairs(subAwardIdxVec) do
- weight = weight + data[1]
- if randWeight <= weight then
- randIdx = data[2]
- break
- end
- end
- return randIdx
- end
- --重置奖励
- local function reset(actData)
- actData.normalAwardRecord = nil
- actData.lineAwardRecord = nil
- actData.rowAwardRecord = nil
- local config = AbsActExcel.AbsLotteryCardLogic
- actData.lineAwardIdxTbl = generateAwardByWeight(config[2].award, FOUR)
- actData.rowAwardIdxTbl = generateAwardByWeight(config[3].award, FOUR)
- end
- --抽奖
- local function lottery(human, actData, lotteryCnt, awardVec)
- local config = AbsActExcel.AbsLotteryCardLogic
- local normalAwardCfg = config[1].award
- local normalAwardRecord = actData.normalAwardRecord
- local normalAwardIdxTbl = actData.normalAwardIdxTbl
- local subCnt = -1
- local randPosList = {}
- --local isRepeat = false
- local repeatPosList = {}
- local getNormalAwardCnt = 0
- if normalAwardRecord then
- for _,_ in pairs(normalAwardRecord) do
- getNormalAwardCnt = getNormalAwardCnt + 1
- end
- end
- for i=1, lotteryCnt do
- local randPos = randAwardIdx(normalAwardIdxTbl, normalAwardRecord, normalAwardCfg)
- randPosList[#randPosList+1] = randPos
- local cfgIndex = normalAwardIdxTbl[randPos]
- local itemInfo = normalAwardCfg[cfgIndex]
- awardVec[#awardVec+1] = {itemInfo[1], itemInfo[2]}
- getNormalAwardCnt = getNormalAwardCnt + 1
- --当前抽得普通奖励大于4个且之前未抽到过该位置的奖励
- if getNormalAwardCnt >= FOUR and not normalAwardRecord[randPos] then
- local linePos, rowPos = calcLineRowPos(randPos)
- local lineAwardRecord = actData.lineAwardRecord
- local rowAwardRecord = actData.rowAwardRecord
- --更新普通奖励获得记录
- normalAwardRecord[randPos] = '1'
- local isGetLine, isGetRow = false, false
- --是否获得横排(上方的)大奖
- if not lineAwardRecord or not lineAwardRecord[rowPos] then
- isGetLine = isGetLineAward(rowPos, normalAwardRecord)
- if isGetLine then
- local cfgIdx = actData.lineAwardIdxTbl[rowPos]
- local lineAwardItem = config[2].award[cfgIdx]
- awardVec[#awardVec+1] = {lineAwardItem[1], lineAwardItem[2]}
- actData.lineAwardRecord = actData.lineAwardRecord or {}
- actData.lineAwardRecord[rowPos] = '1'
- end
- end
- --是否获得竖排(右方的)大奖
- if not rowAwardRecord or not rowAwardRecord[linePos] then
- isGetRow = isGetRowAward(linePos, normalAwardRecord)
- if isGetRow then
- local cfgIdx = actData.rowAwardIdxTbl[linePos]
- local rowAwardItem = config[3].award[cfgIdx]
- awardVec[#awardVec+1] = {rowAwardItem[1], rowAwardItem[2]}
- actData.rowAwardRecord = actData.rowAwardRecord or {}
- actData.rowAwardRecord[linePos] = '1'
- end
- end
- --是否所有奖励都领完, 需要重置奖励
- if isGetLine or isGetRow then
- if isReset(actData.lineAwardRecord, actData.rowAwardRecord) then
- reset(actData)
- subCnt = lotteryCnt - i
- break
- end
- end
- else
- if normalAwardRecord and normalAwardRecord[randPos] then
- --isRepeat = true
- repeatPosList[#repeatPosList+1] = randPos
- else
- normalAwardRecord = normalAwardRecord or {}
- normalAwardRecord[randPos] = '1'
- actData.normalAwardRecord = normalAwardRecord
- end
- end
- end
- return randPosList, repeatPosList, subCnt
- end
- --GM接口,设置本活动是否使用GM模式, val > 0 表示使用GM模式
- function SetMode(val)
- if val > 0 then
- isGmMode = true
- else
- isGmMode = false
- end
- end
- function isOpen(human, YYInfo, funcConfig)
- -- local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig.funcID)
- local state, endTime, startTime = CycleActivityLogic.isStarted(human, funcConfig.funcID)
- return state, endTime, startTime
- end
- function isActive(human, YYInfo, funcConfig)
- local state = isOpen(human, YYInfo, funcConfig)
- return not state
- end
- --红点判断
- function isRed(human, YYInfo, funcConfig)
- local actData = human.db.absAct[funcConfig.funcID]
- if not actData then
- return false
- end
- local freeCnt = actData.freeCnt
- if freeCnt and freeCnt == 0 then
- return false
- end
- return true
- 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.freeCnt = 1
- --红点刷新
- YunYingLogic.sendBanner(human)
- local config = AbsActExcel.absActivity[id]
- YunYingLogic.sendGroupUpdate(YYInfo[id], human, config.panelID)
- end
- --查询
- function Query(human, id)
- -- 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 msgRet = Msg.gc.GC_LOTTERYCARD_QUERY
- local config = AbsActExcel.AbsLotteryCardLogic
- if not actData.lineAwardIdxTbl then
- actData.lineAwardIdxTbl = generateAwardByWeight(config[2].award, FOUR)
- actData.rowAwardIdxTbl = generateAwardByWeight(config[3].award, FOUR)
- actData.normalAwardIdxTbl = generateAwardByWeight(config[1].award, 16)
- end
- populateMsg(msgRet, actData)
- Grid.makeItem(msgRet.lottery1Spend, LOTTERYCOSTTYPE, LOTTERY1COSTCNT)
- Grid.makeItem(msgRet.lottery10Spend, LOTTERYCOSTTYPE, LOTTERY10COSTCNT)
- Grid.makeItem(msgRet.resetSpend, LOTTERYCOSTTYPE, RESETCOSTCNT)
- Msg.send(msgRet, human.fd)
- end
- --抽奖, 可抽到重复奖励, 某行/列的普通奖励都获得时,自动获得对应行列的大奖,所有普通和大奖都获得时,重置奖励
- function Lottery(human, id, lotteryCnt)
- -- 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 lotteryCnt ~= 1 and lotteryCnt ~= 10 then
- return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
- end
- local itemSpendCnt = LOTTERY1COSTCNT
- if lotteryCnt == 1 then
- if not actData.freeCnt or actData.freeCnt ~= 0 then
- itemSpendCnt = 0
- actData.freeCnt = 0
- end
- else
- itemSpendCnt = LOTTERY10COSTCNT
- end
- if itemSpendCnt > 0 then
- if BagLogic.getItemCnt(human, LOTTERYCOSTTYPE) < itemSpendCnt then
- return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
- end
- --扣消耗
- BagLogic.delItem(human, LOTTERYCOSTTYPE, itemSpendCnt, LOGTAG)
- end
- --抽奖
- local awardVec = {}
- local randPosList, repeatPosList, subCnt = lottery(human, actData, lotteryCnt, awardVec)
- --全部奖励已获得,还有抽奖次数,需要先重置奖励
- if subCnt > 0 then
- local msgRet = Msg.gc.GC_LOTTERYCARD_RESET
- msgRet.isActive = 1
- populateMsg(msgRet, actData)
- Msg.send(msgRet, human.fd)
- randPosList, repeatPosList = lottery(human, actData, subCnt, awardVec)
- end
- --发放抽到的道具
- BagLogic.addItemList(human, awardVec, LOGTAG)
- local config = AbsActExcel.AbsLotteryCardLogic
- local awardCfg = config[1].award
- local msgRet = Msg.gc.GC_LOTTERYCARD_LOTTERY
- local normalAwardInfo = msgRet.normalAwardInfo
- normalAwardInfo[0] = #randPosList
- --小奖卡牌重复被翻到后,更换该牌的奖励
- local normalAwardIdxTbl = actData.normalAwardIdxTbl
- local newAwardPosList = generateAwardByWeight(config[1].award, #randPosList)
- for i, dbIdx in ipairs(repeatPosList) do
- --print(string.format("重复随机到奖励位置: %d, 新奖励在配置中位置: %d\n", dbIdx, newAwardPosList[i]))
- local cfgIdx = newAwardPosList[i]
- normalAwardIdxTbl[dbIdx] = cfgIdx
- end
- for i, dbIdx in ipairs(randPosList) do
- normalAwardInfo[i].idx = dbIdx
- normalAwardInfo[i].getState = 1
- local cfgIdx = normalAwardIdxTbl[dbIdx]
- local itemInfo = awardCfg[cfgIdx]
- Grid.makeItem(normalAwardInfo[i].item, itemInfo[1], itemInfo[2])
- end
- --下发数据
- msgRet.isRepeat = #repeatPosList > 0 and 1 or 0
- msgRet.freeCnt = 0
- local freeCnt = actData.freeCnt
- if not freeCnt or freeCnt ~= 0 then
- msgRet.freeCnt = 1
- end
- --普通奖励
- --populateAwardMsg(msgRet.normalAwardInfo, config[1].award, actData.normalAwardRecord, actData.normalAwardIdxTbl)
- --横排大奖
- populateAwardMsg(msgRet.lineAwardInfo, config[2].award, actData.lineAwardRecord, actData.lineAwardIdxTbl)
- --竖排大奖
- populateAwardMsg(msgRet.rowAwardInfo, config[3].award, actData.rowAwardRecord, actData.rowAwardIdxTbl)
- Msg.send(msgRet, human.fd)
- -- for i, idx in ipairs(randIds) do
- -- local cfgIdx = newAwardPosList[i]
- -- normalAwardIdxTbl[idx] = cfgIdx
- -- end
- --全部奖励已获得,没有抽奖次数,最后重置奖励
- if subCnt == 0 then
- local msgRet = Msg.gc.GC_LOTTERYCARD_RESET
- msgRet.isActive = 1
- populateMsg(msgRet, actData)
- Msg.send(msgRet, human.fd)
- -- 代表秘境翻盘完成一次?
- TriggerLogic.PublishEvent(TriggerDefine.SECRET_REALM, human.db._id, 1)
- end
- --更新红点
- if itemSpendCnt <= 0 then
- YunYingLogic.sendBanner(human)
- local config = AbsActExcel.absActivity[id]
- YunYingLogic.sendGroupUpdate(YYInfo[id], human, config.panelID)
- end
- end
- --重置
- function ResetAward(human, id)
- -- 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 BagLogic.getItemCnt(human, LOTTERYCOSTTYPE) < RESETCOSTCNT then
- return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
- end
- --扣消耗
- BagLogic.delItem(human, LOTTERYCOSTTYPE, RESETCOSTCNT, LOGTAG)
- --重置
- reset(actData)
- --下发数据
- local msgRet = Msg.gc.GC_LOTTERYCARD_RESET
- msgRet.isActive = 0
- populateMsg(msgRet, actData)
- Msg.send(msgRet, human.fd)
- end
|