From d5330d5bed7ab785a439f68cdfd7ca454c36cea4 Mon Sep 17 00:00:00 2001 From: YoumuKon <38815081+YoumuKon@users.noreply.github.com> Date: Mon, 19 Jun 2023 00:20:50 +0800 Subject: [PATCH] =?UTF-8?q?isInLimit=E7=AD=89=E5=90=84=E7=A7=8D=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=20+=20bugfix=20(#201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 没来得及转远程url,这是最后一次从fork来的更新了 - 修复了fk.currentresponsepattern = nil的时机 - 添加unlimited/withinTimesLimit和withinDistanceLimit,整合并实现真正的“无次数限制”/“无距离限制” - 给观星框上了标题(暂时不往上加标题变量) - 青龙刀会临时追加“对此人不限次数”+“对此人不限距离”的标记,响应(包括取消)后清除 - 添加了“对某人无次数/距离限制”的标记及对应两个global技能 --- Fk/Pages/RoomLogic.js | 2 ++ Fk/RoomElement/GuanxingBox.qml | 3 ++- lua/core/skill_type/target_mod.lua | 8 ++++++++ lua/core/skill_type/usable_skill.lua | 17 +++++++++++++++++ lua/fk_ex.lua | 4 ++++ lua/server/events/gameflow.lua | 2 +- lua/server/events/usecard.lua | 4 ++-- lua/server/mark_enum.lua | 4 ++++ lua/server/room.lua | 9 +++++++-- lua/server/serverplayer.lua | 2 ++ lua/server/system_enum.lua | 2 +- packages/maneuvering/init.lua | 4 ++-- packages/standard/aux_skills.lua | 23 +++++++++++++++++++++++ packages/standard/init.lua | 4 ++-- packages/standard_cards/init.lua | 20 ++++++++++++-------- 15 files changed, 89 insertions(+), 19 deletions(-) diff --git a/Fk/Pages/RoomLogic.js b/Fk/Pages/RoomLogic.js index 544524db..55420f61 100644 --- a/Fk/Pages/RoomLogic.js +++ b/Fk/Pages/RoomLogic.js @@ -746,6 +746,7 @@ callbacks["AskForGuanxing"] = (jsonData) => { const max_bottom_cards = data.max_bottom_cards; const top_area_name = data.top_area_name; const bottom_area_name = data.bottom_area_name; + const prompt = data.prompt; roomScene.state = "replying"; roomScene.popupBox.sourceComponent = Qt.createComponent("../RoomElement/GuanxingBox.qml"); data.cards.forEach(id => { @@ -753,6 +754,7 @@ callbacks["AskForGuanxing"] = (jsonData) => { cards.push(JSON.parse(d)); }); const box = roomScene.popupBox.item; + box.prompt = prompt; if (max_top_cards === 0) { box.areaCapacities = [max_bottom_cards]; box.areaLimits = [min_bottom_cards]; diff --git a/Fk/RoomElement/GuanxingBox.qml b/Fk/RoomElement/GuanxingBox.qml index cdcb2c05..01a07e38 100644 --- a/Fk/RoomElement/GuanxingBox.qml +++ b/Fk/RoomElement/GuanxingBox.qml @@ -6,6 +6,7 @@ import Fk.Pages GraphicsBox { id: root + property string prompt property var cards: [] property var result: [] property var areaCapacities: [] @@ -13,7 +14,7 @@ GraphicsBox { property var areaNames: [] property int padding: 25 - title.text: Backend.translate("Please arrange cards") + title.text: Backend.translate(prompt !== "" ? prompt : "Please arrange cards") width: body.width + padding * 2 height: title.height + body.height + padding * 2 diff --git a/lua/core/skill_type/target_mod.lua b/lua/core/skill_type/target_mod.lua index 13e9614b..5e762afa 100644 --- a/lua/core/skill_type/target_mod.lua +++ b/lua/core/skill_type/target_mod.lua @@ -3,6 +3,14 @@ ---@class TargetModSkill : StatusSkill local TargetModSkill = StatusSkill:subclass("TargetModSkill") +---@param player Player +---@param card_skill ActiveSkill +---@param scope integer +---@param card Card +function TargetModSkill:isUnlimited(player, card_skill, scope, card, to) + return false +end + ---@param player Player ---@param card_skill ActiveSkill ---@param scope integer diff --git a/lua/core/skill_type/usable_skill.lua b/lua/core/skill_type/usable_skill.lua index 77c46f83..ecb1244d 100644 --- a/lua/core/skill_type/usable_skill.lua +++ b/lua/core/skill_type/usable_skill.lua @@ -24,4 +24,21 @@ function UsableSkill:getMaxUseTime(player, scope, card, to) return ret end +function UsableSkill:withinTimesLimit(player, scope, card, to) + scope = scope or Player.HistoryTurn + local status_skills = Fk:currentRoom().status_skills[TargetModSkill] or Util.DummyTable + for _, skill in ipairs(status_skills) do + if skill:isUnlimited(player, self, scope, card, to) then return true end + end + return player:usedCardTimes(card.trueName, scope) < self:getMaxUseTime(player, scope, card, to) +end + +function UsableSkill:withinDistanceLimit(player, isattack, card, to) + local status_skills = Fk:currentRoom().status_skills[AttackRangeSkill] or Util.DummyTable + for _, skill in ipairs(status_skills) do + if skill:withinAttackRange(player, to) then return true end + end + return isattack and player:inMyAttackRange(to, self:getDistanceLimit(player, card, to)) or player:distanceTo(to) <= self:getDistanceLimit(player, card, to) +end + return UsableSkill diff --git a/lua/fk_ex.lua b/lua/fk_ex.lua index 4b839e2b..8b8250d9 100644 --- a/lua/fk_ex.lua +++ b/lua/fk_ex.lua @@ -350,6 +350,7 @@ function fk.CreateMaxCardsSkill(spec) end ---@class TargetModSpec: StatusSkillSpec +---@field public unlimited fun(self: TargetModSkill, player: Player, skill: ActiveSkill, scope: integer, card: Card, to: Player) ---@field public residue_func fun(self: TargetModSkill, player: Player, skill: ActiveSkill, scope: integer, card: Card, to: Player) ---@field public distance_limit_func fun(self: TargetModSkill, player: Player, skill: ActiveSkill, card: Card, to: Player) ---@field public extra_target_func fun(self: TargetModSkill, player: Player, skill: ActiveSkill, card: Card) @@ -361,6 +362,9 @@ function fk.CreateTargetModSkill(spec) local skill = TargetModSkill:new(spec.name) readStatusSpecToSkill(skill, spec) + if spec.unlimited then + skill.isUnlimited = spec.unlimited + end if spec.residue_func then skill.getResidueNum = spec.residue_func end diff --git a/lua/server/events/gameflow.lua b/lua/server/events/gameflow.lua index 76151365..dfb9d015 100644 --- a/lua/server/events/gameflow.lua +++ b/lua/server/events/gameflow.lua @@ -258,7 +258,7 @@ GameEvent.functions[GameEvent.Phase] = function(self) tos = { {player.id} }, } room:doCardEffect(effect_data) - if effect_data.isCancellOut and card.skill then + if effect_data.isCanCellout and card.skill then card.skill:onNullified(room, effect_data) end end diff --git a/lua/server/events/usecard.lua b/lua/server/events/usecard.lua index c5f0bd4d..2e64fbfb 100644 --- a/lua/server/events/usecard.lua +++ b/lua/server/events/usecard.lua @@ -311,10 +311,10 @@ GameEvent.functions[GameEvent.CardEffect] = function(self) local self = self.room for _, event in ipairs({ fk.PreCardEffect, fk.BeforeCardEffect, fk.CardEffecting, fk.CardEffectFinished }) do - if cardEffectEvent.isCancellOut then + if cardEffectEvent.isCanCellout then local user = cardEffectEvent.from and self:getPlayerById(cardEffectEvent.from) or nil if self.logic:trigger(fk.CardEffectCancelledOut, user, cardEffectEvent) then - cardEffectEvent.isCancellOut = false + cardEffectEvent.isCanCellout = false else self.logic:breakEvent() end diff --git a/lua/server/mark_enum.lua b/lua/server/mark_enum.lua index 864e0dcf..ccb054be 100644 --- a/lua/server/mark_enum.lua +++ b/lua/server/mark_enum.lua @@ -19,6 +19,10 @@ MarkEnum.MinusMaxCards = "MinusMaxCards" ---@field AddMaxCards string @ 于本回合内减少标记值数量的手牌上限 MarkEnum.MinusMaxCardsInTurn = "MinusMaxCards-turn" +---@field BypassTimesLimit string @ 对其使用牌无次数限制,可带清除标记后缀 +MarkEnum.BypassTimesLimit = "bypasstimeslimit" +---@field BypassDistanceLimit string @ 对其使用牌无距离限制,可带清除标记后缀 +MarkEnum.BypassDistanceLimit = "bypassdistancelimit" ---@field UncompulsoryInvalidity string @ 非锁定技失效,可带清除标记后缀 MarkEnum.UncompulsoryInvalidity = "uncompulsoryInvalidity" diff --git a/lua/server/room.lua b/lua/server/room.lua index 4c94e8d3..b1e799aa 100644 --- a/lua/server/room.lua +++ b/lua/server/room.lua @@ -642,6 +642,7 @@ function Room:doRequest(player, command, jsonData, wait) if wait then local ret = player:waitForReply(self.timeout) player.serverplayer:setBusy(false) + player.serverplayer:setThinking(false) return ret end end @@ -667,6 +668,7 @@ function Room:doBroadcastRequest(command, players, jsonData) for _, p in ipairs(players) do p.serverplayer:setBusy(false) + p.serverplayer:setThinking(false) end end @@ -731,6 +733,7 @@ function Room:doRaceRequest(command, players, jsonData) for _, p in ipairs(self.players) do p.serverplayer:setBusy(false) + p.serverplayer:setThinking(false) end return ret @@ -1365,6 +1368,7 @@ end ---@param top_limit integer[] @ 置于牌堆顶的牌的限制(下限,上限),不填写则不限 ---@param bottom_limit integer[] @ 置于牌堆底的牌的限制(下限,上限),不填写则不限 ---@param customNotify string|null @ 自定义读条操作提示 +---@param prompt string|null @ 观星框的标题(暂时雪藏) ---@param noPut boolean|null @ 是否进行放置牌操作 ---@param areaNames string[]|null @ 左侧提示信息 ---@return table @@ -1389,6 +1393,7 @@ function Room:askForGuanxing(player, cards, top_limit, bottom_limit, customNotif local command = "AskForGuanxing" self:notifyMoveFocus(player, customNotify or command) local data = { + prompt = prompt or "", cards = cards, min_top_cards = top_limit and top_limit[1] or 0, max_top_cards = top_limit and top_limit[2] or #cards, @@ -2231,11 +2236,11 @@ function Room:handleCardEffect(event, cardEffectEvent) self:useCard(use) end - if not cardEffectEvent.isCancellOut then + if not cardEffectEvent.isCanCellout then break end - cardEffectEvent.isCancellOut = i == loopTimes + cardEffectEvent.isCanCellout = i == loopTimes end elseif cardEffectEvent.card.type == Card.TypeTrick and diff --git a/lua/server/serverplayer.lua b/lua/server/serverplayer.lua index c663c69f..016276e4 100644 --- a/lua/server/serverplayer.lua +++ b/lua/server/serverplayer.lua @@ -140,10 +140,12 @@ function ServerPlayer:waitForReply(timeout) result = "" self.reply_cancel = true self.serverplayer:setBusy(false) + self.serverplayer:setThinking(false) end if result ~= "" then self.reply_ready = true self.serverplayer:setBusy(false) + self.serverplayer:setThinking(false) end local queue = self.room.request_queue[self.serverplayer] diff --git a/lua/server/system_enum.lua b/lua/server/system_enum.lua index b62acdc4..a1c24cb6 100644 --- a/lua/server/system_enum.lua +++ b/lua/server/system_enum.lua @@ -133,7 +133,7 @@ fk.IceDamage = 4 ---@field public cardsResponded Card[]|null ---@field public disresponsive boolean|null ---@field public unoffsetable boolean|null ----@field public isCancellOut boolean|null +---@field public isCanCellout boolean|null ---@field public fixedResponseTimes table|integer|null ---@field public fixedAddTimesResponsors integer[] ---@field public prohibitedCardNames string[]|null diff --git a/packages/maneuvering/init.lua b/packages/maneuvering/init.lua index 1a541e4d..87dd88f4 100644 --- a/packages/maneuvering/init.lua +++ b/packages/maneuvering/init.lua @@ -80,7 +80,7 @@ local analepticSkill = fk.CreateActiveSkill{ name = "analeptic_skill", max_turn_use_time = 1, can_use = function(self, player, card) - return player:usedCardTimes("analeptic", Player.HistoryTurn) < self:getMaxUseTime(Self, Player.HistoryTurn, card, Self) + return self:withinTimesLimit(player, Player.HistoryTurn, card, player) end, on_use = function(self, room, use) if not use.tos or #TargetGroup:getRealTargets(use.tos) == 0 then @@ -240,7 +240,7 @@ local supplyShortageSkill = fk.CreateActiveSkill{ local player = Fk:currentRoom():getPlayerById(to_select) if Self ~= player then return not player:hasDelayedTrick("supply_shortage") and - Self:distanceTo(player) <= self:getDistanceLimit(Self, card, player) + self:withinDistanceLimit(Self, false, card, player) end end return false diff --git a/packages/standard/aux_skills.lua b/packages/standard/aux_skills.lua index 587a3041..ac724048 100644 --- a/packages/standard/aux_skills.lua +++ b/packages/standard/aux_skills.lua @@ -122,6 +122,27 @@ local uncompulsoryInvalidity = fk.CreateInvaliditySkill { end } +local noTimesLimit = fk.CreateTargetModSkill{ + name = "noTimesLimit", + global = true, + unlimited = function(self, player, skill, scope, card, to) + return to:getMark(MarkEnum.BypassTimesLimit) ~= 0 or + table.find(MarkEnum.TempMarkSuffix, function(s) + return to:getMark(MarkEnum.BypassTimesLimit .. s) ~= 0 + end) + end +} + +local noDistanceLimit = fk.CreateAttackRangeSkill{ + name = "noDistanceLimit", + global = true, + within_func = function(self, player, to) + return to:getMark(MarkEnum.BypassDistanceLimit) ~= 0 or + table.find(MarkEnum.TempMarkSuffix, function(s) + return to:getMark(MarkEnum.BypassDistanceLimit .. s) ~= 0 + end) + end +} AuxSkills = { discardSkill, chooseCardsSkill, @@ -129,4 +150,6 @@ AuxSkills = { maxCardsSkill, choosePlayersToMoveCardInBoardSkill, uncompulsoryInvalidity, + noTimesLimit, + noDistanceLimit, } diff --git a/packages/standard/init.lua b/packages/standard/init.lua index a2867304..4b568106 100644 --- a/packages/standard/init.lua +++ b/packages/standard/init.lua @@ -509,10 +509,10 @@ local paoxiaoAudio = fk.CreateTriggerSkill{ } local paoxiao = fk.CreateTargetModSkill{ name = "paoxiao", - residue_func = function(self, player, skill, scope) + unlimited = function(self, player, skill, scope) if player:hasSkill(self.name) and skill.trueName == "slash_skill" and scope == Player.HistoryPhase then - return 999 + return true end end, } diff --git a/packages/standard_cards/init.lua b/packages/standard_cards/init.lua index f8bf5fb0..9dfd2f34 100644 --- a/packages/standard_cards/init.lua +++ b/packages/standard_cards/init.lua @@ -50,14 +50,14 @@ local slashSkill = fk.CreateActiveSkill{ can_use = function(self, player, card) return table.find(Fk:currentRoom().alive_players, function(p) - return player:usedCardTimes("slash", Player.HistoryPhase) < self:getMaxUseTime(Self, Player.HistoryPhase, card, p) + return self:withinTimesLimit(player, Player.HistoryPhase, card, p) end) end, target_filter = function(self, to_select, selected, _, card) if #selected < self:getMaxTargetNum(Self, card) then local player = Fk:currentRoom():getPlayerById(to_select) - return Self ~= player and Self:inMyAttackRange(player, self:getDistanceLimit(Self, card, player)) and - (#selected > 0 or Self:usedCardTimes("slash", Player.HistoryPhase) < self:getMaxUseTime(Self, Player.HistoryPhase, card, player)) + return Self ~= player and self:withinDistanceLimit(Self, true, card, player) and + (#selected > 0 or self:withinTimesLimit(Self, Player.HistoryPhase, card, player)) end end, on_effect = function(self, room, effect) @@ -125,7 +125,7 @@ local jinkSkill = fk.CreateActiveSkill{ end, on_effect = function(self, room, effect) if effect.responseToEvent then - effect.responseToEvent.isCancellOut = true + effect.responseToEvent.isCanCellout = true end end } @@ -245,7 +245,7 @@ local snatchSkill = fk.CreateActiveSkill{ local player = Fk:currentRoom():getPlayerById(to_select) return Self ~= player and - Self:distanceTo(player) <= self:getDistanceLimit(Self, card, player) and -- for no distance limit for snatch + self:withinDistanceLimit(Self, false, card, player) and -- for no distance limit for snatch not player:isAllNude() end end, @@ -436,7 +436,7 @@ local nullificationSkill = fk.CreateActiveSkill{ end, on_effect = function(self, room, effect) if effect.responseToEvent then - effect.responseToEvent.isCancellOut = true + effect.responseToEvent.isCanCellout = true end end } @@ -778,10 +778,10 @@ local crossbowAudio = fk.CreateTriggerSkill{ local crossbowSkill = fk.CreateTargetModSkill{ name = "#crossbow_skill", attached_equip = "crossbow", - residue_func = function(self, player, skill, scope) + unlimited = function(self, player, skill, scope) if player:hasSkill(self.name) and skill.trueName == "slash_skill" and scope == Player.HistoryPhase then - return 999 + return true end end, } @@ -941,8 +941,12 @@ local bladeSkill = fk.CreateTriggerSkill{ end, on_cost = function(self, event, target, player, data) local room = player.room + room:setPlayerMark(target, MarkEnum.BypassDistanceLimit, 1) + room:setPlayerMark(target, MarkEnum.BypassTimesLimit, 1) local use = room:askForUseCard(player, "slash", nil, "#blade_slash:" .. target.id, true, { must_targets = {target.id}, exclusive_targets = {target.id} }) + room:setPlayerMark(target, MarkEnum.BypassDistanceLimit, 0) + room:setPlayerMark(target, MarkEnum.BypassTimesLimit, 0) if use then use.extraUse = true self.cost_data = use