HangAction.lua 9.69 KB
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
	end
	local carbonData = csvdb["idle_battleCsv"][hangInfo.carbonId]
	local nowCoinTime = math.min(skynet.timex(), hangInfo.endCoinTime or 0)
	local nowItemTime = math.min(skynet.timex(), hangInfo.endItemTime or 0)

	local coinCount = math.max(0, math.floor((nowCoinTime - hangInfo.coinTime) / globalCsv.idle_money_produce_cd))
	hangInfo.coinTime = hangInfo.coinTime + coinCount * globalCsv.idle_money_produce_cd

	local itemCount = math.max(0, math.floor((nowItemTime - hangInfo.itemTime) / globalCsv.idle_item_produce_cd))
	hangInfo.itemTime = hangInfo.itemTime + itemCount * globalCsv.idle_item_produce_cd

	local items = role:getProperty("hangBag")
	items[ItemId.Gold] = (items[ItemId.Gold] or 0) + coinCount * carbonData.money
	items[ItemId.Exp] = (items[ItemId.Exp] or 0) + coinCount * carbonData.exp
	items[ItemId.PlayerExp] = (items[ItemId.PlayerExp] or 0) + coinCount * carbonData.playerExp

	local pool = {}
	for _, temp in pairs(carbonData.item:toArray()) do
		table.insert(pool, temp:toArray(true, "="))
	end
	local curTypeCount = 0
	for id, _ in pairs(items) do
		if id ~= ItemId.Gold and id ~= ItemId.Exp and id ~= ItemId.PlayerExp then
			curTypeCount = curTypeCount + 1
		end
	end
	for i = 1, itemCount do
		local cur = pool[math.randWeight(pool, 3)]
		if items[cur[1]] or curTypeCount < role:getProperty("hangBagLimit") then
			if not items[cur[1]] then
				curTypeCount = curTypeCount + 1
			end
			items[cur[1]] = (items[cur[1]] or 0) + cur[2]
		end
	end

	if coinCount > 0 or itemCount > 0 then
		return true
	end
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 end

	local hangPass = role:getProperty("hangPass")

	for _, preCarbonId in ipairs(carbonData.prepose:toArray(true, "=")) do
		if not hangPass[preCarbonId] then return 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
	local nowTime = skynet.timex()
	hangInfo.coinTime = nowTime
	hangInfo.itemTime = nowTime
	if isNew then
		hangInfo.endCoinTime = nowTime + globalCsv.idle_producetime_max
		hangInfo.endItemTime = nowTime + globalCsv.idle_producetime_max
	end
	if not hangPass[carbonId] then
		hangInfo.bossTime = nowTime + carbonData.idle_time
	else
		hangInfo.bossTime = nil
	end
	role:updateProperty({field = "hangInfo", value = hangInfo})

	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

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")
	if curData.main ~= 1 then
		if carbonId ~= hangInfo.carbonId then 
			return 2
		end
	end

	local hangPass = role:getProperty("hangPass")
	if hangPass[carbonId] then 
		return 3
	end

	local key = tostring(math.random())
	hangInfo.key = key
	local nowTime = skynet.timex()
	role:updateProperty({field = "hangInfo", value = hangInfo})
	SendPacket(actionCodes.Hang_startBattleRpc, MsgPack.pack({key = key}))
	return true
end

function _M.endBattleRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local hangInfo = role:getProperty("hangInfo")
	if not msg.key or msg.key ~= hangInfo.key then 
		return 1
	end
	local carbonId = msg.carbonId
	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
	local hangPass = role:getProperty("hangPass")
	if hangPass[carbonId] then 
		return 4
	end
	local reward
	if msg.starNum and msg.starNum > 0 then --win
		hangPass[carbonId] = 1
		role:updateProperty({field = "hangPass", value = hangPass})
		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 = role:award(reward)

		role:checkTaskEnter(role.TaskType.HangPass, {id = carbonId})
	end
	hangInfo.key = nil
	role:updateProperty({field = "hangInfo", value = hangInfo})
	SendPacket(actionCodes.Hang_endBattleRpc, MsgPack.pack({
		starNum = msg.starNum, 
		reward = reward,
		}))
	return true
end

function _M.roleFormatRpc(agent , data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local hangTeam = role:getProperty("hangTeam")
	for slot, heroId in pairs(msg.heros) do
		if not role.heros[heroId] then
			return
		end
	end
	table.clear(hangTeam)
	hangTeam.heros = {}
	for slot, heroId in pairs(msg.heros) do
		hangTeam.heros[slot] = heroId
	end
	hangTeam.leader = msg.leader

	role:updateProperty({field = "hangTeam", value = hangTeam}) 
	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 = role:award(items)
	table.clear(items)
	local hangInfo = role:getProperty("hangInfo")
	local nowTime = skynet.timex()
	hangInfo.endItemTime = nowTime + globalCsv.idle_producetime_max
	hangInfo.endCoinTime = nowTime + globalCsv.idle_producetime_max
	hangInfo.coinTime = nowTime
	hangInfo.itemTime = nowTime
	role:updateProperty({field = "hangBag", value = items})
	role:updateProperty({field = "hangInfo", value = hangInfo})

	SendPacket(actionCodes.Hang_getRewardRpc, MsgPack.pack({
		reward = reward
	}))
	return true
end

function _M.getRewardItemRpc(agent , data)
	local role = agent.role
	checkReward(role)
	local items = role:getProperty("hangBag")
	if not next(items) then return end

	local notNeed = {[ItemId.Gold] = 1, [ItemId.Exp] = 1, [ItemId.PlayerExp] = 1}
	local reward = {}
	for itemId , count in pairs(items) do
		if not notNeed[itemId] then
			reward[itemId] = count
			items[itemId] = nil
		end
	end
	if not next(reward) then return end
	local reward = role:award(reward)

	local hangInfo = role:getProperty("hangInfo")
	local nowTime = skynet.timex()
	hangInfo.endItemTime = nowTime + globalCsv.idle_producetime_max
	hangInfo.itemTime = nowTime
	role:updateProperty({field = "hangBag", value = items})
	role:updateProperty({field = "hangInfo", value = hangInfo})

	SendPacket(actionCodes.Hang_getRewardItemRpc, MsgPack.pack({
		reward = reward
	}))
	return true
end

function _M.getRewardCoinRpc(agent , data)
	local role = agent.role
	checkReward(role)
	local items = role:getProperty("hangBag")
	if not next(items) then return end

	local need = {[ItemId.Gold] = 1, [ItemId.Exp] = 1, [ItemId.PlayerExp] = 1}
	local reward = {}
	for itemId , count in pairs(items) do
		if need[itemId] then
			reward[itemId] = count
			items[itemId] = nil
		end
	end
	local reward = role:award(reward)
	
	local hangInfo = role:getProperty("hangInfo")
	local nowTime = skynet.timex()
	hangInfo.endCoinTime = nowTime + globalCsv.idle_producetime_max
	hangInfo.coinTime = nowTime
	role:updateProperty({field = "hangBag", value = items})
	role:updateProperty({field = "hangInfo", value = hangInfo})

	SendPacket(actionCodes.Hang_getRewardCoinRpc, MsgPack.pack({
		reward = reward
	}))
	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 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]})
	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] = (reward[ItemId.Gold] or 0) + coinCount * carbonData.money
	reward[ItemId.Exp] = (reward[ItemId.Exp] or 0) + coinCount * carbonData.exp

	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

	reward = role:award(reward)

	SendPacket(actionCodes.Hang_quickRpc, MsgPack.pack({
		reward = reward
	}))
	return true
end

return _M