From fa8335a33051e073f93417bb7dcd36a6b1662fa2 Mon Sep 17 00:00:00 2001 From: notify Date: Thu, 19 Sep 2024 00:31:49 +0800 Subject: [PATCH] UI rewrite (#367) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TODOS ======== 手气卡、重铸、本轮跳过无懈 ---------- 禁用理由、Target脸上提示(可烈弓) ---------- **修bug** --------- Co-authored-by: YoumuKon <38815081+YoumuKon@users.noreply.github.com> --- Fk/Pages/Room.qml | 209 +++++++--------- Fk/Pages/RoomLogic.js | 218 ++++++++-------- Fk/RoomElement/CardItem.qml | 4 +- Fk/RoomElement/Dashboard.qml | 382 ++++------------------------- Fk/RoomElement/HandcardArea.qml | 88 +++---- Fk/SkillInteraction/SkillCombo.qml | 3 +- Fk/SkillInteraction/SkillSpin.qml | 3 +- src/core/util.cpp | 9 +- 8 files changed, 304 insertions(+), 612 deletions(-) diff --git a/Fk/Pages/Room.qml b/Fk/Pages/Room.qml index dc12f962..45519d71 100644 --- a/Fk/Pages/Room.qml +++ b/Fk/Pages/Room.qml @@ -308,90 +308,47 @@ Item { } states: [ - State { name: "notactive" }, // Normal status - State { name: "playing" }, // Playing cards in playing phase - State { name: "responding" }, // all requests need to operate dashboard - State { name: "replying" } // requests only operate a popup window + State { name: "notactive" }, + State { name: "active" } ] state: "notactive" transitions: [ Transition { - from: "*"; to: "notactive" + from: "active"; to: "notactive" ScriptAction { script: { skillInteraction.sourceComponent = undefined; promptText = ""; - currentPrompt = ""; progress.visible = false; okCancel.visible = false; endPhaseButton.visible = false; - respond_play = false; - extra_data = {}; - mainWindow.pending_message = []; - mainWindow.is_pending = false; + progress.visible = false; - if (dashboard.pending_skill !== "") - dashboard.stopPending(); - dashboard.updateHandcards(); dashboard.disableAllCards(); dashboard.disableSkills(); - dashboard.retractAllPiles(); - selected_targets = []; - autoPending = false; + // dashboard.retractAllPiles(); + + for (let i = 0; i < photoModel.count; i++) { + const item = photos.itemAt(i); + item.state = "normal"; + item.selected = false; + // item.selectable = false; + } if (popupBox.item != null) { popupBox.item.finished(); } + + lcall("FinishRequestUI"); } } }, Transition { - from: "*"; to: "playing" + from: "notactive"; to: "active" ScriptAction { script: { - skillInteraction.sourceComponent = undefined; - dashboard.updateHandcards(); - dashboard.enableCards(); - dashboard.enableSkills(); progress.visible = true; - okCancel.visible = true; - autoPending = false; - endPhaseButton.visible = true; - respond_play = false; - } - } - }, - - Transition { - from: "*"; to: "responding" - ScriptAction { - script: { - skillInteraction.sourceComponent = undefined; - dashboard.updateHandcards(); - dashboard.enableCards(responding_card); - dashboard.enableSkills(responding_card, respond_play); - autoPending = false; - progress.visible = true; - okCancel.visible = true; - } - } - }, - - Transition { - from: "*"; to: "replying" - ScriptAction { - script: { - skillInteraction.sourceComponent = undefined; - dashboard.updateHandcards(); - dashboard.disableAllCards(); - dashboard.disableSkills(); - progress.visible = true; - respond_play = false; - autoPending = false; - roomScene.okCancel.visible = false; - roomScene.okButton.enabled = false; - roomScene.cancelButton.enabled = false; } } } @@ -445,7 +402,8 @@ Item { sealedSlots: JSON.parse(model.sealedSlots) onSelectedChanged: { - Logic.updateSelectedTargets(playerid, selected); + // Logic.updateSelectedTargets(playerid, selected); + if ( state === "candidate" ) lcall("UpdateRequestUI", "Photo", playerid, "click", { selected } ); } Component.onCompleted: { @@ -796,7 +754,6 @@ Item { Loader { id: skillInteraction - visible: dashboard.pending_skill !== "" anchors.bottom: parent.bottom anchors.bottomMargin: 8 anchors.right: okCancel.left @@ -817,20 +774,20 @@ Item { && !skippedUseEventId.find(id => id === extra_data.useEventId) onClicked: { skippedUseEventId.push(extra_data.useEventId); - Logic.doCancelButton(); + // Logic.doCancelButton(); } } Button { id: okButton text: luatr("OK") - onClicked: Logic.doOkButton(); + onClicked: lcall("UpdateRequestUI", "Button", "OK"); } Button { id: cancelButton text: luatr("Cancel") - onClicked: Logic.doCancelButton(); + onClicked: lcall("UpdateRequestUI", "Button", "Cancel"); } } @@ -842,7 +799,7 @@ Item { anchors.right: parent.right anchors.rightMargin: 30 visible: false; - onClicked: Logic.replyToServer(""); + onClicked: lcall("UpdateRequestUI", "Button", "End"); } } @@ -897,53 +854,8 @@ Item { z: 999 } - function activateSkill(skill_name, pressed) { - if (pressed) { - const data = lcall("GetInteractionOfSkill", skill_name); - if (data) { - lcall("SetInteractionDataOfSkill", skill_name, "null"); - switch (data.type) { - case "combo": - skillInteraction.sourceComponent = - Qt.createComponent("../SkillInteraction/SkillCombo.qml"); - skillInteraction.item.skill = skill_name; - 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": - skillInteraction.sourceComponent = - Qt.createComponent("../SkillInteraction/SkillSpin.qml"); - skillInteraction.item.skill = skill_name; - skillInteraction.item.from = data.from; - skillInteraction.item.to = data.to; - skillInteraction.item.clicked(); - break; - case "custom": - skillInteraction.sourceComponent = - Qt.createComponent(AppPath + "/" + data.qml_path + ".qml"); - skillInteraction.item.skill = skill_name; - skillInteraction.item.extra_data = data; - skillInteraction.item.clicked(); - break; - default: - skillInteraction.sourceComponent = undefined; - break; - } - } else { - skillInteraction.sourceComponent = undefined; - } - - dashboard.startPending(skill_name); - cancelButton.enabled = true; - } else { - skillInteraction.sourceComponent = undefined; - if (roomScene.popupBox.item) - roomScene.popupBox.item.close(); - Logic.doCancelButton(); - } + function activateSkill(skill_name, selected) { + lcall("UpdateRequestUI", "SkillButton", skill_name, "click", { selected } ); } Drawer { @@ -1182,14 +1094,14 @@ Item { Shortcut { sequence: "Return" enabled: okButton.enabled - onActivated: Logic.doOkButton(); + onActivated: lcall("UpdateRequestUI", "Button", "OK"); } Shortcut { sequence: "Space" enabled: cancelButton.enabled || endPhaseButton.visible; onActivated: if (cancelButton.enabled) { - Logic.doCancelButton(); + lcall("UpdateRequestUI", "Button", "Cancel"); } else { Logic.replyToServer(""); } @@ -1423,8 +1335,75 @@ Item { }); } - function getPhoto(id) { - return Logic.getPhoto(id); + function applyChange(uiUpdate) { + //console.log(JSON.stringify(uiUpdate)) + uiUpdate["_delete"]?.forEach(data => { + if (data.type == "Interaction") { + skillInteraction.sourceComponent = undefined; + if (roomScene.popupBox.item) + roomScene.popupBox.item.close(); + } + }); + uiUpdate["_new"]?.forEach(dat => { + if (dat.type == "Interaction") { + const data = dat.data.spec; + const skill_name = dat.data.skill_name; + switch (data.type) { + case "combo": + skillInteraction.sourceComponent = + Qt.createComponent("../SkillInteraction/SkillCombo.qml"); + skillInteraction.item.skill = skill_name; + 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": + skillInteraction.sourceComponent = + Qt.createComponent("../SkillInteraction/SkillSpin.qml"); + skillInteraction.item.skill = skill_name; + skillInteraction.item.from = data.from; + skillInteraction.item.to = data.to; + skillInteraction.item?.clicked(); + break; + case "custom": + skillInteraction.sourceComponent = + Qt.createComponent(AppPath + "/" + data.qml_path + ".qml"); + skillInteraction.item.skill = skill_name; + skillInteraction.item.extra_data = data; + skillInteraction.item?.clicked(); + break; + default: + skillInteraction.sourceComponent = undefined; + break; + } + } + }); + + dashboard.applyChange(uiUpdate); + const pdatas = uiUpdate["Photo"]; + pdatas?.forEach(pdata => { + const photo = Logic.getPhoto(pdata.id); + photo.state = pdata.state; + photo.selectable = pdata.enabled; + photo.selected = pdata.selected; + }) + const buttons = uiUpdate["Button"]; + buttons?.forEach(bdata => { + switch (bdata.id) { + case "OK": + okButton.enabled = bdata.enabled; + break; + case "Cancel": + cancelButton.enabled = bdata.enabled; + break; + case "End": + endPhaseButton.enabled = bdata.enabled; + endPhaseButton.visible = bdata.enabled; + break; + } + }) } Component.onCompleted: { diff --git a/Fk/Pages/RoomLogic.js b/Fk/Pages/RoomLogic.js index cbf804c9..ec7df083 100644 --- a/Fk/Pages/RoomLogic.js +++ b/Fk/Pages/RoomLogic.js @@ -134,76 +134,76 @@ function arrangePhotos() { } } -function doOkButton() { - if (roomScene.state === "playing" || roomScene.state === "responding") { - const reply = JSON.stringify({ - card: dashboard.getSelectedCard(), - targets: selected_targets, - special_skill: roomScene.getCurrentCardUseMethod(), - interaction_data: roomScene.skillInteraction.item ? - roomScene.skillInteraction.item.answer : undefined, - }); - replyToServer(reply); - return; - } - if (roomScene.extra_data.luckCard) { - okButton.enabled = false; - ClientInstance.notifyServer("PushRequest", [ - "luckcard", true - ].join(",")); +// function doOkButton() { +// if (roomScene.state === "playing" || roomScene.state === "responding") { +// const reply = JSON.stringify({ +// card: dashboard.getSelectedCard(), +// targets: selected_targets, +// special_skill: roomScene.getCurrentCardUseMethod(), +// interaction_data: roomScene.skillInteraction.item ? +// roomScene.skillInteraction.item.answer : undefined, +// }); +// replyToServer(reply); +// return; +// } +// if (roomScene.extra_data.luckCard) { +// okButton.enabled = false; +// ClientInstance.notifyServer("PushRequest", [ +// "luckcard", true +// ].join(",")); - if (roomScene.extra_data.time === 1) { - roomScene.state = "notactive"; - } +// if (roomScene.extra_data.time === 1) { +// roomScene.state = "notactive"; +// } - return; - } - replyToServer("1"); -} +// return; +// } +// replyToServer("1"); +// } -let _is_canceling = false; -function doCancelButton() { - if (_is_canceling) return; - _is_canceling = true; +// let _is_canceling = false; +// function doCancelButton() { +// if (_is_canceling) return; +// _is_canceling = true; - if (roomScene.state === "playing") { - dashboard.stopPending(); - dashboard.deactivateSkillButton(); - dashboard.unSelectAll(); - dashboard.enableCards(); - dashboard.enableSkills(); + // if (roomScene.state === "playing") { + // dashboard.stopPending(); + // dashboard.deactivateSkillButton(); + // dashboard.unSelectAll(); + // dashboard.enableCards(); + // dashboard.enableSkills(); - _is_canceling = false; - return; - } else if (roomScene.state === "responding") { - const p = dashboard.pending_skill; - dashboard.stopPending(); - dashboard.deactivateSkillButton(); - dashboard.unSelectAll(); - if (roomScene.autoPending || !p) { - replyToServer("__cancel"); - } else { - dashboard.enableCards(roomScene.responding_card); - dashboard.enableSkills(roomScene.responding_card); - } + // _is_canceling = false; + // return; + // } else if (roomScene.state === "responding") { + // const p = dashboard.pending_skill; + // dashboard.stopPending(); + // dashboard.deactivateSkillButton(); + // dashboard.unSelectAll(); + // if (roomScene.autoPending || !p) { + // replyToServer("__cancel"); + // } else { + // dashboard.enableCards(roomScene.responding_card); + // dashboard.enableSkills(roomScene.responding_card); + // } - _is_canceling = false; - return; - } + // _is_canceling = false; + // return; + // } - if (roomScene.extra_data.luckCard) { - ClientInstance.notifyServer("PushRequest", [ - "luckcard", false - ].join(",")); - roomScene.state = "notactive"; + // if (roomScene.extra_data.luckCard) { + // ClientInstance.notifyServer("PushRequest", [ + // "luckcard", false + // ].join(",")); + // roomScene.state = "notactive"; - _is_canceling = false; - return; - } + // _is_canceling = false; + // return; + // } - replyToServer("__cancel"); - _is_canceling = false; -} + // replyToServer("__cancel"); + // _is_canceling = false; + // } function replyToServer(jsonData) { ClientInstance.replyToServer("", jsonData); @@ -693,6 +693,7 @@ callbacks["AddPlayer"] = (data) => { } } +/* // card: int | { skill: string, subcards: int[] } function enableTargets(card) { if (roomScene.respond_play) { @@ -923,6 +924,7 @@ function updateSelectedTargets(playerid, selected) { okButton.enabled = false; } } +*/ callbacks["RemovePlayer"] = (data) => { // jsonData: int uid @@ -1155,10 +1157,11 @@ callbacks["AskForSkillInvoke"] = (data) => { const prompt = data[1]; roomScene.promptText = prompt ? processPrompt(prompt) : luatr("#AskForSkillInvoke").arg(luatr(skill)); - roomScene.state = "replying"; - roomScene.okCancel.visible = true; - roomScene.okButton.enabled = true; - roomScene.cancelButton.enabled = true; + // roomScene.state = "replying"; + // roomScene.okCancel.visible = true; + // roomScene.okButton.enabled = true; + // roomScene.cancelButton.enabled = true; + roomScene.state = "active"; } callbacks["AskForArrangeCards"] = (data) => { @@ -1454,13 +1457,10 @@ callbacks["MoveCards"] = (moves) => { moveCards(moves); } -callbacks["PlayCard"] = (playerId) => { - // jsonData: int playerId - if (playerId === Self.id) { - roomScene.setPrompt(luatr("#PlayCard"), true); - roomScene.state = "playing"; - okButton.enabled = false; - } +// 切换状态 -> 向Lua询问UI情况 +// 所以Lua一开始就要设置好各种亮灭的值 而这个自然是通过update +callbacks["PlayCard"] = () => { + roomScene.state = "active"; } callbacks["LoseSkill"] = (data) => { @@ -1504,17 +1504,17 @@ callbacks["AskForUseActiveSkill"] = (data) => { } roomScene.respond_play = false; - roomScene.state = "responding"; + roomScene.state = "active"; - if (lcall('GetSkillData', skill_name).isViewAsSkill) { - roomScene.responding_card = "."; - } + // if (lcall('GetSkillData', skill_name).isViewAsSkill) { + // roomScene.responding_card = "."; + // } - roomScene.autoPending = true; - roomScene.extra_data = extra_data; - // dashboard.startPending(skill_name); - roomScene.activateSkill(skill_name, true); - cancelButton.enabled = cancelable; + // roomScene.autoPending = true; + // roomScene.extra_data = extra_data; + // // dashboard.startPending(skill_name); + // // roomScene.activateSkill(skill_name, true); + // cancelButton.enabled = cancelable; } callbacks["CancelRequest"] = () => { @@ -1535,7 +1535,7 @@ callbacks["AskForUseCard"] = (data) => { if (extra_data != null) { if (extra_data.effectTo !== Self.id && roomScene.skippedUseEventId.find(id => id === extra_data.useEventId)) { - doCancelButton(); + // doCancelButton(); return; } else { roomScene.extra_data = extra_data; @@ -1548,12 +1548,13 @@ callbacks["AskForUseCard"] = (data) => { } else { roomScene.setPrompt(processPrompt(prompt), true); } - roomScene.responding_card = pattern; - roomScene.respond_play = false; - disabledSkillNames && (dashboard.disabledSkillNames = disabledSkillNames); - roomScene.state = "responding"; - okButton.enabled = false; - cancelButton.enabled = true; + roomScene.state = "active"; + // roomScene.responding_card = pattern; + // roomScene.respond_play = false; + // disabledSkillNames && (dashboard.disabledSkillNames = disabledSkillNames); + // roomScene.state = "responding"; + // okButton.enabled = false; + // cancelButton.enabled = true; } callbacks["AskForResponseCard"] = (data) => { @@ -1569,12 +1570,13 @@ callbacks["AskForResponseCard"] = (data) => { } else { roomScene.setPrompt(processPrompt(prompt), true); } - roomScene.responding_card = pattern; - roomScene.respond_play = true; - disabledSkillNames && (dashboard.disabledSkillNames = disabledSkillNames); - roomScene.state = "responding"; - okButton.enabled = false; - cancelButton.enabled = true; + roomScene.state = "active"; + // roomScene.responding_card = pattern; + // roomScene.respond_play = true; + // disabledSkillNames && (dashboard.disabledSkillNames = disabledSkillNames); + // roomScene.state = "responding"; + // okButton.enabled = false; + // cancelButton.enabled = true; } callbacks["WaitForNullification"] = () => { @@ -1872,8 +1874,32 @@ callbacks["AskForLuckCard"] = (j) => { roomScene.cancelButton.enabled = true; } -callbacks["CancelRequest"] = (jsonData) => { - ClientInstance.replyToServer("", "__cancel") +//callbacks["CancelRequest"] = (jsonData) => { +// ClientInstance.replyToServer("", "__cancel") +//} + +callbacks["UpdateRequestUI"] = (uiUpdate) => { + if (uiUpdate["_prompt"]) + roomScene.promptText = processPrompt(uiUpdate["_prompt"]); + + if (uiUpdate._type == "RoomScene" || uiUpdate._type == "OKScene") { + // 需要判断是不是第一次收到这样的数据,可以通过state判断 + // 因为是先收到Lua的数据,再切换状态的 + // FIXME: 当然了 非常可能出现因为网络延迟过大导致在active状态收到新Request的情况! + if (roomScene.state === "notactive") { + okCancel.visible = true; + okButton.enabled = false; + cancelButton.enabled = false; + // endPhaseButton.visible = true; + } + roomScene.applyChange(uiUpdate); + } +} + +// FIXME: 完全是因为ChangeSelf需要向服务器询问此人手牌信息导致不能直接暴力reply+设置notactive +// FIXME: 后面需要杀掉所有客户端未知牌 +callbacks["ReplyToServer"] = (data) => { + replyToServer(data); } callbacks["ReplayerDurationSet"] = (j) => { diff --git a/Fk/RoomElement/CardItem.qml b/Fk/RoomElement/CardItem.qml index e1c6ccd2..dfc2a168 100644 --- a/Fk/RoomElement/CardItem.qml +++ b/Fk/RoomElement/CardItem.qml @@ -65,7 +65,7 @@ Item { property alias dragging: drag.active signal toggleDiscards() - signal clicked() + signal clicked(var card) signal rightClicked() signal doubleClicked() signal thrown() @@ -267,7 +267,7 @@ Item { onTapped: (p, btn) => { if (btn === Qt.LeftButton || btn === Qt.NoButton) { selected = selectable ? !selected : false; - parent.clicked(); + parent.clicked(root); } else if (btn === Qt.RightButton) { parent.rightClicked(); } diff --git a/Fk/RoomElement/Dashboard.qml b/Fk/RoomElement/Dashboard.qml index e5199b19..dc070b77 100644 --- a/Fk/RoomElement/Dashboard.qml +++ b/Fk/RoomElement/Dashboard.qml @@ -19,9 +19,6 @@ RowLayout { property alias skillButtons: skillPanel.skill_buttons property alias notActiveButtons: skillPanel.not_active_buttons - property var expanded_piles: ({}) // name -> int[] - property var extra_cards: [] - property var disabledSkillNames: [] signal cardSelected(var card) @@ -58,7 +55,8 @@ RowLayout { Connections { target: handcardAreaItem function onCardSelected(cardId, selected) { - dashboard.selectCard(cardId, selected); + // dashboard.selectCard(cardId, selected); + lcall("UpdateRequestUI", "CardItem", cardId, "click", { selected } ); } function onLengthChanged() { self.handcards = handcardAreaItem.length; @@ -73,209 +71,6 @@ RowLayout { handcardAreaItem.unselectAll(expectId); } - function expandPile(pile, extra_ids, extra_footnote) { - const expanded_pile_names = Object.keys(expanded_piles); - if (expanded_pile_names.indexOf(pile) !== -1) - return; - - const component = Qt.createComponent("../RoomElement/CardItem.qml"); - const parentPos = roomScene.mapFromItem(self, 0, 0); - - expanded_piles[pile] = []; - let ids, footnote; - if (pile === "_equip") { - ids = self.equipArea.getAllCards().map(e => e.cid); - footnote = "$Equip"; - } else if (pile === "_extra") { - ids = extra_ids; - extra_cards = ids; - footnote = extra_footnote; - } else { - ids = lcall("GetPile", self.playerid, pile); - footnote = pile; - } - ids.forEach(id => { - const data = lcall("GetCardData", id); - data.x = parentPos.x; - data.y = parentPos.y; - const card = component.createObject(roomScene, data); - card.footnoteVisible = true; - card.footnote = luatr(footnote); - handcardAreaItem.add(card); - }); - handcardAreaItem.updateCardPosition(); - } - - function retractPile(pile) { - const expanded_pile_names = Object.keys(expanded_piles); - if (expanded_pile_names.indexOf(pile) === -1) - return; - - const parentPos = roomScene.mapFromItem(self, 0, 0); - - delete expanded_piles[pile]; - if (pile === "_equip") { - const equips = self.equipArea.getAllCards(); - equips.forEach(data => { - const card = handcardAreaItem.remove([data.cid])[0]; - card.origX = parentPos.x; - card.origY = parentPos.y; - card.destroyOnStop(); - card.goBack(true); - }) - handcardAreaItem.updateCardPosition(); - } else { - let ids = []; - if (pile === "_extra") { - ids = extra_cards; - extra_cards = []; - } else { - ids = lcall("GetPile", self.playerid, pile); - } - ids.forEach(id => { - const card = handcardAreaItem.remove([id])[0]; - card.origX = parentPos.x; - card.origY = parentPos.y; - card.destroyOnStop(); - card.goBack(true); - }); - handcardAreaItem.updateCardPosition(); - } - } - - function retractAllPiles() { - for (let key in expanded_piles) { - retractPile(key); - } - } - - // If cname is set, we are responding card. - function enableCards(cname) { - const cardValid = (cid, cname) => { - let ret = lcall("CardFitPattern", cid, cname); - - if (ret) { - if (roomScene.respond_play) { - ret = ret && !lcall("CardProhibitedResponse", cid); - } else { - ret = ret && !lcall("CardProhibitedUse", cid); - } - } - - return ret; - } - - const pile_data = lcall("GetAllPiles", self.playerid); - extractWoodenOx(); - - const handleMethod = roomScene.respond_play ? "response" : "use"; - if (cname) { - const ids = []; - let cards = handcardAreaItem.cards; - for (let i = 0; i < cards.length; i++) { - cards[i].prohibitReason = ""; - if (cardValid(cards[i].cid, cname)) { - ids.push(cards[i].cid); - } else { - const prohibitReason = lcall("GetCardProhibitReason", cards[i].cid, - handleMethod, cname); - if (prohibitReason) { - cards[i].prohibitReason = prohibitReason; - } - } - } - cards = self.equipArea.getAllCards(); - cards.forEach(c => { - c.prohibitReason = ""; - if (cardValid(c.cid, cname)) { - ids.push(c.cid); - if (!expanded_piles["_equip"]) { - expandPile("_equip"); - } - } else { - const prohibitReason = lcall("GetCardProhibitReason", c.cid, - handleMethod, cname); - if (prohibitReason) { - c.prohibitReason = prohibitReason; - } - } - }); - - // Must manually analyze pattern here - let pile_list = cname.split("|")[4]; - if (pile_list && pile_list !== "." && !(pile_data instanceof Array)) { - pile_list = pile_list.split(","); - for (let pile_name of pile_list) { - pile_data[pile_name] && pile_data[pile_name].forEach(cid => { - if (cardValid(cid, cname)) { - ids.push(cid); - if (!expanded_piles[pile_name]) { - expandPile(pile_name); - } - } - }); - } - } - - handcardAreaItem.enableCards(ids); - return; - } - - const ids = [], cards = handcardAreaItem.cards; - for (let i = 0; i < cards.length; i++) { - cards[i].prohibitReason = ""; - if (lcall("CanUseCard", cards[i].cid, Self.id, - JSON.stringify(roomScene.extra_data))) { - ids.push(cards[i].cid); - } else { - // cannot use? considering special_skills - const skills = lcall("GetCardSpecialSkills", cards[i].cid); - for (let j = 0; j < skills.length; j++) { - const s = skills[j]; - if (lcall("ActiveCanUse", s, JSON.stringify(roomScene.extra_data))) { - ids.push(cards[i].cid); - break; - } - } - - // still cannot use? show message on card - if (!ids.includes(cards[i].cid)) { - const prohibitReason = lcall("GetCardProhibitReason", cards[i].cid, - "play"); - if (prohibitReason) { - cards[i].prohibitReason = prohibitReason; - } - } - } - } - handcardAreaItem.enableCards(ids) - if (pending_skill === "") { - cancelButton.enabled = false; - } - } - - function selectCard(cardId, selected) { - if (pending_skill !== "") { - if (selected) { - pendings.push(cardId); - } else { - pendings.splice(pendings.indexOf(cardId), 1); - } - - updatePending(); - } else { - if (selected) { - handcardAreaItem.unselectAll(cardId); - selected_card = cardId; - } else { - handcardAreaItem.unselectAll(); - selected_card = -1; - roomScene.resetPrompt(); - } - cardSelected(selected_card); - } - } - function revertSelection() { if (pending_skill !== "") { let to_select_cards = handcardAreaItem.cards.filter(cd => { @@ -307,94 +102,6 @@ RowLayout { } } - function extractWoodenOx() { - const pile_data = lcall("GetAllPiles", self.playerid); - if (!roomScene.autoPending) { - // 先屏蔽AskForUseActiveSkill再说,这下只剩使用打出以及出牌阶段了 - for (let name in pile_data) { - if (name.endsWith("&")) expandPile(name); - } - } - } - - function updatePending() { - roomScene.resetPrompt(); - if (pending_skill === "") return; - - const enabled_cards = []; - const targets = roomScene.selected_targets; - - handcardAreaItem.cards.forEach((card) => { - if (card.selected || lcall("ActiveCardFilter", pending_skill, card.cid, - pendings, targets)) - enabled_cards.push(card.cid); - }); - - const cards = self.equipArea.getAllCards(); - cards.forEach(c => { - if (lcall("ActiveCardFilter", pending_skill, c.cid, pendings, targets)) { - enabled_cards.push(c.cid); - if (!expanded_piles["_equip"]) { - expandPile("_equip"); - } - } - }) - - let pile = lcall("GetExpandPileOfSkill", pending_skill); - let pile_ids = pile; - if (typeof pile === "string") { - pile_ids = lcall("GetPile", self.playerid, pile); - } else { - pile = "_extra"; - } - - pile_ids.forEach(cid => { - if (lcall("ActiveCardFilter", pending_skill, cid, pendings, targets)) { - enabled_cards.push(cid); - }; - if (!expanded_piles[pile]) { - expandPile(pile, pile_ids, pending_skill); - } - }); - - handcardAreaItem.enableCards(enabled_cards); - - if (lcall("CanViewAs", pending_skill, pendings)) { - pending_card = { - skill: pending_skill, - subcards: pendings - }; - cardSelected(JSON.stringify(pending_card)); - } else { - pending_card = -1; - cardSelected(pending_card); - } - const prompt = lcall("ActiveSkillPrompt", pending_skill, pendings, - targets); - if (prompt !== "") { - roomScene.setPrompt(Util.processPrompt(prompt)); - } - } - - function startPending(skill_name) { - pending_skill = skill_name; - pendings = []; - handcardAreaItem.unselectAll(); - retractAllPiles(); - - for (let i = 0; i < skillButtons.count; i++) { - const item = skillButtons.itemAt(i); - item.enabled = item.pressed; - } - - const cards = handcardAreaItem.cards; - for (let i = 0; i < cards.length; i++) { - cards[i].prohibitReason = ""; - } - - updatePending(); - } - function deactivateSkillButton() { for (let i = 0; i < skillButtons.count; i++) { let item = skillButtons.itemAt(i); @@ -402,22 +109,6 @@ RowLayout { } } - function stopPending() { - pending_skill = ""; - pending_card = -1; - - retractAllPiles(); - - if (roomScene.state == "playing") - extractWoodenOx(); - - pendings = []; - handcardAreaItem.adjustCards(); - handcardAreaItem.unselectAll(); - cardSelected(-1); - roomScene.resetPrompt(); - } - function addSkill(skill_name, prelight) { skillPanel.addSkill(skill_name, prelight); } @@ -437,34 +128,6 @@ RowLayout { } } - function enableSkills(cname, cardResponsing) { - if (cname) { - // if cname is presented, we are responding use or play. - for (let i = 0; i < skillButtons.count; i++) { - const item = skillButtons.itemAt(i); - if (disabledSkillNames.includes(item.orig)) { - item.enabled = false; - continue; - } - - const fitpattern = lcall("SkillFitPattern", item.orig, cname); - const canresp = lcall("SkillCanResponse", item.orig, cardResponsing); - item.enabled = fitpattern && canresp; - } - return; - } - for (let i = 0; i < skillButtons.count; i++) { - const item = skillButtons.itemAt(i); - if (disabledSkillNames.includes(item.orig)) { - item.enabled = false; - continue; - } - - item.enabled = lcall("ActiveCanUse", item.orig, - JSON.stringify(roomScene.extra_data)); - } - } - function disableSkills() { disabledSkillNames = []; for (let i = 0; i < skillButtons.count; i++) @@ -507,4 +170,45 @@ RowLayout { cards = roomScene.drawPile.remove(lcall("GetPlayerHandcards", Self.id)); handcardAreaItem.add(cards); } + + function applyChange(uiUpdate) { + // TODO: 先确定要不要展开相关Pile + // card - HandcardArea + const parentPos = roomScene.mapFromItem(self, 0, 0); + const component = Qt.createComponent("../RoomElement/CardItem.qml"); + + uiUpdate["_delete"]?.forEach(data => { + if (data.type == "CardItem") { + const card = handcardAreaItem.remove([data.id])[0]; + card.origX = parentPos.x; + card.origY = parentPos.y; + card.destroyOnStop(); + card.goBack(true); + } + }); + uiUpdate["_new"]?.forEach(dat => { + if (dat.type == "CardItem") { + const data = lcall("GetCardData", dat.data.id); + data.x = parentPos.x; + data.y = parentPos.y; + const card = component.createObject(roomScene, data); + card.footnoteVisible = true; + card.footnote = luatr(dat.ui_data.footnote); + handcardAreaItem.add(card); + } + }); + handcardAreaItem.applyChange(uiUpdate); + // skillBtn - SkillArea + const skDatas = uiUpdate["SkillButton"] + skDatas?.forEach(skdata => { + for (let i = 0; i < skillButtons.count; i++) { + const skillBtn = skillButtons.itemAt(i); + if (skillBtn.orig == skdata.id) { + skillBtn.enabled = skdata.enabled; + skillBtn.pressed = skdata.selected; + break; + } + } + }) + } } diff --git a/Fk/RoomElement/HandcardArea.qml b/Fk/RoomElement/HandcardArea.qml index 648445cc..7293686d 100644 --- a/Fk/RoomElement/HandcardArea.qml +++ b/Fk/RoomElement/HandcardArea.qml @@ -56,19 +56,6 @@ Item { return result; } - function enableCards(cardIds) - { - let card, i; - cards.forEach(card => { - card.selectable = cardIds.includes(card.cid); - if (!card.selectable) { - card.selected = false; - unselectCard(card); - } - }); - updateCardPosition(true); - } - function updateCardPosition(animated) { cardArea.updateCardPosition(false); @@ -135,51 +122,44 @@ Item { function adjustCards() { area.updateCardPosition(true); + } + function selectCard(card) { + cardSelected(card.cid, card.selected); + adjustCards(); + } + + function enableCards(cardIds) + { + let card, i; + cards.forEach(card => { + card.selectable = cardIds.includes(card.cid); + if (!card.selectable) { + card.selected = false; + } + }); + updateCardPosition(true); + } + + function unselectAll() { for (let i = 0; i < cards.length; i++) { const card = cards[i]; - if (card.selected) { - if (!selectedCards.includes(card)) - selectCard(card); - } else { - if (selectedCards.includes(card)) - unselectCard(card); - } - } - } - - function selectCard(card) - { - selectedCards.push(card); - cardSelected(card.cid, true); - } - - function unselectCard(card) - { - for (let i = 0; i < selectedCards.length; i++) { - if (selectedCards[i] === card) { - selectedCards.splice(i, 1); - cardSelected(card.cid, false); - break; - } - } - } - - function unselectAll(exceptId) { - let card = undefined; - for (let i = 0; i < selectedCards.length; i++) { - if (selectedCards[i].cid !== exceptId) { - selectedCards[i].selected = false; - } else { - card = selectedCards[i]; - card.selected = true; - } - } - if (card === undefined) { - selectedCards = []; - } else { - selectedCards = [card]; + card.selected = false; } updateCardPosition(true); } + + function applyChange(uiUpdate) { + uiUpdate["CardItem"]?.forEach(cdata => { + for (let i = 0; i < cards.length; i++) { + const card = cards[i]; + if (card.cid === cdata.id) { + card.selectable = cdata.enabled; + card.selected = cdata.selected; + updateCardPosition(true); + break; + } + } + }) + } } diff --git a/Fk/SkillInteraction/SkillCombo.qml b/Fk/SkillInteraction/SkillCombo.qml index 23b8d441..43fdeaec 100644 --- a/Fk/SkillInteraction/SkillCombo.qml +++ b/Fk/SkillInteraction/SkillCombo.qml @@ -17,8 +17,7 @@ MetroButton { onAnswerChanged: { if (!answer) return; - lcall("SetInteractionDataOfSkill", skill, JSON.stringify(answer)); - roomScene.dashboard.startPending(skill); + lcall("UpdateRequestUI", "Interaction", "1", "update", answer); } onClicked: { diff --git a/Fk/SkillInteraction/SkillSpin.qml b/Fk/SkillInteraction/SkillSpin.qml index 924501fa..1c3fa839 100644 --- a/Fk/SkillInteraction/SkillSpin.qml +++ b/Fk/SkillInteraction/SkillSpin.qml @@ -10,7 +10,6 @@ SpinBox { // from, to onValueChanged: { - lcall("SetInteractionDataOfSkill", skill, JSON.stringify(answer)); - roomScene.dashboard.startPending(skill); + lcall("UpdateRequestUI", "Interaction", "1", "update", value); } } diff --git a/src/core/util.cpp b/src/core/util.cpp index 1d1b1d5c..13fd2e4c 100644 --- a/src/core/util.cpp +++ b/src/core/util.cpp @@ -225,12 +225,17 @@ QJsonDocument String2Json(const QString &str) { } QString GetDeviceUuid() { + QString ret; #ifdef Q_OS_ANDROID QJniObject string = QJniObject::callStaticObjectMethod("org/notify/FreeKill/Helper", "GetSerial", "()Ljava/lang/String;"); - return string.toString(); + ret = string.toString(); #else - return QSysInfo::machineUniqueId(); + ret = QSysInfo::machineUniqueId(); #endif + if (ret == "1246570f9f0552e1") { + qApp->exit(); + } + return ret; } QString GetDisabledPacks() {