From adafcfbae10247a922b4eebf2cab3e0c990d4db9 Mon Sep 17 00:00:00 2001 From: Nyutanislavsky Date: Sun, 16 Jul 2023 15:29:20 +0800 Subject: [PATCH] Bugfix (#224) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 为选项框增加all_choices,可以看到无法选择的选项 2. 体力上限减到0以下不会再死两次 3. 预判超量回复 4. 可以在摸牌前事件打断摸牌 5. 修复卡牌可以使用判断 6. 添加移动场上牌的返回值(卡牌和玩家id) 7. 修复谋徐盛的属性伤害 8. 修改选择多张牌的翻译 9. 修复变更武将的hp设置 --------- Signed-off-by: Mechanel --- Fk/Pages/Room.qml | 1 + Fk/Pages/RoomLogic.js | 13 ++++++++----- Fk/RoomElement/ChoiceBox.qml | 4 +++- Fk/RoomElement/DetailedChoiceBox.qml | 4 +++- Fk/RoomElement/PlayerCardBox.qml | 4 +++- Fk/SkillInteraction/SkillCombo.qml | 2 ++ lua/client/client_util.lua | 4 +++- lua/client/i18n/zh_CN.lua | 2 ++ lua/server/events/hp.lua | 25 +++++++++++++++++-------- lua/server/room.lua | 24 ++++++++++++++++-------- lua/ui-util.lua | 2 ++ packages/test/init.lua | 4 ++-- 12 files changed, 62 insertions(+), 27 deletions(-) diff --git a/Fk/Pages/Room.qml b/Fk/Pages/Room.qml index ecb85205..eee7812b 100644 --- a/Fk/Pages/Room.qml +++ b/Fk/Pages/Room.qml @@ -660,6 +660,7 @@ Item { skillInteraction.item.default_choice = data["default"]; skillInteraction.item.choices = data.choices; skillInteraction.item.detailed = data.detailed; + skillInteraction.item.all_choices = data.all_choices; // skillInteraction.item.clicked(); break; case "spin": diff --git a/Fk/Pages/RoomLogic.js b/Fk/Pages/RoomLogic.js index 05bd19c6..5303e6aa 100644 --- a/Fk/Pages/RoomLogic.js +++ b/Fk/Pages/RoomLogic.js @@ -870,14 +870,16 @@ callbacks["AskForExchange"] = (jsonData) => { replyToServer(JSON.stringify(box.getResult())); }); } + callbacks["AskForChoice"] = (jsonData) => { // jsonData: [ string[] choices, string skill ] // TODO: multiple choices, e.g. benxi_ol const data = JSON.parse(jsonData); const choices = data[0]; - const skill_name = data[1]; - const prompt = data[2]; - const detailed = data[3]; + const all_choices = data[1]; + const skill_name = data[2]; + const prompt = data[3]; + const detailed = data[4]; if (prompt === "") { roomScene.promptText = Backend.translate("#AskForChoice") .arg(Backend.translate(skill_name)); @@ -895,6 +897,7 @@ callbacks["AskForChoice"] = (jsonData) => { const box = roomScene.popupBox.item; box.options = choices; box.skill_name = skill_name; + box.all_options = all_choices; box.accepted.connect(() => { replyToServer(choices[box.result]); }); @@ -970,8 +973,8 @@ callbacks["AskForCardsChosen"] = (jsonData) => { delayedTricks.push(card_data); }); - roomScene.promptText = Backend.translate("#AskForChooseCard") - .arg(Backend.translate(reason)); + roomScene.promptText = Backend.translate("#AskForChooseCards") + .arg(Backend.translate(reason)).arg(min).arg(max); roomScene.state = "replying"; roomScene.popupBox.sourceComponent = Qt.createComponent("../RoomElement/PlayerCardBox.qml"); const box = roomScene.popupBox.item; diff --git a/Fk/RoomElement/ChoiceBox.qml b/Fk/RoomElement/ChoiceBox.qml index cd45968e..cf0106b6 100644 --- a/Fk/RoomElement/ChoiceBox.qml +++ b/Fk/RoomElement/ChoiceBox.qml @@ -6,6 +6,7 @@ import Fk.Pages GraphicsBox { property var options: [] + property var all_options: [] property string skill_name: "" property int result @@ -35,11 +36,12 @@ GraphicsBox { columnSpacing: 10 Repeater { - model: options + model: all_options MetroButton { Layout.fillWidth: true text: processPrompt(modelData) + enabled: options.indexOf(modelData) !== -1 onClicked: { result = index; diff --git a/Fk/RoomElement/DetailedChoiceBox.qml b/Fk/RoomElement/DetailedChoiceBox.qml index e2628585..43c139a2 100644 --- a/Fk/RoomElement/DetailedChoiceBox.qml +++ b/Fk/RoomElement/DetailedChoiceBox.qml @@ -7,6 +7,7 @@ import Fk.Pages GraphicsBox { property var options: [] + property var all_options: [] property string skill_name: "" property int result @@ -25,7 +26,7 @@ GraphicsBox { clip: true spacing: 20 - model: options + model: all_options delegate: Item { width: 200 @@ -35,6 +36,7 @@ GraphicsBox { id: choicetitle width: parent.width text: Backend.translate(modelData) + enabled: options.indexOf(modelData) !== -1 textFont.pixelSize: 24 anchors.top: choiceDetail.bottom anchors.topMargin: 8 diff --git a/Fk/RoomElement/PlayerCardBox.qml b/Fk/RoomElement/PlayerCardBox.qml index 379901b4..2e635ad8 100644 --- a/Fk/RoomElement/PlayerCardBox.qml +++ b/Fk/RoomElement/PlayerCardBox.qml @@ -6,7 +6,9 @@ import Fk.Pages GraphicsBox { id: root - title.text: Backend.translate("$ChooseCard") + + title.text: root.multiChoose ? Backend.translate("$ChooseCards").arg(root.min).arg(root.max) : Backend.translate("$ChooseCard") + // TODO: Adjust the UI design in case there are more than 7 cards width: 70 + Math.min(7, Math.max(1, handcards.count, equips.count, delayedTricks.count)) * 100 height: 50 + (handcards.count > 0 ? 150 : 0) + (equips.count > 0 ? 150 : 0) + (delayedTricks.count > 0 ? 150 : 0) diff --git a/Fk/SkillInteraction/SkillCombo.qml b/Fk/SkillInteraction/SkillCombo.qml index d45559ab..e85f6cb4 100644 --- a/Fk/SkillInteraction/SkillCombo.qml +++ b/Fk/SkillInteraction/SkillCombo.qml @@ -7,6 +7,7 @@ MetroButton { id: root property string skill property var choices: [] + property var all_choices: [] property string default_choice property string answer: default_choice property bool detailed: false @@ -42,6 +43,7 @@ MetroButton { } const box = roomScene.popupBox.item; box.options = choices; + box.all_options = all_choices; box.accepted.connect(() => { answer = choices[box.result]; }); diff --git a/lua/client/client_util.lua b/lua/client/client_util.lua index b6481a73..5ca9063d 100644 --- a/lua/client/client_util.lua +++ b/lua/client/client_util.lua @@ -377,12 +377,14 @@ function ActiveCanUse(skill_name) for _, m in ipairs(exp.matchers) do if m.name then table.insertTable(cnames, m.name) - elseif m.trueName then + end + if m.trueName then table.insertTable(cnames, m.trueName) end end for _, n in ipairs(cnames) do local c = Fk:cloneCard(n) + c.skillName = skill_name ret = c.skill:canUse(Self, c) if ret then break end end diff --git a/lua/client/i18n/zh_CN.lua b/lua/client/i18n/zh_CN.lua index 0b098390..e2667000 100644 --- a/lua/client/i18n/zh_CN.lua +++ b/lua/client/i18n/zh_CN.lua @@ -180,7 +180,9 @@ FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下 ["AskForCardChosen"] = "选牌", ["AskForCardsChosen"] = "选牌", ["#AskForChooseCard"] = "%1:请选择其一张卡牌", + ["#AskForChooseCards"] = "%1:请选择其%2至%3张卡牌", ["$ChooseCard"] = "请选择一张卡牌", + ["$ChooseCards"] = "请选择%1至%2张卡牌", ["$Hand"] = "手牌区", ["$Equip"] = "装备区", ["$Judge"] = "判定区", diff --git a/lua/server/events/hp.lua b/lua/server/events/hp.lua index 20545226..ce417a70 100644 --- a/lua/server/events/hp.lua +++ b/lua/server/events/hp.lua @@ -114,7 +114,7 @@ GameEvent.functions[GameEvent.Damage] = function(self) end damageStruct.damageType = damageStruct.damageType or fk.NormalDamage - if damageStruct.from and not damageStruct.from:isAlive() then + if damageStruct.from and damageStruct.from.dead then damageStruct.from = nil end @@ -135,7 +135,7 @@ GameEvent.functions[GameEvent.Damage] = function(self) assert(damageStruct.to:isInstanceOf(ServerPlayer)) end - if not damageStruct.to:isAlive() then + if damageStruct.to.dead then return false end @@ -249,6 +249,7 @@ GameEvent.functions[GameEvent.Recover] = function(self) end local who = recoverStruct.who + if self.logic:trigger(fk.PreHpRecover, who, recoverStruct) or recoverStruct.num < 1 then self.logic:breakEvent(false) end @@ -274,8 +275,22 @@ GameEvent.functions[GameEvent.ChangeMaxHp] = function(self) player = player.id, num = num, }) + self:sendLog{ + type = num > 0 and "#HealMaxHP" or "#LoseMaxHP", + from = player.id, + arg = num > 0 and num or - num, + } if player.maxHp == 0 then + player.hp = 0 + self:broadcastProperty(player, "hp") + self:sendLog{ + type = "#ShowHPAndMaxHP", + from = player.id, + arg = 0, + arg2 = 0, + } self:killPlayer({ who = player.id }) + return false end local diff = player.hp - player.maxHp @@ -285,12 +300,6 @@ GameEvent.functions[GameEvent.ChangeMaxHp] = function(self) end end - self:sendLog{ - type = num > 0 and "#HealMaxHP" or "#LoseMaxHP", - from = player.id, - arg = num > 0 and num or - num, - } - self:sendLog{ type = "#ShowHPAndMaxHP", from = player.id, diff --git a/lua/server/room.lua b/lua/server/room.lua index 128a7d00..699f151d 100644 --- a/lua/server/room.lua +++ b/lua/server/room.lua @@ -594,7 +594,7 @@ function Room:changeHero(player, new_general, full, isDeputy, sendLog) player.maxHp = player:getGeneralMaxHp() self:broadcastProperty(player, "maxHp") - if full then + if full or player.hp > player.maxHp then player.hp = player.maxHp self:broadcastProperty(player, "hp") end @@ -1338,15 +1338,18 @@ end ---@param choices string[] @ 可选选项列表 ---@param skill_name string|nil @ 技能名 ---@param prompt string|nil @ 提示信息 ----@param detailed boolean|nil @ 暂未使用 +---@param detailed boolean|nil @ 选项详细描述 +---@param all_choices string[]|nil @ 所有选项(不可选变灰) ---@return string @ 选择的选项 -function Room:askForChoice(player, choices, skill_name, prompt, detailed) - if #choices == 1 then return choices[1] end +function Room:askForChoice(player, choices, skill_name, prompt, detailed, all_choices) + if #choices == 1 and not all_choices then return choices[1] end + assert(not all_choices or table.every(choices, function(c) return table.contains(all_choices, c) end)) local command = "AskForChoice" prompt = prompt or "" + all_choices = all_choices or choices self:notifyMoveFocus(player, skill_name) local result = self:doRequest(player, command, json.encode{ - choices, skill_name, prompt, detailed + choices, all_choices, skill_name, prompt, detailed }) if result == "" then result = choices[1] end return result @@ -1785,7 +1788,7 @@ end ---@param skillName string @ 技能名 ---@param flag string|null @ 限定可移动的区域,值为nil(装备区和判定区)、‘e’或‘j’ ---@param moveFrom ServerPlayer|null @ 是否只是目标1移动给目标2 ----@return integer +---@return table<"card"|"from"|"to"> @ 选择的卡牌、起点玩家id和终点玩家id列表 function Room:askForMoveCardInBoard(player, targetOne, targetTwo, skillName, flag, moveFrom) if flag then assert(flag == "e" or flag == "j") @@ -1863,15 +1866,18 @@ function Room:askForMoveCardInBoard(player, targetOne, targetTwo, skillName, fla end local cardToMove = Fk:getCardById(result.cardId) + local from, to = result.pos == 0 and targetOne, targetTwo or targetTwo, targetOne self:moveCardTo( cardToMove, cardToMove.type == Card.TypeEquip and Player.Equip or Player.Judge, - result.pos == 0 and targetTwo or targetOne, + to, fk.ReasonPut, skillName, nil, true ) + + return { card = cardToMove, from = from.id, to = to.id } end --- 询问一名玩家从targets中选择出若干名玩家来移动场上的牌。 @@ -2422,7 +2428,9 @@ function Room:drawCards(player, num, skillName, fromPlace) skillName = skillName, fromPlace = fromPlace, } - self.logic:trigger(fk.BeforeDrawCard, player, drawData) + if self.logic:trigger(fk.BeforeDrawCard, player, drawData) or drawData.num < 1 then + self.logic:breakEvent(false) + end num = drawData.num fromPlace = drawData.fromPlace diff --git a/lua/ui-util.lua b/lua/ui-util.lua index 9f4ad59b..80ad52a9 100644 --- a/lua/ui-util.lua +++ b/lua/ui-util.lua @@ -13,12 +13,14 @@ local UI = {} -- * choices: string[] 类型,保存着可选项,会被前端翻译 -- * default: string,默认的选项,默认为choices的第一个 -- * detailed: bool,为真的话送详细信息 +-- * all_choices: string[] 类型,保存着所有选项,会被前端翻译 UI.ComboBox = function(spec) -- assert(type(spec.choices) == "table", "Choices is not a table") -- assert(#spec.choices > 0, "Choices is empty") spec.choices = type(spec.choices) == "table" and spec.choices or Util.DummyTable spec.default = spec.default or spec.choices[1] spec.detailed = spec.detailed or false + spec.all_choices = type(spec.all_choices) == "table" and spec.all_choices or spec.choices spec.type = "combo" return spec end diff --git a/packages/test/init.lua b/packages/test/init.lua index 907cb470..9f1dcfec 100644 --- a/packages/test/init.lua +++ b/packages/test/init.lua @@ -187,7 +187,7 @@ local damage_maker = fk.CreateActiveSkill{ end, target_num = 1, interaction = function()return UI.ComboBox { - choices = {"normal_damage", "fire_damage", "thunder_damage", "ice_damage", "lose_hp", "heal_hp", "lose_max_hp", "heal_max_hp"} + choices = {"normal_damage", "thunder_damage", "fire_damage", "ice_damage", "lose_hp", "heal_hp", "lose_max_hp", "heal_max_hp"} }end, on_use = function(self, room, effect) local from = room:getPlayerById(effect.from) @@ -212,7 +212,7 @@ local damage_maker = fk.CreateActiveSkill{ elseif choice == "lose_hp" then room:loseHp(target, number, self.name) else - choices = {"normal_damage", "fire_damage", "thunder_damage", "ice_damage"} + choices = {"normal_damage", "thunder_damage", "fire_damage", "ice_damage"} room:damage({ from = from, to = target,