local ipairs = ipairs local table = table local math = math local next = next local string = string local redisproxy = redisproxy local MsgPack = MsgPack local getRandomName = getRandomName local mcast_util = mcast_util local string_format = string.format local tonumber = tonumber local require = require local table_insert = table.insert local tconcat = table.concat local table_unpack = table.unpack local _M = {} local function checkReward(role) local hangInfo = role:getProperty("hangInfo") if not hangInfo.carbonId or not hangInfo.coinTime or not hangInfo.itemTime then return false end local carbonData = csvdb["idle_battleCsv"][hangInfo.carbonId] local expCarbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId] local nowCoinTime = math.min(skynet.timex(), hangInfo.endCoinTime or 0) local nowItemTime = math.min(skynet.timex(), hangInfo.endItemTime or 0) local expCoef, itemCoef = role.storeData:getHangDropCoef() -- 此次挂机,其中翻倍时长占多少 local doubleTime = role.activity:getActHangDoubleTime(hangInfo.coinTime, nowCoinTime) local normalTime = nowCoinTime - hangInfo.coinTime - doubleTime local coinCount = math.max(0, math.floor((normalTime) / globalCsv.idle_money_produce_cd)) local coinDoubleCount = math.max(0, math.floor((doubleTime) / globalCsv.idle_money_produce_cd)) * 2 hangInfo.coinTime = nowCoinTime normalTime = nowItemTime - hangInfo.itemTime local itemCount = math.max(0, math.floor((normalTime) / globalCsv.idle_item_produce_cd)) hangInfo.itemTime = nowItemTime local items = role:getProperty("hangBag") coinCount = (coinCount + coinDoubleCount) * expCoef items[ItemId.Gold] = math.floor((items[ItemId.Gold] or 0) + coinCount * expCarbonData.money) items[ItemId.Exp] = math.floor((items[ItemId.Exp] or 0) + coinCount * expCarbonData.exp) items[ItemId.PlayerExp] = math.floor((items[ItemId.PlayerExp] or 0) + coinCount * expCarbonData.playerExp) local pool = {} for _, temp in pairs(carbonData.item:toArray()) do table.insert(pool, temp:toArray(true, "=")) end local curFC = 0 local curIC = 0 for id, count in pairs(items) do if id ~= ItemId.Gold and id ~= ItemId.Exp and id ~= ItemId.PlayerExp then curFC = curFC + math.ceil(count / globalCsv.idle_field_limit) curIC = curIC + count end end -- 特权卡挂机额外栏位 local privExtraCnt = role.storeData:getHangSlotExtraCount() --local selfFC = role:getProperty("hangBagLimit") + privExtraCnt local selfFC = 50 local selfIC = selfFC * globalCsv.idle_field_limit local function randomItem() if curIC >= selfIC then return end local tempPool = clone(pool) while #tempPool > 0 do local idx = math.randWeight(tempPool, 3) local cur = clone(pool[idx]) if cur[1] ~= 0 then -- 轮空 id if cur[1] == ItemId.BreakCost and doubleTime > 0 then cur[2] = cur[2] * 2 end cur[2] = cur[2] * itemCoef if (items[cur[1]] and math.ceil((items[cur[1]] + cur[2]) / globalCsv.idle_field_limit) > math.ceil(items[cur[1]] / globalCsv.idle_field_limit)) or not items[cur[1]] then --要占用新栏位的情况 local addFC if not items[cur[1]] then addFC = math.ceil(cur[2] / globalCsv.idle_field_limit) else local frontC = items[cur[1]] % globalCsv.idle_field_limit if frontC == 0 then frontC = globalCsv.idle_field_limit end addFC = math.ceil((cur[2] - (globalCsv.idle_field_limit - frontC)) / globalCsv.idle_field_limit) end if curFC + addFC <= selfFC then curFC = curFC + addFC items[cur[1]] = (items[cur[1]] or 0) + cur[2] break else --加不了,换别的东西 table.remove(tempPool, idx) end else items[cur[1]] = items[cur[1]] + cur[2] break end else break end end curIC = curIC + 1 end for i = 1, itemCount do randomItem() end if coinCount > 0 or itemCount > 0 then return true end return false end --开始一个新的关卡 function _M.startRpc( agent, data ) local role = agent.role local msg = MsgPack.unpack(data) local carbonId = msg.carbonId local carbonData = csvdb["idle_battleCsv"][carbonId] if not carbonData then return 1 end if math.floor(carbonId / 10000) ~= 1 then if not role:isFuncUnlock(FuncUnlock.DifficultHang) then return end end for _, preCarbonId in ipairs(carbonData.prepose:toArray(true, "=")) do if not role:checkHangPass(preCarbonId) then return 2 end end if checkReward(role) then role:updateProperty({field = "hangBag", value = role:getProperty("hangBag")}) end local hangInfo = role:getProperty("hangInfo") local isNew = not hangInfo.carbonId hangInfo.carbonId = carbonId hangInfo.expCarbonId = isNew and carbonId or hangInfo.expCarbonId local nowTime = skynet.timex() if isNew then hangInfo.coinTime = nowTime hangInfo.itemTime = nowTime hangInfo.endCoinTime = nowTime + globalCsv.idle_producetime_max hangInfo.endItemTime = nowTime + globalCsv.idle_producetime_max else hangInfo.coinTime = math.min(nowTime, hangInfo.endCoinTime) hangInfo.itemTime = math.min(nowTime, hangInfo.endItemTime) end role:pushMsg({type = "hang", time = math.min(hangInfo.endCoinTime - nowTime, hangInfo.endItemTime - nowTime)}) if not role:checkHangPass(carbonId) then hangInfo.bossTime = nowTime + carbonData.idle_time else hangInfo.bossTime = nil end role:updateProperty({field = "hangInfo", value = hangInfo}) role:mylog("hang_action", {desc = "startHang", int1 = carbonId}) SendPacket(actionCodes.Hang_startRpc, '') return true end -- 每隔1分钟检查一次 function _M.checkRpc(agent, data) local role = agent.role -- local msg = MsgPack.unpack(data) if checkReward(role) then role:updateProperty({field = "hangBag", value = role:getProperty("hangBag")}) role:updateProperty({field = "hangInfo", value = role:getProperty("hangInfo")}) end SendPacket(actionCodes.Hang_checkRpc, MsgPack.pack({})) return true end local _BattleKey = nil function _M.startBattleRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local carbonId = msg.carbonId local curData = csvdb["idle_battleCsv"][carbonId] if not curData then return 1 end --local hangInfo = role:getProperty("hangInfo") or {} --if curData.main ~= 1 then -- if carbonId ~= hangInfo.carbonId then -- return 2 -- end --end if role:checkHangPass(carbonId) then return 3 end _BattleKey = tostring(math.random()) role:checkTaskEnter("HangBattle", {id = carbonId}) SendPacket(actionCodes.Hang_startBattleRpc, MsgPack.pack({key = _BattleKey})) return true end function _M.endBattleRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hangInfo = role:getProperty("hangInfo") or {} if not msg.key or msg.key ~= _BattleKey then SendPacket(actionCodes.Hang_endBattleRpc, MsgPack.pack({errorCode = 1})) return true end local carbonId = msg.carbonId local isWin = msg.starNum and msg.starNum > 0 local carbonData = csvdb["idle_battleCsv"][carbonId] if not carbonData then return 2 end --if carbonData.main ~= 1 then -- if carbonId ~= hangInfo.carbonId then -- return 3 -- end --end if role:checkHangPass(carbonId) then return 4 end -- 防作弊 if not role:checkBattleCheat("hang", { id = carbonId, isWin = isWin, info = msg.info }) then SendPacket(actionCodes.Hang_endBattleRpc, MsgPack.pack({errorCode = 1})) return true end local reward, change if isWin then --win role:hangFinish(carbonId) if carbonData.main ~= 1 then hangInfo.bossTime = nil end -- reward reward = {} reward[ItemId.Gold] = carbonData.money_clear reward[ItemId.Exp] = carbonData.exp_clear reward[ItemId.PlayerExp] = carbonData.playerExp_clear for itemId, count in pairs(carbonData.item_clear:toNumMap()) do reward[itemId] = count end reward, change = role:award(reward, {log = {desc = "hangBattle", int1 = carbonId}}) role:checkTaskEnter("HangPass", {id = carbonId}) -- 引导 if carbonId == 10101 then role:finishGuide(6) elseif carbonId == 20101 then role:finishGuide(22) end for _, guideData in pairs(csvdb["guide_unlockCsv"]) do if guideData.type == 3 and guideData.carbonId == carbonId then role:saveGuide(guideData.guideId,1,true) break end end end local nextCarbonId = role:getNextCarbonId(carbonId) -- 设置挂机关卡 if isWin then --and (hangInfo.carbonId or 0) < nextCarbonId then if not hangInfo.expCarbonId then hangInfo.expCarbonId = carbonId else local oldCarbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId] local newCarbonData = csvdb["idle_battleCsv"][carbonId] if oldCarbonData.money < newCarbonData.money then hangInfo.expCarbonId = carbonId end end --local cfg = csvdb["idle_battleCsv"][nextCarbonId] --if cfg then -- hangInfo.bossTime = skynet.timex() + cfg.idle_time --end end role:updateProperty({field = "hangInfo", value = hangInfo}) role:checkBattle("hang", { id = carbonId, isWin = isWin, info = msg.info, reward = reward, }) local team = role:getProperty("pvpTC") role:mylog("hang_action", {desc = "hangBattle", short1 = msg.starNum > 0 and 1 or 0, int1 = carbonId, int2 = role:getProperty("hangTBV"), cint1 = role:getHerosCamp(team.heros)}) SendPacket(actionCodes.Hang_endBattleRpc, MsgPack.pack({ starNum = msg.starNum, reward = reward, change = change, })) return true end local function checkLeader(heros, leader) if not leader then return end for slot, heroId in pairs(heros) do if heroId == leader then return true end end end function _M.roleFormatRpc(agent , data) local role = agent.role local msg = MsgPack.unpack(data) local index = msg.index -- 阵容索引 local title = msg.title -- 阵容名称 local tactics = msg.tactics -- 战术 local tower = msg.tower local team = {} for slot, heroId in pairs(msg.heros) do if not role.heros[heroId] then return 1 end end local supports = {} for slot, support in pairs(msg.supports or {}) do if slot ~= 1 and slot ~= 2 then return 2 end local level = role.dinerData:getProperty("dishTree"):getv(support, 0) if level <= 0 then return 3 end supports[slot] = support end if not checkLeader(msg.heros, msg.leader) then return 4 end if index > 10 then return 5 end if #title > 100 then return 6 end team.heros = {} for slot, heroId in pairs(msg.heros) do team.heros[slot] = heroId end team.leader = msg.leader team.supports = supports team.title = title if msg.tactics and globalCsv.tactics_skill_passive_cell[msg.tactics] then team.tactics = msg.tactics end if tower then role:setTowerTeamFormat(index, team) else role:setTeamFormat(index, team) end SendPacket(actionCodes.Hang_roleFormatRpc, '') return true end function _M.getRewardRpc(agent , data) local role = agent.role checkReward(role) local items = role:getProperty("hangBag") if not next(items) then return end local reward, change = role:award(items, {log = {desc = "hangReward"}}) table.clear(items) local hangInfo = role:getProperty("hangInfo") local nowTime = skynet.timex() local timeAdd = role:getBnousHangTime() hangInfo.endItemTime = nowTime + globalCsv.idle_producetime_max + timeAdd hangInfo.endCoinTime = nowTime + globalCsv.idle_producetime_max + timeAdd hangInfo.coinTime = nowTime hangInfo.itemTime = nowTime role:updateProperty({field = "hangBag", value = items}) role:updateProperty({field = "hangInfo", value = hangInfo}) role:pushMsg({type = "hang", time = globalCsv.idle_producetime_max}) role:checkTaskEnter("HangGet", {reward = reward}) if reward[ItemId.Gold] then role:checkTaskEnter("HangGetGold", {count = reward[ItemId.Gold]}) end role:log("residence_reward", { mission_threadid = math.floor(hangInfo.carbonId / 10000), --大关卡ID mission_id = hangInfo.carbonId, --关卡ID mission_type = 100, --关卡类型,见关卡类型枚举表 residence_reward_type = 0, --领取奖励方式,快速(超前领取)记录为1,正常领取记录为0 residence_time = 0, --挂机或排名时长 residence_reward = reward, --获得奖励,建议使用json格式记录。示例:{ "XX": "1", "XXX": "3"} }) SendPacket(actionCodes.Hang_getRewardRpc, MsgPack.pack({ reward = reward, change = change })) return true end function _M.quickRpc(agent , data) local role = agent.role local hangInfo = role:getProperty("hangInfo") if not hangInfo.carbonId then return end local carbonData = csvdb["idle_battleCsv"][hangInfo.carbonId] local expCarbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId] local curCount = role.dailyData:getProperty("hangQC") + 1 local costs = globalCsv.idle_quickproduce_cost:toArray(true, "=") if not costs[curCount] then return end if costs[curCount] > 0 then if not role:checkItemEnough({[ItemId.Diamond] = costs[curCount]}) then return end role:costItems({[ItemId.Diamond] = costs[curCount]}, {log = {desc = "quickHang", int1 = hangInfo.carbonId}}) end role.dailyData:updateProperty({field = "hangQC", value = curCount}) local time = globalCsv.idle_quickproduce_time local reward = {} local coinCount = math.floor(time / globalCsv.idle_money_produce_cd) local itemCount = math.floor(time / globalCsv.idle_item_produce_cd) reward[ItemId.Gold] = math.floor((reward[ItemId.Gold] or 0) + coinCount * expCarbonData.money) reward[ItemId.Exp] = math.floor((reward[ItemId.Exp] or 0) + coinCount * expCarbonData.exp) reward[ItemId.PlayerExp] = math.floor((reward[ItemId.PlayerExp] or 0) + coinCount * expCarbonData.playerExp) local pool = {} for _, temp in pairs(carbonData.item:toArray()) do table.insert(pool, temp:toArray(true, "=")) end for i = 1, itemCount do local cur = pool[math.randWeight(pool, 3)] reward[cur[1]] = (reward[cur[1]] or 0) + cur[2] end local doubleCoef = role.activity:isOpen("DoubleDrop") and 2 or 1 -- 特权卡获取加速获得额外道具 local coef = role.storeData:getProduceItemSpeedCoef() if coef > 1 or doubleCoef > 1 then for k, cnt in pairs(reward) do reward[k] = math.floor(cnt * coef * doubleCoef) end end local change reward, change = role:award(reward, {log = {desc = "quickHang", int1 = hangInfo.carbonId}}) if reward[ItemId.Gold] then role:checkTaskEnter("HangGetGold", {count = reward[ItemId.Gold]}) end role:checkTaskEnter("HangQuick") role:log("residence_reward", { mission_threadid = math.floor(hangInfo.carbonId / 10000), --大关卡ID mission_id = hangInfo.carbonId, --关卡ID mission_type = 100, --关卡类型,见关卡类型枚举表 residence_reward_type = 1, --领取奖励方式,快速(超前领取)记录为1,正常领取记录为0 residence_time = time, --挂机或排名时长 residence_reward = reward, --获得奖励,建议使用json格式记录。示例:{ "XX": "1", "XXX": "3"} }) SendPacket(actionCodes.Hang_quickRpc, MsgPack.pack({ reward = reward, change = change })) return true end function _M.buyBonusCountRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local count = msg.count local btype = msg.type if not TimeReset["DailyBattle" .. btype] then return end local open, actId = role.activity:isOpen("BonusDouble") local actData = csvdb["activity_ctrlCsv"][actId] local coef = 1 if open and actData then coef= tonumber(actData.condition2) end local bonusC = role.dailyData:getProperty("bonusC") local extraCnt = role.storeData:getBonusExtraFightCount() bonusC[btype] = bonusC[btype] or {c = 0, b = 0} local lastCount = globalCsv.bonus_daily_buy_count * coef + extraCnt - bonusC[btype]["b"] if math.illegalNum(count, 1, lastCount) then return 1 end if not role:checkItemEnough({[ItemId.Diamond] = globalCsv.bonus_buy_cost * count}) then return 2 end role:costItems({[ItemId.Diamond] = globalCsv.bonus_buy_cost * count}, {log = {desc = "buyBonusCount", int1 = btype, int2 = count}}) bonusC[btype]["b"] = bonusC[btype]["b"] + count bonusC[btype]["c"] = bonusC[btype]["c"] - count role.dailyData:updateProperty({field = "bonusC", value = bonusC}) SendPacket(actionCodes.Hang_buyBonusCountRpc, '') return true end local function bonusWinReward(role, bonusData, rewardType, count, sweep) count = count or 1 local reward, change = {} if rewardType == 1 or rewardType == 4 then for k, v in pairs(bonusData.clear_reward:toNumMap()) do reward[k] = (reward[k] or 0) + v end end if rewardType == 2 or rewardType == 4 then for k, v in pairs(bonusData.perfect_reward:toNumMap()) do reward[k] = (reward[k] or 0) + v end end if rewardType == 3 then local open, actId = role.activity:isOpen("BonusDouble") local actData if open then actData = csvdb["activity_ctrlCsv"][actId] end reward = bonusData.reward:toNumMap() for itemId, c in pairs(reward) do reward[itemId] = c * count end for i = 1, count do local chance = bonusData.chance:randWeight(true) if chance[1] ~= 0 then reward[chance[1]] = (reward[chance[1]] or 0) + chance[2] end end if open and actData then for k, v in pairs(reward) do reward[k] = v * (actData.condition > 1 and actData.condition or 1) end end end if sweep then local bnousReward = role:getBnousSweep() for key, value in pairs(bnousReward) do reward[key] = (reward[key] or 0) + value * count end end reward, change = role:award(reward, {log = {desc = "bonusBattle", int1 = bonusData.id}}) role:checkTaskEnter("BonusPass", {id = bonusData.id, count = count}) return reward, change end function _M.startBonusBattleRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local id = msg.id local count = msg.count or 1 local open, actId = role.activity:isOpen("BonusDouble") if not role:isFuncUnlock(FuncUnlock.BonusBattle) then return 1 end local bonusData = csvdb["bonus_battleCsv"][id] if not open then if not role:isTimeResetOpen(TimeReset["DailyBattle" .. bonusData.type]) then return 2 end end if not bonusData then return 3 end local bonusStar = role:getProperty("bonusStar") if bonusData.unlock ~= 0 and (not bonusStar[bonusData.unlock] or bonusStar[bonusData.unlock] == 0) then return 4 end if bonusStar[id] and bonusStar[id] >= (1 << #bonusData.sweep_condition:toTableArray(true)) - 1 then local bonusC = role.dailyData:getProperty("bonusC") bonusC[bonusData.type] = bonusC[bonusData.type] or {c = 0, b = 0} local actData = csvdb["activity_ctrlCsv"][actId] local extraCnt = role.storeData:getBonusExtraFightCount() local coef = 1 if open and actData then coef = tonumber(actData.condition2) end if math.illegalNum(count, 1, globalCsv.bonus_daily_count * coef + extraCnt - bonusC[bonusData.type]["c"]) then return 7 end bonusC[bonusData.type]["c"] = bonusC[bonusData.type]["c"] + count role.dailyData:updateProperty({field = "bonusC", value = bonusC}) local reward, change = bonusWinReward(role, bonusData, 3, count, true) SendPacket(actionCodes.Hang_startBonusBattleRpc, MsgPack.pack({reward = reward, change = change})) role:checkTaskEnter("BonusQuick", {count = count}) else local bTeam = role:getTeamFormatByType(TeamSystemType.BonusBattle) if not next(bTeam) then return 5 end role.__bonusBattleCache = { key = tostring(math.random()), id = id, } SendPacket(actionCodes.Hang_startBonusBattleRpc, MsgPack.pack({key = role.__bonusBattleCache.key})) end return true end function _M.endBonusBattleRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local id = msg.id local key = msg.key local starNum = msg.starNum if not role.__bonusBattleCache then return 1 end if role.__bonusBattleCache.id ~= id or role.__bonusBattleCache.key ~= key then SendPacket(actionCodes.Hang_endBonusBattleRpc, MsgPack.pack({errorCode = 1})) return true end role.__bonusBattleCache = nil -- 防作弊 if not role:checkBattleCheat("bonus", { id = id, isWin = starNum and starNum > 0, info = msg.info }) then SendPacket(actionCodes.Hang_endBonusBattleRpc, MsgPack.pack({errorCode = 1})) return true end local bonusData = csvdb["bonus_battleCsv"][id] local reward, change = {} local bonusStar = role:getProperty("bonusStar") local oldStar = bonusStar[id] or 0 local curStar = 0 if starNum and starNum > 0 then -- 胜利扣除次数 local bTeam = role:getTeamFormatByType(TeamSystemType.BonusBattle) local herosInfo = role:getTeamHerosInfo(bTeam).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 curStar = 0 local sweepConds = bonusData.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 local status local rewardType = 0 if curStar >= (1 << #sweepConds) - 1 then -- 满星 rewardType = 2 if oldStar == 0 then --通关 rewardType = 4 end elseif oldStar == 0 then --通关 rewardType = 1 end if rewardType ~= 0 then reward, change = bonusWinReward(role, bonusData, rewardType) end else curStar = oldStar end if curStar ~= oldStar then bonusStar[id] = curStar role:updateProperty({field = "bonusStar", value = bonusStar}) end role:checkBattle("bonus", { id = id, isWin = starNum and starNum > 0, info = msg.info, reward = reward, }) role:mylog("hang_action", {desc = "bonusBattle", short1 = msg.starNum > 0 and 1 or 0, int1 = id}) SendPacket(actionCodes.Hang_endBonusBattleRpc, MsgPack.pack({ starNum = starNum, reward = reward, change = change })) return true end local function workWinReward(role, bonusData, rewardType, count, sweep) count = count or 1 local reward, change = {} if rewardType == 2 or rewardType == 4 then for k, v in pairs(bonusData.perfect_reward:toNumMap()) do reward[k] = (reward[k] or 0) + v end end if rewardType == 3 then reward = bonusData.reward:toNumMap() for itemId, c in pairs(reward) do reward[itemId] = c * count end for i = 1, count do local chance = bonusData.chance:randWeight(true) if chance[1] ~= 0 then reward[chance[1]] = (reward[chance[1]] or 0) + chance[2] end end end if sweep then -- local bnousReward = role:getBnousSweep() -- for key, value in pairs(bnousReward) do -- reward[key] = (reward[key] or 0) + value * count -- end end reward, change = role:award(reward, {log = {desc = "workBattle", int1 = bonusData.id}}) -- role:checkTaskEnter("BonusPass", {id = bonusData.id, count = count}) return reward, change end function _M.workBattleInfoRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local workMainCsv = csvdb["work_mainCsv"][msg.type] if not workMainCsv then return 1 end if not role:isTimeResetOpen(TimeReset["WorkBattle" .. msg.type]) then return 2 end SendPacket(actionCodes.Hang_workBattleInfoRpc, MsgPack.pack({count = tonum(redisproxy:hget(WORK_BATTLE_COUNT, role:getTimeResetRound(TimeReset["WorkBattle" .. msg.type]) * 10 + msg.type))})) return true end function _M.getWorkRewardRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local workMainCsv = csvdb["work_mainCsv"][msg.type] if not workMainCsv then return 1 end if not role:isTimeResetOpen(TimeReset["WorkBattle" .. msg.type]) then return 2 end local count = tonum(redisproxy:hget(WORK_BATTLE_COUNT, role:getTimeResetRound(TimeReset["WorkBattle" .. msg.type]) * 10 + msg.type)) if count < workMainCsv.target_num then return 3 end local workBattle = role:getProperty("workBattle") if workBattle[msg.type] ~= 1 then return 4 end workBattle[msg.type] = -1 role:updateProperty({field = "workBattle", value = workBattle}) local reward, change = role:award(workMainCsv.phase_award, {log = {desc = "workReward"}}) SendPacket(actionCodes.Hang_getWorkRewardRpc, MsgPack.pack({reward = reward, change = change})) return true end function _M.startWorkBattleRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local id = msg.id local count = msg.count or 1 if not role:isFuncUnlock(FuncUnlock.BonusBattle) then return 1 end local bonusData = csvdb["work_battleCsv"][id] if not bonusData then return 3 end if not role:isTimeResetOpen(TimeReset["WorkBattle" .. bonusData.type]) then return 2 end local ticketId = csvdb["work_mainCsv"][bonusData.type].ticket local workStar = role:getProperty("workStar") if bonusData.unlock ~= 0 and (not workStar[bonusData.unlock] or workStar[bonusData.unlock] == 0) then return 4 end local workBattle = role:getProperty("workBattle") workBattle[bonusData.type] = workBattle[bonusData.type] or 0 local needCount = count - (workBattle[bonusData.type] == 0 and 1 or 0) if needCount ~= 0 and not role:checkItemEnough({[ticketId] = needCount}) then return 11 end if workStar[id] and workStar[id] >= (1 << #bonusData.sweep_condition:toTableArray(true)) - 1 then if workBattle[bonusData.type] == 0 then workBattle[bonusData.type] = 1 role:updateProperty({field = "workBattle", value = workBattle}) end if needCount > 0 then role:costItems({[ticketId] = needCount}, {log = {desc = "workBattle", int1 = id}}) end redisproxy:hincrby(WORK_BATTLE_COUNT, role:getTimeResetRound(TimeReset["WorkBattle" .. bonusData.type]) * 10 + bonusData.type, count * bonusData.target_add) local reward, change = workWinReward(role, bonusData, 3, count, true) SendPacket(actionCodes.Hang_startWorkBattleRpc, MsgPack.pack({reward = reward, change = change})) else local bTeam = role:getTeamFormatByType(TeamSystemType.BonusBattle) if not next(bTeam) then return 5 end role.__bonusBattleCache = { key = tostring(math.random()), id = id, } SendPacket(actionCodes.Hang_startWorkBattleRpc, MsgPack.pack({key = role.__bonusBattleCache.key})) end return true end function _M.endWorkBattleRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local id = msg.id local key = msg.key local starNum = msg.starNum if not role.__bonusBattleCache then return 1 end if role.__bonusBattleCache.id ~= id or role.__bonusBattleCache.key ~= key then SendPacket(actionCodes.Hang_endWorkBattleRpc, MsgPack.pack({errorCode = 1})) return true end role.__bonusBattleCache = nil -- 防作弊 if not role:checkBattleCheat("work", { id = id, isWin = starNum and starNum > 0, info = msg.info }) then SendPacket(actionCodes.Hang_endWorkBattleRpc, MsgPack.pack({errorCode = 1})) return true end local bonusData = csvdb["work_battleCsv"][id] local ticketId = csvdb["work_mainCsv"][bonusData.type].ticket local reward, change = {} local workStar = role:getProperty("workStar") local oldStar = workStar[id] or 0 local curStar = 0 if starNum and starNum > 0 then -- 胜利扣除次数 local bTeam = role:getTeamFormatByType(TeamSystemType.BonusBattle) local herosInfo = role:getTeamHerosInfo(bTeam).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 curStar = 0 local sweepConds = bonusData.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 local status local rewardType = 0 if curStar >= (1 << #sweepConds) - 1 then -- 满星 rewardType = 2 if oldStar == 0 then --通关 rewardType = 4 end elseif oldStar == 0 then --通关 rewardType = 1 end if rewardType ~= 0 then local workBattle = role:getProperty("workBattle") workBattle[bonusData.type] = workBattle[bonusData.type] or 0 local needCount = 1 - (workBattle[bonusData.type] == 0 and 1 or 0) if workBattle[bonusData.type] == 0 then workBattle[bonusData.type] = 1 role:updateProperty({field = "workBattle", value = workBattle}) end if needCount > 0 then role:costItems({[ticketId] = needCount}, {log = {desc = "workBattle", int1 = id}}) end redisproxy:hincrby(WORK_BATTLE_COUNT, role:getTimeResetRound(TimeReset["WorkBattle" .. bonusData.type]) * 10 + bonusData.type, bonusData.target_add) reward, change = workWinReward(role, bonusData, rewardType) end else curStar = oldStar end if curStar ~= oldStar then workStar[id] = curStar role:updateProperty({field = "workStar", value = workStar}) end role:checkBattle("work", { id = id, isWin = starNum and starNum > 0, info = msg.info, reward = reward, }) role:mylog("hang_action", {desc = "workBattle", short1 = msg.starNum > 0 and 1 or 0, int1 = id}) SendPacket(actionCodes.Hang_endWorkBattleRpc, MsgPack.pack({ starNum = starNum, reward = reward, change = change })) return true end function _M.hangGiftRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local id = msg.id local carbonData = csvdb["idle_battleCsv"][id] if not carbonData or carbonData.item_clear_special == "" then return 1 end local hangGift = role:getProperty("hangGift") if hangGift[id] then return 2 end local reward, change = role:award(carbonData.item_clear_special, {log = {desc = "hangGift", int1 = id}}) role:changeUpdates({{type = "hangGift", field = id, value = 1}}) role:mylog("hang_action", {desc = "hangGift", int1 = id}) SendPacket(actionCodes.Hang_hangGiftRpc, MsgPack.pack({reward = reward, change = change})) return true end function _M.bagFieldRpc(agent, data) local role = agent.role local curBL = role:getProperty("hangBagLimit") local costD = globalCsv.idle_field_cost[curBL - globalCsv.idle_field_origin] if not costD then return 1 end if costD ~= 0 and not role:checkItemEnough({[ItemId.Diamond] = costD}) then return 2 end role:updateProperty({field = "hangBagLimit", value = curBL + 1}) role:costItems({[ItemId.Diamond] = costD}, {log = {desc = "bagField"}}) SendPacket(actionCodes.Hang_bagFieldRpc, '') return true end function _M.chatLineRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local id = msg.id local idleData = csvdb["idle_battleCsv"][id] if not idleData or idleData.chatline == 0 then return end local chatline = role:getProperty("chatline") if chatline[id] then return end if not role:checkHangPass(id) then return end chatline[id] = skynet.timex() role:updateProperty({field = "chatline", value = chatline}) local reward, change = role:award(idleData.chatline_reward, {log = {desc = "chatline", int1 = id}}) SendPacket(actionCodes.Hang_chatLineRpc, MsgPack.pack({reward = reward, change = change})) return true end function _M.selectTeamRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local index = msg.index -- 阵容索引 local type = msg.type -- 系统类型 if index > 10 then return 1 end local team = role:getTeamFormat(index) if not next(team) then return 2 end local teamIndex = role:getProperty("teamIndex") or {} teamIndex[type] = index role:updateProperty({field = "teamIndex", value = teamIndex}) if type == TeamSystemType.Hang then role:finishGuide(5) role:updateHangTeamInfo() end SendPacket(actionCodes.Hang_selectTeamRpc, '') return true end return _M