AdvAction.lua 8.57 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 checkFormat(role, format, isHang)
	local advHang = role:getProperty("advHang")
	local hadHero = {}
	for chapterId, info in pairs(advHang) do
		if info.format then
			for _, heroId in pairs(info.format.heros) do
				hadHero[heroId] = true
			end
		end
	end

	if isHang then
		for _, heroId in pairs(role:getProperty("advTeam").heros or {}) do
			hadHero[heroId] = true
		end
	end

	if not format.leader then return end
	local hadLeader = false
	for slot, heroId in pairs(format.heros) do
		if not role.heros[heroId] or hadHero[heroId] then
			return
		end
		if heroId == format.leader then
			hadLeader = true
		end
	end
	if not hadLeader then return end
	return true
end

--开始一个新的关卡
function _M.startAdvRpc( agent, data )
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local chapterId = msg.chapterId --关卡id
	local layer = msg.layer or 1	--选择层数
	local format = msg.format 		--编队
	local chapterData = csvdb["adv_chapterCsv"][chapterId]
	if not chapterData then return end

	if role.dailyData:getProperty("advC") >= role:getAdvHangLimit() then return end -- 是否有体力

	local oklayer = false --层是否合法
	if layer ~= 1 then
		for _, exLayer in ipairs(globalCsv.adv_can_out_layer) do
			if exLayer + 1 == layer then
				oklayer = true
				break
			end
		end
	end

	if not oklayer then return end
	if layer > chapterData.limitlevel then return end
	local advPass = role:getProperty("advPass")
	for _, id in ipairs(chapterData.prepose:toArray(true, "=")) do
		if advPass[id] ~= csvdb["adv_chapterCsv"][id].limitlevel then return end -- 前置
	end

	if layer ~= 1 and (advPass[chapterId] or 0) < (layer - 1) then return end --中继

	if not checkFormat(role, format) then return end

	--上一个关卡结束才可以开始新的关卡
	local advInfo = role:getProperty("advInfo")
	if next(advInfo) then return end

	local advTeam = role:getProperty("advTeam")
	table.clear(advTeam)

	advTeam.heros = {}
	for slot, heroId in pairs(msg.heros) do
		advTeam.heros[slot] = heroId
	end
	advTeam.leader = msg.leader
	role:updateProperty({field = "advTeam", value = advTeam})
	role.dailyData:updateProperty({field = "advC", delta = 1})

	role:getAdvData():initByChapter(chapterId, layer)

	SendPacket(actionCodes.Adv_startAdvRpc, '')
	return true
end


function _M.startHangRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local chapterId = msg.chapterId --关卡id
	local format = msg.format --编队

	local chapterData = csvdb["adv_chapterCsv"][chapterId]
	if not chapterData then return end

	local advHang = role:getProperty("advHang")
	if advHang[chapterId] then return end --正在挂机

	local advPass = role:getProperty("advPass")
	if advPass[chapterId] ~= chapterData.limitlevel then return end -- 没有全通关


	if role.dailyData:getProperty("advC") >= role:getAdvHangLimit() then return end -- 是否有体力

	if not checkFormat(role, format, true) then return end --编队是否正确

	local battleV = 0
	for _, heroId in pairs(format.heros) do
		local hero = role.heros[heroId]
		battleV = battleV + hero:getProperty("battleV")
	end
	if battleV < chapterData.idleValue then return end -- 战斗力是否满足

	local info = {}
	info.format = {}
	info.format.leader = format.leader
	info.format.heros  = {}
	for slot, heroId in pairs(format.heros) do
		info.format.heros[slot] = heroId
	end
	info.time = skynet.timex() + chapterData.idleTime --挂机时间

	role:changeUpdates({{type = "advHang", field = chapterId, value = info}})

	role.dailyData:updateProperty({field = "advC", delta = 1})

	SendPacket(actionCodes.Adv_startHangRpc, '')
	return true
end

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

	local chapterId = msg.chapterId --关卡id
	local cancel = msg.cancel  --是否是取消
	
	local advHang = role:getProperty("advHang")
	local info = advHang[chapterId]
	if not info then return end 

	local chapterData = csvdb["adv_chapterCsv"][chapterId]
	if not chapterData then return end
	
	local reward, isFull
	if skynet.timex() >= info.time then
		reward = role:award(chapterData.idleReward)
	else
		if cancel then
			if role.dailyData:getProperty("advC") <= 0 then 
				isFull = true
			else
				role.dailyData:updateProperty({field = "advC", delta = -1})
			end
		else
			return
		end
	end
	
	role:changeUpdates({{type = "advHang", field = chapterId, value = nil}})

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

