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 = {} function _M.levelUpRpc( agent, data ) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return 1 end if hero:getProperty("level") >= hero:getMaxLevel() then return 2 end local curData = csvdb["unit_expCsv"][hero:getProperty("level")] local cost = {[ItemId.Exp] = curData.exp, [ItemId.Gold] = curData.gold} if not role:checkItemEnough(cost) then return 3 end role:costItems(cost, {log = {desc = "heroLevelUp", int1 = msg.id, int2 = hero:getProperty("type")}}) hero:updateProperty({field = "level", delta = 1}) hero:log({desc = "levelUp", int1 = hero:getProperty("level")}) if hero:getProperty("type") == 103 then role:finishGuide(7) end role:checkTaskEnter("HeroLevelUp", {level = hero:getProperty("level")}) SendPacket(actionCodes.Hero_levelUpRpc, '') return true end function _M.breakRpc( agent, data ) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return 1 end if hero:getProperty("level") < hero:getMaxLevel() then return 2 end if hero:getProperty("breakL") >= #csvdb["unit_breakCsv"] then return 3 end local curData = csvdb["unit_breakCsv"][hero:getProperty("breakL")] local cost = {[ItemId.BreakCost] = curData.cost, [ItemId.Gold] = curData.gold} if not role:checkItemEnough(cost) then return 4 end role:costItems(cost, {log = {desc = "heroBreak", int1 = msg.id, int2 = hero:getProperty("type")}}) hero:updateProperty({field = "breakL", delta = 1}) hero:log({desc = "break", int1 = hero:getProperty("breakL")}) SendPacket(actionCodes.Hero_breakRpc, '') return true end function _M.wakeRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return 1 end if hero:getProperty("wakeL") >= #csvdb["unit_wakeCsv"] then return 2 end local typ = hero:getProperty("type") local wakeData = csvdb["unit_wakeCsv"][hero:getProperty("wakeL")] if not wakeData then return 3 end local costMaterial = wakeData.costMaterial:toArray(true,"=") local cost = {[typ] = wakeData.costFigment,[globalCsv.unit_wake_cost[hero:getCamp()][costMaterial[1]]] = costMaterial[2]} if not role:checkItemEnough(cost) then return 4 end role:costItems(cost, {log = {desc = "heroWake", int1 = msg.id, int2 = hero:getProperty("type")}}) hero:updateProperty({field = "wakeL", delta = 1}) local curLevel = hero:getProperty("wakeL") role:checkTaskEnter("Wake", {heroType = typ, wakeL = curLevel}) if curLevel == 4 then -- 解锁cg role:checkTaskEnter("WakeCG", {heroType = typ}) end hero:log({desc = "wake", int1 = hero:getProperty("wakeL")}) SendPacket(actionCodes.Hero_wakeRpc, '') return true end function _M.talentRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return 1 end local index = msg.index -- 第几个天赋 local need = {[0] = 1, [1] = 1, [2] = 1, [3] = 1, [4] = 1} if not need[index] then return 2 end local talent = hero:getProperty("talent") local curStage = talent:getv(0, 1) local curData = csvdb["unit_talentCsv"][curStage] if not curData then return 4 end if index == 0 then --是否进阶 local max = true for i = 1, 4 do if talent:getv(i, 0) < #curData then max = false break end end if max then talent = talent:setv(0, curStage + 1) for i = 1, 4 do talent = talent:setv(i, 0) end else return 12 end else local level = talent:getv(index, 0) if level >= #curData then return 5 end local talentData = curData[level] if not talentData then return end if talentData.lvRequire > hero:getProperty("level") then return 6 end local cost = talentData.money:toNumMap() local cost2 = talentData.cost:toNumMap() for k,v in pairs(cost2) do cost[globalCsv.unit_talent_cost[csvdb["unitCsv"][hero:getProperty("type")].camp][k]] = v end if not role:checkItemEnough(cost) then return 6 end role:costItems(cost, {log = {desc = "heroTalent", int1 = msg.id, int2 = hero:getProperty("type")}}) talent = talent:incrv(index, 1) local aheadLevel = 0 for i = 1, talent:getv(0, 1) - 1 do aheadLevel = aheadLevel + #csvdb["unit_talentCsv"][i] end aheadLevel = aheadLevel + talent:getv(index, 0) role:checkTaskEnter("HeroTalent", {heroType = hero:getProperty("type"), alv = aheadLevel}) end hero:updateProperty({field = "talent", value = talent}) hero:log({desc = "talent", int1 = index, int2 = talent:getv(index, 0)}) SendPacket(actionCodes.Hero_talentRpc, '') return true end -- 暂时没有这个功能 function _M.likeHeroRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local heroType = msg.type local result = {status = 0} local isLike = false local hadLike = role:getProperty("likeHero"):toArray(true, "=") for _, v in pairs(hadLike) do if v == heroType then isLike = true break end end if isLike then result.status = 1 else redisproxy:hincrby("hero:like", "hero:"..heroType, 1) table.insert(hadLike, heroType) role:setProperty("likeHero", table.concat(hadLike, "=")) end SendPacket(actionCodes.Hero_likeHeroRpc, MsgPack.pack(result)) return true end local RankLikeNum = 5 --热度显示几个 local TimeLikeNum = 95 -- 时间显示几个 local function getCommentKey(heroType) return { commentListKey = string.format("list:%d:herocomments", heroType), commentRankKey = string.format("rank:%d:herocomments", heroType), commentKey = string.format("hero:%d:comments", heroType), } end local function trimComment(heroType, commentId) -- 剪裁 CommentList local commentKey = getCommentKey(heroType) local redret = redisproxy:pipelining(function (red) red:lpush(commentKey.commentListKey, commentId) red:lrange(commentKey.commentListKey, TimeLikeNum,-1) red:ltrim(commentKey.commentListKey, 0, TimeLikeNum - 1) red:zrevrange(commentKey.commentRankKey, 0, RankLikeNum - 1) end) local hots = {} for _, hot in pairs(redret[4]) do hots[hot] = 1 end redisproxy:pipelining(function (red) local needDel = {} for _, tempId in pairs(redret[2]) do if not hots[tempId] then table.insert(needDel, tempId) end end if #needDel > 0 then red:zrem(commentKey.commentRankKey, table_unpack(needDel)) red:hdel(commentKey.commentKey, table_unpack(needDel)) end end) end function _M.commentHeroRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local heroType = msg.type local content = msg.content local result = {status = 0} -- status 0 成功 1 已经评论过了 local curStutus = role.dailyData:getProperty("commentHero") if curStutus:getv(heroType, 0) ~= 0 then result.status = 1 else local commentKey = getCommentKey(heroType) local SERV = string.format(".chated%d", math.random(1, 5)) local legal, mod = skynet.call(SERV, "lua", "check", content) if not legal then content = mod or "" end local commentId = tostring(redisproxy:hincrby("hero:comment:autoincr", "hero:" .. heroType, 1)) local comment = { commentId = commentId, content = content, roleId = role:getProperty("id"), name = role:getProperty("name"), -- time = skynet.timex() } redisproxy:hset(commentKey.commentKey, commentId, json.encode(comment)) trimComment(heroType, commentId) comment.like = 0 result.comment = comment role.dailyData:setProperty("commentHero", curStutus:setv(heroType, 1)) end SendPacket(actionCodes.Hero_commentHeroRpc, MsgPack.pack(result)) return true end function _M.getCommentsRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local heroType = msg.type local list = {} -- 评论列表 local commentKey = getCommentKey(heroType) local commentRoleKey = string.format("comment:%d:like", role:getProperty("id")) local redret = redisproxy:pipelining(function (red) red:lrange(commentKey.commentListKey, 0,TimeLikeNum - 1) red:zrevrange(commentKey.commentRankKey, 0, -1, "WITHSCORES") --热门 red:hget("hero:like", "hero:"..heroType) red:lrange(commentRoleKey, 0, 999) end) local likeMap = {} local idList = {} local liked = {} for i = 1, #redret[2], 2 do likeMap[redret[2][i]] = redret[2][i + 1] if i < RankLikeNum * 2 then table.insert(idList, redret[2][i]) end end for i = 1, #redret[1] do table.insert(idList, redret[1][i]) end for i = 1, #redret[4] do liked[redret[4][i]] = 1 end local commentData = redisproxy:pipelining(function (red) for _, commentId in ipairs(idList) do red:hget(commentKey.commentKey, commentId) end end) for _, commentS in ipairs(commentData or {}) do local comment = json.decode(commentS) comment.like = likeMap[tostring(comment.commentId)] or 0 comment.liked = liked[heroType .. ":" .. comment.commentId] or 0 table.insert(list, comment) end SendPacket(actionCodes.Hero_getCommentsRpc, MsgPack.pack({list = list, like = tonumber(redret[3] or 0)})) return true end function _M.likeCommentRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local actType = msg.actType -- 1 顶 2 踩 local heroType = msg.type local commentId = msg.commentId --评论id local commentKey = getCommentKey(heroType) local add = 0 if actType == 1 then add = 1 elseif actType == 2 then add = -1 else return end local result = {status = 0} local commentIndex = heroType .. ":" .. commentId local commentRoleKey = string.format("comment:%d:like", role:getProperty("id")) local redret = redisproxy:pipelining(function (red) red:hexists(commentKey.commentKey, commentId) red:lrem(commentRoleKey, 1, commentIndex) red:lpush(commentRoleKey, commentIndex) red:ltrim(commentRoleKey, 0, 999) end) if (tonumber(redret[2]) or 0) > 0 then result.status = 1 else if redret[1] == 1 then-- 查不到也返回ture local redret2 = redisproxy:pipelining(function (red) red:zrevrange(commentKey.commentRankKey, 0, RankLikeNum - 1) --热门 red:zincrby(commentKey.commentRankKey, add, commentId) red:zrevrange(commentKey.commentRankKey, 0, RankLikeNum - 1) --热门 end) local out = {} for _, v in pairs(redret2[1]) do out[v] = 1 end local new = {} for _, v in pairs(redret2[3]) do if out[v] then out[v] = nil else new[v] = 1 end end for tempId, _ in pairs(out) do trimComment(heroType, tempId) end redisproxy:pipelining(function (red) for tempId, _ in pairs(new) do red:lrem(commentKey.commentListKey, 0, tempId) end end) end end SendPacket(actionCodes.Hero_likeCommentRpc, MsgPack.pack(result)) return true end -- function _M.loveItemRpc(agent, data) -- local role = agent.role -- local msg = MsgPack.unpack(data) -- local hero = role.heros[msg.heroId] -- if not hero then -- return -- end -- local curL = hero:getProperty("loveL") -- local curExp = hero:getProperty("loveExp") -- local curType = hero:getProperty("type") -- local curPlus = csvdb["unit_love_plusCsv"][curType] -- if not curPlus then -- return -- end -- if curL >= curPlus.limit then -- SendPacket(actionCodes.Hero_loveItemRpc, MsgPack.pack({errMsg = 1})) --已满级 -- return true -- end -- local curEffect = csvdb["unit_love_effectCsv"][curL] -- if not curEffect then -- return -- end -- if curExp >= curEffect.loveValue and not msg.bBreak then -- SendPacket(actionCodes.Hero_loveItemRpc, MsgPack.pack({errMsg = 2})) --当前等级经验已满 -- return true -- end -- if msg.bBreak then -- local cost = curEffect.cost:toArray(true, "=") -- if not role:checkItemEnough({[cost[1]] = cost[2]}) then -- SendPacket(actionCodes.Hero_loveItemRpc, MsgPack.pack({errMsg = 3, itemId = cost[1]})) --物品不足 -- return true -- end -- role:costItems({[cost[1]] = cost[2]}) -- local newLevel = curL + 1 -- hero:updateProperty({field = "loveL", value = newLevel}) -- hero:updateProperty({field = "loveExp", value = 0}) -- if role:getProperty("loveStatus"):getv(curType, 0) < newLevel then -- role:changeUpdates({{type = "loveStatus", field = curType, value = newLevel}}) -- 总的 -- end -- role:checkTaskEnter("LoveBreak", {heroType = curType, loveL = newLevel}) -- else -- local delta = globalCsv.unit_love_presentValue[msg.itemId] -- if not delta then -- return -- end -- if not role:checkItemEnough({[msg.itemId] = 1}) then -- SendPacket(actionCodes.Hero_loveItemRpc, MsgPack.pack({errMsg = 3, itemId = msg.itemId})) -- return true -- end -- local newExp = curExp + delta -- if newExp > curEffect.loveValue then -- newExp = curEffect.loveValue -- end -- role:costItems({[msg.itemId] = 1}) -- hero:updateProperty({field = "loveExp", value = newExp}) -- end -- SendPacket(actionCodes.Hero_loveItemRpc, "") -- return true -- end -- function _M.loveTaskRpc(agent, data) -- local role = agent.role -- local msg = MsgPack.unpack(data) -- local hero = role.heros[msg.id] -- if not hero then return end -- local curL = hero:getProperty("loveL") -- local curExp = hero:getProperty("loveExp") -- local curType = hero:getProperty("type") -- local curPlus = csvdb["unit_love_plusCsv"][curType] -- if not curPlus or curL >= curPlus.limit then return end -- local curEffect = csvdb["unit_love_effectCsv"][curL] -- if not curEffect or curExp < curEffect.loveValue then return end -- local lastEffect = csvdb["unit_love_effectCsv"][curL + 1] -- local newExp = curExp - curEffect.loveValue -- if lastEffect and curL + 1 < curPlus.limit then -- if newExp >= lastEffect.loveValue then -- -- todo 发任务 -- end -- else -- newExp = 0 -- end -- local newLevel = curL + 1 -- hero:updateProperty({field = "loveExp", value = newExp}) -- hero:updateProperty({field = "loveL", value = newLevel}) -- if role:getProperty("loveStatus"):getv(curType, 0) < newLevel then -- role:changeUpdates({{type = "loveStatus", field = curType, value = newLevel}}) -- 总的 -- end -- role:checkTaskEnter("LoveBreak", {heroType = curType, loveL = newLevel}) -- SendPacket(actionCodes.Hero_loveTaskRpc, "") -- return true -- end function _M.createHeroRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local heroType = msg.heroType local unitData = csvdb["unitCsv"][heroType] if not unitData then return end local cost = globalCsv.unit_fragment_cost[unitData["rare"]] if not cost then return end if role:getItemCount(heroType) < cost then return end for _, hero in pairs(role.heros) do if hero:getProperty("type") == heroType then return end end role:costItems({[heroType] = cost}, {log = {desc = "createHero"}}) role:award({[heroType + ItemStartId.Hero] = 1}, {log = {desc = "createHero"}}) SendPacket(actionCodes.Hero_createHeroRpc, "") return true end -- typ 位置,level等级对应唯一装备,level为0时为移除,不为0时无则装备,有则替换 function _M.referEquipsRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return 10 end local equips = msg.equips if not equips or not next(equips) then return 11 end for typ = 1, 4 do -- 4件装备 if equips[typ] and equips[typ] ~= 0 then if role:getEquipCount(typ, equips[typ]) <= 0 then return end end end local curEquip = hero:getProperty("equip") for typ = 1, 4 do -- 4件装备 if equips[typ] then local cur = curEquip:getv(typ, 0) if cur ~= equips[typ] then if equips[typ] == 0 then curEquip = curEquip:delk(typ) else role:addEquip(typ, equips[typ], -1, {log = {desc = "refer"}}) -- 穿上 curEquip = curEquip:setv(typ, equips[typ]) end if cur ~= 0 then role:addEquip(typ, cur, 1, {log = {desc = "refer"}}) -- 脱掉 end end end end -- 更新角色 hero:updateProperty({field = "equip", value = curEquip}) role:finishGuide(23) SendPacket(actionCodes.Hero_referEquipsRpc, "") return true end -- typ 位置,uid对应唯一符文,uid为0时为移除,不为0时无则装备,有则替换 function _M.referRunesRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return 10 end local runes = msg.runes if not runes or not next(runes) then return 11 end local used = {} for typ = 1, 6 do if runes[typ] and runes[typ] ~= 0 then local ownRune = role.runeBag[runes[typ]] if not ownRune then return end if ownRune:getProperty("refer") ~= 0 then used[ownRune:getProperty("refer")] = used[ownRune:getProperty("refer")] or {} used[ownRune:getProperty("refer")][runes[typ]] = 1 end end end for cheroId, cIds in pairs(used) do local chero = role.heros[cheroId] local hrunes = chero:getProperty("rune") for slot, rId in pairs(hrunes:toNumMap()) do if cIds[rId] then hrunes = hrunes:delk(slot) end end chero:updateProperty({field = "rune", value = hrunes}) end local curRune = hero:getProperty("rune") for typ = 1, 6 do if runes[typ] then local cur = curRune:getv(typ, 0) if cur ~= runes[typ] then if runes[typ] == 0 then curRune = curRune:delk(typ) else local newRune = role.runeBag[runes[typ]] newRune:updateProperty({field = "refer",value = hero:getProperty("id")}) curRune = curRune:setv(typ, runes[typ]) end if cur ~= 0 then local oldR = role.runeBag[cur] if oldR then oldR:updateProperty({field = "refer",value = 0}) end end end end end hero:updateProperty({field = "rune", value = curRune}) SendPacket(actionCodes.Hero_referRunesRpc, "") return true end function _M.createHeroRandomRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local itemId = msg.itemId local itemData = csvdb["itemCsv"][itemId] if not itemData or itemData.type ~= ItemType.HeroFCommon then return end local cost = globalCsv.unit_fragment_cost[itemData.quality] if not cost or role:getItemCount(itemId) < cost then return end local randomData = csvdb["item_randomCsv"][tonumber(itemData.use_effect)] if not randomData then return end local temp = randomData.gift1:randWeight(true) if not temp or not next(temp) then return end role:costItems({[itemId] = cost}, {log = {desc = "createHeroRandom"}}) local reward, change = role:award({[temp[1] + ItemStartId.Hero] = 1}, {log = {desc = "createHeroRandom"}}) SendPacket(actionCodes.Hero_createHeroRandomRpc, MsgPack.pack(role:packReward(reward, change))) return true end function _M.getResetRewardRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local hero = role.heros[msg.id] if not hero then return end local level = hero:getProperty("level") local breakL = hero:getProperty("breakL") local talent = hero:getProperty("talent") if level <= 1 and talent == "" then return end local reward = {} while level > 1 do local curData = csvdb["unit_expCsv"][level - 1] reward[ItemId.Exp] = (reward[ItemId.Exp] or 0) + curData.exp reward[ItemId.Gold] = (reward[ItemId.Gold] or 0) + curData.gold level = level - 1 end while breakL > 0 do local curData = csvdb["unit_breakCsv"][breakL - 1] reward[ItemId.BreakCost] = (reward[ItemId.BreakCost] or 0) + curData.cost reward[ItemId.Gold] = (reward[ItemId.Gold] or 0) + curData.gold breakL = breakL - 1 end local stage = talent:getv(0, 1) local tlevel = {talent:getv(1, 0), talent:getv(2, 0), talent:getv(3, 0), talent:getv(4, 0)} local talentCostIds = globalCsv.unit_talent_cost[csvdb["unitCsv"][hero:getProperty("type")].camp] while stage > 0 do local curData = csvdb["unit_talentCsv"][stage] for level = math.max(table.unpack(tlevel)), 1, -1 do local add = 0 for i = 1, 4 do if tlevel[i] == level then add = add + 1 tlevel[i] = tlevel[i] - 1 end end local talentData = curData[level - 1] for itemId, count in pairs(talentData.money:toNumMap()) do reward[itemId] = (reward[itemId] or 0) + count * add end for idx , count in pairs(talentData.cost:toNumMap()) do reward[talentCostIds[idx]] = (reward[talentCostIds[idx]] or 0) + count * add end end stage = stage - 1 curData = csvdb["unit_talentCsv"][stage] if curData then tlevel = {#curData, #curData, #curData, #curData} end end hero:updateProperty({field = "level", value = level}) hero:updateProperty({field = "breakL", value = breakL}) hero:updateProperty({field = "talent", value = ""}) hero:log({desc = "resetHero"}) for itemId, count in pairs(reward) do reward[itemId] = math.floor(count * globalCsv.unit_back_discount) end local change reward, change = role:award(reward, {log = {desc = "resetHero", int1 = msg.id, int2 = hero:getProperty("type")}}) SendPacket(actionCodes.Hero_getResetRewardRpc, MsgPack.pack(role:packReward(reward, change))) return true end function _M.unuse_drawHeroRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) if not role:isFuncUnlock(FuncUnlock.GetHero) then return end local btype = msg.pool -- 1 2 3 4 local drawType = msg.type -- 1 单抽 2 十连 local buildTypeData = csvdb["build_typeCsv"][btype] if not buildTypeData then return 1 end local drawCount = {1, 10} -- 抽取次数 if not drawCount[drawType] then return 2 end local newerDraw if btype == 4 then newerDraw = role:getProperty("newerDraw") if math.illegalNum(globalCsv.draw_newer[2] - (newerDraw[1] or 0), drawCount[drawType], globalCsv.draw_newer[2]) then return 11 end end local cost = {} local lastCount = drawCount[drawType] for _, costType in ipairs({"draw_card", "draw_coin"}) do if buildTypeData[costType] ~= "" then local curCost = buildTypeData[costType]:toArray(true, "=") local hadCount = role:getItemCount(curCost[1]) local curCount = math.floor(hadCount / curCost[2]) if curCount >= lastCount then cost[curCost[1]] = curCost[2] * lastCount lastCount = 0 break elseif curCount > 0 then cost[curCost[1]] = curCost[2] * curCount lastCount = lastCount - curCount end end end if lastCount > 0 then -- 钱不够 return 3 end -- pool 固定的 local poolEnum = { [1] = { [1] = 1, [2] = 2, [3] = 3, }, [2] = 10, [3] = 11, [4] = 12, } -- 抽取的池子 local pool = poolEnum[btype] if btype == 1 then -- 超级卡池子 每周轮换 有活动覆盖之 --TODO 活动判断 if false then else for idx, poolId in pairs(pool) do if role:isTimeResetOpen(TimeReset["DrawType" .. idx]) then pool = poolId break end end if type(pool) ~= "number" then pool = -1 end end end local unitPool = csvdb["build_unitCsv"][pool] if not unitPool then return 4 end -- 开始抽 local resultPool = {} local function fillDrawPool(fixRare, fixCamp, ssrUp, floorBack) local condition = {"rare", "camp"} local values = {fixRare, fixCamp} for idx, field in ipairs(condition) do if not values[idx] then local lpool = {} local curIdx = 1 while unitPool[field .. "_" .. curIdx] do lpool[curIdx] = {unitPool[field .. "_" .. curIdx]} curIdx = curIdx + 1 end -- 稀有度 ssr up if field == "rare" then local all = 0 for _, weight in pairs(lpool) do all = all + weight[1] end --[[ SSR概率值:初始概率 + 步长概率 SR概率值:初始概率 * [ (初始概率+R初始概率) - 步长概率 ] /(初始概率+R初始概率) R概率值:初始概率 * [ (初始概率+SR初始概率) - 步长概率 ] /(初始概率+SR初始概率) ]] local ssrAdd = (ssrUp or 0) * all local last = all - lpool[4][1] lpool[4][1] = lpool[4][1] + ssrAdd lpool[3][1] = lpool[3][1] * (last - ssrAdd) / last lpool[2][1] = lpool[2][1] * (last - ssrAdd) / last end if next(lpool) then values[idx] = math.randWeight(lpool, 1) end end end for itemId, oneData in pairs(floorBack and csvdb["build_floorCsv"] or csvdb["build_poolCsv"]) do if oneData["pool_" .. pool] and oneData["pool_" .. pool] ~= "" then local itemData = csvdb["itemCsv"][itemId] while itemData do if itemData.type ~= ItemType.Hero then break end local heroData = csvdb["unitCsv"][itemData.id - ItemStartId.Hero] if not heroData then break end local ok = true for idx, field in ipairs(condition) do if heroData[field] ~= values[idx] then ok = false break end end if not ok then break end if oneData["pool_" .. pool] > 0 then resultPool[itemId] = {oneData["pool_" .. pool]} -- itemId, count, 概率 end break end end end end role:costItems(cost, {log = {desc = "drawHero", short1 = btype, int1 = pool}}) local draw_floor_back_counts = globalCsv.draw_floor_back_counts[btype] local draw_ssr_up_count_rate = globalCsv.draw_ssr_up_count_rate[btype] local floorHeroCount = role:getProperty("floorHero")[btype] or 0 local ssrUpCount = role:getProperty("ssrUp")[btype] or 0 local newerDrawCount, newerHadSSR if btype == 4 then newerDrawCount = newerDraw[1] or 0 newerHadSSR = newerDraw[2] or 0 end local guideHero local funcGuide = role:getProperty("funcGuide") if funcGuide:getv(11001,0) == 1 and funcGuide:getv(12001,0) == 0 then guideHero = 613 end local ssrCount = 0 local reward = {} for i = 1, drawCount[drawType] do floorHeroCount = floorHeroCount + 1 if btype == 4 then newerDrawCount = newerDrawCount + 1 end resultPool = {} local isFloorBack = draw_floor_back_counts and floorHeroCount >= draw_floor_back_counts local isNewerSSR = btype == 4 and (newerHadSSR == 0 and newerDrawCount >= globalCsv.draw_newer[1]) or false local ssrUp = 0 if draw_ssr_up_count_rate and ssrUpCount > draw_ssr_up_count_rate[1] then ssrUp = math.min((ssrUpCount - draw_ssr_up_count_rate[1]) * draw_ssr_up_count_rate[2], draw_ssr_up_count_rate[3]) / 100 end while not next(resultPool) do if isNewerSSR then fillDrawPool(4) -- 新手保底的 ssr elseif isFloorBack then -- 保底 sr 【郑斌】明确 -- 保底 sr 改为 池子随机 sr 或者 ssr【郑斌】 fillDrawPool(nil, nil, nil, true) else fillDrawPool(nil, nil, ssrUp) end end -- 引导必送 613 丝路德 local itemId = math.randWeight(resultPool, 1) if guideHero then itemId = guideHero guideHero = nil end local itemData = csvdb["itemCsv"][itemId] if itemData.quality == 4 then ssrCount = ssrCount + 1 ssrUpCount = 0 if btype == 4 then newerHadSSR = newerHadSSR + 1 end else ssrUpCount = ssrUpCount + 1 end if itemData.quality >= 3 then floorHeroCount = 0 end if role:isHaveHero(itemData.id - ItemStartId.Hero) then local fragId = itemData.id - ItemStartId.Hero local heroData = csvdb["unitCsv"][fragId] local count = globalCsv.draw_unit_tofragment[heroData.rare] role:award({[fragId] = count}, {log = {desc = "drawHero", short1 = btype, int1 = pool}}) table.insert(reward, {id = fragId, count = count, from = itemId, fcount = 1}) else role:award({[itemId] = 1}, {log = {desc = "drawHero", short1 = btype, int1 = pool}}) table.insert(reward, {id = itemId, count = 1}) end end if draw_floor_back_counts then local floorHero = role:getProperty("floorHero") floorHero[btype] = floorHeroCount role:setProperty("floorHero", floorHero) end if draw_ssr_up_count_rate then local ssrUp = role:getProperty("ssrUp") ssrUp[btype] = ssrUpCount role:setProperty("ssrUp", ssrUp) end if btype == 4 then newerDraw[1] = newerDrawCount newerDraw[2] = newerHadSSR role:updateProperty({field = "newerDraw", value = newerDraw}) end -- if pool == 1 then -- local repayHero = role:getProperty("repayHero") -- repayHero = math.min(globalCsv.draw_super_repay_count, repayHero + drawCount[drawType]) -- role:updateProperty({field = "repayHero", value = repayHero}) -- end role:finishGuide(11) role:checkTaskEnter("DrawHero", {pool = btype, count = drawCount[drawType]}) if ssrCount > 0 then role:checkTaskEnter("DrawSSR", {count = ssrCount}) end role:log("hero_action", {desc = "drawHero", short1 = btype, int1 = drawCount[drawType], int2 = pool}) SendPacket(actionCodes.Hero_drawHeroRpc, MsgPack.pack({reward = reward})) -- 这个 reward 是数组 return true end function _M.drawHeroRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) if not role:isFuncUnlock(FuncUnlock.GetHero) then return end local btype = msg.pool -- 1 2 3 卡池类型 local subType = msg.subType or 1-- 定向卡池需要传 子类型 local drawType = msg.type -- 1 单抽 2 十连 local guide = msg.guide -- 是否是引导抽的 if btype ~= 1 then subType = 1 end local buildTypeData = csvdb["build_typeCsv"][btype] if not buildTypeData then return 1 end local drawCount = {1, 10} -- 抽取次数 if not drawCount[drawType] then return 2 end -- 计算抽卡消耗品 local cost = {} local lastCount = drawCount[drawType] for _, costType in ipairs({"draw_card", "draw_coin"}) do if buildTypeData[costType] ~= "" then local curCost = buildTypeData[costType]:toArray(true, "=") local hadCount = role:getItemCount(curCost[1]) local curCount = math.floor(hadCount / curCost[2]) if curCount >= lastCount then cost[curCost[1]] = curCost[2] * lastCount lastCount = 0 break elseif curCount > 0 then cost[curCost[1]] = curCost[2] * curCount lastCount = lastCount - curCount end end end if lastCount > 0 then -- 钱不够 return 3 end -- 抽取的池子 local poolMap = buildTypeData["pool"]:toNumMap() local poolId = poolMap[subType] if not poolId then return end --判断定向卡池是否开启 if btype == 1 then if not role:isTimeResetOpen(TimeReset["DrawType" .. subType]) then local unlockPool = role.dailyData:getProperty("unlockPool") if not unlockPool[subType] then return 1 end end end --TODO 活动覆盖 local unitPool = csvdb["build_unitCsv"][poolId] if not unitPool then return 4 end -- 开始抽 local resultPool = {} local function fillDrawPool() local condition = {"rare", "camp"} local values = {} for idx, field in ipairs(condition) do if not values[idx] then local lpool = {} local curIdx = 1 while unitPool[field .. "_" .. curIdx] do lpool[curIdx] = {unitPool[field .. "_" .. curIdx]} curIdx = curIdx + 1 end if next(lpool) then values[idx] = math.randWeight(lpool, 1) end end end for itemId, oneData in pairs(csvdb["build_poolCsv"]) do if oneData["pool_" .. poolId] and oneData["pool_" .. poolId] ~= "" then local itemData = csvdb["itemCsv"][itemId] while itemData do if itemData.type ~= ItemType.Hero then break end local heroData = csvdb["unitCsv"][itemData.id - ItemStartId.Hero] if not heroData then break end local ok = true for idx, field in ipairs(condition) do if heroData[field] ~= values[idx] then ok = false break end end if not ok then break end if oneData["pool_" .. poolId] > 0 then resultPool[itemId] = {oneData["pool_" .. poolId]} -- itemId, count, 概率 end break end end end end role:costItems(cost, {log = {desc = "drawHero", short1 = btype, int1 = poolId}}) local ssrCount = 0 local reward = {} for i = 1, drawCount[drawType] do resultPool = {} while not next(resultPool) do fillDrawPool() end -- 引导必送 613 丝路德 local itemId = guide and 613 or math.randWeight(resultPool, 1) local itemData = csvdb["itemCsv"][itemId] if itemData.quality == HeroQuality.SSR then ssrCount = ssrCount + 1 end if role:isHaveHero(itemData.id - ItemStartId.Hero) then local fragId = itemData.id - ItemStartId.Hero local heroData = csvdb["unitCsv"][fragId] local count = globalCsv.draw_unit_tofragment[heroData.rare] role:award({[fragId] = count}, {log = {desc = "drawHero", short1 = btype, int1 = poolId}}) table.insert(reward, {id = fragId, count = count, from = itemId, fcount = 1}) else role:award({[itemId] = 1}, {log = {desc = "drawHero", short1 = btype, int1 = poolId}}) table.insert(reward, {id = itemId, count = 1}) end end if btype == 1 or btype == 2 then local repayHero = role:getProperty("repayHero") or 0 repayHero = repayHero + drawCount[drawType] role:updateProperty({field = "repayHero", value = repayHero}) end role:checkTaskEnter("DrawHero", {pool = btype, count = drawCount[drawType]}) if ssrCount > 0 then role:checkTaskEnter("DrawSSR", {count = ssrCount}) end role:log("hero_action", {desc = "drawHero", short1 = btype, int1 = drawCount[drawType], int2 = poolId}) SendPacket(actionCodes.Hero_drawHeroRpc, MsgPack.pack({reward = reward})) -- 这个 reward 是数组 return true end function _M.repayHeroRpc(agent, data) local role = agent.role local repayHero = role:getProperty("repayHero") local cnt = globalCsv.draw_times_to_get_ssr or 100 if repayHero < cnt then return end local result = repayHero - cnt role:updateProperty({field = "repayHero", value = result}) local id = math.randWeight(csvdb["build_giftCsv"], "pool_1") local reward = {} local itemData = csvdb["itemCsv"][id] if itemData.type == ItemType.Hero and role:isHaveHero(itemData.id - ItemStartId.Hero) then local fragId = itemData.id - ItemStartId.Hero local heroData = csvdb["unitCsv"][fragId] local count = globalCsv.draw_unit_tofragment[heroData.rare] role:award({[fragId] = count}, {log = {desc = "heroRepay"}}) reward = {id = fragId, count = count, from = id, fcount = 1} else role:award({[id] = 1}, {log = {desc = "heroRepay"}}) reward = {id = id, count = 1} end role:log("hero_action", {desc = "heroRepay", int1=result}) SendPacket(actionCodes.Hero_repayHeroRpc, MsgPack.pack({reward = reward})) return true end function _M.unlockPoolRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) if not role:isFuncUnlock(FuncUnlock.GetHero) then return end local type = msg.type -- 指定定向卡池需要类型 1, 2, 3 local needCost = true --当前开启的类型不用解锁 if role:isTimeResetOpen(TimeReset["DrawType" .. type]) then needCost = false end --已经解锁的不需要重复解锁 local unlockPool = role.dailyData:getProperty("unlockPool") if unlockPool[type] then needCost = false end if needCost then if not role:costDiamond({count = globalCsv.draw_unlock_pool_diamond or 300, log = {desc = "unlockPool", short1 = type}}) then return end end unlockPool[type] = 1 role.dailyData:updateProperty({field="unlockPool", value = unlockPool}) role.dailyData:updateProperty({field="curPool", value = type}) role:log("hero_action", {desc = "unlockPool", short1=type}) SendPacket(actionCodes.Hero_unlockPoolRpc, MsgPack.pack({})) return true end return _M