AdvPassive.lua 10.3 KB
local Filter = class("Filter")

Filter.HP_UP_WITH_EQUAL = 1 -- 血量>=value%
Filter.HP_UP = 2 -- 血量>value%
Filter.HP_LOW_WITH_EQUAL = 3 -- 血量<=value%
Filter.HP_LOW = 4 -- 血量<value%
Filter.BUFF_BY_TYPE = 5 -- 指定类型buff
Filter.BUFF_BY_ID = 6 -- 指定id的buff

local FilterFactory = {}
FilterFactory[Filter.HP_UP_WITH_EQUAL] = function (_Filter)
	_Filter._execute = function (self, target)
		return target.hp >= self.value * target.hpMax / 100
	end
end
FilterFactory[Filter.HP_UP] = function (_Filter)
	_Filter._execute = function (self, target)
		return target.hp > self.value * target.hpMax / 100
	end
end
FilterFactory[Filter.HP_LOW_WITH_EQUAL] = function (_Filter)
	_Filter._execute = function (self, target)
		return target.hp <= self.value * target.hpMax / 100
	end
end
FilterFactory[Filter.HP_LOW] = function (_Filter)
	_Filter._execute = function (self, target)
		return target.hp < self.value * target.hpMax / 100
	end
end
FilterFactory[Filter.BUFF_BY_TYPE] = function (_Filter)
	_Filter._execute = function (self, target)
		return target:hadBuff(self.value)
	end
end
FilterFactory[Filter.BUFF_BY_ID] = function (_Filter)
	_Filter._execute = function (self, target)
		return target:hadBuffById(self.value)
	end
end

function Filter:ctor(params)
	self.owner = params.owner
	self.skill = params.skill
	self.fType = params.fType -- 筛选类型
	self.oType = params.oType -- 主体类型 0:owner 1:trigger 2:releaser
	self.value = params.value -- 筛选值
	
	if FilterFactory[self.fType] then
		FilterFactory[self.fType](self)
	end
end

function Filter:getTarget(params)
	local target
	if self.oType == 0 then
		target = self.owner
	end
	if self.oType == 1 and params.trigger then
		target = params.trigger
	end
	if self.oType == 2 and params.releaser then
		target = params.releaser
	end
	return target
end

function Filter:execute(params)
	local target = self:getTarget(params)
	if not target then
		return
	end
	if self:_execute(target) then
		return self:_execute(target)
	end
end

-->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
local Passive = class("Passive")

-- 每回合触发的使用 afterRound
-- 其他触发的使用 triggerPassive 

Passive.BORN_ONCE = 1 -- 自身出生(翻开所在格子)触发
Passive.ROOM_SHOW = 2 --自身所在房间被展示时,触发1次 
Passive.HURT_PERCENT_SELF = 3 --自身,每损失N%生命值,触发1次
Passive.HURT_PERCENT_TEAM = 4 --队友,每损失N%生命值,触发1次
Passive.HP_LOW_SELF = 5 --自身生命值<N%时,每回合触发
Passive.HP_LOW_TEAM = 6 --敌人生命值<N%时,每回合触发
Passive.HP_UP_SELF = 7 --自身生命值>N%时,每回合触发
Passive.HP_UP_TEAM = 8 --敌人生命值>N%时,每回合触发
Passive.SELF_ATK = 9 --自身攻击N次后,触发1次
Passive.SELF_HURT = 10 --自身受击N次后,触发1次
Passive.TEAM_ATK = 11 --队友攻击N次后,触发1次
Passive.TEAM_HURT = 12 --队友受击N次后,触发1次
Passive.MONSTER_COUNT_UP = 13  --场上存在N个以上怪物,每回合触发
Passive.MONSTER_COUNT_LOW = 14  --场上存在N个以下怪物,每回合触发
Passive.SELF_DEAD = 15 --自身死亡后,触发1次
Passive.TEAM_DEAD = 16 --队友死亡后,触发1次
Passive.TARGET_SKILL = 17 --目标每使用N次技能,触发1次
Passive.TEAM_SKILL = 18 --队友每使用N次技能,触发1次


