初步隅泣

This commit is contained in:
YoumuKon 2024-04-02 00:33:43 +08:00
parent 5a1bd8c81e
commit 0d2dd3a623
7 changed files with 142 additions and 25 deletions

View File

@ -1192,6 +1192,46 @@ callbacks["AskForPoxi"] = (jsonData) => {
}); });
} }
callbacks["AskForYuqi"] = (jsonData) => {
const { type, data, extra_data, cancelable } = JSON.parse(jsonData);
roomScene.state = "replying";
roomScene.popupBox.sourceComponent =
Qt.createComponent("../RoomElement/YuqiBox.qml");
const box = roomScene.popupBox.item;
const area_names = [];
const card_data = [];
const card_items = [];
const carditems = [];
for (let d of data) {
const arr = d[0];
const card_arr = [];
const ids = d[1];
area_names.push(arr);
card_data.push(ids);
ids.forEach(id => {
const cdata = lcall("GetCardData", id)
card_arr.push(cdata);
carditems.push(cdata);
});
card_items.push(card_arr);
}
box.yuqi_type = type;
box.areaNames = area_names;
box.pilecards = card_data;
box.result = card_items;
box.extra_data = extra_data;
box.cancelable = cancelable;
box.cards = carditems;
box.arrangeCards();
roomScene.popupBox.moveToCenter();
box.cardsSelected.connect((ids) => {
replyToServer(JSON.stringify(ids));
});
}
callbacks["AskForMoveCardInBoard"] = (jsonData) => { callbacks["AskForMoveCardInBoard"] = (jsonData) => {
const data = JSON.parse(jsonData); const data = JSON.parse(jsonData);
const { cards, cardsPosition, generalNames, playerIds } = data; const { cards, cardsPosition, generalNames, playerIds } = data;

View File

@ -7,7 +7,7 @@ import Fk.Pages
GraphicsBox { GraphicsBox {
id: root id: root
property string Yuqi_type property string yuqi_type
property var cards: [] // property var cards: [] //
property var result: [] // property var result: [] //
property var pilecards: [] // property var pilecards: [] //
@ -16,6 +16,8 @@ GraphicsBox {
property var extra_data property var extra_data
property int padding: 25 property int padding: 25
signal cardsSelected(var ids)
title.text: "" title.text: ""
width: body.width + padding * 2 width: body.width + padding * 2
@ -63,7 +65,7 @@ GraphicsBox {
height: 130 height: 130
} }
// property alias cardsArea: cardsArea property alias cardsArea: cardsArea
} }
} }
@ -77,9 +79,9 @@ GraphicsBox {
width: 120 width: 120
height: 35 height: 35
text: luatr("OK") text: luatr("OK")
enabled: lcall("YuqiFeasible", root.Yuqi_type, root.selected_ids, enabled: lcall("YuqiFeasible", root.yuqi_type, root.getResult(),
root.card_data, root.extra_data); root.pilecards, root.extra_data);
onClicked: root.cardsSelected(findAllModel()) onClicked: root.cardsSelected(root.getResult())
} }
MetroButton { MetroButton {
@ -87,14 +89,14 @@ GraphicsBox {
height: 35 height: 35
text: luatr("Cancel") text: luatr("Cancel")
visible: root.cancelable visible: root.cancelable
onClicked: root.cardsSelected(card_data) onClicked: root.cardsSelected([])
} }
} }
} }
Repeater { Repeater {
id: cardItem id: cardsItem
model: cards model: cards
CardItem { CardItem {
@ -105,16 +107,38 @@ GraphicsBox {
suit: modelData.suit suit: modelData.suit
number: modelData.number number: modelData.number
draggable: true draggable: true
onReleased: updateCardsReleased(); onReleased: updateCardsReleased(this);
} }
} }
function updateCardsReleased() { function updateCardsReleased(card) {
for (i = 0; i < cardItem.count; i++) { let orig, from, to;
_card = result[0][i] let i, j;
if (Math.abs(card.x - _card.x) <= 50) { const result_cards = getResult();
result[1][result[1].indexOf(card)] = _card; for (i = 0; i < pilecards.count; i++) {
result[0][i] = card; const _pile = result[i];
const box = pile.cardsArea;
const pos = mapFromItem(pile, box.x, box.y);
const posid = _pile.indexOf(card.cid)
if (posid !== -1) {
from = i;
orig = posid;
}
const spacing = (_pile.length > 8) ? (700 / (_pile.length - 1)) : 100
if (Math.abs(card.y - pos.y) <= spacing / 2) {
to = i
}
if (from !== null && to !== null) {
if (pilecards[to].indexOf(card.cid) === -1 && !lcall("YuqiEntryFilter", root.yuqi_type, card.cid, from, to,
result_cards, root.extra_data) ) break;
result[from].splice(orig, 1)
for (j = 0; j < result[0].length; j++) {
let _card = result[orig][i]
if (Math.abs(card.x - _card.x) <= card.width / 2) {
result[to].splice(j, 0, card.cid);
break;
}
}
break; break;
} }
} }
@ -124,7 +148,8 @@ GraphicsBox {
function arrangeCards() { function arrangeCards() {
let i, j; let i, j;
let card, box, pos, pile; let card, box, pos, pile;
let spacing let spacing;
const result_cards = getResult();
for (j = 0; j < pilecards.length; j++){ for (j = 0; j < pilecards.length; j++){
pile = areaRepeater.itemAt(j); pile = areaRepeater.itemAt(j);
if (pile.y === 0){ if (pile.y === 0){
@ -135,7 +160,8 @@ GraphicsBox {
box = pile.cardsArea; box = pile.cardsArea;
pos = mapFromItem(pile, box.x, box.y); pos = mapFromItem(pile, box.x, box.y);
card = result[j][i]; card = result[j][i];
card.draggable = (j > 0) card.draggable = lcall("YuqiOutFilter", root.yuqi_type, card.cid, j,
result_cards, root.extra_data);
card.origX = pos.x + i * spacing; card.origX = pos.x + i * spacing;
card.origY = pos.y; card.origY = pos.y;
card.z = i + 1; card.z = i + 1;
@ -147,7 +173,17 @@ GraphicsBox {
refreshPrompt(); refreshPrompt();
} }
function getResult() {
const ret = [];
result.forEach(t => {
const t2 = [];
t.forEach(v => t2.push(v.cid));
ret.push(t2);
});
return ret;
}
function refreshPrompt() { function refreshPrompt() {
root.title.text = Util.processPrompt(lcall("YuqiPrompt", Yuqi_type, card_data, extra_data)) root.title.text = Util.processPrompt(lcall("YuqiPrompt", yuqi_type, root.result, root.pilecards, extra_data))
} }
} }

View File

@ -791,13 +791,13 @@ end
function YuqiEntryFilter(yuqi_type, to_select, from_pile, to_pile, data, extra_data) function YuqiEntryFilter(yuqi_type, to_select, from_pile, to_pile, data, extra_data)
local yuqi = Fk.yuqi_methods[yuqi_type] local yuqi = Fk.yuqi_methods[yuqi_type]
if not yuqi then return "false" end if not yuqi then return "false" end
return json.encode(yuqi.entry_filter(to_select, from_pile, to_pile, data, extra_data)) return json.encode(yuqi.entry_filter(to_select, from_pile + 1, to_pile + 1, data, extra_data))
end end
function YuqiOutFilter(yuqi_type, to_select, from_pile, data, extra_data) function YuqiOutFilter(yuqi_type, to_select, from_pile, data, extra_data)
local yuqi = Fk.yuqi_methods[yuqi_type] local yuqi = Fk.yuqi_methods[yuqi_type]
if not yuqi then return "false" end if not yuqi then return "false" end
return json.encode(yuqi.out_filter(to_select, from_pile, data, extra_data)) return json.encode(yuqi.out_filter(to_select, from_pile + 1, data, extra_data))
end end
function YuqiFeasible(yuqi_type, current, origin, extra_data) function YuqiFeasible(yuqi_type, current, origin, extra_data)

View File

@ -72,6 +72,7 @@ function Engine:initialize()
self.poxi_methods = {} self.poxi_methods = {}
self.qml_marks = {} self.qml_marks = {}
self.mini_games = {} self.mini_games = {}
self.yuqi_methods = {}
self:loadPackages() self:loadPackages()
self:loadDisabled() self:loadDisabled()
@ -396,10 +397,10 @@ end
---@param spec YuqiSpec ---@param spec YuqiSpec
function Engine:addYuqiMethod(spec) function Engine:addYuqiMethod(spec)
assert(type(spec.name) == "string") assert(type(spec.name) == "string")
assert(type(spec.feasible) == "function")
self.yuqi_methods[spec.name] = spec self.yuqi_methods[spec.name] = spec
spec.entry_filter = spec.entry_filter or function() return true end spec.entry_filter = spec.entry_filter or Util.TrueFunc
spec.out_filter = spec.out_filter or function() return true end spec.out_filter = spec.out_filter or Util.TrueFunc
spec.feasible = spec.feasible or Util.TrueFunc
end end
--- 从已经开启的拓展包中,随机选出若干名武将。 --- 从已经开启的拓展包中,随机选出若干名武将。

View File

@ -635,7 +635,7 @@ end
---@class YuqiSpec ---@class YuqiSpec
---@field name string ---@field name string
---@field feasible fun(current_data: any, old_data: any, extra_data: any): bool ---@field feasible? fun(current_data: any, old_data: any, extra_data: any): bool
---@field entry_filter fun(card: int, from_pile: int, to_pile: int, data: any, extra_data: any): bool ---@field entry_filter? fun(card: int, from_pile: int, to_pile: int, data: any, extra_data: any): bool
---@field out_filter fun(card: int, from_pile: int, data: any, extra_data: any): bool ---@field out_filter? fun(card: int, from_pile: int, data: any, extra_data: any): bool
---@field prompt? string | fun(data: any, extra_data: any): string ---@field prompt? string | fun(data: any, extra_data: any): string

View File

@ -1756,6 +1756,31 @@ function Room:askForPoxi(player, poxi_type, data, extra_data, cancelable)
end end
end end
--- 咕了太久的隅泣
---
--- data填入所有卡的列表类似ui.card_data
---@param player ServerPlayer
---@param yuqi_type string
---@param data any
---@param extra_data any
---@param cancelable? boolean
---@return integer[]
function Room:askForYuqi(player, yuqi_type, data, extra_data, cancelable)
local yuqi = Fk.yuqi_methods[yuqi_type]
if not yuqi then return {} end
local command = "AskForYuqi"
self:notifyMoveFocus(player, yuqi_type)
local result = self:doRequest(player, command, json.encode {
type = yuqi_type,
data = data,
extra_data = extra_data,
cancelable = (cancelable == nil) and true or cancelable
})
return result == "" and {} or json.decode(result)
end
--- 询问一名玩家从众多选项中选择一个。 --- 询问一名玩家从众多选项中选择一个。
---@param player ServerPlayer @ 要询问的玩家 ---@param player ServerPlayer @ 要询问的玩家
---@param choices string[] @ 可选选项列表 ---@param choices string[] @ 可选选项列表

View File

@ -83,6 +83,11 @@ local control = fk.CreateActiveSkill{
-- p(room:askForYiji(from, from:getCardIds(Player.Hand), table.map(effect.tos, Util.Id2PlayerMapper), self.name, 2, 10, nil, false, nil, false, 3, true)) -- p(room:askForYiji(from, from:getCardIds(Player.Hand), table.map(effect.tos, Util.Id2PlayerMapper), self.name, 2, 10, nil, false, nil, false, 3, true))
for _, pid in ipairs(effect.tos) do for _, pid in ipairs(effect.tos) do
local to = room:getPlayerById(pid) local to = room:getPlayerById(pid)
p(room:askForYuqi(from, "test", {
{"牌堆顶", table.slice(room.draw_pile, 1, 5)},
{"你自己", {}},
{"对方", {}},
}, to.hp, true))
-- p(room:askForPoxi(from, "test", { -- p(room:askForPoxi(from, "test", {
-- { "你自己", from:getCardIds "h" }, -- { "你自己", from:getCardIds "h" },
-- { "对方", to:getCardIds "h" }, -- { "对方", to:getCardIds "h" },
@ -130,6 +135,16 @@ local control = fk.CreateActiveSkill{
-- room:useVirtualCard("slash", nil, from, room:getOtherPlayers(from), self.name, true) -- room:useVirtualCard("slash", nil, from, room:getOtherPlayers(from), self.name, true)
end, end,
} }
Fk:addYuqiMethod{
name = "test",
prompt = "隅泣:请分配这些卡牌",
entry_filter = function(card, from_pile, to_pile, data, extra_data)
if table.contains({2, 3}, to_pile) and #data[to_pile] >= 5 then
return false
end
return true
end
}
--[[ --[[
Fk:addMiniGame{ Fk:addMiniGame{
name = "test", name = "test",