AdvBlock.lua 9.71 KB
--块类型
local AdvCommon = require "adv.AdvCommon"
local Passive = require "adv.AdvPassive"

local Block = class("AdvBlock")
function Block:ctor(room, blockId, event, isOpen, trapId)
	self.room = room
	self.blockId = blockId
	self.col, self.row = AdvCommon.getCrById(self.blockId)

	self.isOpen = isOpen and true or false
	self.trapId = trapId

	self:updateEvent(event, true)
end
function Block:isBoss()
	return self:getEventType() == AdvEventType.BOSS
end

function Block:isMonster()
	return (self:getEventType() == AdvEventType.BOSS or self:getEventType() == AdvEventType.Monster)
end

function Block:isBuild()
	return self:getEventType() == AdvEventType.Build
end

function Block:isChoose()
	return self:getEventType() == AdvEventType.Choose
end

function Block:getEventType()
	return self.event and self.event.etype
end

function Block:getStageType()
	return self.room:getStageType(self.blockId)
end

function Block:updateEvent(event, isInit)
	if not isInit then
		-- 有些事件删除 需要处理
		if self:isBuild() then 
			self.room.map.adv.battle:removeBuildByPos(self.room.roomId, self.blockId)
		elseif self:isMonster() then
			if self.event.mId then
				self.room.map.adv.battle:removeEnemyById(self.event.mId)
			end
		end
	end
	local oldet = self:getEventType()

	self.event = event
	if not isInit and self.event then
		-- 判断下类型是不是错的
		if not self:getEventData() and (self:getEventType() ~= AdvEventType.Drop or not self.event.item) then
			self:clear()
			assert(false, "updateEvent error, : event " .. (event.etype or "nil"))
			return
		end
		self:randomEvent()
	end
	self:quickDrop()

	if not isInit and self.isOpen then
		local newet = self:getEventType()
		if oldet ~= newet then
			local em = {}
			if oldet then
				em[oldet] =1 
			end
			if newet then
				em[newet] =1 
			end

			local player = self.room.map.adv.battle.player
			player:attrChangeCondBuffCheck(4, em)
			for _, monster in pairs(player:getTeam(2)) do
				monster:attrChangeCondBuffCheck(4, em)
			end
		end
	end
end

function Block:clear()
	local et = self:getEventType()
	if et == AdvEventType.Trap then 
		self.trapId = self.event.id
	elseif et == AdvEventType.Build then
		local build = self.room.map.adv.battle:getBuild(self.room.roomId, self.blockId, self.room.map.mapIdx)
		if build then
			build.isDead = true
		end
	end
	self.event = nil


	if et then
		local em = {[et] = 1}
		local player = self.room.map.adv.battle.player
		player:attrChangeCondBuffCheck(4, em)
		for _, monster in pairs(player:getTeam(2)) do
			monster:attrChangeCondBuffCheck(4, em)
		end
	end
end


