TowerAction.lua 7.52 KB
local ipairs = ipairs
local table = table
local math = math
local redisproxy = redisproxy
local MsgPack = MsgPack


local _M = {}



local function getUpdateTime(lastCount, lastTime)
	local nextCount, nextTime = lastCount, skynet.timex()
	if lastTime then
		local addCount = math.floor((skynet.timex() - lastTime) / (globalCsv.tower_count_up * 60))
		nextCount = math.min(lastCount + addCount, globalCsv.tower_count_limit)
		nextTime = lastTime + addCount * (globalCsv.tower_count_up * 60)
	end
	return nextCount, nextTime
end

function _M.startBattleRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id
	local towerType = math.floor(id / 10000)

	if not id or towerType < 0 or towerType > 3 then return 0 end
	if not role:isFuncUnlock(FuncUnlock.Tower) then return 1 end

	local towerInfo = role:getProperty("towerInfo")

	if towerType == 0 and (towerInfo.l or 1) ~= id then return 2 end  -- 层数不对
	if towerType == 1 and ((towerInfo.l1 or 10001) ~= id or (towerInfo.l or 1) <= globalCsv.tower_open[towerType]) then return 2 end  -- 层数不对
	if towerType == 2 and ((towerInfo.l2 or 20001) ~= id or (towerInfo.l or 1) <= globalCsv.tower_open[towerType]) then return 2 end  -- 层数不对
	if towerType == 3 and ((towerInfo.l3 or 30001) ~= id or (towerInfo.l or 1) <= globalCsv.tower_open[towerType]) then return 2 end  -- 层数不对

	if not csvdb["tower_battleCsv"][id] then return 4 end

	local teams = role:getTowerTeamFormat(towerType + 1)
	if not next(teams) then return 5 end

	if towerType ~= 0 then
		for _, heroId in pairs(teams.heros) do
			local hero = role.heros[heroId]
			if not hero then return 6 end
			local unit = csvdb["unitCsv"][hero:getProperty("type")]
			if unit.camp ~= towerType then return 7 end
		end
	end

	local curCount, nextTime = getUpdateTime(towerInfo.c, towerInfo.t)
	--if curCount < 1 then return end -- 没有次数返回

	--搞起来
	towerInfo.c = curCount - 1
	if curCount == globalCsv.tower_count_limit then --满的情况下的消耗了 恢复时间从当下开始
		nextTime = skynet.timex()
	end
	towerInfo.t = nextTime
	local key = tostring(math.random())
	towerInfo.k = key

	role:updateProperty({field = "towerInfo", value = towerInfo})
	role:checkTaskEnter("TowerBattle", {level = towerInfo.l})
	role:mylog("tower_action", {desc = "startBattle", int1 = id})
	SendPacket(actionCodes.Tower_startBattleRpc, '')
	return true
end

