local Activity = class("Activity", require("shared.ModelBase")) local string_format = string.format Activity.ActivityType = { Sign = 1, -- 签到 DoubleDrop = 2, -- 双倍掉落 FoodSell = 3, --贩卖周 料理 DrawHero = 4, --抽卡周 招募 AdvDraw = 5, --拾荒抽周 资助 OpenBox = 6, --拆解周 时钟箱 PaySignIn = 7, --付费签到 PayBack = 9, --返利 SsrUpPoolChange = 10, -- 特定英雄活动,切卡池 } local function checkActivityType(activityType) if type(activityType) == "string" then activityType = Activity.ActivityType[activityType] end return activityType or 0 end function Activity:ctor(properties) Activity.super.ctor(self, properties) self._isOpen = {} end Activity.schema = { actime = {"table", {}}, -- 最近检查某项活动的开始时间 {id = time} round = {"table", {}}, -- 记录活动到了第几轮 {id = roundnum} act1 = {"table", {}}, -- {0 = day, 1= -1, 2 = -1} == 签到活动 act3 = {"table", {}}, -- {0 = 抽卡次数, 1=1, 2=1} 抽卡周活动 1表示领取过该档位的奖励 act4 = {"table", {}}, -- {0 = 贩卖数量, 1=1, 2=1} 贩卖周活动 1表示领取过该档位的奖励 act5 = {"table", {}}, -- {0 = 拆解数量, 1=1, 2=1} 拆解周活动 1表示领取过该档位的奖励 act6 = {"table", {}}, -- {0 = 拾荒消耗远古金币数量, 1=1, 2=1} 拾荒周活动 1表示领取过该档位的奖励 act7 = {"table", {}}, -- {1 = 1, 2 = 1} == 付费签到活动 act9 = {"number", 0}, -- 充值返利 } function Activity:data() return { actime = self:getProperty("actime"), round = self:getProperty("round"), act1 = self:getProperty("act1"), act3 = self:getProperty("act3"), act4 = self:getProperty("act4"), act5 = self:getProperty("act5"), act6 = self:getProperty("act6"), act7 = self:getProperty("act7"), act9 = self:getProperty("act9"), } end function Activity:updateProperty(params) local type, default = table.unpack(self.schema[params.field]) if params.delta then self:incrProperty(params.field, params.delta) if not params.notNotify then self.owner:notifyUpdateProperty(params.field, self:getProperty(params.field)) end return true end if params.value then self:setProperty(params.field, params.value) if not params.notNotify then self.owner:notifyUpdateProperty(params.field, self:getProperty(params.field)) end return true end return false end function Activity:isOpenRaw(activityType, now) activityType = checkActivityType(activityType) local actData = csvdb["activity_ctrlCsv"][activityType] if not actData then return end if actData.time == "" then -- 关闭 return false end local st = 0 local et = 0 local now = skynet.timex() if actData.ttype == 0 then -- 时间开放 local openTimes = actData.time:toArray(false, "=") if openTimes[1] ~= "0" then st = toUnixtime(openTimes[1]..string_format("%02x", RESET_TIME)) end if openTimes[2] ~= "0" then et = toUnixtime(openTimes[2]..string_format("%02x", RESET_TIME)) end elseif actData.ttype == 1 then -- 周期开放 local openTimes = actData.time:toArray(true, "=") local resetTime = toUnixtime(tostring(openTimes[1]) .. string_format("%02x", RESET_TIME)) local r = math.floor((now - resetTime) / (openTimes[3] * 86400)) st = resetTime + r * (openTimes[3] * 86400) et = st + openTimes[2] * 86400 else return end if now >= st and (et == 0 or now < et) then return true, st end return false end -- 缓存开放 function Activity:isOpen(activityType) activityType = checkActivityType(activityType) return self._isOpen[activityType] end function Activity:getActData(actType) actType = checkActivityType(actType) return self:getProperty("act" .. actType) end function Activity:updateActData(actType, data, notNotify) actType = checkActivityType(actType) self:updateProperty({field = "act" .. actType, value = data, notNotify = notNotify}) end -- 跨天刷新 --登录刷新 function Activity:checkActivityStatus(now, isCrossDay, notify) self._isOpen = {} local actime = self:getProperty("actime") local change = false for actType, actData in pairs(csvdb["activity_ctrlCsv"]) do local isOpen, startTime = self:isOpenRaw(actType, now) self._isOpen[actType] = isOpen if isOpen then if actime[actType] and actime[actType] == startTime then -- 还是之前的状态 开放中 else -- 重置 actime[actType] = startTime self:closeActivity(actType, notify, true) self:initActivity(actType, isCrossDay, notify) change = true end else if actime[actType] then self:closeActivity(actType, notify) actime[actType] = nil change = true end end end if change then self:updateProperty({field = "actime", value = actime, notNotify = not notify}) end end local activityFunc = {} activityFunc[Activity.ActivityType.Sign] = { -- ["check"] = function(self, actType, notify) -- 检查 -- end, ["init"] = function(self, actType, isCrossDay, notify) if not isCrossDay then activityFunc[Activity.ActivityType.Sign]["crossDay"](self, actType, notify) end end, -- ["close"] = function(self, actType, notify) -- end, ["crossDay"] = function(self, actType, notify) local curData = self:getActData(actType) curData[0] = (curData[0] or 0) + 1 local actData = csvdb["new_signInCsv"] if curData[0] > #actData then return end -- 满了就忽略了 -- 没满更新一下 self:updateActData(actType, curData, not notify) end, } --loop1:累计料理贩卖N次 --loop2:累计招募N次 --loop3:累计资助N次 --loop4:时钟箱拆解N个 function Activity:checkWeeklyAct(actType, notify, count, pool) local actInfoMap = { [Activity.ActivityType.DrawHero] = {mailId = MailId.ActDrawCardReward, table = "activity_loop2Csv"}, [Activity.ActivityType.AdvDraw] = {mailId = MailId.ActAdvDrawReward, table = "activity_loop3Csv"}, [Activity.ActivityType.OpenBox] = {mailId = MailId.ActOpenBoxReward, table = "activity_loop4Csv"}, [Activity.ActivityType.FoodSell] = {mailId = MailId.ActSellFoodReward, table = "activity_loop1Csv"} } if actType == Activity.ActivityType.DrawHero and pool == DrawCardType.FriendDraw then return end local info = actInfoMap[actType] if not info then return end local curData = self:getActData(actType) local roundData = self:getProperty("round") local curRound = roundData[actType] or 0 local ctrlData = csvdb["activity_ctrlCsv"][actType] if not ctrlData then return end if curRound >= ctrlData.condition then return end curData[0] = (curData[0] or 0) + count local totalCnt = 0 local finishCnt = 0 local maxCondition = 0 for k, cfg in pairs(csvdb[info.table] or {}) do totalCnt = totalCnt + 1 if maxCondition < cfg.condition1 then maxCondition = cfg.condition1 end if not curData[cfg.id] and curData[0] >= cfg.condition1 then if info.mailId then self.owner:log("activity", { activity_id = cfg.id, -- 活动ID(或活动指定任务的ID) activity_type = actType, -- 活动类型,见活动类型枚举表 activity_reward = cfg.reward:toNumMap(), -- 活动奖励,json格式记录,{'itemid1':123,'itemid2':456,………...} }) self.owner:sendMail(info.mailId, nil, cfg.reward, {cfg.condition1}) curData[cfg.id] = 1 end end if curData[cfg.id] then finishCnt = finishCnt + 1 end end if totalCnt == finishCnt then roundData[actType] = curRound + 1 for k,v in pairs(curData) do if k == 0 then curData[k] = curData[0] >= maxCondition and curData[0] - maxCondition or 0 else curData[k] = nil end end self:updateProperty({field = "round", value = roundData, notNotify = not notify}) end self:updateActData(actType, curData, not notify) end -- 抽卡周 activityFunc[Activity.ActivityType.DrawHero] = { ["check"] = function(self, actType, notify, count, pool) -- 检查 self:checkWeeklyAct(actType, notify, count, pool) end, ["init"] = function(self, actType, isCrossDay, notify) local roundData = self:getProperty("round") roundData[actType] = 0 self:updateProperty({field = "round", value = roundData, notNotify = not notify}) end, -- ["close"] = function(self, actType, notify) -- end, ["crossDay"] = function(self, actType, notify) self.owner:sendMail(MailId.ActDrawCard) end, } -- 售卖周 activityFunc[Activity.ActivityType.FoodSell] = { ["check"] = function(self, actType, notify, count) -- 检查 self:checkWeeklyAct(actType, notify, count) end, ["init"] = function(self, actType, isCrossDay, notify) local roundData = self:getProperty("round") roundData[actType] = 0 self:updateProperty({field = "round", value = roundData, notNotify = not notify}) end, -- ["close"] = function(self, actType, notify) -- end, ["crossDay"] = function(self, actType, notify) self.owner:sendMail(MailId.ActSellFood) end, } -- 拾荒周 activityFunc[Activity.ActivityType.AdvDraw] = { ["check"] = function(self, actType, notify, count) -- 检查 self:checkWeeklyAct(actType, notify, count) end, ["init"] = function(self, actType, isCrossDay, notify) local roundData = self:getProperty("round") roundData[actType] = 0 self:updateProperty({field = "round", value = roundData, notNotify = not notify}) end, -- ["close"] = function(self, actType, notify) -- end, ["crossDay"] = function(self, actType, notify) self.owner:sendMail(MailId.ActAdvDraw) end, } -- 拆解周 activityFunc[Activity.ActivityType.OpenBox] = { ["check"] = function(self, actType, notify, count) -- 检查 self:checkWeeklyAct(actType, notify, count) end, ["init"] = function(self, actType, isCrossDay, notify) local roundData = self:getProperty("round") roundData[actType] = 0 self:updateProperty({field = "round", value = roundData, notNotify = not notify}) end, -- ["close"] = function(self, actType, notify) -- end, ["crossDay"] = function(self, actType, notify) self.owner:sendMail(MailId.ActOpenBox) end, } -- 付费签到 activityFunc[Activity.ActivityType.PaySignIn] = { ["init"] = function(self, actType, isCrossDay, notify) self:updateActData(actType, {}, not notify) end, -- ["close"] = function(self, actType, notify) -- end, } -- 充值反馈 activityFunc[Activity.ActivityType.PayBack] = { ["check"] = function(self, actType, notify, twd) -- 检查 local oldVal = self:getActData(actType) or 0 local newVal = oldVal + twd local gift = self.owner:getPaybackReward(oldVal, newVal) if gift ~= "" then self.owner:sendMail(MailId.MonthCard, nil, gift) end self:updateActData(actType, newVal, not notify) end, ["init"] = function(self, actType, isCrossDay, notify) self:updateActData(actType, {}, not notify) end, -- ["close"] = function(self, actType, notify) -- end, } function Activity:initActivity(actType, isCrossDay, notify) if activityFunc[actType] and activityFunc[actType]['close'] then activityFunc[actType]["init"](self, actType, isCrossDay, notify) end end function Activity:closeActivity(actType, notify, notUpdateAct) if activityFunc[actType] and activityFunc[actType]['close'] then activityFunc[actType]["close"](self, actType, notify) end if Activity.schema["act".. actType] then self:updateActData(actType, Activity.schema["act" .. actType][2], not notify or notUpdateAct) end end function Activity:refreshDailyData(notify) for actType, status in pairs(self._isOpen) do if status then if activityFunc[actType] and activityFunc[actType]['crossDay'] then activityFunc[actType]["crossDay"](self, actType, notify) end end end end function Activity:checkActivity(notNotify, activityType, ...) if not activityType then return end if not self:isOpen(activityType) then return end if activityFunc[activityType] and activityFunc[activityType]['check'] then activityFunc[activityType]["check"](self, activityType, not notNotify, ...) end end -- 获取此次挂机掉落翻倍时长 function Activity:getActHangDoubleTime(lastTs, nowTs) local type = "DoubleDrop" local actId = checkActivityType(type) local isOpen = self:isOpen(type) local openTs = self:getProperty("actime")[actId] or 0 local timeNow = skynet.timex() lastTs = math.max(lastTs, openTs) if isOpen then if nowTs > openTs and nowTs > lastTs then return nowTs - lastTs else return 0 end end return 0 end -- 获取活动卡池id function Activity:getActivityPool(mainType, subType) if not self:isOpen(Activity.ActivityType.SsrUpPoolChange) then return 0 end local actData = csvdb["activity_ctrlCsv"][Activity.ActivityType.SsrUpPoolChange] if not actData then return 0 end local poolMap = actData.condition2:toMap(true, "=") local key = mainType .. "_" .. subType for k, v in pairs(poolMap) do if k == key then return v end end return 0 end -- 付费签到可领奖励 function Activity:getPaySignReward() local actGoodsFlag = self.owner.storeData:getProperty("actGoodsFlag") local index = GetActGoodsIndex("paySignIn") local flag = actGoodsFlag[index] or 0 if flag == 0 then return {} end if not self.owner.activity:isOpen("PaySignIn") then return {} end local diffDay = diffFromOpen() + 1 local curData = self:getActData("PaySignIn") local reward, change = {} for day, csvData in pairs(csvdb["pay_signInCsv"]) do if day <= diffDay then if not curData[day] then curData[day] = 1 -- 奖励 for itemId, count in pairs(csvData.reward:toNumMap()) do reward[itemId] = (reward[itemId] or 0) + count end end else break end end return reward, curData --if next(reward) then --role.activity:updateActData("PaySignIn", curData) --reward, change = role:award(reward, {log = {desc = "actPaySign"}}) --end --role:log("activity", { -- activity_id = curData[0], -- 活动ID(或活动指定任务的ID) -- activity_type = role.activity.ActivityType.PaySignIn, -- 活动类型,见活动类型枚举表 -- activity_reward = reward, -- 活动奖励,json格式记录,{'itemid1':123,'itemid2':456,………...} --}) --SendPacket(actionCodes.Activity_actPaySignRpc, MsgPack.pack(role:packReward(reward, change))) end return Activity