function _M.buyAdvCountRpc(agent , data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	
	local count = msg.count --购买次数
	if math.illegalNum(count, 1, math.min(globalCsv.adv_daily_buy_count - role.dailyData:getProperty("advBC"), role.dailyData:getProperty("advC"))) then return end

	local cost = {[ItemId.Diamond] = count * globalCsv.adv_daily_buy_cost}
	if not role:checkItemEnough(cost) then return end
	role:costItems(cost)
	role.dailyData:updateProperty({field = "advC", delta = -count})
	
	SendPacket(actionCodes.Adv_buyAdvCountRpc, '')
	return true
end

-- 点击地块(解锁)(触发事件)
function _M.clickBlockRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)

	local adv = role:getAdvData()
	local status = adv:clickBlock(msg.roomId, msg.blockId, msg)
	if not status then return end
	SendPacket(actionCodes.Adv_clickBlockRpc, MsgPack.pack({events = adv:popBackEvents()}))
	return true
end

--use item 使用背包道具
function _M.useItemRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)

	local adv = role:getAdvData()
	local status = adv:useItem(msg.itemId, msg.count, msg.target) -- target {roomId = 1, blockId = 1} 选择的目标
	if not status then return end
	SendPacket(actionCodes.Adv_useItemRpc, MsgPack.pack({events = adv:popBackEvents()}))
	return true
end

--使用营养技能
function _M.usePotionRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local dishLevel = role.dinerData:getProperty("dishTree"):getv(msg.potionId, 0)
	if dishLevel == 0 then
		return
	end
	local adv = role:getAdvData()
	local status = adv:usePotion(msg.potionId, dishLevel, msg.target) -- target {roomId = 1, blockId = 1} 选择的目标
	if not status then return end
	SendPacket(actionCodes.Adv_usePotionRpc, MsgPack.pack({events = adv:popBackEvents()}))
	return true
end

--退出
function _M.exitAdvRpc(agent, data)
	local role = agent.role
	-- local msg = MsgPack.unpack(data)
	local adv = role:getAdvData()
	local status = adv:exit() -- target {roomId = 1, blockId = 1} 选择的目标
	SendPacket(actionCodes.Adv_exitAdvRpc, MsgPack.pack({events = adv:popBackEvents()}))
	return true
end 

--开始战斗
function _M.startBattleRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)

	-- 校验一下信息
	local roomId = msg.roomId
	local blockId = msg.blockId
	local monsterId = msg.monsterId
	local enemyId = msg.enemyId
	if not enemyId then return end

	local adv = role:getAdvData()
	local enemy = adv.battle:getEnemyById(enemyId)

	if enemy.monsterId ~= monsterId or enemy.roomId ~= roomId or enemy.blockId ~= blockId or enemy.lock or enemy.isDead then return end

	local key = tostring(math.random())
	adv.__battleCache = {
		enemyId = enemyId,
		key = key
	}
	SendPacket(actionCodes.Adv_startBattleRpc, MsgPack.pack({key = key}))
	return true
end

-- 结束战斗
function _M.endBattleRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local roomId = msg.roomId
	local blockId = msg.blockId
	local monsterId = msg.monsterId
	local enemyId = msg.enemyId
	local key =  msg.key
	local player = msg.player

	if not player or not player.hp or not player.sp or not enemyId or not key then return end
	local adv = role:getAdvData()
	-- 校验
	if not adv.__battleCache then return end
	if adv.__battleCache.enemyId ~= enemyId then return end
	local enemy = adv.battle:getEnemyById(enemyId)
	if enemy.monsterId ~= monsterId or enemy.roomId ~= roomId or enemy.blockId ~= blockId then return end
	adv.__battleCache = nil

	
	local status = adv:clickBlock(roomId, blockId, {player = player})
	if not status then return end
	SendPacket(actionCodes.Adv_endBattleRpc, MsgPack.pack({events = adv:popBackEvents()}))
	return true
end



return _M