-- 不同的开启条件
local PassiveCondFactory = {}
PassiveCondFactory[Passive.HURT_PERCENT_SELF] = function(_Passive)
	_Passive._trigger = function(self, params)
		local value = params.value or 1
		self.rv = math.floor(self.rv + value)
		if self.rv >= self.passiveData.value then
			self.rv = self.rv % self.passiveData.value  -- 取余
			return true
		end
	end
	_Passive._initDB = function(self, data)
		self.rv = data.rv or 0
	end
	_Passive._getDB = function(self)
		return {rv = self.rv}
	end
end

PassiveCondFactory[Passive.HURT_PERCENT_TEAM] = PassiveCondFactory[Passive.HURT_PERCENT_SELF]  --逻辑相同
PassiveCondFactory[Passive.SELF_ATK] = PassiveCondFactory[Passive.HURT_PERCENT_SELF]  --逻辑相同
PassiveCondFactory[Passive.SELF_HURT] = PassiveCondFactory[Passive.HURT_PERCENT_SELF]  --逻辑相同
PassiveCondFactory[Passive.TEAM_ATK] = PassiveCondFactory[Passive.HURT_PERCENT_SELF]  --逻辑相同
PassiveCondFactory[Passive.TEAM_HURT] = PassiveCondFactory[Passive.HURT_PERCENT_SELF]  --逻辑相同
PassiveCondFactory[Passive.TARGET_SKILL] = PassiveCondFactory[Passive.HURT_PERCENT_SELF]  --逻辑相同
PassiveCondFactory[Passive.TEAM_SKILL] = PassiveCondFactory[Passive.HURT_PERCENT_SELF]  --逻辑相同

PassiveCondFactory[Passive.ROOM_SHOW] = function(_Passive)
	_Passive._trigger = function(self, params)
		local roomId = params.roomId
		if self.roomId == roomId then
			return true
		end
	end
end

PassiveCondFactory[Passive.HP_LOW_SELF] = function(_Passive)
	_Passive._afterRound = function(self)
		if self.owner.hp / self.owner.hpMax * 100 < self.passiveData.value then
			self:trigger(Passive.HP_LOW_SELF)
		end
	end
end

PassiveCondFactory[Passive.HP_LOW_TEAM] = function(_Passive)
	_Passive._afterRound = function(self)
		for _, player in ipairs(self.owner:getTeam(2)) do
			if player.hp / player.hpMax * 100 < self.passiveData.value then
				self:trigger(Passive.HP_LOW_TEAM, {trigger = player})
			end
		end
	end
end

PassiveCondFactory[Passive.HP_UP_SELF] = function(_Passive)
	_Passive._afterRound = function(self)
		if self.owner.hp / self.owner.hpMax * 100 > self.passiveData.value then
			self:trigger(Passive.HP_UP_SELF)
		end
	end
end

PassiveCondFactory[Passive.HP_UP_TEAM] = function(_Passive)
	_Passive._afterRound = function(self)
		for _, player in ipairs(self.owner:getTeam(2)) do
			if player.hp / player.hpMax * 100 > self.passiveData.value then
				self:trigger(Passive.HP_UP_TEAM, {trigger = player})
			end
		end
	end
end

PassiveCondFactory[Passive.MONSTER_COUNT_UP] = function(_Passive)
	_Passive._afterRound = function(self)
		local monsters = self.owner.battle.player:getTeam(2)
		if #monsters > self.passiveData.value then
			self:trigger(Passive.MONSTER_COUNT_UP)
		end
	end
end

PassiveCondFactory[Passive.MONSTER_COUNT_LOW] = function(_Passive)
	_Passive._afterRound = function(self)
		local monsters = self.owner.battle.player:getTeam(2)
		if #monsters < self.passiveData.value then
			self:trigger(Passive.MONSTER_COUNT_LOW)
		end
	end
end


