diff --git a/lua/server/room.lua b/lua/server/room.lua index b18d84ee..065ab732 100644 --- a/lua/server/room.lua +++ b/lua/server/room.lua @@ -1282,7 +1282,23 @@ end --- 观星完成后,相关的牌会被置于牌堆顶或者牌堆底。所以这些cards最好不要来自牌堆,一般先用getNCards从牌堆拿出一些牌。 ---@param player ServerPlayer @ 要询问的玩家 ---@param cards integer[] @ 可以被观星的卡牌id列表 -function Room:askForGuanxing(player, cards) +---@param top_limit integer[] @ 置于牌堆顶的牌的限制(下限,上限),不填写则不限 +---@param bottom_limit integer[] @ 置于牌堆顶的牌的限制(下限,上限),不填写则不限 +function Room:askForGuanxing(player, cards, top_limit, bottom_limit) + -- 这一大堆都是来提前报错的 + top_limit = top_limit or {} + bottom_limit = bottom_limit or {} + if #top_limit > 0 then + assert(top_limit[1] >= 0 and top_limit[2] >= 0, "牌堆顶区间设置错误:数值小于0") + assert(top_limit[1] <= top_limit[2], "牌堆顶区间设置错误:上限小于下限") + end + if #bottom_limit > 0 then + assert(bottom_limit[1] >= 0 and bottom_limit[2] >= 0, "牌堆底区间设置错误:数值小于0") + assert(bottom_limit[1] <= bottom_limit[2], "牌堆底区间设置错误:上限小于下限") + end + if #top_limit > 0 and #bottom_limit > 0 then + assert(#cards >= top_limit[1] + bottom_limit[1] and #cards <= top_limit[2] + bottom_limit[2], "限定区间设置错误:可用空间不能容纳所有牌。") + end if #cards == 1 then table.insert(self.draw_pile, 1, cards[1]) return @@ -1291,14 +1307,23 @@ function Room:askForGuanxing(player, cards) self:notifyMoveFocus(player, command) local data = { cards = cards, + min_top_cards = top_limit and top_limit[1] or 0, + max_top_cards = top_limit and top_limit[2] or #cards, + min_bottom_cards = bottom_limit and bottom_limit[1] or 0, + max_bottom_cards = bottom_limit and bottom_limit[2] or #cards, } local result = self:doRequest(player, command, json.encode(data)) local top, bottom if result ~= "" then local d = json.decode(result) - top = d[1] - bottom = d[2] + if #top_limit > 0 and top_limit[1] == 0 then + top = {} + bottom = d[1] + else + top = d[1] + bottom = d[2] + end else top = cards bottom = {} diff --git a/qml/Pages/RoomElement/GuanxingBox.qml b/qml/Pages/RoomElement/GuanxingBox.qml index d7629185..0e0d93e1 100644 --- a/qml/Pages/RoomElement/GuanxingBox.qml +++ b/qml/Pages/RoomElement/GuanxingBox.qml @@ -9,6 +9,7 @@ GraphicsBox { property var cards: [] property var result: [] property var areaCapacities: [] + property var areaLimits: [] property var areaNames: [] property int padding: 25 @@ -56,6 +57,7 @@ GraphicsBox { MetroButton { Layout.alignment: Qt.AlignHCenter + id: buttonConfirm text: Backend.translate("OK") width: 120 height: 35 @@ -83,8 +85,9 @@ GraphicsBox { function arrangeCards() { result = new Array(areaCapacities.length); let i; - for (i = 0; i < result.length; i++) + for (i = 0; i < result.length; i++){ result[i] = []; + } let card, j, area, cards, stay; for (i = 0; i < cardItem.count; i++) { @@ -101,16 +104,25 @@ GraphicsBox { } } - if (stay) - result[0].push(card); + if (stay) { + if (result[0].length >= areaCapacities[0]) { + result[1].push(card); + } else { + result[0].push(card); + } + } } - for(i = 0; i < result.length; i++) result[i].sort((a, b) => a.x - b.x); + + 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); @@ -120,6 +132,14 @@ GraphicsBox { card.goBack(true); } } + + for (i = 0; i < areaRepeater.count; i++) { + if (result[i].length < areaLimits[i]) { + buttonConfirm.enabled = false; + break; + } + buttonConfirm.enabled = true; + } } function getResult() { diff --git a/qml/Pages/RoomLogic.js b/qml/Pages/RoomLogic.js index ed0bb211..1016122a 100644 --- a/qml/Pages/RoomLogic.js +++ b/qml/Pages/RoomLogic.js @@ -604,7 +604,10 @@ callbacks["AskForSkillInvoke"] = function(jsonData) { callbacks["AskForGuanxing"] = function(jsonData) { let data = JSON.parse(jsonData); let cards = []; - + let min_top_cards = data.min_top_cards; + let max_top_cards = data.max_top_cards; + let min_bottom_cards = data.min_bottom_cards; + let max_bottom_cards = data.max_bottom_cards; roomScene.state = "replying"; roomScene.popupBox.source = "RoomElement/GuanxingBox.qml"; data.cards.forEach(id => { @@ -612,8 +615,15 @@ callbacks["AskForGuanxing"] = function(jsonData) { cards.push(JSON.parse(d)); }); let box = roomScene.popupBox.item; - box.areaCapacities = [cards.length, cards.length]; - box.areaNames = ["Top", "Bottom"]; + if (max_top_cards == 0) { + box.areaCapacities = [max_bottom_cards]; + box.areaLimits = [min_bottom_cards]; + box.areaNames = ["Bottom"]; + } else { + box.areaCapacities = [max_top_cards, max_bottom_cards]; + box.areaLimits = [min_top_cards, min_bottom_cards]; + box.areaNames = ["Top", "Bottom"]; + } box.cards = cards; box.arrangeCards(); box.accepted.connect(() => {