From a812af8d97982ff886d3b7350c2e4e97defbd942 Mon Sep 17 00:00:00 2001 From: YoumuKon <38815081+YoumuKon@users.noreply.github.com> Date: Fri, 14 Jul 2023 22:17:54 +0800 Subject: [PATCH] =?UTF-8?q?bug=20fix=E5=92=8C=E9=BB=91=E5=90=8D=E5=8D=95?= =?UTF-8?q?=20(#223)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复了旁观skill出错的bug - 为模式和扩展包提供相互之间的黑/白名单 --- Fk/Pages/RoomLogic.js | 2 +- Fk/RoomElement/ChoiceBox.qml | 2 +- Fk/RoomElement/Dashboard.qml | 2 +- Fk/SkillInteraction/SkillCombo.qml | 2 +- lua/core/card.lua | 2 +- lua/core/engine.lua | 27 ++++- lua/core/game_mode.lua | 3 + lua/core/package.lua | 19 ++++ lua/core/player.lua | 20 ++-- lua/core/skill.lua | 1 + lua/core/skill_type/trigger.lua | 2 +- lua/core/util.lua | 4 +- lua/fk_ex.lua | 8 +- lua/server/gamelogic.lua | 4 +- lua/server/room.lua | 153 +++++++++++++++-------------- lua/server/serverplayer.lua | 4 +- packages/standard/i18n/zh_CN.lua | 2 + packages/standard/init.lua | 4 +- packages/test/init.lua | 10 +- 19 files changed, 159 insertions(+), 112 deletions(-) diff --git a/Fk/Pages/RoomLogic.js b/Fk/Pages/RoomLogic.js index 84e07822..05bd19c6 100644 --- a/Fk/Pages/RoomLogic.js +++ b/Fk/Pages/RoomLogic.js @@ -1068,8 +1068,8 @@ function processPrompt(prompt) { const dest = parseInt(data[2]); 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])); + if (raw.match("%arg")) raw = raw.replace(/%arg/g, Backend.translate(data[3])); return raw; } diff --git a/Fk/RoomElement/ChoiceBox.qml b/Fk/RoomElement/ChoiceBox.qml index 34b17740..cd45968e 100644 --- a/Fk/RoomElement/ChoiceBox.qml +++ b/Fk/RoomElement/ChoiceBox.qml @@ -21,8 +21,8 @@ GraphicsBox { const dest = parseInt(data[2]); 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])); + if (raw.match("%arg")) raw = raw.replace(/%arg/g, Backend.translate(data[3])); return raw; } diff --git a/Fk/RoomElement/Dashboard.qml b/Fk/RoomElement/Dashboard.qml index 15ae3195..1abb4686 100644 --- a/Fk/RoomElement/Dashboard.qml +++ b/Fk/RoomElement/Dashboard.qml @@ -278,8 +278,8 @@ RowLayout { const dest = parseInt(data[2]); 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])); + if (raw.match("%arg")) raw = raw.replace(/%arg/g, Backend.translate(data[3])); return raw; } diff --git a/Fk/SkillInteraction/SkillCombo.qml b/Fk/SkillInteraction/SkillCombo.qml index 3ca631df..d45559ab 100644 --- a/Fk/SkillInteraction/SkillCombo.qml +++ b/Fk/SkillInteraction/SkillCombo.qml @@ -18,8 +18,8 @@ MetroButton { const dest = parseInt(data[2]); 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])); + if (raw.match("%arg")) raw = raw.replace(/%arg/g, Backend.translate(data[3])); return raw; } diff --git a/lua/core/card.lua b/lua/core/card.lua index d04dffdf..d01f9a43 100644 --- a/lua/core/card.lua +++ b/lua/core/card.lua @@ -238,7 +238,7 @@ function Card:matchPattern(pattern) end --- 获取卡牌花色并返回花色文字描述(如 黑桃、红桃、梅花、方块)或者符号(如♠♥♣♦,带颜色)。 ----@param symbol boolean @ 是否以符号形式显示 +---@param symbol boolean|nil @ 是否以符号形式显示 ---@return string @ 描述花色的字符串 function Card:getSuitString(symbol) local suit = self.suit diff --git a/lua/core/engine.lua b/lua/core/engine.lua index 8eca61b8..dc653f6c 100644 --- a/lua/core/engine.lua +++ b/lua/core/engine.lua @@ -19,6 +19,7 @@ ---@field public cards Card[] @ 所有卡牌 ---@field public translations table> @ 翻译表 ---@field public game_modes table @ 所有游戏模式 +---@field public game_mode_disabled table @ 游戏模式禁用的包 ---@field public currentResponsePattern string @ 要求用牌的种类(如要求用特定花色的桃···) ---@field public currentResponseReason string @ 要求用牌的原因(如濒死,被特定牌指定,使用特定技能···) ---@field public filtered_cards table @ 被锁视技影响的卡牌 @@ -49,9 +50,11 @@ function Engine:initialize() self.cards = {} -- Card[] self.translations = {} -- srcText --> translated self.game_modes = {} + self.game_mode_disabled = {} self.kingdoms = {} self:loadPackages() + self:loadDisabled() self:addSkills(AuxSkills) end @@ -133,6 +136,22 @@ function Engine:loadPackages() end end +---@return nil +function Engine:loadDisabled() + for mode_name, game_mode in pairs(self.game_modes) do + local disabled_packages = {} + for name, pkg in pairs(self.packages) do + if table.contains(game_mode.blacklist or Util.DummyTable, name) or + (game_mode.whitelist and not table.contains(game_mode.whitelist, name)) or + table.contains(pkg.game_modes_blacklist or Util.DummyTable, mode_name) or + (pkg.game_modes_whitelist and not table.contains(pkg.game_modes_whitelist, mode_name)) then + table.insert(disabled_packages, name) + end + end + self.game_mode_disabled[game_mode.name] = disabled_packages + end +end + --- 向翻译表中加载新的翻译表。 ---@param t table @ 要加载的翻译表,这是一个 原文 --> 译文 的键值对表 ---@param lang string|nil @ 目标语言,默认为zh_CN @@ -271,8 +290,8 @@ end --- --- 返回的牌是一张虚拟牌。 ---@param name string @ 牌名 ----@param suit Suit @ 花色 ----@param number integer @ 点数 +---@param suit Suit|nil @ 花色 +---@param number integer|nil @ 点数 ---@return Card function Engine:cloneCard(name, suit, number) local cd = _card_name_table[name] @@ -308,7 +327,7 @@ end ---@param num integer @ 要选出的武将数量 ---@param generalPool General[] | nil @ 选择的范围,默认是已经启用的所有武将 ---@param except string[] | nil @ 特别要排除掉的武将名列表,默认是空表 ----@param filter fun(g: General): boolean | nil @ 可选参数,若这个函数返回true的话这个武将被排除在外 +---@param filter nil | fun(g: General): boolean @ 可选参数,若这个函数返回true的话这个武将被排除在外 ---@return General[] @ 随机选出的武将列表 function Engine:getGeneralsRandomly(num, generalPool, except, filter) if filter then @@ -385,7 +404,7 @@ end --- 根据id返回相应的卡牌。 ---@param id integer @ 牌的id ----@param ignoreFilter boolean @ 是否要无视掉锁定视为技,直接获得真牌 +---@param ignoreFilter boolean|nil @ 是否要无视掉锁定视为技,直接获得真牌 ---@return Card @ 这个id对应的卡牌 function Engine:getCardById(id, ignoreFilter) local ret = self.cards[id] diff --git a/lua/core/game_mode.lua b/lua/core/game_mode.lua index 5ab380fd..6237ee92 100644 --- a/lua/core/game_mode.lua +++ b/lua/core/game_mode.lua @@ -11,12 +11,15 @@ ---@field public rule TriggerSkill @ 规则(通过技能完成,通常用来为特定角色及特定时机提供触发事件) ---@field public logic fun() @ 逻辑(通过function完成,通常用来初始化、分配身份及座次) ---@field public surrenderFunc fun() +---@field public whitelist string[]|nil @ 白名单 +---@field public blacklist string[]|nil @ 黑名单 local GameMode = class("GameMode") --- 构造函数,不可随意调用。 ---@param name string @ 游戏模式名 ---@param min integer @ 最小玩家数 ---@param max integer @ 最大玩家数 +---@param filter string @ 过滤卡包,格式参考exppattern function GameMode:initialize(name, min, max) self.name = name self.minPlayer = math.max(min, 2) diff --git a/lua/core/package.lua b/lua/core/package.lua index d0b0e71d..283295bc 100644 --- a/lua/core/package.lua +++ b/lua/core/package.lua @@ -13,6 +13,8 @@ ---@field public related_skills table @ 对于额外技能而言的关联技能 ---@field public cards Card[] @ 拓展包包含的卡牌 ---@field public game_modes GameMode[] @ 拓展包包含的游戏模式 +---@field public game_modes_whitelist string[]|nil @ 拓展包关于游戏模式的白名单 +---@field public game_modes_blacklist string[]|nil @ 拓展包关于游戏模式的黑名单 local Package = class("Package") ---@alias PackageType integer @@ -83,4 +85,21 @@ function Package:addGameMode(game_mode) table.insert(self.game_modes, game_mode) end +--- 向拓展包中设置游戏模式过滤。 +---@param whitelist string[] @ 白名单 +---@param blacklist string[] @ 黑名单 +function Package:setGameModeFilter(whitelist, blacklist) + self.game_modes_whitelist = whitelist + self.game_modes_blacklist = blacklist +end + +--- 向拓展包中添加游戏模式过滤。 +---@param whitelist string[] @ 白名单 +---@param blacklist string[] @ 黑名单 +function Package:addGameModeFilter(whitelist, blacklist) + assert(type(whitelist) == "table") + assert(type(blacklist) == "table") + table.insertTable(self.game_modes_whitelist, whitelist) + table.insertTable(self.game_modes_blacklist, blacklist) +end return Package diff --git a/lua/core/player.lua b/lua/core/player.lua index f20591f3..8cff72d1 100644 --- a/lua/core/player.lua +++ b/lua/core/player.lua @@ -303,8 +303,8 @@ function Player:hasDelayedTrick(card_name) end --- 获取玩家特定区域所有牌的ID。 ----@param playerAreas PlayerCardArea @ 玩家牌所在的区域 ----@param specialName string @私人牌堆名 +---@param playerAreas PlayerCardArea|nil @ 玩家牌所在的区域 +---@param specialName string|nil @私人牌堆名 ---@return integer[] @ 返回对应区域的所有牌对应的ID function Player:getCardIds(playerAreas, specialName) local rightAreas = { Player.Hand, Player.Equip, Player.Judge } @@ -419,8 +419,8 @@ end --- --- 通过 二者位次+距离技能之和 与 两者间固定距离 进行对比,更大的为实际距离。 ---@param other Player @ 其他玩家 ----@param mode string @ 计算模式(left/right/both) ----@param ignore_dead boolean @ 是否忽略尸体 +---@param mode string|nil @ 计算模式(left/right/both) +---@param ignore_dead boolean|nil @ 是否忽略尸体 function Player:distanceTo(other, mode, ignore_dead) assert(other:isInstanceOf(Player)) mode = mode or "both" @@ -579,7 +579,7 @@ end --- 获取玩家使用特定牌的历史次数。 ---@param cardName string @ 牌名 ----@param scope integer @ 查询历史范围 +---@param scope integer|nil @ 查询历史范围 function Player:usedCardTimes(cardName, scope) if not self.cardUsedHistory[cardName] then return 0 @@ -636,8 +636,8 @@ end --- 检索玩家是否有对应技能。 ---@param skill string | Skill @ 技能名 ----@param ignoreNullified boolean @ 忽略技能是否被无效 ----@param ignoreAlive boolean @ 忽略角色在场与否 +---@param ignoreNullified boolean|nil @ 忽略技能是否被无效 +---@param ignoreAlive boolean|nil @ 忽略角色在场与否 function Player:hasSkill(skill, ignoreNullified, ignoreAlive) if not ignoreAlive and self.dead then return false @@ -726,7 +726,7 @@ function Player:loseSkill(skill, source_skill) end -- clear derivative skills of this skill as well - local tolose = self.derivative_skills[skill] + local tolose = self.derivative_skills[skill] or {} table.insert(tolose, skill) self.derivative_skills[skill] = nil @@ -815,8 +815,8 @@ fk.SwitchYin = 1 --- 获取转换技状态 ---@param skillName string @ 技能名 ----@param afterUse boolean @ 是否提前计算转换后状态 ----@param inWord boolean @ 是否返回文字 +---@param afterUse boolean|nil @ 是否提前计算转换后状态 +---@param inWord boolean|nil @ 是否返回文字 ---@return number @ 转换技状态 function Player:getSwitchSkillState(skillName, afterUse, inWord) if afterUse then diff --git a/lua/core/skill.lua b/lua/core/skill.lua index 5128e3e9..ddf7317a 100644 --- a/lua/core/skill.lua +++ b/lua/core/skill.lua @@ -9,6 +9,7 @@ ---@field public frequency Frequency @ 技能发动的频繁程度,通常compulsory(锁定技)及limited(限定技)用的多。 ---@field public visible boolean @ 技能是否会显示在游戏中 ---@field public mute boolean @ 决定是否关闭技能配音 +---@field public global boolean @ 决定是否是全局技能 ---@field public anim_type string @ 技能类型定义 ---@field public related_skills Skill[] @ 和本技能相关的其他技能,有时候一个技能实际上是通过好几个技能拼接而实现的。 ---@field public attached_equip string @ 属于什么装备的技能? diff --git a/lua/core/skill_type/trigger.lua b/lua/core/skill_type/trigger.lua index 9f7e944b..799c6ecc 100644 --- a/lua/core/skill_type/trigger.lua +++ b/lua/core/skill_type/trigger.lua @@ -93,7 +93,7 @@ end ---@param target ServerPlayer @ Player who triggered this event ---@param player ServerPlayer @ Player who is operating ---@param data any @ useful data of the event ----@return boolean +---@return boolean|nil function TriggerSkill:use(event, target, player, data) end function TriggerSkill:canWake(event, target, player, data) diff --git a/lua/core/util.lua b/lua/core/util.lua index f0c4bed7..e83f3b45 100644 --- a/lua/core/util.lua +++ b/lua/core/util.lua @@ -204,7 +204,7 @@ end ---@generic T ---@param self T[] ----@param n integer +---@param n integer|nil ---@return T|T[] function table:random(n) local n0 = n @@ -327,7 +327,7 @@ FileIO = { isDir = fk.QmlBackend_isDir } -os.getms = fk.GetMicroSecond +os.getms = function() return fk.GetMicroSecond(fk) end ---@class Stack : Object Stack = class("Stack") diff --git a/lua/fk_ex.lua b/lua/fk_ex.lua index afe3ddc7..fe556fe8 100644 --- a/lua/fk_ex.lua +++ b/lua/fk_ex.lua @@ -75,7 +75,7 @@ end ---@class StatusSkillSpec: StatusSkill ----@alias TrigFunc fun(self: TriggerSkill, event: Event, target: ServerPlayer, player: ServerPlayer):boolean +---@alias TrigFunc fun(self: TriggerSkill, event: Event, target: ServerPlayer, player: ServerPlayer, data: any):boolean|nil ---@class TriggerSkillSpec: UsableSkillSpec ---@field public global boolean ---@field public events Event | Event[] @@ -166,9 +166,9 @@ end ---@field public card_filter fun(self: ActiveSkill, to_select: integer, selected: integer[], selected_targets: integer[]): boolean ---@field public target_filter fun(self: ActiveSkill, to_select: integer, selected: integer[], selected_cards: integer[], card: Card): boolean ---@field public feasible fun(self: ActiveSkill, selected: integer[], selected_cards: integer[]): boolean ----@field public on_use fun(self: ActiveSkill, room: Room, cardUseEvent: CardUseStruct): boolean +---@field public on_use fun(self: ActiveSkill, room: Room, cardUseEvent: CardUseStruct): boolean|nil ---@field public about_to_effect fun(self: ActiveSkill, room: Room, cardEffectEvent: CardEffectEvent): boolean ----@field public on_effect fun(self: ActiveSkill, room: Room, cardEffectEvent: CardEffectEvent): boolean +---@field public on_effect fun(self: ActiveSkill, room: Room, cardEffectEvent: CardEffectEvent): boolean|nil ---@field public on_nullified fun(self: ActiveSkill, room: Room, cardEffectEvent: CardEffectEvent): boolean ---@field public prompt fun(self: ActiveSkill, selected: integer[], selected_cards: integer[]): string @@ -543,6 +543,8 @@ function fk.CreateGameMode(spec) assert(type(spec.minPlayer) == "number") assert(type(spec.maxPlayer) == "number") local ret = GameMode:new(spec.name, spec.minPlayer, spec.maxPlayer) + ret.whitelist = spec.whitelist + ret.blacklist = spec.blacklist ret.rule = spec.rule ret.logic = spec.logic diff --git a/lua/server/gamelogic.lua b/lua/server/gamelogic.lua index 49a3d74d..bf862532 100644 --- a/lua/server/gamelogic.lua +++ b/lua/server/gamelogic.lua @@ -375,8 +375,8 @@ function GameLogic:addTriggerSkill(skill) end ---@param event Event ----@param target ServerPlayer ----@param data any +---@param target ServerPlayer|nil +---@param data any|nil function GameLogic:trigger(event, target, data, refresh_only) local room = self.room local broken = false diff --git a/lua/server/room.lua b/lua/server/room.lua index 7327501d..0a283e6d 100644 --- a/lua/server/room.lua +++ b/lua/server/room.lua @@ -94,6 +94,7 @@ function Room:initialize(_room) self.settings = json.decode(self.room:settings()) self.disabled_packs = self.settings.disabledPack + table.insertTable(self.disabled_packs, Fk.game_mode_disabled[self.settings.gameMode]) self.disabled_generals = self.settings.disabledGenerals end @@ -332,7 +333,7 @@ function Room:getAllPlayers(sortBySeat) end --- 获得所有存活玩家,参看getAllPlayers ----@param sortBySeat boolean +---@param sortBySeat boolean|nil ---@return ServerPlayer[] function Room:getAlivePlayers(sortBySeat) if sortBySeat == nil or sortBySeat then @@ -359,8 +360,8 @@ end --- 获得除一名玩家外的其他玩家。 ---@param player ServerPlayer @ 要排除的玩家 ----@param sortBySeat boolean @ 是否要按座位排序? ----@param include_dead boolean @ 是否要把死人也算进去? +---@param sortBySeat boolean|nil @ 是否要按座位排序? +---@param include_dead boolean|nil @ 是否要把死人也算进去? ---@return ServerPlayer[] @ 其他玩家列表 function Room:getOtherPlayers(player, sortBySeat, include_dead) if sortBySeat == nil then @@ -398,7 +399,7 @@ end --- --- 如果牌堆中没有足够的牌可以获得,那么会触发洗牌;还是不够的话,游戏就平局。 ---@param num integer @ 要获得的牌的数量 ----@param from string @ 获得牌的位置,可以是 ``"top"`` 或者 ``"bottom"``,表示牌堆顶还是牌堆底 +---@param from string|nil @ 获得牌的位置,可以是 ``"top"`` 或者 ``"bottom"``,表示牌堆顶还是牌堆底 ---@return integer[] @ 得到的id function Room:getNCards(num, from) from = from or "top" @@ -558,22 +559,22 @@ function Room:setDeputyGeneral(player, general) end ---@param player ServerPlayer @ 要换将的玩家 ----@param new_general string @ 要变更的武将,若不存在则变身为孙策,孙策也不存在则nil错 ----@param full boolean @ 是否血量满状态变身 ----@param isDeputy boolean @ 是否变的是副将 ----@param sendLog boolean @ 是否发Log +---@param new_general string|nil @ 要变更的武将,若不存在则变身为孙策,孙策也不存在则nil错 +---@param full boolean|nil @ 是否血量满状态变身 +---@param isDeputy boolean|nil @ 是否变的是副将 +---@param sendLog boolean|nil @ 是否发Log function Room:changeHero(player, new_general, full, isDeputy, sendLog) local orig = isDeputy and (player.deputyGeneral or "") or player.general orig = Fk.generals[orig] local orig_skills = orig and orig:getSkillNameList() or Util.DummyTable - local new = Fk.generals[new_general] or Fk.generals["liubei"] - local new_skills = new:getSkillNameList() - - table.insertTable(new_skills, table.map(orig_skills, function(e) + local new = Fk.generals[new_general] or Fk.generals["sunce"] + local new_skills = table.map(orig_skills, function(e) return "-" .. e - end)) + end) + + table.insertTable(new_skills, new:getSkillNameList()) self:handleAddLoseSkills(player, table.concat(new_skills, "|"), nil, false) @@ -639,7 +640,7 @@ end ---@param player ServerPlayer @ 发出这个请求的目标玩家 ---@param command string @ 请求的类型 ---@param jsonData string @ 请求的数据 ----@param wait boolean @ 是否要等待答复,默认为true +---@param wait boolean|nil @ 是否要等待答复,默认为true ---@return string | nil @ 收到的答复,如果wait为false的话就返回nil function Room:doRequest(player, command, jsonData, wait) if wait == nil then wait = true end @@ -656,8 +657,8 @@ end --- 向多名玩家发出请求。 ---@param command string @ 请求类型 ----@param players ServerPlayer[] @ 发出请求的玩家列表 ----@param jsonData string @ 请求数据 +---@param players ServerPlayer[]|nil @ 发出请求的玩家列表 +---@param jsonData string|nil @ 请求数据 function Room:doBroadcastRequest(command, players, jsonData) players = players or self.players self.request_queue = {} @@ -762,7 +763,7 @@ end --- 向多名玩家告知一次移牌行为。 ---@param players ServerPlayer[] | nil @ 要被告知的玩家列表,默认为全员 ---@param card_moves CardsMoveStruct[] @ 要告知的移牌信息列表 ----@param forceVisible boolean @ 是否让所有牌对告知目标可见 +---@param forceVisible boolean|nil @ 是否让所有牌对告知目标可见 function Room:notifyMoveCards(players, card_moves, forceVisible) if players == nil or players == {} then players = self.players end for _, p in ipairs(players) do @@ -960,10 +961,10 @@ end --- 如果发动的话,那么会执行一下技能的onUse函数,然后返回选择的牌和目标等。 ---@param player ServerPlayer @ 询问目标 ---@param skill_name string @ 主动技的技能名 ----@param prompt string @ 烧条上面显示的提示文本内容 ----@param cancelable boolean @ 是否可以点取消 ----@param extra_data table @ 额外信息,因技能而异了 ----@param no_indicate boolean @ 是否不显示指示线 +---@param prompt string|nil @ 烧条上面显示的提示文本内容 +---@param cancelable boolean|nil @ 是否可以点取消 +---@param extra_data table|nil @ 额外信息,因技能而异了 +---@param no_indicate boolean|nil @ 是否不显示指示线 ---@return boolean, table function Room:askForUseActiveSkill(player, skill_name, prompt, cancelable, extra_data, no_indicate) prompt = prompt or "" @@ -1023,13 +1024,13 @@ Room.askForUseViewAsSkill = Room.askForUseActiveSkill ---@param player ServerPlayer @ 弃牌角色 ---@param minNum integer @ 最小值 ---@param maxNum integer @ 最大值 ----@param includeEquip boolean @ 能不能弃装备区? ----@param skillName string @ 引发弃牌的技能名 ----@param cancelable boolean @ 能不能点取消? ----@param pattern string @ 弃牌需要符合的规则 ----@param prompt string @ 提示信息 ----@param skipDiscard boolean @ 是否跳过弃牌(即只询问选择可以弃置的牌) ----@param no_indicate boolean @ 是否不显示指示线 +---@param includeEquip boolean|nil @ 能不能弃装备区? +---@param skillName string|nil @ 引发弃牌的技能名 +---@param cancelable boolean|nil @ 能不能点取消? +---@param pattern string|nil @ 弃牌需要符合的规则 +---@param prompt string|nil @ 提示信息 +---@param skipDiscard boolean|nil @ 是否跳过弃牌(即只询问选择可以弃置的牌) +---@param no_indicate boolean|nil @ 是否不显示指示线 ---@return integer[] @ 弃掉的牌的id列表,可能是空的 function Room:askForDiscard(player, minNum, maxNum, includeEquip, skillName, cancelable, pattern, prompt, skipDiscard, no_indicate) cancelable = (cancelable == nil) and true or cancelable @@ -1103,10 +1104,10 @@ end ---@param targets integer[] @ 可以选的目标范围,是玩家id数组 ---@param minNum integer @ 最小值 ---@param maxNum integer @ 最大值 ----@param prompt string @ 提示信息 ----@param skillName string @ 技能名 ----@param cancelable boolean @ 能否点取消 ----@param no_indicate boolean @ 是否不显示指示线 +---@param prompt string|nil @ 提示信息 +---@param skillName string|nil @ 技能名 +---@param cancelable boolean|nil @ 能否点取消 +---@param no_indicate boolean|nil @ 是否不显示指示线 ---@return integer[] @ 选择的玩家id列表,可能为空 function Room:askForChoosePlayers(player, targets, minNum, maxNum, prompt, skillName, cancelable, no_indicate) if maxNum < 1 then @@ -1140,13 +1141,13 @@ end ---@param player ServerPlayer @ 要询问的玩家 ---@param minNum integer @ 最小值 ---@param maxNum integer @ 最大值 ----@param includeEquip boolean @ 能不能选装备 +---@param includeEquip boolean|nil @ 能不能选装备 ---@param skillName string @ 技能名 ----@param cancelable boolean @ 能否点取消 ----@param pattern string @ 选牌规则 ----@param prompt string @ 提示信息 ----@param expand_pile string @ 可选私人牌堆名称 ----@param no_indicate boolean @ 是否不显示指示线 +---@param cancelable boolean|nil @ 能否点取消 +---@param pattern string|nil @ 选牌规则 +---@param prompt string|nil @ 提示信息 +---@param expand_pile string|nil @ 可选私人牌堆名称 +---@param no_indicate boolean|nil @ 是否不显示指示线 ---@return integer[] @ 选择的牌的id列表,可能是空的 function Room:askForCard(player, minNum, maxNum, includeEquip, skillName, cancelable, pattern, prompt, expand_pile, no_indicate) if minNum < 1 then @@ -1192,10 +1193,10 @@ end ---@param targets integer[] @ 选择目标的id范围 ---@param minNum integer @ 选目标最小值 ---@param maxNum integer @ 选目标最大值 ----@param pattern string @ 选牌规则 ----@param prompt string @ 提示信息 ----@param cancelable boolean @ 能否点取消 ----@param no_indicate boolean @ 是否不显示指示线 +---@param pattern string|nil @ 选牌规则 +---@param prompt string|nil @ 提示信息 +---@param cancelable boolean|nil @ 能否点取消 +---@param no_indicate boolean|nil @ 是否不显示指示线 ---@return integer[], integer function Room:askForChooseCardAndPlayers(player, targets, minNum, maxNum, pattern, prompt, skillName, cancelable, no_indicate) if maxNum < 1 then @@ -1335,9 +1336,9 @@ end --- 询问一名玩家从众多选项中选择一个。 ---@param player ServerPlayer @ 要询问的玩家 ---@param choices string[] @ 可选选项列表 ----@param skill_name string @ 技能名 ----@param prompt string @ 提示信息 ----@param detailed boolean @ 暂未使用 +---@param skill_name string|nil @ 技能名 +---@param prompt string|nil @ 提示信息 +---@param detailed boolean|nil @ 暂未使用 ---@return string @ 选择的选项 function Room:askForChoice(player, choices, skill_name, prompt, detailed) if #choices == 1 then return choices[1] end @@ -1354,8 +1355,8 @@ end --- 询问玩家是否发动技能。 ---@param player ServerPlayer @ 要询问的玩家 ---@param skill_name string @ 技能名 ----@param data any @ 未使用 ----@param prompt string @ 提示信息 +---@param data any|nil @ 未使用 +---@param prompt string|nil @ 提示信息 ---@return boolean function Room:askForSkillInvoke(player, skill_name, data, prompt) local command = "AskForSkillInvoke" @@ -1372,8 +1373,8 @@ end --- 观星完成后,相关的牌会被置于牌堆顶或者牌堆底。所以这些cards最好不要来自牌堆,一般先用getNCards从牌堆拿出一些牌。 ---@param player ServerPlayer @ 要询问的玩家 ---@param cards integer[] @ 可以被观星的卡牌id列表 ----@param top_limit integer[] @ 置于牌堆顶的牌的限制(下限,上限),不填写则不限 ----@param bottom_limit integer[] @ 置于牌堆底的牌的限制(下限,上限),不填写则不限 +---@param top_limit integer[]|nil @ 置于牌堆顶的牌的限制(下限,上限),不填写则不限 +---@param bottom_limit integer[]|nil @ 置于牌堆底的牌的限制(下限,上限),不填写则不限 ---@param customNotify string|null @ 自定义读条操作提示 ---@param prompt string|null @ 观星框的标题(暂时雪藏) ---@param noPut boolean|null @ 是否进行放置牌操作 @@ -1400,7 +1401,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 "", + prompt = "", cards = cards, min_top_cards = top_limit and top_limit[1] or 0, max_top_cards = top_limit and top_limit[2] or #cards, @@ -1552,11 +1553,11 @@ end -- * bypass_times: boolean --- 询问玩家使用一张牌。 ---@param player ServerPlayer @ 要询问的玩家 ----@param card_name string @ 使用牌的牌名,若pattern指定了则可随意写,它影响的是烧条的提示信息 ----@param pattern string @ 使用牌的规则,默认就是card_name的值 ----@param prompt string @ 提示信息 ----@param cancelable boolean @ 能否点取消 ----@param extra_data integer @ 额外信息 +---@param card_name string|nil @ 使用牌的牌名,若pattern指定了则可随意写,它影响的是烧条的提示信息 +---@param pattern string|nil @ 使用牌的规则,默认就是card_name的值 +---@param prompt string|nil @ 提示信息 +---@param cancelable boolean|nil @ 能否点取消 +---@param extra_data integer|nil @ 额外信息 ---@param event_data CardEffectEvent|nil @ 事件信息 ---@return CardUseStruct | nil @ 返回关于本次使用牌的数据,以便后续处理 function Room:askForUseCard(player, card_name, pattern, prompt, cancelable, extra_data, event_data) @@ -1626,11 +1627,11 @@ end --- 询问一名玩家打出一张牌。 ---@param player ServerPlayer @ 要询问的玩家 ---@param card_name string @ 牌名 ----@param pattern string @ 牌的规则 ----@param prompt string @ 提示信息 ----@param cancelable boolean @ 能否取消 ----@param extra_data any @ 额外数据 ----@param effectData CardEffectEvent @ 关联的卡牌生效流程 +---@param pattern string|nil @ 牌的规则 +---@param prompt string|nil @ 提示信息 +---@param cancelable boolean|nil @ 能否取消 +---@param extra_data any|nil @ 额外数据 +---@param effectData CardEffectEvent|nil @ 关联的卡牌生效流程 ---@return Card | nil @ 打出的牌 function Room:askForResponse(player, card_name, pattern, prompt, cancelable, extra_data, effectData) if effectData and (effectData.disresponsive or table.contains(effectData.disresponsiveList or Util.DummyTable, player.id)) then @@ -1677,9 +1678,9 @@ end ---@param players ServerPlayer[] @ 要询问的玩家列表 ---@param card_name string @ 询问的牌名,默认为无懈 ---@param pattern string @ 牌的规则 ----@param prompt string @ 提示信息 ----@param cancelable boolean @ 能否点取消 ----@param extra_data any @ 额外信息 +---@param prompt string|nil @ 提示信息 +---@param cancelable boolean|nil @ 能否点取消 +---@param extra_data any|nil @ 额外信息 ---@return CardUseStruct | nil @ 最终决胜出的卡牌使用信息 function Room:askForNullification(players, card_name, pattern, prompt, cancelable, extra_data) if #players == 0 then @@ -1737,7 +1738,7 @@ end --- 给player发一条消息,在他的窗口中用一系列卡牌填充一个AG。 ---@param player ServerPlayer @ 要通知的玩家 ---@param id_list integer[] | Card[] @ 要填充的卡牌 ----@param disable_ids integer[] | Card[] @ 未使用 +---@param disable_ids integer[] | Card[]|nil @ 未使用 function Room:fillAG(player, id_list, disable_ids) id_list = Card:getIdList(id_list) -- disable_ids = Card:getIdList(disable_ids) @@ -2411,8 +2412,8 @@ end --- 让玩家摸牌 ---@param player ServerPlayer @ 摸牌的玩家 ---@param num integer @ 摸牌数 ----@param skillName string @ 技能名 ----@param fromPlace string @ 摸牌的位置,"top" 或者 "bottom" +---@param skillName string|nil @ 技能名 +---@param fromPlace string|nil @ 摸牌的位置,"top" 或者 "bottom" ---@return integer[] @ 摸到的牌 function Room:drawCards(player, num, skillName, fromPlace) local drawData = { @@ -2443,10 +2444,10 @@ end ---@param card Card | Card[] @ 要移动的牌 ---@param to_place integer @ 移动的目标位置 ---@param target ServerPlayer @ 移动的目标玩家 ----@param reason integer @ 移动时使用的移牌原因 ----@param skill_name string @ 技能名 ----@param special_name string @ 私人牌堆名 ----@param visible boolean @ 是否明置 +---@param reason integer|nil @ 移动时使用的移牌原因 +---@param skill_name string|nil @ 技能名 +---@param special_name string|nil @ 私人牌堆名 +---@param visible boolean|nil @ 是否明置 function Room:moveCardTo(card, to_place, target, reason, skill_name, special_name, visible) reason = reason or fk.ReasonJustMove skill_name = skill_name or "" @@ -2482,7 +2483,7 @@ end ---@param player ServerPlayer @ 玩家 ---@param num integer @ 变化量 ---@param reason string|nil @ 原因 ----@param skillName string @ 技能名 +---@param skillName string|nil @ 技能名 ---@param damageStruct DamageStruct|null @ 伤害数据 ---@return boolean function Room:changeHp(player, num, reason, skillName, damageStruct) @@ -2634,8 +2635,8 @@ end ---@param card Card @ 改判的牌 ---@param player ServerPlayer @ 改判的玩家 ---@param judge JudgeStruct @ 要被改判的判定数据 ----@param skillName string @ 技能名 ----@param exchange boolean @ 是否要替换原有判定牌(即类似鬼道那样) +---@param skillName string|nil @ 技能名 +---@param exchange boolean|nil @ 是否要替换原有判定牌(即类似鬼道那样) function Room:retrial(card, player, judge, skillName, exchange) if not card then return end local triggerResponded = self.owner_map[card:getEffectiveId()] == player @@ -2684,9 +2685,9 @@ end --- 弃置一名角色的牌。 ---@param card_ids integer[] @ 被弃掉的牌 ----@param skillName string @ 技能名 +---@param skillName string|nil @ 技能名 ---@param who ServerPlayer @ 被弃牌的人 ----@param thrower ServerPlayer @ 弃别人牌的人 +---@param thrower ServerPlayer|nil @ 弃别人牌的人 function Room:throwCard(card_ids, skillName, who, thrower) if type(card_ids) == "number" then card_ids = {card_ids} @@ -2706,7 +2707,7 @@ end --- 重铸一名角色的牌。 ---@param card_ids integer[] @ 被重铸的牌 ---@param who ServerPlayer @ 重铸的角色 ----@param skillName string @ 技能名,默认为“重铸” +---@param skillName string|nil @ 技能名,默认为“重铸” function Room:recastCard(card_ids, who, skillName) if type(card_ids) == "number" then card_ids = {card_ids} diff --git a/lua/server/serverplayer.lua b/lua/server/serverplayer.lua index 028934da..7187aec5 100644 --- a/lua/server/serverplayer.lua +++ b/lua/server/serverplayer.lua @@ -58,7 +58,7 @@ end --- *timeout* must not be negative. If nil, room.timeout is used. ---@param command string ---@param jsonData string ----@param timeout integer +---@param timeout integer|nil function ServerPlayer:doRequest(command, jsonData, timeout) self.client_reply = "" self.reply_ready = false @@ -442,7 +442,7 @@ function ServerPlayer:gainAnExtraPhase(phase, delay) room:notifyProperty(self, self, "phase") end ----@param phase_table Phase[] +---@param phase_table Phase[]|nil function ServerPlayer:play(phase_table) phase_table = phase_table or {} if #phase_table > 0 then diff --git a/packages/standard/i18n/zh_CN.lua b/packages/standard/i18n/zh_CN.lua index 3dbcbca5..e964c4e4 100644 --- a/packages/standard/i18n/zh_CN.lua +++ b/packages/standard/i18n/zh_CN.lua @@ -21,6 +21,7 @@ Fk:loadTranslationTable{ ["$hujia2"] = "魏将何在?", ["hujia"] = "护驾", [":hujia"] = "主公技,当你需要使用或打出【闪】时,你可以令其他魏势力角色选择是否打出一张【闪】(视为由你使用或打出)。", + ["#hujia-ask"] = "护驾:你可打出一张闪,视为 %src 使用或打出", ["simayi"] = "司马懿", ["~simayi"] = "难道真是天意难违?", @@ -88,6 +89,7 @@ Fk:loadTranslationTable{ ["$jijiang2"] = "尔等敢应战否?", ["jijiang"] = "激将", [":jijiang"] = "主公技,当你需要使用或打出【杀】时,你可以令其他蜀势力角色选择是否打出一张【杀】(视为由你使用或打出)。", + ["#jijiang-ask"] = "激将:你可打出一张杀,视为 %src 使用或打出", ["guanyu"] = "关羽", ["~guanyu"] = "什么?此地名叫麦城?", diff --git a/packages/standard/init.lua b/packages/standard/init.lua index f3f3b66c..f0086786 100644 --- a/packages/standard/init.lua +++ b/packages/standard/init.lua @@ -63,7 +63,7 @@ local hujiaResponse = fk.CreateTriggerSkill{ local room = player.room for _, p in ipairs(room:getOtherPlayers(player)) do if p.kingdom == "wei" then - local cardResponded = room:askForResponse(p, "jink", "jink", "#hujia-ask:%s", player.id) + local cardResponded = room:askForResponse(p, "jink", "jink", "#hujia-ask:" .. player.id, true) if cardResponded then room:responseCard({ from = p.id, @@ -407,7 +407,7 @@ local jijiangResponse = fk.CreateTriggerSkill{ local room = player.room for _, p in ipairs(room:getOtherPlayers(player)) do if p.kingdom == "shu" then - local cardResponded = room:askForResponse(p, "slash", "slash", "#jijiang-ask:%s", player.id) + local cardResponded = room:askForResponse(p, "slash", "slash", "#jijiang-ask:" .. player.id, true) if cardResponded then room:responseCard({ from = p.id, diff --git a/packages/test/init.lua b/packages/test/init.lua index 05c8f3f2..907cb470 100644 --- a/packages/test/init.lua +++ b/packages/test/init.lua @@ -38,15 +38,15 @@ local cheat = fk.CreateActiveSkill{ return end - local cardName = room:askForChoice(from, allCardNames, "cheat", nil, nil, true) + local cardName = room:askForChoice(from, allCardNames, "cheat") local toGain = nil if #allCardMapper[cardName] > 0 then toGain = allCardMapper[cardName][math.random(1, #allCardMapper[cardName])] 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: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 } @@ -279,8 +279,8 @@ Fk:loadTranslationTable{ -- ["cheat"] = "小开", [":cheat"] = "出牌阶段,你可以获得一张想要的牌。", ["#cheat"] = "cheat:你可以获得一张想要的牌", - ["@@test_cheat-phase"] = "苦肉", - ["@@test_cheat-inhand"] = "连营", + -- ["@@test_cheat-phase"] = "苦肉", + -- ["@@test_cheat-inhand"] = "连营", --["#test_trig-ask"] = "你可弃置一张手牌", ["control"] = "控制", [":control"] = "出牌阶段,你可以控制/解除控制若干名其他角色。",