SeaportAction.lua 9 KB
local ipairs = ipairs
local table = table
local math = math
local redisproxy = redisproxy
local MsgPack = MsgPack

local _M = {}

function _M.getServerProcessRpc(agent, data)
	local role = agent.role
	local result = role:getSeaportServerProgress()

	SendPacket(actionCodes.Seaport_getServerProcessRpc, MsgPack.pack(result))
	return true
end

function _M.donateRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	
	local phase = msg.phase or 0
	local id = msg.id or 0
	local itemId = msg.itemId or 0
	local itemCount = msg.count or 0

	if itemId == 0 or itemCount == 0 then return 0 end
	if role:getItemCount(itemId) < itemCount then return 1 end
	local DonateCsv = csvdb["seaport_purchaseCsv"]
	if not DonateCsv[phase] or not DonateCsv[phase][id] then return 2 end

	local ddata = DonateCsv[phase][id]
	local needs = ddata.need_item:toArray(true,"=")
	if itemId ~= needs[1] then return 3 end
	if itemCount % needs[2] ~= 0 then return 4 end

	local group = itemCount / needs[2]
	local rewards = ddata.award:toNumMap()

	for id, value in pairs(rewards) do
		rewards[id] = value * group
	end

	if phase == 1 then
		local old = tonumber(redisproxy:hget(SEAPORT_TRADE_TASK_1,id)) or 0
		local need = ddata.need_num - old
		if need >= itemCount then
			redisproxy:hincrby(SEAPORT_TRADE_TASK_1,id,itemCount)
		else
			redisproxy:hincrby(SEAPORT_TRADE_TASK_1,id,need)
			for _, temp in pairs(DonateCsv[2]) do
				local items = temp.need_item:toArray(true,"=")
				if items[1] == itemId then
					redisproxy:hincrby(SEAPORT_TRADE_TASK_2,temp.id,itemCount - need)
					break
				end
			end
		end
	else
		redisproxy:hincrby(SEAPORT_TRADE_TASK_2,id,itemCount)
	end

	local seaport = role:getProperty("seaport") or {}
	if not seaport.join then
		seaport.join = 1
		role:updateProperty({field = "seaport", value = seaport})
	end

	role:costItems({[itemId] = itemCount}, {log = {desc = "seaportDonate", int1 = phase, int2 = id}})
	local reward, change = role:award(rewards, {log = {desc = "seaportDonate", int1 = ddata.phase, int2 = ddata.id}})

	role:mylog("role_action", {desc = "seaportDonate", int1 = itemId, int2 = itemCount})

	SendPacket(actionCodes.Seaport_donateRpc, MsgPack.pack(role:packReward(reward, change)))
	return true
end

function _M.donateRewardRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)

	local id = msg.id
	local dataCsv = csvdb["seaport_purchaseCsv"]
	if not dataCsv[id] then return 0 end

	local seaport = role:getProperty("seaport") or {}
	local donate = seaport.donate or {}
	if donate[id] then return 3 end

	local data = dataCsv[id][1]

	local result = role:getSeaportServerProgress()
	if not result[id] then return 1 end

	for _, tempData in ipairs(dataCsv[id]) do
		if tempData.need_num > (result[id][tempData.id] or 0) then
			return 2
		end
	end

	donate[id] = 1
	seaport.donate = donate

	local reward, change = role:award(data.phase_award, {log = {desc = "seaportReward", int1 = data.phase, int2 = data.id}})

	role:updateProperty({field = "seaport", value = seaport})
	SendPacket(actionCodes.Seaport_donateRewardRpc, MsgPack.pack(role:packReward(reward, change)))
	return true
end

-- 获取英雄大成功率
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