function Passive:ctor(owner, data)
	self.owner = owner
	self.id = data.id
	self.level = data.level or 1
	self.passiveData = csvdb["adv_map_passiveCsv"][self.id][self.level]
	self.isDel = false
	self.round = data.round or 0	--触发剩余回合数
	self.count = data.count or self.passiveData.count	--触发剩余次数
	self.delay = data.delay or self.passiveData.delayRound    --触发延迟回合数

	self.effects = self.passiveData.effect:toTableArray(true)
	self.filters = {}

	if self.passiveData.count < 0 then -- count < 0 无限次触发
		self.count = 999
	end
	
	if PassiveCondFactory[self.passiveData.condition] then
		PassiveCondFactory[self.passiveData.condition](self)
	end
	self:initFilter()
	if self._initDB then
		self:_initDB(data)
	end
end

function Passive:initFilter()
	local filterList = self.passiveData.filter:toTableArray(true)
	for _, fParams in ipairs(filterList) do
		local filter = Filter.new({owner = self.owner, skill = self, oType = fParams[1], fType = fParams[2], value = fParams[3] })
		table.insert(self.filters, filter)
	end
end

function Passive:getCondType()
	return self.passiveData.condition, self.passiveData.value
end

-- effect 生效篩選
function Passive:canEffect(effType, effValue)
	if self.owner.lock and effType ~= 3 then -- 锁定的只能触发翻开自己格子的固有技
		return
	end
	return true
end

function Passive:effect(trigger)
	for _, effect in pairs(self.effects) do
		local effType = effect[1]
		local effValue = effect[2]
		if self:canEffect(effType, effValue) then
			self["effect" .. effType](self, effValue, trigger)
		end
	end

	if self.count > 0 then
		self.count = self.count < 999 and self.count - 1 or self.count
		self.round = self.passiveData.round
	end
	
	if self.count <= 0 and self.passiveData.refresh == 1 then  -- 次数 <= 0 并且一次冒险内不刷新,被动可以直接移除
		self.isDel = true
	end
end

function Passive:afterRound()
	if self.isDel or self.owner.isDead then return end
	if self._afterRound then
		self:_afterRound()  --有的触发自己检测在这里检查
	end
	if self.round > 0 then  --回合触发的
		self.round = self.round - 1
	end
	if self.delay > 0 then
		self.delay = self.delay - 1
	end
end

-- 可以触发
function  Passive:canTrigger( )
	return self.count > 0 and self.delay <= 0
end

function Passive:trigger(condType, params) --触发检查
	params = params or {}
	if self.isDel or self.owner.isDead then return end
	if self:getCondType() ~= condType then return end
	if not self:canTrigger() then return end
	if self._trigger then
		if not self:_trigger(params) then return end  --检查
	end
	if not self:filter(params) then
		return
	end
	if math.randomInt(1, 100) > self.passiveData.chance then
		return
	end
	if self.round > 0 and self.turn > 0 then  -- cd
		return
	end
	self:effect(params.trigger)
end

function Passive:filter(params)
	for _, filter in ipairs(self.filters) do
		if not filter:execute(params) then
			return
		end
	end
	return true
end

function Passive:getDB()
	local db = {}
	if self._getDB then
		db = self:_getDB()
	end
	db.id = self.id
	db.level = self.level
	db.round = self.round
	db.count = self.count
	db.delay = self.delay
	return db
end

--默认=0=使用技能,
function Passive:effect0(value)
	self.owner:releaseSkill(value)
end
--1=自身获得buff
function Passive:effect1(value)
	self.owner:addBuff(value, self.owner)
end
--2=触发目标获得buff
function Passive:effect2(value, trigger)
	if trigger then
		trigger:addBuff(value, self.owner)
	end
end
--3=翻开自己所在格子
function Passive:effect3()
	self.owner.battle.adv:openBlock(self.owner.roomId, self.owner.blockId)
end
--4=逃跑
function Passive:effect4()
	self.owner.isDead = true --跑了
	self.owner.battle.adv:enemyDead(self.owner.roomId,self.owner.blockId, true)
end
--5=给随机一个敌方增加一个buff
function Passive:effect5(value)
	local monsters = self.owner.battle.player:getTeam(2)
	local randomId = math.random( 1, #monsters )
	monsters[randomId]:addBuff(value, self.owner)
end
--6=给自己加一個被動技能
function Passive:effect6(value)
	self.owner:addPassive({id = value})
end

return Passive