From 874e681868b9ec39cc5d911385b96649fed0e3d1 Mon Sep 17 00:00:00 2001 From: YoumuKon <38815081+YoumuKon@users.noreply.github.com> Date: Sun, 31 Dec 2023 18:41:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=88=E8=BF=99=E4=B9=88=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Fk/RoomElement/YuqiBox.qml | 169 +++++++++++++++++++++++++++++++++++++ lua/client/client_util.lua | 25 ++++++ lua/core/engine.lua | 14 +++ lua/fk_ex.lua | 7 ++ 4 files changed, 215 insertions(+) create mode 100644 Fk/RoomElement/YuqiBox.qml diff --git a/Fk/RoomElement/YuqiBox.qml b/Fk/RoomElement/YuqiBox.qml new file mode 100644 index 00000000..6b53d1f2 --- /dev/null +++ b/Fk/RoomElement/YuqiBox.qml @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick +import QtQuick.Layouts +import Fk.Pages + +GraphicsBox { + id: root + property string prompt + property var data + property var old_cards: [] + property var cards: [] + property var areaNames: [] + property int length: 1 + property var extra_data + property bool cancelable: true + property string yuqi_type + property int padding: 25 + + signal returnResults(var ids) + + title.text: Backend.callLuaFunction("YuqiPrompt", [yuqi_type, data, extra_data]) + width: body.width + padding * 2 + height: title.height + body.height + padding * 2 + + ColumnLayout { + id: body + x: padding + y: parent.height - padding - height + spacing: 20 + + Repeater { + id: areaRepeater + model: old_cards + + Row { + spacing: 5 + + property int areaCapacity: modelData + property string areaName: index < data.length ? qsTr(areaNames.name[index]) : "" + + Rectangle { + anchors.verticalCenter: parent.verticalCenter + color: "#6B5D42" + width: 20 + height: 100 + radius: 5 + + Text { + anchors.fill: parent + width: 20 + height: 100 + text: Backend.translate(areaName) + color: "white" + font.family: fontLibian.name + font.pixelSize: 18 + style: Text.Outline + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + } + + Repeater { + id: cardRepeater + model: areaCapacity + + Rectangle { + color: "#1D1E19" + width: 93 + height: 130 + + Text { + anchors.centerIn: parent + text: Backend.translate(areaName) + color: "#59574D" + width: parent.width * 0.8 + wrapMode: Text.WordWrap + } + } + } + property alias cardRepeater: cardRepeater + } + } + Row { + anchors.margins: 8 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + spacing: 32 + + MetroButton { + width: 120 + height: 35 + text: Backend.translate("OK") + enabled: { + return JSON.parse(Backend.callLuaFunction( + "YuqiFeasible", + [root.yuqi_type, root.cards, root.data, root.extra_data] + )); + } + onClicked: root.getResult(true); + } + + MetroButton { + width: 120 + height: 35 + text: Backend.translate("Cancel") + enabled: root.cancelable + onClicked: root.getResult(false); + } + + } + } + + Repeater { + id: cardItem + model: cards + + CardItem { + x: index + y: -1 + cid: modelData.cid + name: modelData.name + suit: modelData.suit + number: modelData.number + draggable: { + return JSON.parse(Backend.callLuaFunction( + "YuqiOutFilter", + [root.yuqi_type, model.cid, root.cards, root.extra_data] + )); + } + onReleased: arrangeCards(model.cid); + } + } + + function arrangeCards(var moved_card) { + let pos; + for (i = 0; i < cards.length; i++) { + let pile = cards[i]; + if (moved_card != null) { + if (pile[j] == moved_card) + } + for (j = 0; j < pile.length; j++) { + } + } + + + let box, pos, pile; + for (j = 0; j < areaRepeater.count; j++) { + pile = areaRepeater.itemAt(j); + if (pile.y === 0){ + pile.y = j * 150 + } + for (i = 0; i < result[j].length; i++) { + box = pile.cardRepeater.itemAt(i); + pos = mapFromItem(pile, box.x, box.y); + card = result[j][i]; + card.origX = pos.x; + card.origY = pos.y; + card.goBack(true); + } + } + } + + function getResult(var bol) { + if (!bol) return old_cards; + return cards; + } +} diff --git a/lua/client/client_util.lua b/lua/client/client_util.lua index 7b0bd104..26f4ebe4 100644 --- a/lua/client/client_util.lua +++ b/lua/client/client_util.lua @@ -748,4 +748,29 @@ function GetQmlMark(mtype, name, value, p) } end +function YuqiPrompt(yuqi_type, data, extra_data) + local yuqi = Fk.yuqi_methods[yuqi_type] + if not yuqi or not yuqi.prompt then return "" end + if type(yuqi.prompt) == "string" then return Fk:translate(yuqi.prompt) end + return yuqi.prompt(data, extra_data) +end + +function YuqiEntryFilter(yuqi_type, to_select, position, to_pile, data, extra_data) + local yuqi = Fk.yuqi_methods[yuqi_type] + if not yuqi then return "false" end + return json.encode(yuqi.entry_filter(to_select, position, to_pile, data, extra_data)) +end + +function YuqiOutFilter(yuqi_type, to_select, data, extra_data) + local yuqi = Fk.yuqi_methods[yuqi_type] + if not yuqi then return "false" end + return json.encode(yuqi.out_filter(to_select, data, extra_data)) +end + +function YuqiFeasible(yuqi_type, current, origin, extra_data) + local yuqi = Fk.yuqi_methods[yuqi_type] + if not yuqi then return "false" end + return json.encode(yuqi.feasible(current, origin, extra_data)) +end + dofile "lua/client/i18n/init.lua" diff --git a/lua/core/engine.lua b/lua/core/engine.lua index 00d3bf93..5004ed0d 100644 --- a/lua/core/engine.lua +++ b/lua/core/engine.lua @@ -28,6 +28,7 @@ ---@field private _custom_events any[] @ 自定义事件列表 ---@field public poxi_methods table @ “魄袭”框操作方法表 ---@field public qml_marks table @ 自定义Qml标记的表 +---@field public yuqi_methods table @ “隅泣”框操作方法表 local Engine = class("Engine") --- Engine的构造函数。 @@ -343,6 +344,7 @@ function Engine:addGameEvent(name, pfunc, mfunc, cfunc, efunc) table.insert(self._custom_events, { name = name, p = pfunc, m = mfunc, c = cfunc, e = efunc }) end +--- 向Engine中添加一个魄袭用方法。 ---@param spec PoxiSpec function Engine:addPoxiMethod(spec) assert(type(spec.name) == "string") @@ -356,6 +358,8 @@ function Engine:addPoxiMethod(spec) spec.post_select = spec.post_select or function(s) return s end end +--- 向Engine中添加一个隅泣用方法。 +---@param spec QmlMarkSpec function Engine:addQmlMark(spec) assert(type(spec.name) == "string") if self.qml_marks[spec.name] then @@ -364,6 +368,16 @@ function Engine:addQmlMark(spec) self.qml_marks[spec.name] = spec end +--- 向Engine中添加一个隅泣用方法。 +---@param spec YuqiSpec +function Engine:addYuqiMethod(spec) + assert(type(spec.name) == "string") + assert(type(spec.feasible) == "function") + self.yuqi_methods[spec.name] = spec + spec.entry_filter = spec.entry_filter or function() return true end + spec.out_filter = spec.out_filter or function() return true end +end + --- 从已经开启的拓展包中,随机选出若干名武将。 --- --- 对于同名武将不会重复选取。 diff --git a/lua/fk_ex.lua b/lua/fk_ex.lua index 8d94de46..821104ba 100644 --- a/lua/fk_ex.lua +++ b/lua/fk_ex.lua @@ -608,3 +608,10 @@ end ---@field name string ---@field qml_path string | fun(name: string, value?: any, player?: Player): string ---@field how_to_show fun(name: string, value?: any, player?: Player): string? + +---@class YuqiSpec +---@field name string +---@field feasible fun(current_data: any, old_data: any, extra_data: any): bool +---@field entry_filter fun(card: int, pos: int, pile: int[], data: any, extra_data: any): bool +---@field out_filter fun(card: int, data: any, extra_data: any): bool +---@field prompt? string | fun(data: any, extra_data: any): string \ No newline at end of file