From e9a81cd185fc27778af12b62f5782fcdc4d27cce Mon Sep 17 00:00:00 2001 From: YoumuKon <38815081+YoumuKon@users.noreply.github.com> Date: Tue, 11 Jul 2023 23:16:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=A1=E7=89=8C=E6=A0=87=E8=AE=B0=E6=B8=85?= =?UTF-8?q?=E9=99=A4=E5=90=8E=E7=BC=80+pattern=E7=9B=B8=E5=85=B3fix=20(#22?= =?UTF-8?q?0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复了翻译只替换一次参数(%src之类的)的bug - 添加了卡牌专属的清除后缀,现在cheat获得的牌自带信仰之力 - 补齐了neg判定相关的函数 - 添加multiple_targets,标记多目标牌 - 添加复原武将牌的描述 - 房间名带省略号 --------- Co-authored-by: notify --- Fk/Pages/Lobby.qml | 3 ++- Fk/Pages/RoomLogic.js | 8 ++++---- Fk/RoomElement/ChoiceBox.qml | 8 ++++---- Fk/RoomElement/Dashboard.qml | 8 ++++---- Fk/SkillInteraction/SkillCombo.qml | 8 ++++---- lua/client/i18n/zh_CN.lua | 6 +++++- lua/core/card.lua | 2 ++ lua/core/exppattern.lua | 6 +++--- lua/core/player.lua | 5 ++--- lua/fk_ex.lua | 3 +++ lua/server/events/gameflow.lua | 24 ++++++++++++++++++++++++ lua/server/events/movecard.lua | 8 ++++++++ lua/server/mark_enum.lua | 5 ++++- lua/server/serverplayer.lua | 14 +++++++++++--- packages/maneuvering/init.lua | 1 + packages/standard_cards/i18n/zh_CN.lua | 2 ++ packages/standard_cards/init.lua | 4 ++++ packages/test/init.lua | 4 ++++ test/lua/pattern.lua | 10 +++++++++- 19 files changed, 100 insertions(+), 29 deletions(-) diff --git a/Fk/Pages/Lobby.qml b/Fk/Pages/Lobby.qml index 32896d13..75303d62 100644 --- a/Fk/Pages/Lobby.qml +++ b/Fk/Pages/Lobby.qml @@ -64,8 +64,9 @@ Item { Text { horizontalAlignment: Text.AlignLeft Layout.fillWidth: true - text: roomName + (hasPassword ? "(有密码)" : "") + text: (hasPassword ? Backend.translate("Has Password") : "") + roomName font.pixelSize: 20 + elide: Label.ElideRight } Text { diff --git a/Fk/Pages/RoomLogic.js b/Fk/Pages/RoomLogic.js index 54a4d6c8..84e07822 100644 --- a/Fk/Pages/RoomLogic.js +++ b/Fk/Pages/RoomLogic.js @@ -1066,10 +1066,10 @@ function processPrompt(prompt) { let raw = Backend.translate(data[0]); const src = parseInt(data[1]); const dest = parseInt(data[2]); - if (raw.match("%src")) raw = raw.replace("%src", Backend.translate(getPhoto(src).general)); - if (raw.match("%dest")) raw = raw.replace("%dest", Backend.translate(getPhoto(dest).general)); - if (raw.match("%arg")) raw = raw.replace("%arg", Backend.translate(data[3])); - if (raw.match("%arg2")) raw = raw.replace("%arg2", Backend.translate(data[4])); + if (raw.match("%src")) raw = raw.replace(/%src/g, Backend.translate(getPhoto(src).general)); + if (raw.match("%dest")) raw = raw.replace(/%dest/g, Backend.translate(getPhoto(dest).general)); + if (raw.match("%arg")) raw = raw.replace(/%arg/g, Backend.translate(data[3])); + if (raw.match("%arg2")) raw = raw.replace(/%arg2/g, Backend.translate(data[4])); return raw; } diff --git a/Fk/RoomElement/ChoiceBox.qml b/Fk/RoomElement/ChoiceBox.qml index 967eac5d..34b17740 100644 --- a/Fk/RoomElement/ChoiceBox.qml +++ b/Fk/RoomElement/ChoiceBox.qml @@ -19,10 +19,10 @@ GraphicsBox { let raw = Backend.translate(data[0]); const src = parseInt(data[1]); const dest = parseInt(data[2]); - if (raw.match("%src")) raw = raw.replace("%src", Backend.translate(getPhoto(src).general)); - if (raw.match("%dest")) raw = raw.replace("%dest", Backend.translate(getPhoto(dest).general)); - if (raw.match("%arg")) raw = raw.replace("%arg", Backend.translate(data[3])); - if (raw.match("%arg2")) raw = raw.replace("%arg2", Backend.translate(data[4])); + if (raw.match("%src")) raw = raw.replace(/%src/g, Backend.translate(getPhoto(src).general)); + if (raw.match("%dest")) raw = raw.replace(/%dest/g, Backend.translate(getPhoto(dest).general)); + if (raw.match("%arg")) raw = raw.replace(/%arg/g, Backend.translate(data[3])); + if (raw.match("%arg2")) raw = raw.replace(/%arg2/g, Backend.translate(data[4])); return raw; } diff --git a/Fk/RoomElement/Dashboard.qml b/Fk/RoomElement/Dashboard.qml index c73152dc..15ae3195 100644 --- a/Fk/RoomElement/Dashboard.qml +++ b/Fk/RoomElement/Dashboard.qml @@ -276,10 +276,10 @@ RowLayout { let raw = Backend.translate(data[0]); const src = parseInt(data[1]); const dest = parseInt(data[2]); - if (raw.match("%src")) raw = raw.replace("%src", Backend.translate(getPhoto(src).general)); - if (raw.match("%dest")) raw = raw.replace("%dest", Backend.translate(getPhoto(dest).general)); - if (raw.match("%arg")) raw = raw.replace("%arg", Backend.translate(data[3])); - if (raw.match("%arg2")) raw = raw.replace("%arg2", Backend.translate(data[4])); + if (raw.match("%src")) raw = raw.replace(/%src/g, Backend.translate(getPhoto(src).general)); + if (raw.match("%dest")) raw = raw.replace(/%dest/g, Backend.translate(getPhoto(dest).general)); + if (raw.match("%arg")) raw = raw.replace(/%arg/g, Backend.translate(data[3])); + if (raw.match("%arg2")) raw = raw.replace(/%arg2/g, Backend.translate(data[4])); return raw; } diff --git a/Fk/SkillInteraction/SkillCombo.qml b/Fk/SkillInteraction/SkillCombo.qml index 3500f3f6..3ca631df 100644 --- a/Fk/SkillInteraction/SkillCombo.qml +++ b/Fk/SkillInteraction/SkillCombo.qml @@ -16,10 +16,10 @@ MetroButton { let raw = Backend.translate(data[0]); const src = parseInt(data[1]); const dest = parseInt(data[2]); - if (raw.match("%src")) raw = raw.replace("%src", Backend.translate(getPhoto(src).general)); - if (raw.match("%dest")) raw = raw.replace("%dest", Backend.translate(getPhoto(dest).general)); - if (raw.match("%arg")) raw = raw.replace("%arg", Backend.translate(data[3])); - if (raw.match("%arg2")) raw = raw.replace("%arg2", Backend.translate(data[4])); + if (raw.match("%src")) raw = raw.replace(/%src/g, Backend.translate(getPhoto(src).general)); + if (raw.match("%dest")) raw = raw.replace(/%dest/g, Backend.translate(getPhoto(dest).general)); + if (raw.match("%arg")) raw = raw.replace(/%arg/g, Backend.translate(data[3])); + if (raw.match("%arg2")) raw = raw.replace(/%arg2/g, Backend.translate(data[4])); return raw; } diff --git a/lua/client/i18n/zh_CN.lua b/lua/client/i18n/zh_CN.lua index 00a499cd..6f56ec69 100644 --- a/lua/client/i18n/zh_CN.lua +++ b/lua/client/i18n/zh_CN.lua @@ -36,6 +36,7 @@ Fk:loadTranslationTable{ ["No enough generals"] = "可用武将不足!", ["Operation timeout"] = "操作时长(秒)", ["Luck Card Times"] = "手气卡次数", + ["Has Password"] = "(有密码)", ["Room Password"] = "房间密码", ["Please input room's password"] = "请输入房间的密码", ["Add Robot"] = "添加机器人", @@ -267,13 +268,15 @@ Fk:loadTranslationTable{ ["chained"] = "横置", ["un-chained"] = "竖置", - ["not-chained"] = "重置", + ["reset-general"] = "重置", ["yang"] = "阳", ["yin"] = "阴", ["quest_succeed"] = "成功", ["quest_failed"] = "失败", + ["card"] = "牌", + ["hand_card"] = "手牌", ["pile_draw"] = "牌堆", ["pile_discard"] = "弃牌堆", ["processing_area"] = "处理区", @@ -379,6 +382,7 @@ Fk:loadTranslationTable{ ["#GuanxingResult"] = "%from 的观星结果为 %arg 上 %arg2 下", ["#ChainStateChange"] = "%from %arg 了武将牌", ["#ChainDamage"] = "%from 处于连环状态,将受到传导的伤害", + ["#ResetGeneral"] = "%from 复原了武将牌", } -- card footnote diff --git a/lua/core/card.lua b/lua/core/card.lua index 3dec05fb..d04dffdf 100644 --- a/lua/core/card.lua +++ b/lua/core/card.lua @@ -23,6 +23,7 @@ ---@field public skill Skill @ 技能(用于实现卡牌效果) ---@field public special_skills string[] | nil @ 衍生技能,如重铸 ---@field public is_damage_card boolean @ 是否为会造成伤害的牌 +---@field public multiple_targets boolean @ 是否为指定多个目标的牌 ---@field public is_derived boolean|null @ 判断是否为衍生牌 local Card = class("Card") @@ -145,6 +146,7 @@ function Card:clone(suit, number) newCard.equip_skill = self.equip_skill newCard.attack_range = self.attack_range newCard.is_damage_card = self.is_damage_card + newCard.multiple_targets = self.multiple_targets newCard.is_derived = self.is_derived return newCard end diff --git a/lua/core/exppattern.lua b/lua/core/exppattern.lua index 67f29890..1cf1f9fd 100644 --- a/lua/core/exppattern.lua +++ b/lua/core/exppattern.lua @@ -117,6 +117,7 @@ local function matchCard(matcher, card) end local function hasNegIntersection(a, b) + -- 注意,这里是拿a.neg和b比 local neg_pass = false -- 第一次比较: 比较neg和正常值,如有不同即认为可以匹配 @@ -134,11 +135,11 @@ local function hasNegIntersection(a, b) -- 第二次比较: 比较双方neg -- 比如 ^jink 可以匹配 ^slash - -- 暂时想不出好方案 + -- 没法比 end local function hasIntersection(a, b) - if a == nil or b == nil then + if a == nil or b == nil or (#a + #b == 0) then return true end @@ -151,7 +152,6 @@ local function hasIntersection(a, b) return true end end - local neg_pass = hasNegIntersection(a, b) or hasNegIntersection(b, a) return neg_pass diff --git a/lua/core/player.lua b/lua/core/player.lua index f6650c90..f20591f3 100644 --- a/lua/core/player.lua +++ b/lua/core/player.lua @@ -394,7 +394,7 @@ function Player:getAttackRange() local status_skills = Fk:currentRoom().status_skills[AttackRangeSkill] or Util.DummyTable for _, skill in ipairs(status_skills) do local correct = skill:getCorrect(self) - baseAttackRange = baseAttackRange + correct + baseAttackRange = baseAttackRange + (correct or 0) end return math.max(baseAttackRange, 0) @@ -460,8 +460,7 @@ function Player:distanceTo(other, mode, ignore_dead) ret = fixed break end - if correct == nil then correct = 0 end - ret = ret + correct + ret = ret + (correct or 0) end if self.fixedDistance[other] then diff --git a/lua/fk_ex.lua b/lua/fk_ex.lua index 1b97634f..afe3ddc7 100644 --- a/lua/fk_ex.lua +++ b/lua/fk_ex.lua @@ -419,7 +419,9 @@ end ---@class CardSpec: Card ---@field public skill Skill ---@field public equip_skill Skill +---@field public special_skills string[] | nil ---@field public is_damage_card boolean +---@field public multiple_targets boolean local defaultCardSkill = fk.CreateActiveSkill{ name = "default_card_skill", @@ -443,6 +445,7 @@ local function readCardSpecToCard(card, spec) card.skill.cardSkill = true card.special_skills = spec.special_skills card.is_damage_card = spec.is_damage_card + card.multiple_targets = spec.multiple_targets end ---@param spec CardSpec diff --git a/lua/server/events/gameflow.lua b/lua/server/events/gameflow.lua index 74a3b1f6..bf1117d7 100644 --- a/lua/server/events/gameflow.lua +++ b/lua/server/events/gameflow.lua @@ -172,6 +172,14 @@ GameEvent.cleaners[GameEvent.Round] = function(self) end end end + + for cid, cmark in pairs(room.card_marks) do + for name, _ in pairs(cmark) do + if name:endsWith("-round") then + room:setCardMark(Fk:getCardById(cid), name, 0) + end + end + end end GameEvent.functions[GameEvent.Turn] = function(self) @@ -203,6 +211,14 @@ GameEvent.cleaners[GameEvent.Turn] = function(self) end end + for cid, cmark in pairs(room.card_marks) do + for name, _ in pairs(cmark) do + if name:endsWith("-turn") then + room:setCardMark(Fk:getCardById(cid), name, 0) + end + end + end + local current = room.current local logic = room.logic if self.interrupted then @@ -324,6 +340,14 @@ GameEvent.cleaners[GameEvent.Phase] = function(self) end end + for cid, cmark in pairs(room.card_marks) do + for name, _ in pairs(cmark) do + if name:endsWith("-phase") then + room:setCardMark(Fk:getCardById(cid), name, 0) + end + end + end + if self.interrupted then room.logic:trigger(fk.EventPhaseEnd, player, nil, true) end diff --git a/lua/server/events/movecard.lua b/lua/server/events/movecard.lua index e452214b..25bf9c7b 100644 --- a/lua/server/events/movecard.lua +++ b/lua/server/events/movecard.lua @@ -124,6 +124,14 @@ GameEvent.functions[GameEvent.MoveCards] = function(self) end local currentCard = Fk:getCardById(info.cardId) + for name, _ in pairs(currentCard.mark) do + if name:endsWith("-inhand") and + realFromArea == Player.Hand and + data.from + then + self:setCardMark(currentCard, name, 0) + end + end if data.toArea == Player.Equip and currentCard.type == Card.TypeEquip and diff --git a/lua/server/mark_enum.lua b/lua/server/mark_enum.lua index d070ca02..2f021293 100644 --- a/lua/server/mark_enum.lua +++ b/lua/server/mark_enum.lua @@ -28,7 +28,10 @@ MarkEnum.BypassTimesLimitTo = "BypassTimesLimitTo" ---@field BypassDistancesLimitTo string @ 对其使用牌无距离限制,可带清除标记后缀 MarkEnum.BypassDistancesLimitTo = "BypassDistancesLimitTo" ---@field UncompulsoryInvalidity string @ 非锁定技失效,可带清除标记后缀 -MarkEnum.UncompulsoryInvalidity = "uncompulsoryInvalidity" +MarkEnum.UncompulsoryInvalidity = "UncompulsoryInvalidity" ---@field TempMarkSuffix string[] @ 各种清除标记后缀 MarkEnum.TempMarkSuffix = { "-phase", "-turn", "-round" } + +---@field CardTempMarkSuffix string[] @ 卡牌标记版本的清除标记后缀 +MarkEnum.CardTempMarkSuffix = { "-phase", "-turn", "-round", "-inhand" } diff --git a/lua/server/serverplayer.lua b/lua/server/serverplayer.lua index 895c315a..12b688af 100644 --- a/lua/server/serverplayer.lua +++ b/lua/server/serverplayer.lua @@ -573,8 +573,7 @@ function ServerPlayer:bury() self:throwAllCards() self:throwAllMarks() self:clearPiles() - self:setChainState(false) - if not self.faceup then self:turnOver() end + self:reset() end function ServerPlayer:throwAllCards(flag) @@ -654,12 +653,21 @@ function ServerPlayer:setChainState(chained) self.room:sendLog{ type = "#ChainStateChange", from = self.id, - arg = self.chained and "chained" or "not-chained" + arg = self.chained and "chained" or "un-chained" } self.room.logic:trigger(fk.ChainStateChanged, self) end +function ServerPlayer:reset() + self.room:sendLog{ + type = "#ResetGeneral", + from = self.id, + } + self:setChainState(false) + if not self.faceup then self:turnOver() end +end + ---@param from ServerPlayer ---@param tos ServerPlayer[] ---@param skillName string diff --git a/packages/maneuvering/init.lua b/packages/maneuvering/init.lua index 03599d6f..2bfcc73d 100644 --- a/packages/maneuvering/init.lua +++ b/packages/maneuvering/init.lua @@ -182,6 +182,7 @@ local ironChain = fk.CreateTrickCard{ name = "iron_chain", skill = ironChainCardSkill, special_skills = { "recast" }, + multiple_targets = true, } extension:addCards{ ironChain:clone(Card.Spade, 11), diff --git a/packages/standard_cards/i18n/zh_CN.lua b/packages/standard_cards/i18n/zh_CN.lua index 8d3e946d..f53dd4dc 100644 --- a/packages/standard_cards/i18n/zh_CN.lua +++ b/packages/standard_cards/i18n/zh_CN.lua @@ -32,6 +32,8 @@ Fk:loadTranslationTable{ ["equip_horse"] = "坐骑牌", ["treasure"] = "宝物牌", ["delayed_trick"] = "延时类锦囊牌", + ["damage_card-"] = "伤害类", + ["multiple_targets-"] = "多目标", ["type_weapon"] = "武器", ["type_armor"] = "防具", diff --git a/packages/standard_cards/init.lua b/packages/standard_cards/init.lua index 1a6a47e1..1e5edb46 100644 --- a/packages/standard_cards/init.lua +++ b/packages/standard_cards/init.lua @@ -481,6 +481,7 @@ local savageAssault = fk.CreateTrickCard{ suit = Card.Spade, number = 7, is_damage_card = true, + multiple_targets = true, skill = savageAssaultSkill, } @@ -520,6 +521,7 @@ local archeryAttack = fk.CreateTrickCard{ suit = Card.Heart, number = 1, is_damage_card = true, + multiple_targets = true, skill = archeryAttackSkill, } @@ -554,6 +556,7 @@ local godSalvation = fk.CreateTrickCard{ name = "god_salvation", suit = Card.Heart, number = 1, + multiple_targets = true, skill = godSalvationSkill, } @@ -636,6 +639,7 @@ local amazingGrace = fk.CreateTrickCard{ name = "amazing_grace", suit = Card.Heart, number = 3, + multiple_targets = true, skill = amazingGraceSkill, } diff --git a/packages/test/init.lua b/packages/test/init.lua index 21b69ba2..05c8f3f2 100644 --- a/packages/test/init.lua +++ b/packages/test/init.lua @@ -45,6 +45,8 @@ local cheat = fk.CreateActiveSkill{ end from:addToPile(self.name, toGain, true, self.name) + room:setCardMark(Fk:getCardById(toGain), "@@test_cheat-phase", 1) + room:setCardMark(Fk:getCardById(toGain), "@@test_cheat-inhand", 1) room:obtainCard(effect.from, toGain, true, fk.ReasonPrey) end } @@ -277,6 +279,8 @@ Fk:loadTranslationTable{ -- ["cheat"] = "小开", [":cheat"] = "出牌阶段,你可以获得一张想要的牌。", ["#cheat"] = "cheat:你可以获得一张想要的牌", + ["@@test_cheat-phase"] = "苦肉", + ["@@test_cheat-inhand"] = "连营", --["#test_trig-ask"] = "你可弃置一张手牌", ["control"] = "控制", [":control"] = "出牌阶段,你可以控制/解除控制若干名其他角色。", diff --git a/test/lua/pattern.lua b/test/lua/pattern.lua index 23543c22..782f0601 100644 --- a/test/lua/pattern.lua +++ b/test/lua/pattern.lua @@ -21,6 +21,8 @@ TestExppattern = { lu.assertFalse(basic:matchExp("nullification")) lu.assertTrue(basic:matchExp("slash,vine")) lu.assertTrue(Exppattern:Parse(".|.|.|.|.|armor"):matchExp("slash,vine")) + lu.assertTrue(Exppattern:Parse(".|.|.|.|.|trick"):matchExp("lightning")) + lu.assertFalse(Exppattern:Parse(".|.|.|.|.|delayed_trick"):matchExp("savage_assault")) end, testMatchNeg = function() @@ -28,7 +30,9 @@ TestExppattern = { local not_nul = Exppattern:Parse("^nullification") local not_slash_jink = Exppattern:Parse("^(slash,jink)") local not_basic = Exppattern:Parse(".|.|.|.|.|^basic") + local not_black = Exppattern:Parse(".|.|^(spade,club)") local slash_jink = Exppattern:Parse("slash,jink") + local no_slash_jink = Exppattern:Parse("^(slash,jink)|.|.|.|.|basic") local slash = Fk:cloneCard("slash") lu.assertFalse(not_nul:matchExp("nullification")) @@ -38,7 +42,11 @@ TestExppattern = { lu.assertFalse(not_slash_jink:match(slash)) lu.assertFalse(not_basic:match(slash)) lu.assertTrue(not_nul:matchExp("peach")) - lu.assertFalse(not_slash_jink:matchExp(not_basic)) + lu.assertFalse(not_basic:matchExp(no_slash_jink)) + lu.assertTrue(not_slash_jink:matchExp(not_basic)) lu.assertFalse(slash_jink:matchExp(not_slash_jink)) + lu.assertFalse(not_black:matchExp("slash|A~Q|spade")) + lu.assertTrue(not_black:matchExp("vine|10|^club")) end, + }