diff --git a/image/photo/skill/quest.png b/image/photo/skill/quest.png new file mode 100644 index 00000000..5913400d Binary files /dev/null and b/image/photo/skill/quest.png differ diff --git a/lua/core/skill.lua b/lua/core/skill.lua index 48aaaef1..b6441a4e 100644 --- a/lua/core/skill.lua +++ b/lua/core/skill.lua @@ -37,6 +37,7 @@ function Skill:initialize(name, frequency) self.frequency = frequency self.visible = true self.lordSkill = false + self.cardSkill = false self.mute = false self.anim_type = "" self.related_skills = {} @@ -78,6 +79,10 @@ end ---@param player Player @ 玩家 ---@return boolean function Skill:isEffectable(player) + if self.cardSkill then + return true + end + local nullifySkills = Fk:currentRoom().status_skills[InvaliditySkill] or {} for _, nullifySkill in ipairs(nullifySkills) do if self.name ~= nullifySkill.name and nullifySkill:getInvalidity(player, self) then diff --git a/lua/core/skill_type/active.lua b/lua/core/skill_type/active.lua index ad717298..7fc0a689 100644 --- a/lua/core/skill_type/active.lua +++ b/lua/core/skill_type/active.lua @@ -28,7 +28,7 @@ end ---@param player Player ---@param card Card @ helper function ActiveSkill:canUse(player, card) - return true + return self:isEffectable(player) end --- Determine whether a card can be selected by this skill diff --git a/lua/fk_ex.lua b/lua/fk_ex.lua index 382a2cf4..dc3cb77b 100644 --- a/lua/fk_ex.lua +++ b/lua/fk_ex.lua @@ -426,6 +426,7 @@ end local function readCardSpecToCard(card, spec) card.skill = spec.skill or defaultCardSkill + card.skill.cardSkill = true card.special_skills = spec.special_skills card.is_damage_card = spec.is_damage_card end diff --git a/lua/server/events/hp.lua b/lua/server/events/hp.lua index 5bb04226..20545226 100644 --- a/lua/server/events/hp.lua +++ b/lua/server/events/hp.lua @@ -148,6 +148,11 @@ GameEvent.functions[GameEvent.Damage] = function(self) end end + if damageStruct.damageType ~= fk.NormalDamage and damageStruct.to.chained then + damageStruct.beginnerOfTheDamage = true + damageStruct.to:setChainState(false) + end + -- 先扣减护甲,再扣体力值 local shield_to_lose = math.min(damageStruct.damage, damageStruct.to.shield) self:changeShield(damageStruct.to, -shield_to_lose) @@ -179,6 +184,29 @@ GameEvent.functions[GameEvent.Damage] = function(self) return true end +GameEvent.exit_funcs[GameEvent.Damage] = function(self) + local room = self.room + local damageStruct = self.data[1] + + room.logic:trigger(fk.DamageFinished, damageStruct.to, damageStruct) + + if damageStruct.beginnerOfTheDamage and not damageStruct.chain then + local targets = table.filter(room:getAlivePlayers(), function(p) + return p.chained + end) + for _, p in ipairs(targets) do + room:sendLog{ + type = "#ChainDamage", + from = p.id + } + local dmg = table.simpleClone(damageStruct) + dmg.to = p + dmg.chain = true + room:damage(dmg) + end + end +end + GameEvent.functions[GameEvent.LoseHp] = function(self) local player, num, skillName = table.unpack(self.data) local self = self.room diff --git a/lua/server/events/usecard.lua b/lua/server/events/usecard.lua index a64ded72..71689e98 100644 --- a/lua/server/events/usecard.lua +++ b/lua/server/events/usecard.lua @@ -205,7 +205,7 @@ GameEvent.functions[GameEvent.UseCard] = function(self) if cardUseEvent.responseToEvent then cardUseEvent.responseToEvent.cardsResponded = cardUseEvent.responseToEvent.cardsResponded or {} - table.insert(cardUseEvent.responseToEvent.cardsResponded, cardUseEvent.card) + table.insertIfNeed(cardUseEvent.responseToEvent.cardsResponded, cardUseEvent.card) end for _, event in ipairs({ fk.AfterCardUseDeclared, fk.AfterCardTargetDeclared, fk.CardUsing }) do diff --git a/lua/server/mark_enum.lua b/lua/server/mark_enum.lua index 573b3d5c..4118b69b 100644 --- a/lua/server/mark_enum.lua +++ b/lua/server/mark_enum.lua @@ -18,3 +18,6 @@ MarkEnum.AddMaxCardsInTurn = "AddMaxCards-turn" MarkEnum.MinusMaxCards = "MinusMaxCards" ---@field AddMaxCards string @ 于本回合内减少标记值数量的手牌上限 MarkEnum.MinusMaxCardsInTurn = "MinusMaxCards-turn" + +---@field uncompulsoryInvalidity string @ 非锁定技失效,可带清除标记后缀 +MarkEnum.UncompulsoryInvalidity = "uncompulsoryInvalidity" diff --git a/lua/server/room.lua b/lua/server/room.lua index 50df3efa..9c7702f1 100644 --- a/lua/server/room.lua +++ b/lua/server/room.lua @@ -2041,7 +2041,7 @@ function Room:doCardUseEffect(cardUseEvent) unoffsetableList = cardUseEvent.unoffsetableList, additionalDamage = cardUseEvent.additionalDamage, additionalRecover = cardUseEvent.additionalRecover, - cardIdsResponded = cardUseEvent.nullifiedTargets, + cardsResponded = cardUseEvent.cardsResponded, prohibitedCardNames = cardUseEvent.prohibitedCardNames, extra_data = cardUseEvent.extra_data, } @@ -2092,7 +2092,15 @@ function Room:doCardUseEffect(cardUseEvent) collaboratorsIndex[toId] = collaboratorsIndex[toId] + 1 - self:doCardEffect(table.simpleClone(cardEffectEvent)) + local curCardEffectEvent = table.simpleClone(cardEffectEvent) + self:doCardEffect(curCardEffectEvent) + + if curCardEffectEvent.cardsResponded then + cardUseEvent.cardsResponded = cardUseEvent.cardsResponded or {} + for _, card in ipairs(curCardEffectEvent.cardsResponded) do + table.insertIfNeed(cardUseEvent.cardsResponded, card) + end + end end end end @@ -2816,6 +2824,10 @@ function Room:getCardsFromPileByRule(pattern, num, fromPile) table.insertTable(pileToSearch, self.discard_pile) end + if #pileToSearch == 0 then + return {} + end + local cardPack = {} if num < 3 then for i = 1, num do diff --git a/packages/maneuvering/init.lua b/packages/maneuvering/init.lua index e874e92e..1a541e4d 100644 --- a/packages/maneuvering/init.lua +++ b/packages/maneuvering/init.lua @@ -158,42 +158,6 @@ extension:addCards({ analeptic:clone(Card.Diamond, 9), }) -local ironChainEffect = fk.CreateTriggerSkill{ - name = "iron_chain_effect", - global = true, - priority = { [fk.BeforeHpChanged] = 10, [fk.DamageFinished] = 0 }, -- game rule - events = { fk.BeforeHpChanged, fk.DamageFinished }, - can_trigger = function(self, event, target, player, data) - if event == fk.BeforeHpChanged then - return target == player and data.damageEvent and data.damageEvent.damageType ~= fk.NormalDamage and player.chained - else - return target == player and data.beginnerOfTheDamage and not data.chain - end - end, - on_trigger = function(self, event, target, player, data) - local room = player.room - if event == fk.BeforeHpChanged then - data.damageEvent.beginnerOfTheDamage = true - player:setChainState(false) - else - local targets = table.filter(room:getAlivePlayers(), function(p) - return p.chained - end) - for _, p in ipairs(targets) do - room:sendLog{ - type = "#ChainDamage", - from = p.id - } - local dmg = table.simpleClone(data) - dmg.to = p - dmg.chain = true - room:damage(dmg) - end - end - end, -} -Fk:addSkill(ironChainEffect) - local recast = fk.CreateActiveSkill{ name = "recast", target_num = 0, diff --git a/packages/standard/aux_skills.lua b/packages/standard/aux_skills.lua index e62fb86b..6c106476 100644 --- a/packages/standard/aux_skills.lua +++ b/packages/standard/aux_skills.lua @@ -106,10 +106,28 @@ local choosePlayersToMoveCardInBoardSkill = fk.CreateActiveSkill{ end, } +local uncompulsoryInvalidity = fk.CreateInvaliditySkill { + name = "uncompulsory_invalidity", + global = true, + invalidity_func = function(self, from, skill) + local suffix = { "-phase", "-turn", "-round" } + return + (skill.frequency ~= Skill.Compulsory and skill.frequency ~= Skill.Wake) and + not (skill:isEquipmentSkill() or skill.name:endsWith("&")) and + ( + from:getMark(MarkEnum.UncompulsoryInvalidity) ~= 0 or + table.find(suffix, function(s) + return from:getMark(MarkEnum.UncompulsoryInvalidity .. s) ~= 0 + end) + ) + end +} + AuxSkills = { discardSkill, chooseCardsSkill, choosePlayersSkill, maxCardsSkill, choosePlayersToMoveCardInBoardSkill, + uncompulsoryInvalidity, } diff --git a/packages/standard/init.lua b/packages/standard/init.lua index 3332fbf1..a2867304 100644 --- a/packages/standard/init.lua +++ b/packages/standard/init.lua @@ -560,6 +560,7 @@ local kongchengAudio = fk.CreateTriggerSkill{ } local kongcheng = fk.CreateProhibitSkill{ name = "kongcheng", + frequency = Skill.Compulsory, is_prohibited = function(self, from, to, card) if to:hasSkill(self.name) and to:isKongcheng() then return card.trueName == "slash" or card.name == "duel" @@ -608,6 +609,7 @@ zhaoyun:addSkill(longdan) local mashu = fk.CreateDistanceSkill{ name = "mashu", + frequency = Skill.Compulsory, correct_func = function(self, from, to) if from:hasSkill(self.name) then return -1 @@ -654,6 +656,7 @@ local jizhi = fk.CreateTriggerSkill{ } local qicai = fk.CreateTargetModSkill{ name = "qicai", + frequency = Skill.Compulsory, distance_limit_func = function(self, player, skill) local card_name = string.sub(skill.name, 1, -7) -- assuming all card skill is named with name_skill local card = Fk:cloneCard(card_name) @@ -879,6 +882,7 @@ daqiao:addSkill(liuli) local qianxun = fk.CreateProhibitSkill{ name = "qianxun", + frequency = Skill.Compulsory, is_prohibited = function(self, from, to, card) if to:hasSkill(self.name) then return card.name == "indulgence" or card.name == "snatch" diff --git a/packages/standard_cards/init.lua b/packages/standard_cards/init.lua index 6271452a..760b1781 100644 --- a/packages/standard_cards/init.lua +++ b/packages/standard_cards/init.lua @@ -780,7 +780,7 @@ extension:addCards({ fk.MarkArmorNullified = "mark__armor_nullified" local armorInvalidity = fk.CreateInvaliditySkill { - name = "armor_invalidity_skill", + name = "armor_invalidity", global = true, invalidity_func = function(self, from, skill) return