function _M.endBattleRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id
	local key = msg.key
	local passTime = msg.passTime

	local curTower = csvdb["tower_battleCsv"][id] 
	if not curTower then return 2 end

	local towerInfo = role:getProperty("towerInfo")
	local towerType = math.floor(id / 10000)
	local towerLevel = {[0] = (towerInfo.l or 1), [1] = (towerInfo.l1 or 10001), [2] = (towerInfo.l2 or 20001), [3] = (towerInfo.l3 or 30001)}
	local curLevel = towerLevel[towerType]

	if curLevel ~= id or not towerInfo.k or towerInfo.k ~= key then 
		SendPacket(actionCodes.Tower_endBattleRpc, MsgPack.pack({errorCode = 1}))
		return true
	end

	-- 防作弊
	if not role:checkBattleCheat("tower", {
		isWin = msg.starNum and msg.starNum > 0,
		info = msg.info,
		tower = towerType + 1
	}) then
		SendPacket(actionCodes.Tower_endBattleRpc, MsgPack.pack({errorCode = 1}))
		return true
	end

	local curCount, nextTime = getUpdateTime(towerInfo.c, towerInfo.t)


	local reward, change
	if msg.starNum and msg.starNum > 0 then --win
		curCount = math.min(curCount + 1, globalCsv.tower_count_limit) -- 返还次数
		--排行榜
		role:setTowerRank(curLevel % 10000, towerType + 1)

		local rewardStr = curTower.reward
		if curTower.special_award ~= "" then
			rewardStr = rewardStr .. " " .. curTower.special_award
		end

		curLevel = curLevel + 1
		reward, change = role:award(rewardStr, {log = {desc = "towerBattle", int1 = id}})
		--if towerType == 0 then
        role:checkTaskEnter("TowerPass", {level = curLevel % 10000, type = towerType + 1})
		--end
	end

	if towerType == 0 then
		towerInfo.l = curLevel
	elseif towerType == 1 then
		towerInfo.l1 = curLevel
	elseif towerType == 2 then
		towerInfo.l2 = curLevel
	elseif towerType == 3 then
		towerInfo.l3 = curLevel
	end

	towerInfo.c = curCount
	towerInfo.t = nextTime
	towerInfo.k = nil
	role:updateProperty({field = "towerInfo", value = towerInfo})

	local RankTower = {[0] = RANK_TOWER,[1] = RANK_TOWER1,[2] = RANK_TOWER2,[3] = RANK_TOWER3}
	local rankName = RankTower[towerType]
	local rank = redisproxy:ZREVRANK(rankName, role:getProperty("id"))
	if not rank then
		rank = -1
	else
		rank = rank + 1
	end
	role:checkBattle("tower", {
		id = id,
		isWin = msg.starNum and msg.starNum > 0,
		info = msg.info,
		reward = reward,
		rank = rank,
		tower = towerType + 1
	})
    local team = role:getTowerTeamFormat(towerType + 1)


	role:mylog("tower_action", {desc = "endBattle", short1 = msg.starNum > 0 and 1 or 0, int1 = id, int2 =  towerType, 
    cint1 = curLevel, key1 = role:getHerosLogStr(team.heros), key2 = role:getRewardLogStr(reward)})

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

function _M.bugCountRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local buyCount = msg.count

	local towerInfo = role:getProperty("towerInfo")
	local curCount, nextTime = getUpdateTime(towerInfo.c, towerInfo.t)
	local needCount = globalCsv.tower_count_limit - curCount
	if needCount > buyCount then
		needCount = buyCount
	end
	if needCount > 0 then -- 补充
		local cost = globalCsv.tower_chance_item:toNumMap()
		for k , v in pairs(cost) do
			cost[k] = v * needCount
		end
		if not role:checkItemEnough(cost) then return end
		role:costItems(cost, {log = {desc = "towerCount"}})
		curCount = curCount + needCount
	end
	towerInfo.c = curCount
	towerInfo.t = nextTime
	role:updateProperty({field = "towerInfo", value = towerInfo})
	role:mylog("tower_action", {desc = "bugCount"})
	SendPacket(actionCodes.Tower_bugCountRpc, '')
	return true
end

function _M.rankRpc(agent , data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local towerType = msg.tower or 1
	SendPacket(actionCodes.Tower_rankRpc, MsgPack.pack(role:getTowerRank(towerType)))
	return true
end

function _M.rankInfoRpc(agent , data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local roleId = msg.roleId
	local towerType = msg.tower or 1
	SendPacket(actionCodes.Tower_rankInfoRpc, MsgPack.pack({format = role:getTowerRankOneInfo(roleId, towerType)}))
	return true
end

function _M.activeTowerBonusRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local tType = msg.tower
	local id = msg.id

	local bnousCsv = csvdb["tower_battle_additionCsv"]

	if not tType or not id or not bnousCsv[tType] then return 0 end
	local bnousData = bnousCsv[tType][id]
	if not bnousData then return 1 end

	local towerInfo = role:getProperty("towerInfo")
	local towerBnous = role:getProperty("towerBnous")

	if towerBnous[tType] and towerBnous[tType][id] then return 2 end
	local towerLevel = {[1] = (towerInfo.l or 1), [2] = (towerInfo.l1 or 10001), [3] = (towerInfo.l2 or 20001), [4] = (towerInfo.l3 or 30001)}
	local curLevel = towerLevel[tType]
	
	if tType ~= 1 then
		if curLevel <= globalCsv.tower_open[tType - 1] then return 4 end
	end

	if (curLevel % 10000) <= bnousData.floor then return 3 end

	if not towerBnous[tType] then
		towerBnous[tType] = {}
	end
	towerBnous[tType][id] = 1
	role:updateProperty({field = "towerBnous", value = towerBnous})
	role:getTowerBnousActive(true)
	SendPacket(actionCodes.Tower_activeTowerBonusRpc, '')
	return true
end

return _M