function _M.taskRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)

	local oper = msg.oper or 0
	local team = msg.team or ""
	local taskId = msg.id or 0
	local level = msg.level or 0

	if oper == 0 then return 0 end
	local TaskCsv = csvdb["seaport_taskCsv"]
	if not TaskCsv[taskId] or not TaskCsv[taskId][level] then return 1 end

	local reward, change = {}, {}
	local heroFaithMap = {}
	local seaport = role:getProperty("seaport")

	local data = TaskCsv[taskId][level]
	if data.phase == 2 then
		local openTime = tonumber(redisproxy:hget("autoincrement_set", "seaportTime0")) or 0
		local nowTime = skynet.timex()
		if nowTime < (openTime + 86400) or nowTime > (openTime + 172800) then return 9 end
	end

	if oper == 1 then -- 开始委托
		if team == "" then return 3 end
		local conditions = data.condition:toTableArray(true)
		local heros = team:toArray(true,"=")
		if not next(heros) then return 8 end
		local UnitCsv = csvdb["unitCsv"]
		for _, conds in pairs(conditions) do
			local count = 0
			for _, heroId in pairs(heros) do
				local hero = role.heros[heroId]
				if not hero then return 8 end

				if conds[1] == 1 then
					if hero:getProperty("level") >= conds[2] then
						count = count + 1
					end
				elseif conds[1] == 2 then
					if UnitCsv[hero:getProperty("type")].rare >= conds[2] then
						count = count + 1
					end
				elseif conds[1] == 3 then
					count = count + 1
				end
			end
			if count < conds[#conds] then
				return 4
			end
		end

		local collect = seaport.collect or {}
		collect[taskId] = {}
		collect[taskId].time = skynet.timex()
		collect[taskId].level = level
		collect[taskId].team = team

		seaport.collect = collect
	elseif oper == 2 then -- 领取委托奖励
		local collects = seaport.collect or {}
		local collect = collects[taskId] or {}
		if not next(collects) or not next(collect) then
			return 5
		end
		local quick = msg.quick
		local endTime = data.time + collect.time
		local remainT = endTime - skynet.timex()
		if not quick and remainT > 0 then return 6 end

		if quick and remainT > 0 then
			local cost = math.ceil(remainT / 3600) * globalCsv.seaport_task_quick
			if not role:checkItemEnough({[ItemId.Jade] = cost}) then return 8 end
			role:costItems({[ItemId.Jade] = cost}, {log = {desc = "seaportTask", int1 = taskId, int2 = level}})
		end

		local carbonCsv = csvdb["idle_battleCsv"]
		local expData = role:getProperty("hangInfo").expData or {}
		--if not carbonCsv[expCarbonId] then return 7 end

		local totalCoef = 0
	    for _, heroId in ipairs(collect.team:toArray(true,"=")) do
	        local hero = role.heros[heroId]
	        if hero then
	            totalCoef = totalCoef + getHeroCoef(hero, data.success)
	            hero:addHeroFaith(data.trust)
	            heroFaithMap[heroId] = hero:getProperty("faith")
	        end
    	end

		local bigSuccess = false
	    local result = math.randomInt(0, 100)
	    if result < totalCoef then
	        bigSuccess = true
	    end

		local money = math.ceil((expData.money or 0) / 5 * data.time * data.money_clear)
		local exp = math.ceil((expData.exp or 0) / 5 * data.time * data.exp_clear)
		local itemReward = data.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

	    reward, change = role:award(itemReward, {log = {desc = "seaportTask", int1 = taskId, int2 = level}})

		seaport.collect[taskId] = nil

		role:mylog("role_action", {desc="seaportTask", int1=taskId, int2=level, short1=bigSuccess and 1 or 0})
	else
		return 0
	end

	role:updateProperty({field = "seaport", value = seaport})

	local result = role:packReward(reward, change)
	result["heroFaith"] = heroFaithMap

	SendPacket(actionCodes.Seaport_taskRpc, MsgPack.pack(result))
	return true
end

function _M.shopRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id or 0
	local count = msg.count or 1

	local shopCsv = {}
	local dataSet = csvdb["shop_normalCsv"]
	for _, datat in pairs(dataSet) do
		if datat.shop == 5 then
			shopCsv[datat.id] = datat
		end
	end
	local sdata = shopCsv[id]
	
	if not sdata then return 2 end

	local seaport = role:getProperty("seaport")
	local shop = seaport.shop or {}

	if (shop[id] or 0) >= sdata.limit then return 1 end

	

	

	if role:getItemCount(sdata.icon) < sdata.cost * count then return 3 end

	role:costItems({[sdata.icon] = sdata.cost * count}, {log = {desc = "seaportShop", int1 = id, int2 = count}})

	local itemReward = sdata.gift:toNumMap()
	for itemId, value in pairs(itemReward) do
		itemReward[itemId] = value * count
	end

	local reward, change = role:award(itemReward, {log = {desc = "seaportShop", int1 = id, int2 = count}})

	shop[id] = (shop[id] or 0) + count
	seaport.shop = shop

	role:updateProperty({field = "seaport", value = seaport})

	SendPacket(actionCodes.Seaport_shopRpc, MsgPack.pack(role:packReward(reward, change)))
	return true
end

function _M.resetRpc(agent, data)
	local role = agent.role
	role:checkSeaportTrade()
	SendPacket(actionCodes.Seaport_resetRpc, MsgPack.pack(""))
	return true
end

return _M