function Block:randomEvent()
	local room = self.room
	local map = room.map
	local adv = map.adv
	--如果翻开有数据处理在这里处理
	local randomFunc = {}
	--怪
	randomFunc[AdvEventType.Monster] = function()
		local enemy = adv.battle:getEnemy(room.roomId, self.blockId, map.mapIdx)
		if enemy then
			enemy:unlock()
		else
			enemy = adv.battle:addEnemy(room, self, map.mapIdx)
		end
		enemy:triggerPassive(Passive.BORN_ONCE)

		adv.battle.player:triggerPassive(Passive.OPEN_MONSTER, {trigger = enemy})
		adv.battle.player:attrChangeCondBuffCheck(3, enemy:getClassify())
		for _, monster in pairs(adv.battle.player:getTeam(2)) do
			monster:triggerPassive(Passive.OPEN_MONSTER, {trigger = enemy})
			monster:attrChangeCondBuffCheck(3, enemy:getClassify())
		end
	end
	randomFunc[AdvEventType.BOSS] = randomFunc[AdvEventType.Monster]
	--掉落
	randomFunc[AdvEventType.Drop] = function()
		if not self.event.item then
			self.event.item = csvdb["event_dropCsv"][self.event.id]["range"]:randWeight(true)
		end
	end
	--交易
	randomFunc[AdvEventType.Trader] = function()
		local data = csvdb["event_traderCsv"][self.event.id]
		self.event.shop = {}
		self.event.status = "" --购买次数状态  1 就是购买过了  -- 购买id就是shop索引
		local needDiscount = data.discount -- 需要的折扣数量
		local curHad = {}
		local advShop = adv.owner:getProperty("advShop")
		local function randomGoods(range, gcount)
			local pool = range:toTableArray(true) -- {{id, weight}, ... }
			local function randomOneGood()
				for i = #pool, 1, -1 do
					local curId = pool[i][1]
					local curData = csvdb["event_trader_goodsCsv"][curId]
					if not curData then
						table.remove(pool, i)
					else
						if curData.restrict == 1 then -- 冒险内限制
							if curData.restrictnum <= ((adv.shopStatus[curId] or 0) + (curHad[curId] or 0)) then
								table.remove(pool, i)
							end
						elseif curData.restrict == 2 then -- 角色限制
							if curData.restrictnum <= ((advShop[curId] or 0) + (curHad[curId] or 0)) then
								table.remove(pool, i)
							end
						end
					end
				end
				if #pool <= 0 then
					return false
				end
				local idx = math.randWeight(pool, 2)
				local getId = pool[idx][1]
				local getData = csvdb["event_trader_goodsCsv"][getId]
				if getData.restrict ~= 0 then 
					curHad[getId] = (curHad[getId] or 0) + 1
				end
				if getData.discount ~= "" and needDiscount > 0 then
					needDiscount = needDiscount - 1
					table.insert(self.event.shop, {getId, getData.discount:randWeight()})
				else
					table.insert(self.event.shop, {getId})
				end
				return true
			end

			for i = 1, gcount do
				if not randomOneGood() then
					break
				end
			end
		end

		for i = 1, 10 do
			local numS, rangeS = "num" .. i, "range" .. i
			if data[numS] and data[rangeS] then
				randomGoods(data[rangeS], data[numS])
			else
				break
			end
		end
	end
	--建筑
	randomFunc[AdvEventType.Build] = function()
		local build = adv.battle:getBuild(room.roomId, self.blockId, map.mapIdx)
		if build then
			build:unlock()
		else
			build = adv.battle:addEnemy(room, self, map.mapIdx)
		end
		build:triggerPassive(Passive.BORN_ONCE)
	end

	randomFunc[AdvEventType.Trap] = function()
		local data = csvdb["event_trapCsv"][self.event.id]
		-- 因为一些神器效果 提前触发被动
		adv.battle.player:triggerPassive(Passive.CLICK_TRAP)

		local buffs = data.effect:toArray(true, "=")
		

		local backTrap = true
		if data.target == 0 then  -- 给玩家增加buff
			for _, buffId in ipairs(buffs) do
				adv.battle.player:addBuff(buffId)
			end
		elseif data.target == 1 then-- 给玩家 和 所有敌人同样增加buff
			local enemys = adv.battle.player:getTeam(2)
			for _, buffId in ipairs(buffs) do
				adv.battle.player:addBuff(buffId)
			end
			for k , enemy in ipairs(enemys) do
				for _, buffId in ipairs(buffs) do
					enemy:addBuff(buffId)
				end
			end
		elseif data.target == 2 then -- 翻开房间
			self.room.map.adv:getCurMap():openBlocksByRoom(self.room.roomId)
			backTrap = false
		elseif data.target == 3 then -- 翻开周围8格,并给怪物附带buff(不伤害玩家)
			self.room.map.adv:getCurMap():openBlocksBySize(self.room.roomId, self.blockId, 2)
			local enemys = self.room.map.adv:getCurMap():getEnemysBySize(self.room.roomId, self.blockId, 2)
			for _, e in ipairs(enemys) do
				for _, buffId in ipairs(buffs) do
					e:addBuff(buffId)
				end
			end
		elseif data.target == 4 then
			local enemys = self.room.map.adv:getCurMap():openBlocksIsMonsterByRoom(self.room.roomId)
			for _, e in ipairs(enemys) do
				for _, buffId in ipairs(buffs) do
					e:addBuff(buffId)
				end
			end
		end

		if data.specialEff ~= "" then
			local effect = data.specialEff:toArray(true, "=")
			if effect[1] == 1 then
				self.room.map.adv:mapItemChange(effect[2])
			end
		end

		adv:checkAchievement(adv.AchievType.Trap, 1, self.event.id)
		if backTrap then
			adv:backTrap()
		end
		self:clear()
	end


	if self.event then -- 随机出具体的事件
		if randomFunc[self:getEventType()] then
			randomFunc[self:getEventType()]()
		end
	end
end

-- 获取event 数据
function Block:getEventData()
	local typToCsv = {
		[AdvEventType.Monster] = "event_monsterCsv",
		[AdvEventType.BOSS] = "event_monsterCsv",
		[AdvEventType.Choose] = "event_chooseCsv",
		[AdvEventType.Drop] = "event_dropCsv",
		[AdvEventType.Build] = "event_buildingCsv",
		[AdvEventType.Trader] = "event_traderCsv",
		[AdvEventType.Trap] = "event_trapCsv",
		[AdvEventType.Click] = "event_clickCsv",
		[AdvEventType.Layer] = "event_layerCsv",
		[AdvEventType.LinkChoose] = "event_linkchooseCsv",
	}

	local etype = self:getEventType()
	if not etype then return end
	if not self.event.id then return end
	if not typToCsv[etype] then return end

	return csvdb[typToCsv[etype]][self.event.id]
end

--事件有需要额外处理的部分
function Block:open()
	if self.isOpen then return end
	local room = self.room
	local map = room.map
	local adv = map.adv
	self.isOpen = true
	self:randomEvent()
	self:quickDrop()

	local et = self:getEventType()
	if et then
		local em = {[et] = 1}
		local player = self.room.map.adv.battle.player
		player:attrChangeCondBuffCheck(4, em)
		for _, monster in pairs(player:getTeam(2)) do
			monster:attrChangeCondBuffCheck(4, em)
		end
	end
	return true
end

function Block:quickDrop()
	if self:getEventType() == AdvEventType.Drop and self.event.item then
		local itemId, count = table.unpack(self.event.item)
		if globalCsv.adv_auto_collect[itemId] then
			self.room.map.adv:award({[itemId] = count}, {log = {desc = "clickDrop"}}, {roomId = self.room.roomId, blockId = self.blockId, tag = 1})
			self:clear()
		end
	end
end

function Block:getObstacle()
	if self:isMonster() then
		local enemy = self.room.map.adv.battle:getEnemy(self.room.roomId, self.blockId)
		if enemy then
			return enemy:getObstacle()	
		end
	end
	local data = self:getEventData()
	if not data then return 0 end
	return data.obstacle or 0
end

-- 是否看守周围地板
function Block:isGuard()
	return self.isOpen and self:getObstacle() == 2
end

-- 是否是路障
function Block:isHinder()
	return self.isOpen and self:getObstacle() == 1
end

-- 玩家是否经过   -- 已经翻开 并且 不是路障
function Block:isWalk()
	return self.isOpen and not self:isHinder()
end

return Block