local ipairs = ipairs local table = table local math = math local string = string local redisproxy = redisproxy local MsgPack = MsgPack local string_format = string.format local tonumber = tonumber local table_insert = table.insert local table_unpack = table.unpack local table_find = table.find local table_nums = table.nums local math_random = math.randomInt local _M = {} function _M.sudokuRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local id = msg.id local sudoku = role:getProperty("sudoku") local phase = sudoku[-1] or 1 local curData = (csvdb["guide_sudokuCsv"][phase] or {})[id] if phase == -1 or not curData then return 1 end sudoku.task = sudoku.task or {} sudoku.task[phase] = sudoku.task[phase] or {} if (sudoku.task[phase][id] or 0) < curData.con1 then return 2 end sudoku.task[phase][id] = -1 local task, tchange = role:award(curData.reward, {log = {desc = "sudoku", int1 = id, int2 = phase}}) -- 任务奖励 local reward, rchange = {} local rId = {} for pid, pdata in pairs(csvdb["guide_sudoku_rewardCsv"][phase] or {}) do local pos = pdata.pos:toArray(true, "=") local ok, is = true, false for _, one in pairs(pos) do if one == id then is = true end if sudoku.task[phase][one] ~= -1 then ok = false break end end if ok and is then for itemId, count in pairs(pdata.reward:toNumMap()) do reward[itemId] = (reward[itemId] or 0) + count end table.insert(rId, pid) end end if not next(reward) then reward = nil else reward, rchange = role:award(reward, {log = {desc = "sudokuR", int1 = id, int2 = phase}}) end role:updateProperty({field = "sudoku", value = sudoku}) role:log("activity", { activity_id = id, -- 活动ID(或活动指定任务的ID) activity_type = 0, -- 活动类型,见活动类型枚举表 activity_reward = reward or {}, -- 活动奖励,json格式记录,{'itemid1':123,'itemid2':456,………...} }) role:mylog("act_action", {desc = "sudoku", int1 = id, int2 = phase}) SendPacket(actionCodes.Activity_sudokuRpc, MsgPack.pack({task = role:packReward(task, tchange), reward = role:packReward(reward, rchange), rId = rId})) return true end function _M.sudokuRewardRpc(agent, data) local role = agent.role local sudoku = role:getProperty("sudoku") local phase = sudoku[-1] or 1 local curData = csvdb["guide_sudokuCsv"][phase] if not curData then return end if not globalCsv.guide_sudoku_reward[phase] then return end local curTask = (sudoku.task or {})[phase] or {} for id, _ in pairs(curData) do if curTask[id] ~= -1 then return end end local reward, change = role:award(globalCsv.guide_sudoku_reward[phase], {log = {desc = "sudokuRP", int1 = phase}}) sudoku[-1] = phase + 1 sudoku.task[phase] = nil if not csvdb["guide_sudokuCsv"][sudoku[-1]] then sudoku[-1] = -1 sudoku.task = nil end role:updateProperty({field = "sudoku", value = sudoku}) role:log("activity", { activity_id = 10000 + phase, -- 活动ID(或活动指定任务的ID) activity_type = 0, -- 活动类型,见活动类型枚举表 activity_reward = reward, -- 活动奖励,json格式记录,{'itemid1':123,'itemid2':456,………...} }) SendPacket(actionCodes.Activity_sudokuRewardRpc, MsgPack.pack(role:packReward(reward, change))) return true end function _M.signRpc(agent, data) local role = agent.role local serverT = skynet.timex() local tm = os.date("*t", serverT) local curDay = tm.day local yearMonth = tm.year * 100 + tm.month local monthData = csvdb["daily_signInCsv"][yearMonth] if not monthData or not monthData[curDay] then return 1 end local signs = role:getProperty("sign") if signs[curDay] == yearMonth then -- 未重置的还可以签到正常(本月已经签到) return 2 end signs[curDay] = yearMonth local reward, change = role:award(monthData[curDay].item, {log = {desc = "sign", int1 = yearMonth, int2 = curDay}}) role:changeUpdates({{type = "sign", field = curDay, value = yearMonth}}) role:checkTaskEnter("SignIn") SendPacket(actionCodes.Activity_signRpc, MsgPack.pack(role:packReward(reward, change))) return true end function _M.actSignRpc(agent, data) local role = agent.role if not role.activity:isOpen("Sign") then return 1 end local curData = role.activity:getActData("Sign") local reward, change = {} for day, csvData in ipairs(csvdb["new_signInCsv"]) do if day <= (curData[0] or 0) 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 if next(reward) then role.activity:updateActData("Sign", curData) reward, change = role:award(reward, {log = {desc = "actSign"}}) end role:log("activity", { activity_id = curData[0], -- 活动ID(或活动指定任务的ID) activity_type = role.activity.ActivityType.Sign, -- 活动类型,见活动类型枚举表 activity_reward = reward, -- 活动奖励,json格式记录,{'itemid1':123,'itemid2':456,………...} }) SendPacket(actionCodes.Activity_actSignRpc, MsgPack.pack(role:packReward(reward, change))) return true end function _M.actPaySignRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local dayIndex = msg.day local actGoodsFlag = role.storeData:getProperty("actGoodsFlag") local index = GetActGoodsIndex("paySignIn") local ts = actGoodsFlag[index] or 0 if ts == 0 then return 1 end local open, actId = role.activity:isOpen("PaySignIn") if not open then return 2 end --local diffDay = diffFromTs(ts) + 1 local curData = role.activity:getActData("PaySignIn") if not curData then return 3 end local reward, change = {} for day, csvData in ipairs(csvdb["pay_signInCsv"]) do if day <= (curData[0] or 0) and day == dayIndex 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 if next(reward) then role.activity:updateActData("PaySignIn", curData) reward, change = role:award(reward, {log = {desc = "actPaySign"}}) end role:log("activity", { activity_id = actId, -- 活动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))) return true end function _M.actCalendaTaskRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local taskId = msg.id local calTask = role:getProperty("calTask") or {} local record = calTask["r"] or {} local flag = record[taskId] or 0 if flag == 1 then return 1 end local open, actId = role.activity:isOpen("CalendaTask") local actData = csvdb["activity_ctrlCsv"][actId] if not open then return 2 end if not actData then return 3 end local taskList = csvdb["activity_taskCsv"][actData.condition] if not taskList then return 4 end local taskCfg = taskList[taskId] if not taskCfg then return 5 end if taskCfg.key ~= actData.condition then return 6 end if (calTask[taskId] or 0) < taskCfg.condition1 then return 7 end record[taskId] = 1 calTask["r"] = record role:updateProperty({field = "calTask", value = calTask}) local reward, change = role:award(taskCfg.reward, {log = {desc = "calendaTask"}}) role:log("activity", { activity_id = taskId, -- 活动ID(或活动指定任务的ID) activity_type = role.activity.ActivityType.CalendaTask, -- 活动类型,见活动类型枚举表 activity_reward = reward, -- 活动奖励,json格式记录,{'itemid1':123,'itemid2':456,………...} }) SendPacket(actionCodes.Activity_actCalendaTaskRpc, MsgPack.pack(role:packReward(reward, change))) return true end function _M.exchangeRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local actid = msg.actid local id = msg.id local count = msg.count if not role.activity:isOpenById(actid, "Exchange") then return 1 end local exchangeCfg = csvdb["activity_exchangeCsv"][actid] if not exchangeCfg then return 2 end if not exchangeCfg[id] then return 3 end local curData = role.activity:getActData("Exchange") or {} local exchangeData = curData[actid] or {} local curCount = exchangeData[id] or 0 local actCfg = exchangeCfg[id] local limitArr = actCfg.limit:toArray(true, "=") if curCount + count > limitArr[2] then return 4 end local costs = actCfg.goods:toNumMap() for k,v in pairs(costs) do costs[k] = v * count end if not role:checkItemEnough(costs) then return 5 end role:costItems(costs, {log = {desc = "actExchange", int1 = actid, int2 = id}}) curCount = curCount + count exchangeData[id] = curCount curData[actid] = exchangeData role.activity:updateActData("Exchange", curData) local award = actCfg.award:toNumMap() for k,v in pairs(award) do award[k] = v * count end local reward, change = role:award(award, {log = {desc = "actExchange", int1 = actid, int2 = id}}) SendPacket(actionCodes.Activity_exchangeRpc, MsgPack.pack(role:packReward(reward, change))) return true end function _M.gachakonRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local actid = msg.actid local count = msg.count if count > 10 then return end if not role.activity:isOpenById(actid, "Gachakon") then return 1 end local actCtrlData = csvdb["activity_ctrlCsv"][actid] if not actCtrlData then return 2 end local cost = actCtrlData.condition2:toNumMap() local actCfg = csvdb["activity_capsuleToysCsv"][actid] if not actCfg then return 3 end local gachakonInfo = role.activity:getActData("Gachakon") or {} local award = {} local remain = 0 local showAward = {} for i = 1, count do local tmpCfg = clone(actCfg) remain = 0 for id, cfg in pairs(tmpCfg) do local num = gachakonInfo[id] or 0 num = cfg.amount >= num and cfg.amount - num or 0 cfg.weight = cfg.weight * num if cfg.weight > 0 then remain = remain + num end --print("num ".. num, id, cfg.weight, cfg.amount) end if remain == 0 then break end local id = math.randWeight(tmpCfg, "weight") if not id then return 4 end gachakonInfo[id] = (gachakonInfo[id] or 0) + 1 local curAward = tmpCfg[id].award:toNumMap() table.insert(showAward, curAward) for k, v in pairs(curAward) do award[k] = (award[k] or 0) + v end end for k, v in pairs(cost) do cost[k] = v * count end if not role:checkItemEnough(cost) then return 5 end role:costItems(cost, {log = {desc = "actGachakon", int1 = actid, int2 = count}}) local reward, change = role:award(award, {log = {desc = "actGachakon", int1 = actid, int2 = count}}) --print("-----------", remain, count) if remain <= 1 then gachakonInfo = {} end role.activity:updateActData("Gachakon", gachakonInfo) SendPacket(actionCodes.Activity_gachakonRpc, MsgPack.pack(showAward)) return true end function _M.hangDropRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local actid = msg.actid if not role.activity:isOpenById(actid, "HangDrop") then return 1 end local actCtrlData = csvdb["activity_ctrlCsv"][actid] if not actCtrlData then return end local actCfg = csvdb["activity_putCsv"][actid] if not actCfg then return 2 end local award, period = "", 0 for i = 1, #actCfg do local cfg = actCfg[i] if not cfg then break end if cfg.condition ~= "" then local arr = cfg.condition:toArray(true, "=") local type = arr[1] if type == 1 then local actId = arr[2] local carbonId = arr[3] if not role.activity:isOpenById(actId, "ChallengeLevel") then return 3 end local clInfo = role.activity:getActData("ChallengeLevel") or {} if not clInfo[carbonId] then break end end end award = cfg.reward period = cfg.period * 60 end local actData = role.activity:getActData("HangDrop") or 0 local timeNow = skynet.timex() if period == 0 or award == "" then return 4 end local num = math.floor((timeNow - actData)/ period) num = num > actCtrlData.condition and actCtrlData.condition or num if num == 0 then return 5 end local reward, change = {}, nil for id, value in pairs(award:toNumMap()) do reward[id] = value * num end reward, change = role:award(reward, {log = {desc = "actHangDrop", int1 = actid, int2 = num}}) if num < 8 then actData = actData + num * period else actData = timeNow end role.activity:updateActData("HangDrop", actData) SendPacket(actionCodes.Activity_hangDropRpc, MsgPack.pack(role:packReward(reward, change))) return true end local function getStarCount(cfg, data) local count = 0 for i = 0, #(cfg.sweep_condition:toTableArray(true)) do if (1 << i & data) > 0 then count = count + 1 end end return count end function _M.startBattleRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local actid = msg.actid local id = msg.id local count = msg.count if not role.activity:isOpenById(actid, "ChallengeLevel") then return 1 end local actCfg = csvdb["activity_battleCsv"][actid] if not actCfg then return 2 end local battleCfg = actCfg[id] if not battleCfg then return 3 end local actData = role.activity:getActData("ChallengeLevel") or {} local preArr = battleCfg.prepose:toArray(true, "=") for _, v in ipairs(preArr) do local battleInfo = actData[v] if not battleInfo then return 4 end local star = battleInfo["star"] or 0 if star <= 0 then return 4 end end -- check cost local changeFlag = false local ticket = actData["ticket"] local num = 0 -- cost num if battleCfg.type ~= "" then role.activity:getBattleTicket(actid) num = battleCfg.type:toArray(true, "=")[3] if count and count > 0 then if battleCfg.rank == 0 then return 7 end local bi = actData[id] if not bi then return 8 end local star = bi["star"] or 0 if star < 1 then return 9 end num = num * count end if ticket < num then return 6 end changeFlag = true end -- 解锁活动剧情 role:checkStoryStatus(false, 5, id) if not count then role.__actBattleCache = { key = tostring(math.random()), actid = actid, id = id, } SendPacket(actionCodes.Activity_startBattleRpc, MsgPack.pack({key = role.__actBattleCache.key})) else if count <= 0 then return end if battleCfg.rank == 0 then return 7 end local bi = actData[id] local star = bi["star"] local award = battleCfg.item_clear:toNumMap() if getStarCount(battleCfg, star) == 3 then local aw = battleCfg.perfect_reward:toNumMap() for k, v in pairs(aw) do award[k] = (award[k] or 0) + v end end for k, v in pairs(award) do award[k] = v * count end local reward, change = role:award(award, {log = {desc = "actBattle", int1 = actid, int2 = count or 0}}) SendPacket(actionCodes.Activity_startBattleRpc, MsgPack.pack(role:packReward(reward, change))) if battleCfg.worldBoss_award ~= 0 and (bi["maxP"] or 0) > 0 then bi["bossP"] = (bi["bossP"] or 0) + bi["maxP"] end bi["sum"] = bi["sum"] + bi["top"] actData["ticket"] = ticket - num actData[id] = bi changeFlag = true local rankVal = 0 if battleCfg.rank == 1 then rankVal = bi["sum"] elseif battleCfg.rank == 2 then rankVal = bi["top"] end role:updateRankCommon(RANK_TYPE.ActBattleBoss, rankVal) end if changeFlag then role.activity:updateActData("ChallengeLevel", actData) end return true end function _M.endBattleRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local actid = msg.actid local id = msg.id local key = msg.key local isWin = msg.isWin local heros = msg.heros local support = msg.support if not role.activity:isOpenById(actid, "ChallengeLevel") then return 1 end if not role.__actBattleCache then return 2 end if role.__actBattleCache.id ~= id or role.__actBattleCache.key ~= key and role.__actBattleCache.actid ~= actid then SendPacket(actionCodes.Activity_endBattleRpc, MsgPack.pack({errorCode = 1})) end local actCfg = csvdb["activity_battleCsv"][actid] if not actCfg then return 3 end local battleCfg = actCfg[id] if not battleCfg then return 4 end local actData = role.activity:getActData("ChallengeLevel") or {} -- 总输出 local dmg = 0 for k, v in pairs(msg.info.damage) do if k % 100 == 2 then dmg = dmg + v end end local reward, change = {}, nil local battleInfo = actData[id] or {} local curStar = 0 if isWin then local herosInfo = msg.heros local check = {} -- 1 通关 check[1] = function(_) return true end -- 2 阵亡人数 <= N check[2] = function(_, cond) return msg.info.dead and msg.info.dead <= cond end -- 3 全员存活 check[3] = function(_) return msg.info.dead and msg.info.dead == 0 end -- 4 指定种族 >= N check[4] = function(_, cond) local count = 0 for _, one in pairs(herosInfo) do local heroData = csvdb["unitCsv"][one.type] if heroData.camp == cond then count = count + 1 end end return count >= cond end -- 5 指定职业 >= N check[5] = function(_, cond) local count = 0 for _, one in pairs(herosInfo) do local heroData = csvdb["unitCsv"][one.type] if heroData.job == cond then count = count + 1 end end return count >= cond end -- 6 含有指定角色 check[6] = function(_, cond) for _, one in pairs(herosInfo) do if one.type == cond then return true end end return false end -- 7 通关耗时 <= X 秒 msg.info.atime check[7] = function(_, cond) return msg.info.atime and msg.info.atime <= cond end -- 8 总输出值 msg.info.atime check[8] = function(_, cond) return dmg >= cond end curStar = 0 local sweepConds = battleCfg.sweep_condition:toTableArray(true) for i, cond in ipairs(sweepConds) do if check[cond[1]] and check[cond[1]](table.unpack(cond)) then curStar = curStar + (1 << (i - 1)) end end else curStar = 0 if battleCfg.rank ~= 0 then curStar = 1 end end local oldStarNum = getStarCount(battleCfg, battleInfo["star"] or 0) local newStarNum = getStarCount(battleCfg, curStar) if newStarNum > oldStarNum then battleInfo["star"] = curStar end if battleCfg.rank ~= 0 and isWin then -- 消耗门票 role.activity:getBattleTicket(actid) local num = battleCfg.type:toArray(true, "=")[3] actData["ticket"] = math.max(actData["ticket"] - num, 0) -- 更新排行榜 最高伤害 battleInfo["top"] = math.max(battleInfo["top"] or 0, dmg) battleInfo["sum"] = (battleInfo["sum"] or 0) + dmg local rankVal = 0 if battleCfg.rank == 1 then rankVal = battleInfo["sum"] elseif battleCfg.rank == 2 then rankVal = battleInfo["top"] end if rankVal > 0 then role:updateRankCommon(RANK_TYPE.ActBattleBoss, rankVal) end end if (oldStarNum == 0 and newStarNum > 0) or battleCfg.rank ~= 0 then reward = battleCfg.item_clear:toNumMap() end if (oldStarNum < 3 and newStarNum == 3) or (battleCfg.rank ~= 0 and newStarNum == 3) then local aw = battleCfg.perfect_reward:toNumMap() for k, v in pairs(aw) do reward[k] = (reward[k] or 0) + v end end role:checkBattle("act_battle", { cfg = battleCfg, star = newStarNum, isWin = isWin, info = msg.info, reward = reward, heros = heros, supports = support, }) -- 解锁活动剧情 if newStarNum >= 3 then role:checkStoryStatus(false, 5, id) end if battleCfg.worldBoss_award ~= 0 and msg.point then battleInfo["bossP"] = (battleInfo["bossP"] or 0) + msg.point battleInfo["maxP"] = math.max(msg.point, (battleInfo["maxP"] or 0)) end actData[id] = battleInfo role.activity:updateActData("ChallengeLevel", actData) reward, change = role:award(reward, {log = {desc = "actBattle", int1 = actid, int2 = newStarNum}}) SendPacket(actionCodes.Activity_endBattleRpc, MsgPack.pack({ reward = reward, change = change })) return true end function _M.battleRankRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local actid = msg.actid local cfg = csvdb["activity_ctrlCsv"][actid] if not cfg then return 1 end if not role.activity:isOpen(cfg.showType) then return 2 end local actTypeToRank = { [role.activity.ActivityType.ChallengeLevel] = RANK_TYPE.ActBattleBoss, [role.activity.ActivityType.Crisis] = RANK_TYPE.ActCrisis, } if not actTypeToRank[cfg.showType] then return end local rankInfo = role:getRankInfoCommon(actTypeToRank[cfg.showType]) SendPacket(actionCodes.Activity_battleRankRpc, MsgPack.pack(rankInfo)) return true end function _M.battleMilestoneRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local actid = msg.actid local id = msg.id local index = msg.index if not role.activity:isOpenById(actid, "ChallengeLevel") then return 1 end local actCfg = csvdb["activity_mileageCsv"][actid] if not actCfg then return 3 end local mileCfg = actCfg[index] if not mileCfg then return 4 end local actData = role.activity:getActData("ChallengeLevel") or {} local battleInfo = actData[id] or {} local val = 0 if mileCfg.type == 1 then val = battleInfo["sum"] or 0 elseif mileCfg.type == 2 then val = battleInfo["top"] or 0 end local record = battleInfo["r"] or "" local flag = string.char(string.getbit(record, index)) if flag == "1" then return 5 end if mileCfg.condition > val then return 6 end battleInfo["r"] = string.setbit(record, index) actData[id] = battleInfo role.activity:updateActData("ChallengeLevel", actData) local award = mileCfg.reward:toNumMap() local reward, change = role:award(award, {log = {desc = "actMilestone", int1 = actid, int2 = index}}) SendPacket(actionCodes.Activity_battleMilestoneRpc, MsgPack.pack(role:packReward(reward, change))) return true end function _M.crisisMilestoneRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local actid = msg.actid local id = msg.id if not role.activity:isOpenById(actid, "Crisis") then return 1 end local actCfg = csvdb["activity_mileageCsv"][actid] if not actCfg then return 3 end local curCsv = actCfg[id] if not curCsv then return 4 end if role:getItemCount(ItemId.CrisisScore) < curCsv.condition then return 5 end local actData = role.activity:getActData("Crisis") or {} actData.score = actData.score or {} if actData.score[id] then return 6 end actData.score[id] = -1 role.activity:updateActData("Crisis", actData) local reward, change = role:award(curCsv.reward, {log = {desc = "actMilecrisis", int1 = actid}}) SendPacket(actionCodes.Activity_crisisMilestoneRpc, MsgPack.pack(role:packReward(reward, change))) return true end function _M.bossRewardRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local actid = msg.actid local id = msg.id local index = msg.index if not role.activity:isOpenById(actid, "ChallengeLevel") then return 1 end local actCfg = csvdb["activity_battleCsv"][actid] if not actCfg then return 2 end local battleCfg = actCfg[id] if not battleCfg then return 3 end if battleCfg.worldBoss_award == 0 then return 4 end actCfg = csvdb["activity_wordboss_awardCsv"][battleCfg.worldBoss_award] if not actCfg then return 5 end local awardCfg = actCfg[index] if not awardCfg then return 6 end local preList = awardCfg.condition1:toArray(true, "=") local actData = role.activity:getActData("ChallengeLevel") or {} local battleInfo = actData[id] or {} local bossPoint = battleInfo["bossP"] or 0 if bossPoint < 1 then return 7 end local bossRecord = battleInfo["bossR"] or "" local r = string.char(string.getbit(bossRecord, index)) if r == "1" then return 9 end local ok = false if #preList == 0 then ok = true else for _, i in ipairs(preList) do local flag = string.char(string.getbit(bossRecord, i)) if flag == "1" then ok = true break end end end if not ok then return 8 end battleInfo["bossR"] = string.setbit(bossRecord, index) battleInfo["bossP"] = bossPoint - 1 actData[id] = battleInfo role.activity:updateActData("ChallengeLevel", actData) local award = awardCfg.reward:toNumMap() local reward, change = role:award(award, {log = {desc = "worldBossReward", int1 = actid, int2 = index}}) SendPacket(actionCodes.Activity_bossRewardRpc, MsgPack.pack(role:packReward(reward, change))) return true end return _M