diff --git a/lua/core/skill_type/active.lua b/lua/core/skill_type/active.lua index eac2014515ac80e284d78e3c008958fdd5c37bec..3fae6c3efe805580a6b42b74ef1378f7db62a53f 100644 --- a/lua/core/skill_type/active.lua +++ b/lua/core/skill_type/active.lua @@ -30,7 +30,7 @@ end ---@param extra_data? UseExtraData @ 额外数据 ---@return bool function ActiveSkill:canUse(player, card, extra_data) - return self:isEffectable(player) + return self:isEffectable(player) and self:withinTimesLimit(player, Player.HistoryPhase, card) end -- 判断一张牌是否可被此技能选中 diff --git a/lua/core/skill_type/target_mod.lua b/lua/core/skill_type/target_mod.lua index 142cd758abd451c71584474d9387e423c0274576..a9e62ce6ed5b877d89e4986ed473e30fba175d84 100644 --- a/lua/core/skill_type/target_mod.lua +++ b/lua/core/skill_type/target_mod.lua @@ -3,50 +3,60 @@ ---@class TargetModSkill : StatusSkill local TargetModSkill = StatusSkill:subclass("TargetModSkill") ----@param player Player ----@param card_skill ActiveSkill ----@param scope integer ----@param card Card +-- 使用某技能在某时间段无次数限制 +---@param player Player @ 使用者 +---@param card_skill ActiveSkill @ 目标技能 +---@param scope integer @ 考察时间段 +---@param card? Card @ 使用牌时的牌 +---@param to? Player @ 目标 function TargetModSkill:bypassTimesCheck(player, card_skill, scope, card, to) return false end ----@param player Player ----@param card_skill ActiveSkill ----@param scope integer ----@param card Card +-- 修改某技能在某时间段的次数上限 +---@param player Player @ 使用者 +---@param card_skill ActiveSkill @ 目标技能 +---@param scope integer @ 考察时间段 +---@param card? Card @ 使用牌时的牌 +---@param to? Player @ 目标 function TargetModSkill:getResidueNum(player, card_skill, scope, card, to) return 0 end ----@param player Player ----@param card_skill ActiveSkill ----@param card Card +-- 使用某技能无距离限制 +---@param player Player @ 使用者 +---@param card_skill ActiveSkill @ 目标技能 +---@param card? Card @ 使用牌时的牌 +---@param to? Player @ 目标 function TargetModSkill:bypassDistancesCheck(player, card_skill, card, to) return false end ----@param player Player ----@param card_skill ActiveSkill ----@param card Card +-- 修改某技能的距离限制 +---@param player Player @ 使用者 +---@param card_skill ActiveSkill @ 目标技能 +---@param card? Card @ 使用牌时的牌 +---@param to? Player @ 目标 function TargetModSkill:getDistanceLimit(player, card_skill, card, to) return 0 end ----@param player Player ----@param card_skill ActiveSkill ----@param card Card +-- 修改某技能的额定目标数 +---@param player Player @ 使用者 +---@param card_skill ActiveSkill @ 目标技能 +---@param card? Card @ 使用牌时的牌 function TargetModSkill:getExtraTargetNum(player, card_skill, card) return 0 end ----@param player Player ----@param to_select integer @ id of the target ----@param selected integer[] @ ids of selected targets ----@param selected_cards integer[] @ ids of selected cards ----@param card Card @ helper ----@param selectable boolean @can be selected ----@param extra_data? any @ extra_data +-- 技能描述 +---@param player Player @ 使用者 +---@param to_select integer @ 待选目标 +---@param selected integer[] @ 已选目标 +---@param selected_cards integer[] @ 已选牌 +---@param card? Card @ 使用牌时的牌 +---@param selectable boolean @ 待选目标是否可选 +---@param extra_data? any @ 额外信息 function TargetModSkill:getTargetTip(player, to_select, selected, selected_cards, card, selectable, extra_data) end return TargetModSkill diff --git a/lua/core/skill_type/usable_skill.lua b/lua/core/skill_type/usable_skill.lua index fa49e59c7b087133d003d384cc18661d01e9f4f2..88b32f94e1396ab2efbbde8a034fc22b80e4a38f 100644 --- a/lua/core/skill_type/usable_skill.lua +++ b/lua/core/skill_type/usable_skill.lua @@ -11,18 +11,19 @@ function UsableSkill:initialize(name, frequency) frequency = frequency or Skill.NotFrequent Skill.initialize(self, name, frequency) - self.max_use_time = {9999, 9999, 9999, 9999} + self.max_use_time = { nil, nil, nil, nil } end -- 获得技能的最大使用次数 ---@param player Player @ 使用者 ---@param scope integer @ 查询历史范围(默认为回合) ----@param card Card @ 卡牌 ----@param to Player @ 目标 ----@return number @ 最大使用次数 +---@param card? Card @ 卡牌 +---@param to? Player @ 目标 +---@return number? @ 最大使用次数,nil就是无限 function UsableSkill:getMaxUseTime(player, scope, card, to) scope = scope or Player.HistoryTurn local ret = self.max_use_time[scope] + if not ret then return nil end local status_skills = Fk:currentRoom().status_skills[TargetModSkill] or Util.DummyTable for _, skill in ipairs(status_skills) do local correct = skill:getResidueNum(player, self, scope, card, to) @@ -37,10 +38,10 @@ end ---@param scope integer @ 查询历史范围(默认为回合) ---@param card? Card @ 牌,若没有牌,则尝试制造一张虚拟牌 ---@param card_name? string @ 牌名 ----@param to any @ 目标 +---@param to? Player @ 目标 ---@return bool function UsableSkill:withinTimesLimit(player, scope, card, card_name, to) - if to and to.dead then return false end + if to and to.dead then return false end -- 一般情况不会对死人使用技能的…… scope = scope or Player.HistoryTurn local status_skills = Fk:currentRoom().status_skills[TargetModSkill] or Util.DummyTable if not card then @@ -50,13 +51,21 @@ function UsableSkill:withinTimesLimit(player, scope, card, card_name, to) card = Fk:cloneCard(self.name:sub(1, #self.name - 6)) end end - if not card_name and card then - card_name = card.trueName - end + + local limit = self:getMaxUseTime(player, scope, card, to) + if not limit then return true end for _, skill in ipairs(status_skills) do if skill:bypassTimesCheck(player, self, scope, card, to) then return true end end + if not card_name then + if card then + card_name = card.trueName + else ---坏了,不是卡的技能 + return player:usedSkillTimes(self.name, scope) < limit + end + end + local temp_suf = table.simpleClone(MarkEnum.TempMarkSuffix) local card_temp_suf = table.simpleClone(MarkEnum.CardTempMarkSuffix) @@ -77,7 +86,7 @@ function UsableSkill:withinTimesLimit(player, scope, card, card_name, to) return false end - return player:usedCardTimes(card_name, scope) < self:getMaxUseTime(player, scope, card, to) or + return player:usedCardTimes(card_name, scope) < limit or hasMark(card, MarkEnum.BypassTimesLimit, card_temp_suf) or hasMark(player, MarkEnum.BypassTimesLimit, temp_suf) or hasMark(to, MarkEnum.BypassTimesLimitTo, temp_suf) diff --git a/lua/fk_ex.lua b/lua/fk_ex.lua index 5c55e41f178e72fed07ca6e1385ada3106d98f6e..1a6965e1c0120bd7e06933f7734c4c80692cff5c 100644 --- a/lua/fk_ex.lua +++ b/lua/fk_ex.lua @@ -75,10 +75,10 @@ function fk.readUsableSpecToSkill(skill, spec) skill.max_card_num = spec.max_card_num or skill.max_card_num skill.card_num_table = spec.card_num_table or skill.card_num_table skill.max_use_time = { - spec.max_phase_use_time or 9999, - spec.max_turn_use_time or 9999, - spec.max_round_use_time or 9999, - spec.max_game_use_time or 9999, + spec.max_phase_use_time, + spec.max_turn_use_time, + spec.max_round_use_time, + spec.max_game_use_time, } skill.distance_limit = spec.distance_limit or skill.distance_limit skill.expand_pile = spec.expand_pile @@ -214,19 +214,19 @@ function fk.CreateTriggerSkill(spec) end ---@class ActiveSkillSpec: UsableSkillSpec ----@field public can_use? fun(self: ActiveSkill, player: Player, card: Card, extra_data: any): any +---@field public can_use? fun(self: ActiveSkill, player: Player, card?: Card, extra_data: any): any ---@field public card_filter? fun(self: ActiveSkill, to_select: integer, selected: integer[], selected_targets: integer[]): any ----@field public target_filter? fun(self: ActiveSkill, to_select: integer, selected: integer[], selected_cards: integer[], card: Card, extra_data: any): any +---@field public target_filter? fun(self: ActiveSkill, to_select: integer, selected: integer[], selected_cards: integer[], card?: Card, extra_data: any): any ---@field public feasible? fun(self: ActiveSkill, selected: integer[], selected_cards: integer[]): any ---@field public on_use? fun(self: ActiveSkill, room: Room, cardUseEvent: CardUseStruct | SkillEffectEvent): any ---@field public on_action? fun(self: ActiveSkill, room: Room, cardUseEvent: CardUseStruct | SkillEffectEvent, finished: boolean): any ---@field public about_to_effect? fun(self: ActiveSkill, room: Room, cardEffectEvent: CardEffectEvent | SkillEffectEvent): any ---@field public on_effect? fun(self: ActiveSkill, room: Room, cardEffectEvent: CardEffectEvent | SkillEffectEvent): any ---@field public on_nullified? fun(self: ActiveSkill, room: Room, cardEffectEvent: CardEffectEvent | SkillEffectEvent): any ----@field public mod_target_filter? fun(self: ActiveSkill, to_select: integer, selected: integer[], user: integer, card: Card, distance_limited: boolean): any +---@field public mod_target_filter? fun(self: ActiveSkill, to_select: integer, selected: integer[], user: integer, card?: Card, distance_limited: boolean): any ---@field public prompt? string|fun(self: ActiveSkill, selected_cards: integer[], selected_targets: integer[]): string ---@field public interaction? any ----@field public target_tip? fun(self: ActiveSkill, to_select: integer, selected: integer[], selected_cards: integer[], card: Card, selectable: boolean, extra_data: any): string|TargetTipDataSpec? +---@field public target_tip? fun(self: ActiveSkill, to_select: integer, selected: integer[], selected_cards: integer[], card?: Card, selectable: boolean, extra_data: any): string|TargetTipDataSpec? ---@param spec ActiveSkillSpec ---@return ActiveSkill @@ -428,12 +428,12 @@ function fk.CreateMaxCardsSkill(spec) end ---@class TargetModSpec: StatusSkillSpec ----@field public bypass_times? fun(self: TargetModSkill, player: Player, skill: ActiveSkill, scope: integer, card: Card, to: Player): any ----@field public residue_func? fun(self: TargetModSkill, player: Player, skill: ActiveSkill, scope: integer, card: Card, to: Player): number? ----@field public bypass_distances? fun(self: TargetModSkill, player: Player, skill: ActiveSkill, card: Card, to: Player): any ----@field public distance_limit_func? fun(self: TargetModSkill, player: Player, skill: ActiveSkill, card: Card, to: Player): number? ----@field public extra_target_func? fun(self: TargetModSkill, player: Player, skill: ActiveSkill, card: Card): number? ----@field public target_tip_func? fun(self: TargetModSkill, player: Player, to_select: integer, selected: integer[], selected_cards: integer[], card: Card, selectable: boolean, extra_data: any): string|TargetTipDataSpec? +---@field public bypass_times? fun(self: TargetModSkill, player: Player, skill: ActiveSkill, scope: integer, card?: Card, to?: Player): any +---@field public residue_func? fun(self: TargetModSkill, player: Player, skill: ActiveSkill, scope: integer, card?: Card, to?: Player): number? +---@field public bypass_distances? fun(self: TargetModSkill, player: Player, skill: ActiveSkill, card?: Card, to?: Player): any +---@field public distance_limit_func? fun(self: TargetModSkill, player: Player, skill: ActiveSkill, card?: Card, to?: Player): number? +---@field public extra_target_func? fun(self: TargetModSkill, player: Player, skill: ActiveSkill, card?: Card): number? +---@field public target_tip_func? fun(self: TargetModSkill, player: Player, to_select: integer, selected: integer[], selected_cards: integer[], card?: Card, selectable: boolean, extra_data: any): string|TargetTipDataSpec? ---@param spec TargetModSpec ---@return TargetModSkill diff --git a/standard/init.lua b/standard/init.lua index ec78651501e1ec893bd81339ca7d8b07003a53f8..efbb3713b9adbd56cf377bc20c47855f8f19ecb4 100644 --- a/standard/init.lua +++ b/standard/init.lua @@ -467,7 +467,7 @@ local paoxiaoAudio = fk.CreateTriggerSkill{ can_refresh = function(self, event, target, player, data) return target == player and player:hasSkill(self) and data.card.trueName == "slash" and - player:usedCardTimes("slash") > 1 + player:usedCardTimes("slash", Player.HistoryPhase) > 1 end, on_refresh = function(self, event, target, player, data) player:broadcastSkillInvoke("paoxiao") @@ -482,7 +482,7 @@ local paoxiao = fk.CreateTargetModSkill{ name = "paoxiao", frequency = Skill.Compulsory, bypass_times = function(self, player, skill, scope) - if player:hasSkill(self) and skill.trueName == "slash_skill" + if player:hasSkill(self) and skill.trueName == "slash_skill" --- 究竟是【杀】的限制呢,还是【杀】技能的限制呢? and scope == Player.HistoryPhase then return true end @@ -636,9 +636,10 @@ local zhiheng = fk.CreateActiveSkill{ name = "zhiheng", prompt = "#zhiheng-active", anim_type = "drawcard", - can_use = function(self, player) - return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 - end, + max_phase_use_time = 1, + -- can_use = function(self, player) + -- return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 + -- end, target_num = 0, min_card_num = 1, card_filter = function(self, to_select) @@ -762,9 +763,10 @@ local yingzi = fk.CreateTriggerSkill{ local fanjian = fk.CreateActiveSkill{ name = "fanjian", prompt = "#fanjian-active", - can_use = function(self, player) - return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 - end, + max_phase_use_time = 1, + -- can_use = function(self, player) + -- return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 + -- end, card_filter = Util.FalseFunc, target_filter = function(self, to_select, selected) return #selected == 0 and to_select ~= Self.id @@ -938,9 +940,10 @@ local jieyin = fk.CreateActiveSkill{ name = "jieyin", prompt = "#jieyin-active", anim_type = "support", - can_use = function(self, player) - return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 - end, + max_phase_use_time = 1, + -- can_use = function(self, player) + -- return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 + -- end, card_filter = function(self, to_select, selected) return #selected < 2 and Fk:currentRoom():getCardArea(to_select) == Player.Hand and not Self:prohibitDiscard(Fk:getCardById(to_select)) end, @@ -980,9 +983,10 @@ local qingnang = fk.CreateActiveSkill{ name = "qingnang", prompt = "#qingnang-active", anim_type = "support", - can_use = function(self, player) - return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 - end, + max_phase_use_time = 1, + -- can_use = function(self, player) + -- return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 + -- end, card_filter = function(self, to_select, selected, targets) return #selected == 0 and Fk:currentRoom():getCardArea(to_select) == Player.Hand and not Self:prohibitDiscard(Fk:getCardById(to_select)) @@ -1066,9 +1070,10 @@ local lijian = fk.CreateActiveSkill{ name = "lijian", prompt = "#lijian-active", anim_type = "offensive", - can_use = function(self, player) - return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 - end, + max_phase_use_time = 1, + -- can_use = function(self, player) + -- return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 + -- end, card_filter = function(self, to_select, selected) return #selected == 0 and not Self:prohibitDiscard(Fk:getCardById(to_select)) end,