RadioAction.lua 8.65 KB
local _M = {}

-- 获取英雄大成功率
local function getHeroCoef(hero, condition)
    -- 基础概率
    local rareMap = {[HeroQuality.N] = 10, [HeroQuality.R] = 10, [HeroQuality.SR] = 15, [HeroQuality.SSR] = 20}
    local rare = hero:getRare()
    local result = 0
    for _, it in ipairs(condition:toTableArray(true)) do
        local type = it[1]
        local value = it[2]
        local add = it[3]
        if type == 1 then   -- 种族加成
            if hero:getCamp() == value then
                result = result + add
            end
        elseif type == 2 then   -- 定位加成
            if hero:getPosition() == value then
                result = result + add
            end
        end
    end

    return result + (rareMap[rare] or 0)
end

local function getQuestMax(role)
    local count = 0
    for _, carbonId in ipairs(globalCsv.crusade_team_unlock or {}) do
        if role:checkHangPass(carbonId) then
            count = count + 1
        end
    end

    return count + (globalCsv.cursade_team_count_initial or 0)
end

local function getCrusadeReward(role, id)
    local radioTask = role:getProperty("radioTask")
    local task = radioTask[id]
    if not task then return 1 end
    --  check id
    local config = csvdb["crusadeCsv"][id]
    if not config then return 2 end
    local carbonData = csvdb["idle_battleCsv"][config.unlock]
    if not carbonData then return 3 end
    --  get heros
    local totalCoef = 0
    local exp = config.time / 60
    local heroFaithMap = {}
    for _, heroId in ipairs(task.heros) do
        local hero = role.heros[heroId]
        if hero then
            totalCoef = totalCoef + getHeroCoef(hero, config.success)
            -- 增加英雄信赖
            hero:addHeroFaith(exp)
            heroFaithMap[heroId] = hero:getProperty("faith")
        end
    end
    -- send award
    local bigSuccess = false
    local result = math.randomInt(0, 100)
    if result < totalCoef then
        bigSuccess = true
    end
    local money = math.ceil(carbonData.money / 5) * config.time * config.money_clear
    local exp = math.ceil(carbonData.exp / 5) * config.time * config.exp_clear
    local itemReward = config.item_clear_special:toNumMap()
    itemReward[ItemId.Gold] = (itemReward[ItemId.Gold] or 0) + money
    itemReward[ItemId.Exp] = (itemReward[ItemId.Exp] or 0) + exp
    if bigSuccess then
        for key, value in pairs(itemReward) do
            itemReward[key] = math.ceil(1.5 * value)
        end
    end

    local r, change = role:award(itemReward, {log = {desc = "radioQuest", int1 = id}})

    radioTask[id] = nil
    role:updateProperty({field="radioTask", value=radioTask, notNotify = true})

    local msg = role:packReward(r, change)
    msg["big"] = bigSuccess
    msg["id"] = id
    msg["heroFaith"] = heroFaithMap

    role:checkTaskEnter("RadioTaskStart", {heroCnt = #task.heros})

    local herolist = {}
    for _, heroId in ipairs(task.heros) do
        local hero = role.heros[heroId]
        if hero then
            table.insert(herolist, hero:getProperty("type"))
        end
    end

    --  讨伐行动
    role:log("punitive_action", {
        mission_id	= id, --关卡ID
        mission_herolist = herolist, -- 英雄ID,排序以玩家出战设置为准,示例:[111, 222, 333, 444, 555]
        mission_success_rate = totalCoef, -- 大成功几率
        mission_reward = r, -- 获得奖励,建议使用json格式记录。示例:{ itemid1: 1,  itemid2: 3,  itemid3: 5}
        mission_result = 1, -- 战斗结果(0-无效,1-胜利,2-失败)
        mission_roundtime = config.time, -- 完成耗时(秒)
        mission_cleartype = 2,  -- 1-开始; 2-完成(领取奖励时)
    })
    role:mylog("role_action", {desc = "radioTask", int1 = id, short1 = bigSuccess and 1 or 0})
    return msg
end

function _M.startQuestRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id
	local heros = msg.heros

    --  check id
    local config = csvdb["crusadeCsv"][id]
    if not config then return 1 end

    local radioTask = role:getProperty("radioTask")

    local getActIDs = function ()
        local actids = {}
        for _, v in pairs(radioTask or {}) do
            actids[v.actid] = (actids[v.actid] or 0) + 1
        end
        return actids
    end

    local actids = getActIDs()
    if config.activity_ctrl_id == 0 then
        --非活动 判断数量
        if (actids[config.activity_ctrl_id] or 0) >= getQuestMax(role) then
            return 2
        end

    else
        --活动 同时只能有一个存在
        if actids[config.activity_ctrl_id] >= 1 then
            return 5
        end
    end

    if not role:checkHangPass(config.unlock) then return 3 end
    if radioTask[id] then return 4 end
    --  check hero
    --1=指定等级=人数
    --2=指定稀有度=人数 
    --3=人数
    local needHeroCnt = 0
    local lvlMap = {}
    local rareMap = {}
    for _, it in ipairs(config.condition:toTableArray(true)) do
        local type = it[1]
        if type == 1 then
            lvlMap[1] = it[2]
            lvlMap[2] = it[3]
        elseif type == 2 then
            rareMap[1] = it[2]
            rareMap[2] = it[3]
        elseif type == 3 then
            needHeroCnt = it[2]
        end
    end
    for _, heroId in pairs(heros) do
        local hero = role.heros[heroId]
        if hero then
            needHeroCnt = needHeroCnt - 1
            if next(lvlMap) then
                if hero:getProperty("level") >= lvlMap[1] then
                    lvlMap[2] = lvlMap[2] - 1
                    if lvlMap[2] <= 0 then
                        lvlMap = {}
                    end
                end
            end
            if next(rareMap) then
                if hero:getRare() >= rareMap[1] then
                    rareMap[2] = rareMap[2] - 1
                end
                    if rareMap[2] <= 0 then
                        rareMap = {}
                    end
            end
        end
    end
    if needHeroCnt > 0 or next(rareMap) or next(lvlMap) then
        return 5
    end
    -- start quest, set finish time
    local timeSub = role:getBnousCrusade(config.time)
    local taskData = {}
    taskData["time"] = skynet.timex() + config.time + timeSub
    taskData["heros"] = heros
    taskData["actid"] = config.activity_ctrl_id
    radioTask[id] = taskData
    role:updateProperty({field="radioTask", value=radioTask, notNotify=true})

    SendPacket(actionCodes.Radio_startQuestRpc, MsgPack.pack({id=id, task=taskData}))

    local herolist = {}
    for _, heroId in ipairs(heros) do
        local hero = role.heros[heroId]
        if hero then
            table.insert(herolist, hero:getProperty("type"))
        end
    end

	--  讨伐行动 
	role:log("punitive_action", {
		mission_id	= id, --关卡ID
		mission_herolist = herolist, -- 英雄ID,排序以玩家出战设置为准,示例:[111, 222, 333, 444, 555]
		mission_success_rate = 0, -- 大成功几率
		mission_reward = {}, -- 获得奖励,建议使用json格式记录。示例:{ itemid1: 1,  itemid2: 3,  itemid3: 5}
		mission_result = 0, -- 战斗结果(0-无效,1-胜利,2-失败)
        mission_roundtime = 0, -- 完成耗时(秒)
        mission_cleartype = 1,  -- 1-开始; 2-完成(领取奖励时)
	})
	return true
end

function _M.finishQuestRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id
    -- check finish time
    local radioTask = role:getProperty("radioTask")
    local task = radioTask[id]
    if not task then return 4 end
    if skynet.timex() < task.time then return 5 end

    local reward = getCrusadeReward(role, id)
    if type(reward) == "number" then
        return reward
    else
        SendPacket(actionCodes.Radio_finishQuestRpc, MsgPack.pack(reward))
    end
	return true
end

function _M.cancelQuestRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id
    -- check finish time
    local radioTask = role:getProperty("radioTask")
    local task = radioTask[id]
    if not task then return 4 end
    if skynet.timex() > task.time then return 5 end

    local remainT = task.time - skynet.timex()
    if remainT > 0 then
        local cost = math.ceil(remainT / 3600) * globalCsv.crusade_quicken
        if not role:checkItemEnough({[ItemId.Jade] = cost}) then return 6 end
        role:costItems({[ItemId.Jade] = cost}, {log = {desc = "radioQuest", int1 = id}})
        local reward = getCrusadeReward(role, id)
        if type(reward) == "number" then
            return reward
        else
            SendPacket(actionCodes.Radio_cancelQuestRpc, MsgPack.pack(reward))
        end
    else
        SendPacket(actionCodes.Radio_cancelQuestRpc, MsgPack.pack({id = id}))
    end
    return true
end

return _M