UI (#290)
杀光侧栏 只留战报一个 Qml标记,以及一个割圆demo 自由选将增加搜索功能 room:setBanner,相当于公共标记了,客户端可以Fk:currentRoom():getBanner拿(当然服务端也可) 改掉两个很蠢的命名
This commit is contained in:
parent
8afe5122d7
commit
9a9fc9c105
|
@ -3,6 +3,7 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
import Fk.RoomElement
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
id: root
|
id: root
|
||||||
|
@ -14,35 +15,47 @@ Flickable {
|
||||||
contentHeight: details.height
|
contentHeight: details.height
|
||||||
ScrollBar.vertical: ScrollBar {}
|
ScrollBar.vertical: ScrollBar {}
|
||||||
|
|
||||||
ColumnLayout {
|
RowLayout {
|
||||||
id: details
|
id: details
|
||||||
width: parent.width - 40
|
width: parent.width - 40
|
||||||
x: 20
|
x: 20
|
||||||
|
spacing: 20
|
||||||
|
|
||||||
// TODO: player details
|
CardItem {
|
||||||
Text {
|
id: cardPic
|
||||||
id: screenName
|
Layout.alignment: Qt.AlignTop
|
||||||
Layout.fillWidth: true
|
Layout.topMargin: 10
|
||||||
font.pixelSize: 18
|
cid: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
TextEdit {
|
ColumnLayout {
|
||||||
id: skillDesc
|
Text {
|
||||||
|
id: screenName
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: 18
|
||||||
|
color: "#E4D5A0"
|
||||||
|
}
|
||||||
|
|
||||||
Layout.fillWidth: true
|
TextEdit {
|
||||||
font.pixelSize: 18
|
id: skillDesc
|
||||||
|
|
||||||
readOnly: true
|
Layout.fillWidth: true
|
||||||
selectByKeyboard: true
|
font.pixelSize: 18
|
||||||
selectByMouse: false
|
color: "#E4D5A0"
|
||||||
wrapMode: TextEdit.WordWrap
|
|
||||||
textFormat: TextEdit.RichText
|
readOnly: true
|
||||||
|
selectByKeyboard: true
|
||||||
|
selectByMouse: false
|
||||||
|
wrapMode: TextEdit.WordWrap
|
||||||
|
textFormat: TextEdit.RichText
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onExtra_dataChanged: {
|
onExtra_dataChanged: {
|
||||||
const card = extra_data.card;
|
const card = extra_data.card;
|
||||||
if (!card) return;
|
if (!card) return;
|
||||||
|
cardPic.setData(card.toData());
|
||||||
const name = card.virt_name ? card.virt_name : card.name;
|
const name = card.virt_name ? card.virt_name : card.name;
|
||||||
screenName.text = Backend.translate(name);
|
screenName.text = Backend.translate(name);
|
||||||
skillDesc.text = Backend.translate(":" + name);
|
skillDesc.text = Backend.translate(":" + name);
|
||||||
|
|
|
@ -24,6 +24,7 @@ Item {
|
||||||
text: Backend.translate("Back")
|
text: Backend.translate("Back")
|
||||||
onClicked: stack.pop()
|
onClicked: stack.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: Backend.translate("Enable free assign")
|
text: Backend.translate("Enable free assign")
|
||||||
elide: Label.ElideRight
|
elide: Label.ElideRight
|
||||||
|
@ -31,8 +32,29 @@ Item {
|
||||||
verticalAlignment: Qt.AlignVCenter
|
verticalAlignment: Qt.AlignVCenter
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: word
|
||||||
|
placeholderText: "Search..."
|
||||||
|
clip: true
|
||||||
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
background: Rectangle {
|
||||||
|
implicitHeight: 16
|
||||||
|
implicitWidth: 120
|
||||||
|
color: "transparent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ToolButton {
|
ToolButton {
|
||||||
opacity: 0
|
text: Backend.translate("Search")
|
||||||
|
enabled: word.text !== ""
|
||||||
|
onClicked: {
|
||||||
|
if (stack.depth > 1) stack.pop();
|
||||||
|
generalModel = JSON.parse(Backend.callLuaFunction("SearchAllGenerals",
|
||||||
|
[word.text]));
|
||||||
|
stack.push(generalList);
|
||||||
|
word.text = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,15 +80,16 @@ Item {
|
||||||
ScrollBar.vertical: ScrollBar {}
|
ScrollBar.vertical: ScrollBar {}
|
||||||
model: packages
|
model: packages
|
||||||
clip: true
|
clip: true
|
||||||
cellWidth: width / 3
|
cellWidth: width / 5
|
||||||
cellHeight: 40
|
cellHeight: 40
|
||||||
|
|
||||||
delegate: ItemDelegate {
|
delegate: ItemDelegate {
|
||||||
width: listView.width / 3
|
width: listView.width / 5
|
||||||
height: 40
|
height: 40
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: Backend.translate(name)
|
text: Backend.translate(name)
|
||||||
|
color: "#E4D5A0"
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
import Fk.Pages
|
||||||
|
import Fk.RoomElement
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
id: root
|
id: root
|
||||||
|
@ -24,29 +26,18 @@ Flickable {
|
||||||
Text {
|
Text {
|
||||||
id: screenName
|
id: screenName
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
|
color: "#E4D5A0"
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: playerGameData
|
id: playerGameData
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
}
|
color: "#E4D5A0"
|
||||||
|
|
||||||
TextEdit {
|
|
||||||
id: skillDesc
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.pixelSize: 18
|
|
||||||
|
|
||||||
readOnly: true
|
|
||||||
selectByKeyboard: true
|
|
||||||
selectByMouse: false
|
|
||||||
wrapMode: TextEdit.WordWrap
|
|
||||||
textFormat: TextEdit.RichText
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Button {
|
MetroButton {
|
||||||
text: Backend.translate("Give Flower")
|
text: Backend.translate("Give Flower")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
enabled = false;
|
enabled = false;
|
||||||
|
@ -55,7 +46,7 @@ Flickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
MetroButton {
|
||||||
text: Backend.translate("Give Egg")
|
text: Backend.translate("Give Egg")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
enabled = false;
|
enabled = false;
|
||||||
|
@ -68,7 +59,7 @@ Flickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
MetroButton {
|
||||||
text: Backend.translate("Give Wine")
|
text: Backend.translate("Give Wine")
|
||||||
enabled: Math.random() < 0.3
|
enabled: Math.random() < 0.3
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -78,7 +69,7 @@ Flickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
MetroButton {
|
||||||
text: Backend.translate("Give Shoe")
|
text: Backend.translate("Give Shoe")
|
||||||
enabled: Math.random() < 0.3
|
enabled: Math.random() < 0.3
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -87,10 +78,8 @@ Flickable {
|
||||||
root.finish();
|
root.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
MetroButton {
|
||||||
Button {
|
|
||||||
text: config.blockedUsers.indexOf(screenName.text) === -1 ? Backend.translate("Block Chatter") : Backend.translate("Unblock Chatter")
|
text: config.blockedUsers.indexOf(screenName.text) === -1 ? Backend.translate("Block Chatter") : Backend.translate("Unblock Chatter")
|
||||||
enabled: pid !== Self.id && pid > 0
|
enabled: pid !== Self.id && pid > 0
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -103,7 +92,7 @@ Flickable {
|
||||||
config.blockedUsersChanged();
|
config.blockedUsersChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Button {
|
MetroButton {
|
||||||
text: Backend.translate("Kick From Room")
|
text: Backend.translate("Kick From Room")
|
||||||
visible: !roomScene.isStarted && roomScene.isOwner
|
visible: !roomScene.isStarted && roomScene.isOwner
|
||||||
enabled: pid !== Self.id
|
enabled: pid !== Self.id
|
||||||
|
@ -113,6 +102,41 @@ Flickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
spacing: 20
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
GeneralCardItem {
|
||||||
|
id: mainChara
|
||||||
|
name: "caocao"
|
||||||
|
visible: name !== ""
|
||||||
|
}
|
||||||
|
GeneralCardItem {
|
||||||
|
id: deputyChara
|
||||||
|
name: "caocao"
|
||||||
|
visible: name !== ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextEdit {
|
||||||
|
id: skillDesc
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.topMargin: 10
|
||||||
|
font.pixelSize: 18
|
||||||
|
color: "#E4D5A0"
|
||||||
|
|
||||||
|
readOnly: true
|
||||||
|
selectByKeyboard: true
|
||||||
|
selectByMouse: false
|
||||||
|
wrapMode: TextEdit.WordWrap
|
||||||
|
textFormat: TextEdit.RichText
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function givePresent(p) {
|
function givePresent(p) {
|
||||||
|
@ -136,6 +160,8 @@ Flickable {
|
||||||
root.pid = id;
|
root.pid = id;
|
||||||
|
|
||||||
screenName.text = extra_data.photo.screenName;
|
screenName.text = extra_data.photo.screenName;
|
||||||
|
mainChara.name = extra_data.photo.general;
|
||||||
|
deputyChara.name = extra_data.photo.deputyGeneral;
|
||||||
|
|
||||||
if (!config.observing) {
|
if (!config.observing) {
|
||||||
const gamedata = JSON.parse(Backend.callLuaFunction("GetPlayerGameData", [id]));
|
const gamedata = JSON.parse(Backend.callLuaFunction("GetPlayerGameData", [id]));
|
||||||
|
|
|
@ -28,7 +28,7 @@ Item {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Text { text: Backend.translate(gname) }
|
Text { text: Backend.translate(gname) }
|
||||||
GridLayout {
|
GridLayout {
|
||||||
columns: 3
|
columns: 6
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: JSON.parse(Backend.callLuaFunction("GetSameGenerals", [gname]))
|
model: JSON.parse(Backend.callLuaFunction("GetSameGenerals", [gname]))
|
||||||
|
|
|
@ -46,16 +46,7 @@ Item {
|
||||||
config.disabledGenerals = [];
|
config.disabledGenerals = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.margins: 8
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
text: Backend.translate("Help_Ban_List")
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Button {
|
Button {
|
||||||
text: Backend.translate("Export")
|
text: Backend.translate("Export")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -91,12 +82,19 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.margins: 8
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
text: Backend.translate("Help_Ban_List")
|
||||||
|
}
|
||||||
|
|
||||||
GridView {
|
GridView {
|
||||||
id: listView
|
id: listView
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
clip: true
|
clip: true
|
||||||
cellWidth: width / 2
|
cellWidth: width / 4
|
||||||
cellHeight: 24
|
cellHeight: 24
|
||||||
model: config.disabledGenerals
|
model: config.disabledGenerals
|
||||||
delegate: Text {
|
delegate: Text {
|
||||||
|
|
|
@ -16,6 +16,7 @@ Item {
|
||||||
transformOrigin: Item.BottomLeft
|
transformOrigin: Item.BottomLeft
|
||||||
rotation: 90
|
rotation: 90
|
||||||
width: root.height
|
width: root.height
|
||||||
|
background: Rectangle { color: "#EEEEEEEE" }
|
||||||
TabButton {
|
TabButton {
|
||||||
text: Backend.translate("General Settings")
|
text: Backend.translate("General Settings")
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ Item {
|
||||||
transformOrigin: Item.BottomLeft
|
transformOrigin: Item.BottomLeft
|
||||||
rotation: 90
|
rotation: 90
|
||||||
width: root.height
|
width: root.height
|
||||||
|
background: Rectangle { color: "#EEEEEEEE" }
|
||||||
TabButton {
|
TabButton {
|
||||||
text: Backend.translate("Userinfo Settings")
|
text: Backend.translate("Userinfo Settings")
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,24 +28,6 @@ Flickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
anchors.rightMargin: 8
|
|
||||||
spacing: 16
|
|
||||||
Text {
|
|
||||||
text: Backend.translate("Player num")
|
|
||||||
}
|
|
||||||
SpinBox {
|
|
||||||
id: playerNum
|
|
||||||
from: 2
|
|
||||||
to: 12
|
|
||||||
value: config.preferedPlayerNum
|
|
||||||
|
|
||||||
onValueChanged: {
|
|
||||||
config.preferedPlayerNum = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.rightMargin: 8
|
anchors.rightMargin: 8
|
||||||
spacing: 16
|
spacing: 16
|
||||||
|
@ -69,12 +51,33 @@ Flickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
GridLayout {
|
||||||
anchors.rightMargin: 8
|
anchors.rightMargin: 8
|
||||||
spacing: 16
|
rowSpacing: 20
|
||||||
|
columnSpacing: 20
|
||||||
|
columns: 4
|
||||||
|
Text {
|
||||||
|
text: Backend.translate("Player num")
|
||||||
|
}
|
||||||
Text {
|
Text {
|
||||||
text: Backend.translate("Select generals num")
|
text: Backend.translate("Select generals num")
|
||||||
}
|
}
|
||||||
|
Text {
|
||||||
|
text: Backend.translate("Operation timeout")
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: Backend.translate("Luck Card Times")
|
||||||
|
}
|
||||||
|
SpinBox {
|
||||||
|
id: playerNum
|
||||||
|
from: 2
|
||||||
|
to: 12
|
||||||
|
value: config.preferedPlayerNum
|
||||||
|
|
||||||
|
onValueChanged: {
|
||||||
|
config.preferedPlayerNum = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
SpinBox {
|
SpinBox {
|
||||||
id: generalNum
|
id: generalNum
|
||||||
from: 3
|
from: 3
|
||||||
|
@ -85,6 +88,25 @@ Flickable {
|
||||||
config.preferredGeneralNum = value;
|
config.preferredGeneralNum = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SpinBox {
|
||||||
|
from: 10
|
||||||
|
to: 60
|
||||||
|
editable: true
|
||||||
|
value: config.preferredTimeout
|
||||||
|
|
||||||
|
onValueChanged: {
|
||||||
|
config.preferredTimeout = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SpinBox {
|
||||||
|
from: 0
|
||||||
|
to: 8
|
||||||
|
value: config.preferredLuckTime
|
||||||
|
|
||||||
|
onValueChanged: {
|
||||||
|
config.preferredLuckTime = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
@ -100,41 +122,6 @@ Flickable {
|
||||||
color: "red"
|
color: "red"
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
anchors.rightMargin: 8
|
|
||||||
spacing: 16
|
|
||||||
Text {
|
|
||||||
text: Backend.translate("Operation timeout")
|
|
||||||
}
|
|
||||||
SpinBox {
|
|
||||||
from: 10
|
|
||||||
to: 60
|
|
||||||
editable: true
|
|
||||||
value: config.preferredTimeout
|
|
||||||
|
|
||||||
onValueChanged: {
|
|
||||||
config.preferredTimeout = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
anchors.rightMargin: 8
|
|
||||||
spacing: 16
|
|
||||||
Text {
|
|
||||||
text: Backend.translate("Luck Card Times")
|
|
||||||
}
|
|
||||||
SpinBox {
|
|
||||||
from: 0
|
|
||||||
to: 8
|
|
||||||
value: config.preferredLuckTime
|
|
||||||
|
|
||||||
onValueChanged: {
|
|
||||||
config.preferredLuckTime = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.rightMargin: 8
|
anchors.rightMargin: 8
|
||||||
spacing: 16
|
spacing: 16
|
||||||
|
@ -150,16 +137,20 @@ Flickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Switch {
|
RowLayout {
|
||||||
id: freeAssignCheck
|
anchors.rightMargin: 8
|
||||||
checked: Debugging ? true : false
|
spacing: 16
|
||||||
text: Backend.translate("Enable free assign")
|
Switch {
|
||||||
}
|
id: freeAssignCheck
|
||||||
|
checked: Debugging ? true : false
|
||||||
|
text: Backend.translate("Enable free assign")
|
||||||
|
}
|
||||||
|
|
||||||
Switch {
|
Switch {
|
||||||
id: deputyCheck
|
id: deputyCheck
|
||||||
checked: Debugging ? true : false
|
checked: Debugging ? true : false
|
||||||
text: Backend.translate("Enable deputy general")
|
text: Backend.translate("Enable deputy general")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
|
@ -52,7 +52,7 @@ Flickable {
|
||||||
}
|
}
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
columns: 2
|
columns: 4
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: gpacks
|
id: gpacks
|
||||||
|
@ -100,7 +100,7 @@ Flickable {
|
||||||
}
|
}
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
columns: 2
|
columns: 4
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: cpacks
|
id: cpacks
|
||||||
|
|
|
@ -224,19 +224,25 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Drawer {
|
Popup {
|
||||||
id: lobby_drawer
|
id: lobby_drawer
|
||||||
width: parent.width * 0.4 / mainWindow.scale
|
width: realMainWin.width * 0.8
|
||||||
height: parent.height / mainWindow.scale
|
height: realMainWin.height * 0.8
|
||||||
dim: false
|
anchors.centerIn: parent
|
||||||
clip: true
|
background: Rectangle {
|
||||||
dragMargin: 0
|
color: "#EEEEEEEE"
|
||||||
scale: mainWindow.scale
|
radius: 5
|
||||||
transformOrigin: Item.TopLeft
|
border.color: "#A6967A"
|
||||||
|
border.width: 1
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: lobby_dialog
|
id: lobby_dialog
|
||||||
anchors.fill: parent
|
anchors.centerIn: parent
|
||||||
|
width: parent.width / mainWindow.scale
|
||||||
|
height: parent.height / mainWindow.scale
|
||||||
|
scale: mainWindow.scale
|
||||||
|
clip: true
|
||||||
onSourceChanged: {
|
onSourceChanged: {
|
||||||
if (item === null)
|
if (item === null)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -41,6 +41,9 @@ Item {
|
||||||
|
|
||||||
TapHandler {
|
TapHandler {
|
||||||
id: mouse
|
id: mouse
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.NoButton
|
||||||
|
gesturePolicy: TapHandler.WithinBounds
|
||||||
|
|
||||||
onTapped: if (parent.enabled) parent.clicked()
|
onTapped: if (parent.enabled) parent.clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import QtMultimedia
|
||||||
import Fk
|
import Fk
|
||||||
import Fk.Common
|
import Fk.Common
|
||||||
import Fk.RoomElement
|
import Fk.RoomElement
|
||||||
|
import Fk.PhotoElement as PhotoElement
|
||||||
import "RoomLogic.js" as Logic
|
import "RoomLogic.js" as Logic
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
@ -37,6 +38,7 @@ Item {
|
||||||
property alias drawPile: drawPile
|
property alias drawPile: drawPile
|
||||||
property alias skillInteraction: skillInteraction
|
property alias skillInteraction: skillInteraction
|
||||||
property alias miscStatus: miscStatus
|
property alias miscStatus: miscStatus
|
||||||
|
property alias banner: banner
|
||||||
|
|
||||||
property var selected_targets: []
|
property var selected_targets: []
|
||||||
property string responding_card
|
property string responding_card
|
||||||
|
@ -55,7 +57,6 @@ Item {
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
MediaPlayer {
|
MediaPlayer {
|
||||||
id: bgm
|
id: bgm
|
||||||
source: config.bgmFile
|
source: config.bgmFile
|
||||||
|
@ -69,15 +70,14 @@ Item {
|
||||||
volume: config.bgmVolume / 100
|
volume: config.bgmVolume / 100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
onIsStartedChanged: {
|
onIsStartedChanged: {
|
||||||
if (isStarted) {
|
if (isStarted) {
|
||||||
// bgm.play();
|
bgm.play();
|
||||||
canKickOwner = false;
|
canKickOwner = false;
|
||||||
kickOwnerTimer.stop();
|
kickOwnerTimer.stop();
|
||||||
} else {
|
} else {
|
||||||
// bgm.stop();
|
bgm.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,14 +533,6 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GlowText {
|
|
||||||
text: Backend.translate("Observing ...")
|
|
||||||
visible: config.observing && !config.replaying
|
|
||||||
color: "#4B83CD"
|
|
||||||
font.family: fontLi2.name
|
|
||||||
font.pixelSize: 48
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: replayControls
|
id: replayControls
|
||||||
visible: config.replaying
|
visible: config.replaying
|
||||||
|
@ -855,7 +847,7 @@ Item {
|
||||||
|
|
||||||
Drawer {
|
Drawer {
|
||||||
id: roomDrawer
|
id: roomDrawer
|
||||||
width: parent.width * 0.3 / mainWindow.scale
|
width: parent.width * 0.36 / mainWindow.scale
|
||||||
height: parent.height / mainWindow.scale
|
height: parent.height / mainWindow.scale
|
||||||
dim: false
|
dim: false
|
||||||
clip: true
|
clip: true
|
||||||
|
@ -901,20 +893,25 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Drawer {
|
Popup {
|
||||||
id: cheatDrawer
|
id: cheatDrawer
|
||||||
edge: Qt.RightEdge
|
width: realMainWin.width * 0.60
|
||||||
width: parent.width * 0.4 / mainWindow.scale
|
height: realMainWin.height * 0.8
|
||||||
height: parent.height / mainWindow.scale
|
anchors.centerIn: parent
|
||||||
dim: false
|
background: Rectangle {
|
||||||
clip: true
|
color: "#CC2E2C27"
|
||||||
dragMargin: 0
|
radius: 5
|
||||||
scale: mainWindow.scale
|
border.color: "#A6967A"
|
||||||
transformOrigin: Item.TopRight
|
border.width: 1
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: cheatLoader
|
id: cheatLoader
|
||||||
anchors.fill: parent
|
anchors.centerIn: parent
|
||||||
|
width: parent.width / mainWindow.scale
|
||||||
|
height: parent.height / mainWindow.scale
|
||||||
|
scale: mainWindow.scale
|
||||||
|
clip: true
|
||||||
onSourceChanged: {
|
onSourceChanged: {
|
||||||
if (item === null)
|
if (item === null)
|
||||||
return;
|
return;
|
||||||
|
@ -931,6 +928,20 @@ Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: dashboard
|
||||||
|
visible: config.observing && !config.replaying
|
||||||
|
color: "transparent"
|
||||||
|
GlowText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: Backend.translate("Observing ...")
|
||||||
|
color: "#4B83CD"
|
||||||
|
font.family: fontLi2.name
|
||||||
|
font.pixelSize: 48
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 这东西似乎一直不好使啊
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: easyChat
|
id: easyChat
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -967,6 +978,16 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shortcut {
|
||||||
|
sequence: "T"
|
||||||
|
onActivated: {
|
||||||
|
easyChat.visible = true;
|
||||||
|
easyChatEdit.enabled = true;
|
||||||
|
easyChatEdit.forceActiveFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
MiscStatus {
|
MiscStatus {
|
||||||
id: miscStatus
|
id: miscStatus
|
||||||
anchors.right: menuButton.left
|
anchors.right: menuButton.left
|
||||||
|
@ -975,20 +996,20 @@ Item {
|
||||||
anchors.topMargin: 8
|
anchors.topMargin: 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PhotoElement.MarkArea {
|
||||||
|
id: banner
|
||||||
|
x: 12; y: 12
|
||||||
|
width: (roomScene.width - 175 * 0.75 * 7) / 4 + 175 - 16
|
||||||
|
transformOrigin: Item.TopLeft
|
||||||
|
scale: 0.75
|
||||||
|
bgColor: "#BB838AEA"
|
||||||
|
}
|
||||||
|
|
||||||
Danmaku {
|
Danmaku {
|
||||||
id: danmaku
|
id: danmaku
|
||||||
width: parent.width
|
width: parent.width
|
||||||
}
|
}
|
||||||
|
|
||||||
Shortcut {
|
|
||||||
sequence: "T"
|
|
||||||
onActivated: {
|
|
||||||
easyChat.visible = true;
|
|
||||||
easyChatEdit.enabled = true;
|
|
||||||
easyChatEdit.forceActiveFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Shortcut {
|
Shortcut {
|
||||||
sequence: "D"
|
sequence: "D"
|
||||||
property bool show_distance: false
|
property bool show_distance: false
|
||||||
|
|
|
@ -1012,7 +1012,7 @@ callbacks["AskForChoice"] = (jsonData) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
callbacks["AskForCheck"] = (jsonData) => {
|
callbacks["AskForChoices"] = (jsonData) => {
|
||||||
// jsonData: [ string[] choices, string skill ]
|
// jsonData: [ string[] choices, string skill ]
|
||||||
// TODO: multiple choices, e.g. benxi_ol
|
// TODO: multiple choices, e.g. benxi_ol
|
||||||
const data = JSON.parse(jsonData);
|
const data = JSON.parse(jsonData);
|
||||||
|
@ -1025,7 +1025,7 @@ callbacks["AskForCheck"] = (jsonData) => {
|
||||||
const prompt = data[5];
|
const prompt = data[5];
|
||||||
const detailed = data[6];
|
const detailed = data[6];
|
||||||
if (prompt === "") {
|
if (prompt === "") {
|
||||||
roomScene.promptText = Backend.translate("#AskForCheck")
|
roomScene.promptText = Backend.translate("#AskForChoices")
|
||||||
.arg(Backend.translate(skill_name));
|
.arg(Backend.translate(skill_name));
|
||||||
} else {
|
} else {
|
||||||
roomScene.setPrompt(processPrompt(prompt), true);
|
roomScene.setPrompt(processPrompt(prompt), true);
|
||||||
|
@ -1335,7 +1335,7 @@ callbacks["SetPlayerMark"] = (jsonData) => {
|
||||||
const data = JSON.parse(jsonData);
|
const data = JSON.parse(jsonData);
|
||||||
const player = getPhoto(data[0]);
|
const player = getPhoto(data[0]);
|
||||||
const mark = data[1];
|
const mark = data[1];
|
||||||
const value = data[2] instanceof Array ? data[2] : data[2].toString();
|
const value = data[2] instanceof Object ? data[2] : data[2].toString();
|
||||||
let area = mark.startsWith("@!") ? player.picMarkArea : player.markArea;
|
let area = mark.startsWith("@!") ? player.picMarkArea : player.markArea;
|
||||||
if (data[2] === 0) {
|
if (data[2] === 0) {
|
||||||
area.removeMark(mark);
|
area.removeMark(mark);
|
||||||
|
@ -1344,6 +1344,18 @@ callbacks["SetPlayerMark"] = (jsonData) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callbacks["SetBanner"] = (jsonData) => {
|
||||||
|
const data = JSON.parse(jsonData);
|
||||||
|
const mark = data[0];
|
||||||
|
const value = data[1] instanceof Object ? data[1] : data[1].toString();
|
||||||
|
let area = roomScene.banner;
|
||||||
|
if (data[1] === 0) {
|
||||||
|
area.removeMark(mark);
|
||||||
|
} else {
|
||||||
|
area.setMark(mark, mark.startsWith("@@") ? "" : value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
callbacks["Animate"] = (jsonData) => {
|
callbacks["Animate"] = (jsonData) => {
|
||||||
// jsonData: [Object object]
|
// jsonData: [Object object]
|
||||||
const data = JSON.parse(jsonData);
|
const data = JSON.parse(jsonData);
|
||||||
|
@ -1581,7 +1593,7 @@ callbacks["ChangeSelf"] = (j) => {
|
||||||
|
|
||||||
callbacks["AskForLuckCard"] = (j) => {
|
callbacks["AskForLuckCard"] = (j) => {
|
||||||
// jsonData: int time
|
// jsonData: int time
|
||||||
if (config.replaying) return;
|
if (config.observing || config.replaying) return;
|
||||||
const time = parseInt(j);
|
const time = parseInt(j);
|
||||||
roomScene.setPrompt(Backend.translate("#AskForLuckCard").arg(time), true);
|
roomScene.setPrompt(Backend.translate("#AskForLuckCard").arg(time), true);
|
||||||
roomScene.state = "replying";
|
roomScene.state = "replying";
|
||||||
|
|
|
@ -6,6 +6,7 @@ import QtQuick.Layouts
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
width: 138
|
width: 138
|
||||||
|
property var bgColor: "#3C3229"
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
id: markList
|
id: markList
|
||||||
|
@ -15,7 +16,7 @@ Item {
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
color: "#3C3229"
|
color: bgColor
|
||||||
opacity: 0.8
|
opacity: 0.8
|
||||||
radius: 4
|
radius: 4
|
||||||
border.color: "white"
|
border.color: "white"
|
||||||
|
@ -68,7 +69,21 @@ Item {
|
||||||
} else {
|
} else {
|
||||||
params.cardNames = data;
|
params.cardNames = data;
|
||||||
}
|
}
|
||||||
|
} else if (mark_name.startsWith('@[')) {
|
||||||
|
// @[xxx]yyy 怀疑是不是qml标记
|
||||||
|
const close_br = mark_name.indexOf(']');
|
||||||
|
if (close_br === -1) return;
|
||||||
|
|
||||||
|
const mark_type = mark_name.slice(2, close_br);
|
||||||
|
const _data = (mark_extra);
|
||||||
|
let data = JSON.parse(Backend.callLuaFunction("GetQmlMark", [mark_type, mark_name, JSON.stringify(_data)]));
|
||||||
|
if (data && data.qml_path) {
|
||||||
|
params.data = _data;
|
||||||
|
roomScene.startCheat("../../" + data.qml_path, params);
|
||||||
|
}
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
if (!root.parent.playerid) return;
|
||||||
let data = JSON.parse(Backend.callLuaFunction("GetPile", [root.parent.playerid, mark_name]));
|
let data = JSON.parse(Backend.callLuaFunction("GetPile", [root.parent.playerid, mark_name]));
|
||||||
data = data.filter((e) => e !== -1);
|
data = data.filter((e) => e !== -1);
|
||||||
if (data.length === 0)
|
if (data.length === 0)
|
||||||
|
@ -103,6 +118,15 @@ Item {
|
||||||
if (mark.startsWith('@$') || mark.startsWith('@&')) {
|
if (mark.startsWith('@$') || mark.startsWith('@&')) {
|
||||||
special_value += data.length;
|
special_value += data.length;
|
||||||
data = data.join(',');
|
data = data.join(',');
|
||||||
|
} else if (mark.startsWith('@[')) {
|
||||||
|
const close_br = mark.indexOf(']');
|
||||||
|
if (close_br !== -1) {
|
||||||
|
const mark_type = mark.slice(2, close_br);
|
||||||
|
const _data = JSON.parse(Backend.callLuaFunction("GetQmlMark", [mark_type, mark, JSON.stringify(data)]));
|
||||||
|
if (_data && _data.text) {
|
||||||
|
special_value = _data.text;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
data = data instanceof Array ? data.map((markText) => Backend.translate(markText)).join(' ') : Backend.translate(data);
|
data = data instanceof Array ? data.map((markText) => Backend.translate(markText)).join(' ') : Backend.translate(data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import QtQuick
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property alias text: pileName.text
|
||||||
|
GlowText {
|
||||||
|
id: pileName
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
width: parent.width
|
||||||
|
font.family: fontLibian.name
|
||||||
|
color: "#E4D5A0"
|
||||||
|
font.pixelSize: 30
|
||||||
|
font.weight: Font.Medium
|
||||||
|
glow.color: "black"
|
||||||
|
glow.spread: 0.3
|
||||||
|
glow.radius: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
LinearGradient {
|
||||||
|
anchors.fill: pileName
|
||||||
|
source: pileName
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0
|
||||||
|
color: "#FEF7C2"
|
||||||
|
}
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
position: 0.5
|
||||||
|
color: "#D2AD4A"
|
||||||
|
}
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
position: 1
|
||||||
|
color: "#BE9878"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import QtQuick.Layouts
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import Qt5Compat.GraphicalEffects
|
import Qt5Compat.GraphicalEffects
|
||||||
|
|
||||||
Item {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
property var extra_data: ({}) // unused
|
property var extra_data: ({}) // unused
|
||||||
|
@ -14,51 +14,40 @@ Item {
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: Backend.translate("Handcard selector")
|
text: Backend.translate("Handcard selector")
|
||||||
width: parent.width
|
Layout.fillWidth: true
|
||||||
anchors.topMargin: 6
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
font.pixelSize: 16
|
font.pixelSize: 18
|
||||||
|
color: "#E4D5A0"
|
||||||
}
|
}
|
||||||
|
|
||||||
Flickable {
|
GridView {
|
||||||
id: flickableContainer
|
id: cardsList
|
||||||
ScrollBar.vertical: ScrollBar {}
|
cellWidth: 93 * 0.9 + 4
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
cellHeight: 130 * 0.9 + 4
|
||||||
anchors.top: parent.top
|
Layout.preferredWidth: root.width - root.width % 88
|
||||||
anchors.topMargin: 40
|
Layout.fillHeight: true
|
||||||
flickableDirection: Flickable.VerticalFlick
|
Layout.alignment: Qt.AlignHCenter
|
||||||
width: parent.width - 20
|
|
||||||
height: parent.height - 40
|
|
||||||
contentWidth: cardsList.width
|
|
||||||
contentHeight: cardsList.height
|
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
GridLayout {
|
model: cards
|
||||||
id: cardsList
|
|
||||||
columns: Math.floor(flickableContainer.width / 90)
|
|
||||||
|
|
||||||
Repeater {
|
delegate: CardItem {
|
||||||
model: cards
|
width: 93 * 0.9
|
||||||
|
height: 130 * 0.9
|
||||||
CardItem {
|
chosenInBox: modelData.chosen
|
||||||
width: 93 * 0.9
|
onClicked: {
|
||||||
height: 130 * 0.9
|
const clist = roomScene.dashboard.handcardArea.cards;
|
||||||
chosenInBox: modelData.chosen
|
for (let cd of clist) {
|
||||||
onClicked: {
|
if (cd.cid == cid) {
|
||||||
const clist = roomScene.dashboard.handcardArea.cards;
|
cd.selected = !cd.selected;
|
||||||
for (let cd of clist) {
|
cd.clicked();
|
||||||
if (cd.cid == cid) {
|
finish();
|
||||||
cd.selected = !cd.selected;
|
|
||||||
cd.clicked();
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
setData(JSON.parse(Backend.callLuaFunction("GetCardData", [modelData.cid])));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
setData(JSON.parse(Backend.callLuaFunction("GetCardData", [modelData.cid])));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,7 @@ CardItem {
|
||||||
height: 80
|
height: 80
|
||||||
x: 2
|
x: 2
|
||||||
y: lineCount > 6 ? 30 : 34
|
y: lineCount > 6 ? 30 : 34
|
||||||
text: Backend.translate(name)
|
text: name !== "" ? Backend.translate(name) : "nil"
|
||||||
visible: Backend.translate(name).length <= 6 && detailed
|
visible: Backend.translate(name).length <= 6 && detailed
|
||||||
color: "white"
|
color: "white"
|
||||||
font.family: fontLibian.name
|
font.family: fontLibian.name
|
||||||
|
|
|
@ -2,87 +2,34 @@
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Controls
|
|
||||||
import Qt5Compat.GraphicalEffects
|
|
||||||
|
|
||||||
Item {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
property var extra_data: ({})
|
property var extra_data: ({})
|
||||||
signal finish()
|
signal finish()
|
||||||
|
|
||||||
Rectangle {
|
BigGlowText {
|
||||||
anchors.fill: parent
|
Layout.fillWidth: true
|
||||||
color: "black"
|
Layout.preferredHeight: childrenRect.height + 4
|
||||||
|
|
||||||
GlowText {
|
text: Backend.translate(extra_data.name)
|
||||||
id: pileName
|
}
|
||||||
text: Backend.translate(extra_data.name)
|
|
||||||
width: parent.width
|
|
||||||
anchors.topMargin: 10
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font.family: fontLibian.name
|
|
||||||
color: "#E4D5A0"
|
|
||||||
font.pixelSize: 30
|
|
||||||
font.weight: Font.Medium
|
|
||||||
glow.color: "black"
|
|
||||||
glow.spread: 0.3
|
|
||||||
glow.radius: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
LinearGradient {
|
GridView {
|
||||||
anchors.fill: pileName
|
cellWidth: 93 + 4
|
||||||
source: pileName
|
cellHeight: 130 + 4
|
||||||
gradient: Gradient {
|
Layout.preferredWidth: root.width - root.width % 97
|
||||||
GradientStop {
|
Layout.fillHeight: true
|
||||||
position: 0
|
Layout.alignment: Qt.AlignHCenter
|
||||||
color: "#FEF7C2"
|
clip: true
|
||||||
}
|
|
||||||
|
|
||||||
GradientStop {
|
model: extra_data.ids || extra_data.cardNames
|
||||||
position: 0.5
|
|
||||||
color: "#D2AD4A"
|
|
||||||
}
|
|
||||||
|
|
||||||
GradientStop {
|
delegate: GeneralCardItem {
|
||||||
position: 1
|
id: cardItem
|
||||||
color: "#BE9878"
|
autoBack: false
|
||||||
}
|
name: modelData
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Flickable {
|
|
||||||
id: flickableContainer
|
|
||||||
ScrollBar.vertical: ScrollBar {}
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 40
|
|
||||||
flickableDirection: Flickable.VerticalFlick
|
|
||||||
width: parent.width - 20
|
|
||||||
height: parent.height - 40
|
|
||||||
contentWidth: cardsList.width
|
|
||||||
contentHeight: cardsList.height
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: cardsList
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
columns: Math.floor(flickableContainer.width / 100)
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: extra_data.ids || extra_data.cardNames
|
|
||||||
|
|
||||||
GeneralCardItem {
|
|
||||||
id: cardItem
|
|
||||||
// width: (flickableContainer.width - 15) / 4
|
|
||||||
// height: cardItem.width * 1.4
|
|
||||||
autoBack: false
|
|
||||||
name: modelData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,98 +2,45 @@
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Controls
|
|
||||||
import Qt5Compat.GraphicalEffects
|
|
||||||
|
|
||||||
Item {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
property var extra_data: ({})
|
property var extra_data: ({})
|
||||||
signal finish()
|
signal finish()
|
||||||
|
|
||||||
Rectangle {
|
BigGlowText {
|
||||||
anchors.fill: parent
|
Layout.fillWidth: true
|
||||||
color: "black"
|
Layout.preferredHeight: childrenRect.height + 4
|
||||||
|
|
||||||
GlowText {
|
text: Backend.translate(extra_data.name)
|
||||||
id: pileName
|
}
|
||||||
text: Backend.translate(extra_data.name)
|
|
||||||
width: parent.width
|
|
||||||
anchors.topMargin: 10
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font.family: fontLibian.name
|
|
||||||
color: "#E4D5A0"
|
|
||||||
font.pixelSize: 30
|
|
||||||
font.weight: Font.Medium
|
|
||||||
glow.color: "black"
|
|
||||||
glow.spread: 0.3
|
|
||||||
glow.radius: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
LinearGradient {
|
GridView {
|
||||||
anchors.fill: pileName
|
cellWidth: 93 + 4
|
||||||
source: pileName
|
cellHeight: 130 + 4
|
||||||
gradient: Gradient {
|
Layout.preferredWidth: root.width - root.width % 97
|
||||||
GradientStop {
|
Layout.fillHeight: true
|
||||||
position: 0
|
Layout.alignment: Qt.AlignHCenter
|
||||||
color: "#FEF7C2"
|
clip: true
|
||||||
}
|
|
||||||
|
model: extra_data.ids || extra_data.cardNames
|
||||||
GradientStop {
|
|
||||||
position: 0.5
|
delegate: CardItem {
|
||||||
color: "#D2AD4A"
|
id: cardItem
|
||||||
}
|
autoBack: false
|
||||||
|
Component.onCompleted: {
|
||||||
GradientStop {
|
let data = {}
|
||||||
position: 1
|
if (extra_data.ids) {
|
||||||
color: "#BE9878"
|
data = JSON.parse(Backend.callLuaFunction("GetCardData", [modelData]));
|
||||||
}
|
} else {
|
||||||
}
|
data.cid = 0;
|
||||||
}
|
data.name = modelData;
|
||||||
|
data.suit = '';
|
||||||
Flickable {
|
data.number = 0;
|
||||||
id: flickableContainer
|
data.color = '';
|
||||||
ScrollBar.vertical: ScrollBar {}
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 40
|
|
||||||
flickableDirection: Flickable.VerticalFlick
|
|
||||||
width: parent.width - 20
|
|
||||||
height: parent.height - 40
|
|
||||||
contentWidth: cardsList.width
|
|
||||||
contentHeight: cardsList.height
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: cardsList
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
columns: 4
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: extra_data.ids || extra_data.cardNames
|
|
||||||
|
|
||||||
CardItem {
|
|
||||||
id: cardItem
|
|
||||||
width: (flickableContainer.width - 15) / 4
|
|
||||||
height: cardItem.width * 1.4
|
|
||||||
autoBack: false
|
|
||||||
Component.onCompleted: {
|
|
||||||
let data = {}
|
|
||||||
if (extra_data.ids) {
|
|
||||||
data = JSON.parse(Backend.callLuaFunction("GetCardData", [modelData]));
|
|
||||||
} else {
|
|
||||||
data.cid = 0;
|
|
||||||
data.name = modelData;
|
|
||||||
data.suit = '';
|
|
||||||
data.number = 0;
|
|
||||||
data.color = '';
|
|
||||||
}
|
|
||||||
setData(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
setData(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ Dashboard 1.0 Dashboard.qml
|
||||||
GameOverBox 1.0 GameOverBox.qml
|
GameOverBox 1.0 GameOverBox.qml
|
||||||
GeneralCardItem 1.0 GeneralCardItem.qml
|
GeneralCardItem 1.0 GeneralCardItem.qml
|
||||||
GlowText 1.0 GlowText.qml
|
GlowText 1.0 GlowText.qml
|
||||||
|
BigGlowText 1.0 BigGlowText.qml
|
||||||
GraphicsBox 1.0 GraphicsBox.qml
|
GraphicsBox 1.0 GraphicsBox.qml
|
||||||
GuanxingBox 1.0 GuanxingBox.qml
|
GuanxingBox 1.0 GuanxingBox.qml
|
||||||
HandcardArea 1.0 HandcardArea.qml
|
HandcardArea 1.0 HandcardArea.qml
|
||||||
|
|
|
@ -334,6 +334,10 @@
|
||||||
<source>Room is full or already started!</source>
|
<source>Room is full or already started!</source>
|
||||||
<translation>房间已满!</translation>
|
<translation>房间已满!</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>rejected your demand of joining room</source>
|
||||||
|
<translation>房主拒绝你加入。</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>server is full!</source>
|
<source>server is full!</source>
|
||||||
<translation>服务器已满!</translation>
|
<translation>服务器已满!</translation>
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
---@field public current ClientPlayer @ 当前回合玩家
|
---@field public current ClientPlayer @ 当前回合玩家
|
||||||
---@field public discard_pile integer[] @ 弃牌堆
|
---@field public discard_pile integer[] @ 弃牌堆
|
||||||
---@field public status_skills Skill[] @ 状态技总和
|
---@field public status_skills Skill[] @ 状态技总和
|
||||||
|
---@field public banners table<string, any> @ 左上角显示的东西
|
||||||
---@field public observing boolean
|
---@field public observing boolean
|
||||||
Client = class('Client')
|
Client = class('Client')
|
||||||
|
|
||||||
|
@ -57,6 +58,8 @@ function Client:initialize()
|
||||||
self.status_skills[class] = {table.unpack(skills)}
|
self.status_skills[class] = {table.unpack(skills)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.banners = {}
|
||||||
|
|
||||||
self.skill_costs = {}
|
self.skill_costs = {}
|
||||||
self.card_marks = {}
|
self.card_marks = {}
|
||||||
self.filtered_cards = {}
|
self.filtered_cards = {}
|
||||||
|
@ -234,6 +237,15 @@ function Client:setCardNote(ids, msg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Client:setBanner(name, value)
|
||||||
|
if value == 0 then value = nil end
|
||||||
|
self.banners[name] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
function Client:getBanner(name)
|
||||||
|
return self.banners[name]
|
||||||
|
end
|
||||||
|
|
||||||
fk.client_callback["SetCardFootnote"] = function(jsonData)
|
fk.client_callback["SetCardFootnote"] = function(jsonData)
|
||||||
local data = json.decode(jsonData)
|
local data = json.decode(jsonData)
|
||||||
ClientInstance:setCardNote(data[1], data[2]);
|
ClientInstance:setCardNote(data[1], data[2]);
|
||||||
|
@ -769,6 +781,17 @@ fk.client_callback["SetPlayerMark"] = function(jsonData)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fk.client_callback["SetBanner"] = function(jsonData)
|
||||||
|
-- jsonData: [ int id, string mark, int value ]
|
||||||
|
local data = json.decode(jsonData)
|
||||||
|
local mark, value = data[1], data[2]
|
||||||
|
ClientInstance:setBanner(mark, value)
|
||||||
|
|
||||||
|
if string.sub(mark, 1, 1) == "@" then
|
||||||
|
ClientInstance:notifyUI("SetBanner", jsonData)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
fk.client_callback["SetCardMark"] = function(jsonData)
|
fk.client_callback["SetCardMark"] = function(jsonData)
|
||||||
-- jsonData: [ int id, string mark, int value ]
|
-- jsonData: [ int id, string mark, int value ]
|
||||||
local data = json.decode(jsonData)
|
local data = json.decode(jsonData)
|
||||||
|
|
|
@ -734,4 +734,14 @@ function PoxiFeasible(poxi_type, selected, data, extra_data)
|
||||||
return json.encode(poxi.feasible(selected, data, extra_data))
|
return json.encode(poxi.feasible(selected, data, extra_data))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function GetQmlMark(mtype, name, value)
|
||||||
|
local spec = Fk.qml_marks[mtype]
|
||||||
|
if not spec then return "{}" end
|
||||||
|
value = json.decode(value)
|
||||||
|
return json.encode {
|
||||||
|
qml_path = spec.qml_path,
|
||||||
|
text = spec.how_to_show(name, value)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
dofile "lua/client/i18n/init.lua"
|
dofile "lua/client/i18n/init.lua"
|
||||||
|
|
|
@ -159,7 +159,7 @@ Fk:loadTranslationTable({
|
||||||
["#AskForLuckCard"] = "Do you want to use luck card (%1 times left)?",
|
["#AskForLuckCard"] = "Do you want to use luck card (%1 times left)?",
|
||||||
["AskForLuckCard"] = "Luck card",
|
["AskForLuckCard"] = "Luck card",
|
||||||
["#AskForChoice"] = "%1: Please choose",
|
["#AskForChoice"] = "%1: Please choose",
|
||||||
["#AskForCheck"] = "%1: Please choose",
|
["#AskForChoices"] = "%1: Please choose",
|
||||||
["#choose-trigger"] = "Please choose the skill to use",
|
["#choose-trigger"] = "Please choose the skill to use",
|
||||||
["trigger"] = "Trigger skill",
|
["trigger"] = "Trigger skill",
|
||||||
-- ["Please arrange cards"] = "请拖拽移动卡牌",
|
-- ["Please arrange cards"] = "请拖拽移动卡牌",
|
||||||
|
@ -170,7 +170,7 @@ Fk:loadTranslationTable({
|
||||||
["AskForGuanxing"] = "Stargazing",
|
["AskForGuanxing"] = "Stargazing",
|
||||||
["AskForExchange"] = "Exchaging",
|
["AskForExchange"] = "Exchaging",
|
||||||
["AskForChoice"] = "Making choice",
|
["AskForChoice"] = "Making choice",
|
||||||
["AskForCheck"] = "Making choice",
|
["AskForChoices"] = "Making choice",
|
||||||
["AskForKingdom"] = "Choosing kingdom",
|
["AskForKingdom"] = "Choosing kingdom",
|
||||||
["AskForPindian"] = "Point fight",
|
["AskForPindian"] = "Point fight",
|
||||||
["AskForMoveCardInBoard"] = "Moving cards",
|
["AskForMoveCardInBoard"] = "Moving cards",
|
||||||
|
|
|
@ -206,7 +206,7 @@ FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下
|
||||||
["#AskForLuckCard"] = "你想使用手气卡吗?还可以使用 %1 次,剩余手气卡∞张",
|
["#AskForLuckCard"] = "你想使用手气卡吗?还可以使用 %1 次,剩余手气卡∞张",
|
||||||
["AskForLuckCard"] = "手气卡",
|
["AskForLuckCard"] = "手气卡",
|
||||||
["#AskForChoice"] = "%1:请选择",
|
["#AskForChoice"] = "%1:请选择",
|
||||||
["#AskForCheck"] = "%1:请选择",
|
["#AskForChoices"] = "%1:请选择",
|
||||||
["#choose-trigger"] = "请选择一项技能发动",
|
["#choose-trigger"] = "请选择一项技能发动",
|
||||||
["trigger"] = "选择技能",
|
["trigger"] = "选择技能",
|
||||||
["Please arrange cards"] = "请拖拽移动卡牌",
|
["Please arrange cards"] = "请拖拽移动卡牌",
|
||||||
|
@ -217,7 +217,7 @@ FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下
|
||||||
["AskForGuanxing"] = "观星",
|
["AskForGuanxing"] = "观星",
|
||||||
["AskForExchange"] = "换牌",
|
["AskForExchange"] = "换牌",
|
||||||
["AskForChoice"] = "选择",
|
["AskForChoice"] = "选择",
|
||||||
["AskForCheck"] = "选择",
|
["AskForChoices"] = "选择",
|
||||||
["AskForKingdom"] = "选择势力",
|
["AskForKingdom"] = "选择势力",
|
||||||
["AskForPindian"] = "拼点",
|
["AskForPindian"] = "拼点",
|
||||||
["AskForMoveCardInBoard"] = "移动卡牌",
|
["AskForMoveCardInBoard"] = "移动卡牌",
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
---@field public printed_cards table<integer, Card> @ 被某些房间现场打印的卡牌,id都是负数且从-2开始
|
---@field public printed_cards table<integer, Card> @ 被某些房间现场打印的卡牌,id都是负数且从-2开始
|
||||||
---@field private _custom_events any[] @ 自定义事件列表
|
---@field private _custom_events any[] @ 自定义事件列表
|
||||||
---@field public poxi_methods table<string, PoxiSpec> @ “魄袭”框操作方法表
|
---@field public poxi_methods table<string, PoxiSpec> @ “魄袭”框操作方法表
|
||||||
|
---@field public qml_marks table<string, QmlMarkSpec> @ 自定义Qml标记的表
|
||||||
local Engine = class("Engine")
|
local Engine = class("Engine")
|
||||||
|
|
||||||
--- Engine的构造函数。
|
--- Engine的构造函数。
|
||||||
|
@ -59,6 +60,7 @@ function Engine:initialize()
|
||||||
self.kingdoms = {}
|
self.kingdoms = {}
|
||||||
self._custom_events = {}
|
self._custom_events = {}
|
||||||
self.poxi_methods = {}
|
self.poxi_methods = {}
|
||||||
|
self.qml_marks = {}
|
||||||
|
|
||||||
self:loadPackages()
|
self:loadPackages()
|
||||||
self:loadDisabled()
|
self:loadDisabled()
|
||||||
|
@ -345,11 +347,22 @@ function Engine:addPoxiMethod(spec)
|
||||||
assert(type(spec.name) == "string")
|
assert(type(spec.name) == "string")
|
||||||
assert(type(spec.card_filter) == "function")
|
assert(type(spec.card_filter) == "function")
|
||||||
assert(type(spec.feasible) == "function")
|
assert(type(spec.feasible) == "function")
|
||||||
|
if self.poxi_methods[spec.name] then
|
||||||
|
fk.qCritical("Warning: duplicated poxi_method " .. spec.name)
|
||||||
|
end
|
||||||
self.poxi_methods[spec.name] = spec
|
self.poxi_methods[spec.name] = spec
|
||||||
spec.default_choice = spec.default_choice or function() return {} end
|
spec.default_choice = spec.default_choice or function() return {} end
|
||||||
spec.post_select = spec.post_select or function(s) return s end
|
spec.post_select = spec.post_select or function(s) return s end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Engine:addQmlMark(spec)
|
||||||
|
assert(type(spec.name) == "string")
|
||||||
|
if self.qml_marks[spec.name] then
|
||||||
|
fk.qCritical("Warning: duplicated qml mark type " .. spec.name)
|
||||||
|
end
|
||||||
|
self.qml_marks[spec.name] = spec
|
||||||
|
end
|
||||||
|
|
||||||
--- 从已经开启的拓展包中,随机选出若干名武将。
|
--- 从已经开启的拓展包中,随机选出若干名武将。
|
||||||
---
|
---
|
||||||
--- 对于同名武将不会重复选取。
|
--- 对于同名武将不会重复选取。
|
||||||
|
|
|
@ -598,3 +598,8 @@ end
|
||||||
---@field post_select? fun(selected: int[], data: any, extra_data: any): int[]
|
---@field post_select? fun(selected: int[], data: any, extra_data: any): int[]
|
||||||
---@field default_choice? fun(data: any, extra_data: any): int[]
|
---@field default_choice? fun(data: any, extra_data: any): int[]
|
||||||
---@field prompt? string | fun(data: any, extra_data: any): string
|
---@field prompt? string | fun(data: any, extra_data: any): string
|
||||||
|
|
||||||
|
---@class QmlMarkSpec
|
||||||
|
---@field name string
|
||||||
|
---@field qml_path string
|
||||||
|
---@field how_to_show function(name: string, value?: any): string?
|
||||||
|
|
|
@ -41,6 +41,11 @@ local function tellRoomToObserver(self, player)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- send banners
|
||||||
|
for k, v in pairs(self.banners) do
|
||||||
|
player:doNotify("SetBanner", json.encode{ k, v })
|
||||||
|
end
|
||||||
|
|
||||||
for _, p in ipairs(self.players) do
|
for _, p in ipairs(self.players) do
|
||||||
self:notifyProperty(player, p, "general")
|
self:notifyProperty(player, p, "general")
|
||||||
self:notifyProperty(player, p, "deputyGeneral")
|
self:notifyProperty(player, p, "deputyGeneral")
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
---@field public game_finished boolean @ 游戏是否已经结束
|
---@field public game_finished boolean @ 游戏是否已经结束
|
||||||
---@field public timeout integer @ 出牌时长上限
|
---@field public timeout integer @ 出牌时长上限
|
||||||
---@field public tag table<string, any> @ Tag清单,其实跟Player的标记是差不多的东西
|
---@field public tag table<string, any> @ Tag清单,其实跟Player的标记是差不多的东西
|
||||||
|
---@field public banners table<string, any> @ 左上角显示点啥好呢?
|
||||||
---@field public general_pile string[] @ 武将牌堆,这是可用武将名的数组
|
---@field public general_pile string[] @ 武将牌堆,这是可用武将名的数组
|
||||||
---@field public draw_pile integer[] @ 摸牌堆,这是卡牌id的数组
|
---@field public draw_pile integer[] @ 摸牌堆,这是卡牌id的数组
|
||||||
---@field public discard_pile integer[] @ 弃牌堆,也是卡牌id的数组
|
---@field public discard_pile integer[] @ 弃牌堆,也是卡牌id的数组
|
||||||
|
@ -77,6 +78,7 @@ function Room:initialize(_room)
|
||||||
self.game_finished = false
|
self.game_finished = false
|
||||||
self.timeout = _room:getTimeout()
|
self.timeout = _room:getTimeout()
|
||||||
self.tag = {}
|
self.tag = {}
|
||||||
|
self.banners = {}
|
||||||
self.general_pile = {}
|
self.general_pile = {}
|
||||||
self.draw_pile = {}
|
self.draw_pile = {}
|
||||||
self.discard_pile = {}
|
self.discard_pile = {}
|
||||||
|
@ -563,6 +565,16 @@ function Room:removeTag(tag_name)
|
||||||
self.tag[tag_name] = nil
|
self.tag[tag_name] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Room:setBanner(name, value)
|
||||||
|
if value == 0 then value = nil end
|
||||||
|
self.banners[name] = value
|
||||||
|
self:doBroadcastNotify("SetBanner", json.encode{ name, value })
|
||||||
|
end
|
||||||
|
|
||||||
|
function Room:getBanner(name)
|
||||||
|
return self.banners[name]
|
||||||
|
end
|
||||||
|
|
||||||
---@return boolean
|
---@return boolean
|
||||||
local function execGameEvent(type, ...)
|
local function execGameEvent(type, ...)
|
||||||
local event = GameEvent:new(type, ...)
|
local event = GameEvent:new(type, ...)
|
||||||
|
@ -1338,9 +1350,9 @@ end
|
||||||
---@param cancelable? boolean @ 能否点取消
|
---@param cancelable? boolean @ 能否点取消
|
||||||
---@param no_indicate? boolean @ 是否不显示指示线
|
---@param no_indicate? boolean @ 是否不显示指示线
|
||||||
---@return integer[], integer[]
|
---@return integer[], integer[]
|
||||||
function Room:askForChooseBoth(player, minCardNum, maxCardNum, targets, minTargetNum, maxTargetNum, pattern, prompt, skillName, cancelable, no_indicate)
|
function Room:askForChooseCardsAndPlayers(player, minCardNum, maxCardNum, targets, minTargetNum, maxTargetNum, pattern, prompt, skillName, cancelable, no_indicate)
|
||||||
if minCardNum < 1 or minTargetNum < 1 then
|
if minCardNum < 1 or minTargetNum < 1 then
|
||||||
return table.unpack({}, {})
|
return {}, {}
|
||||||
end
|
end
|
||||||
cancelable = (cancelable == nil) and true or cancelable
|
cancelable = (cancelable == nil) and true or cancelable
|
||||||
no_indicate = no_indicate or false
|
no_indicate = no_indicate or false
|
||||||
|
@ -1366,7 +1378,7 @@ function Room:askForChooseBoth(player, minCardNum, maxCardNum, targets, minTarge
|
||||||
return ret.targets, ret.cards
|
return ret.targets, ret.cards
|
||||||
else
|
else
|
||||||
if cancelable then
|
if cancelable then
|
||||||
return table.unpack({}, {})
|
return {}, {}
|
||||||
else
|
else
|
||||||
return table.random(targets, minTargetNum), table.random(pcards, minCardNum)
|
return table.random(targets, minTargetNum), table.random(pcards, minCardNum)
|
||||||
end
|
end
|
||||||
|
@ -1675,12 +1687,12 @@ end
|
||||||
---@param detailed? boolean @ 选项详细描述
|
---@param detailed? boolean @ 选项详细描述
|
||||||
---@param all_choices? string[] @ 所有选项(不可选变灰)
|
---@param all_choices? string[] @ 所有选项(不可选变灰)
|
||||||
---@return string[] @ 选择的选项
|
---@return string[] @ 选择的选项
|
||||||
function Room:askForCheck(player, choices, minNum, maxNum, skill_name, prompt, cancelable, detailed, all_choices)
|
function Room:askForChoices(player, choices, minNum, maxNum, skill_name, prompt, cancelable, detailed, all_choices)
|
||||||
cancelable = (cancelable == nil) and true or cancelable
|
cancelable = (cancelable == nil) and true or cancelable
|
||||||
if #choices <= minNum and not all_choices then return choices end
|
if #choices <= minNum and not all_choices then return choices end
|
||||||
assert(minNum <= maxNum)
|
assert(minNum <= maxNum)
|
||||||
assert(not all_choices or table.every(choices, function(c) return table.contains(all_choices, c) end))
|
assert(not all_choices or table.every(choices, function(c) return table.contains(all_choices, c) end))
|
||||||
local command = "AskForCheck"
|
local command = "AskForChoices"
|
||||||
skill_name = skill_name or ""
|
skill_name = skill_name or ""
|
||||||
prompt = prompt or ""
|
prompt = prompt or ""
|
||||||
all_choices = all_choices or choices
|
all_choices = all_choices or choices
|
||||||
|
|
|
@ -362,6 +362,11 @@ function ServerPlayer:reconnect()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- send banners
|
||||||
|
for k, v in pairs(room.banners) do
|
||||||
|
self:doNotify("SetBanner", json.encode{ k, v })
|
||||||
|
end
|
||||||
|
|
||||||
for _, p in ipairs(room.players) do
|
for _, p in ipairs(room.players) do
|
||||||
room:notifyProperty(self, p, "general")
|
room:notifyProperty(self, p, "general")
|
||||||
room:notifyProperty(self, p, "deputyGeneral")
|
room:notifyProperty(self, p, "deputyGeneral")
|
||||||
|
|
|
@ -87,6 +87,10 @@ local control = fk.CreateActiveSkill{
|
||||||
on_use = function(self, room, effect)
|
on_use = function(self, room, effect)
|
||||||
--room:doSuperLightBox("packages/test/qml/Test.qml")
|
--room:doSuperLightBox("packages/test/qml/Test.qml")
|
||||||
local from = room:getPlayerById(effect.from)
|
local from = room:getPlayerById(effect.from)
|
||||||
|
-- room:setPlayerMark(from, "@[test]test", {
|
||||||
|
-- all = {3, 1, 6, 9, 5, 11, 10, 2, 8, 7, 12, 4, 13},
|
||||||
|
-- ok = {10, 2},
|
||||||
|
-- })
|
||||||
-- room:swapSeat(from, to)
|
-- room:swapSeat(from, to)
|
||||||
for _, pid in ipairs(effect.tos) do
|
for _, pid in ipairs(effect.tos) do
|
||||||
local to = room:getPlayerById(pid)
|
local to = room:getPlayerById(pid)
|
||||||
|
@ -145,6 +149,27 @@ Fk:addPoxiMethod{
|
||||||
end,
|
end,
|
||||||
prompt = "魄袭:选你们俩手牌总共四个花色,或者不选直接按确定按钮"
|
prompt = "魄袭:选你们俩手牌总共四个花色,或者不选直接按确定按钮"
|
||||||
}
|
}
|
||||||
|
Fk:loadTranslationTable{['@[test]test']='割圆'}
|
||||||
|
Fk:addQmlMark{
|
||||||
|
name = "test",
|
||||||
|
how_to_show = function(name, value)
|
||||||
|
local all_points = value.all
|
||||||
|
local ok_points = value.ok
|
||||||
|
-- 若没有点亮的就不显示
|
||||||
|
if #ok_points == 0 then return "" end
|
||||||
|
-- 否则,显示相邻的,逻辑上要构成循环
|
||||||
|
local start_idx = table.indexOf(all_points, ok_points[1]) - 1
|
||||||
|
local end_idx = table.indexOf(all_points, ok_points[#ok_points]) + 1
|
||||||
|
if start_idx == 0 then start_idx = #all_points end
|
||||||
|
if end_idx == #all_points + 1 then end_idx = 1 end
|
||||||
|
if start_idx == end_idx then
|
||||||
|
return Card:getNumberStr(all_points[start_idx])
|
||||||
|
else
|
||||||
|
return Card:getNumberStr(all_points[start_idx]) .. Card:getNumberStr(all_points[end_idx])
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
qml_path = "packages/test/qml/TestDialog"
|
||||||
|
}
|
||||||
--]]
|
--]]
|
||||||
local test_vs = fk.CreateViewAsSkill{
|
local test_vs = fk.CreateViewAsSkill{
|
||||||
name = "test_vs",
|
name = "test_vs",
|
||||||
|
|
|
@ -1,38 +1,57 @@
|
||||||
|
// 割圆的例子
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import "../../../qml/Pages/RoomElement"
|
import QtQuick.Layouts
|
||||||
import "../../../qml/Pages"
|
import Fk.RoomElement
|
||||||
|
|
||||||
GraphicsBox {
|
|
||||||
property string custom_string: ""
|
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
title.text: Backend.translate("Test")
|
anchors.fill: parent
|
||||||
width: Math.max(140, body.width + 20)
|
property var extra_data: ({ name: "", data: {
|
||||||
height: body.height + title.height + 20
|
all: [1, 2, 4, 6],
|
||||||
|
ok: [1, 4],
|
||||||
|
} })
|
||||||
|
signal finish()
|
||||||
|
|
||||||
Column {
|
BigGlowText {
|
||||||
id: body
|
Layout.fillWidth: true
|
||||||
x: 10
|
Layout.preferredHeight: childrenRect.height + 4
|
||||||
y: title.height + 5
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Text {
|
text: Backend.translate(extra_data.name)
|
||||||
text: root.custom_string
|
}
|
||||||
color: "#E4D5A0"
|
|
||||||
|
PathView {
|
||||||
|
id: pathView
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
model: extra_data.data.all
|
||||||
|
delegate: Rectangle{
|
||||||
|
width: 42; height: 42
|
||||||
|
color: extra_data.data.ok.includes(modelData) ? "yellow" : "#CCEEEEEE"
|
||||||
|
radius: 2
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: modelData
|
||||||
|
font.pixelSize: 24
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
path: Path {
|
||||||
MetroButton {
|
// 默认横屏了,应该没人用竖屏玩这游戏
|
||||||
text: Backend.translate("OKOK")
|
startX: pathView.width / 2
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
startY: 40
|
||||||
|
PathArc {
|
||||||
onClicked: {
|
x: pathView.width / 2
|
||||||
close();
|
y: pathView.height - 40
|
||||||
ClientInstance.replyToServer("", "Hello from test dialog");
|
radiusX: (pathView.height - 80) / 2
|
||||||
|
radiusY: (pathView.height - 80) / 2
|
||||||
|
direction: PathArc.Clockwise
|
||||||
|
}
|
||||||
|
PathArc {
|
||||||
|
x: pathView.width / 2
|
||||||
|
y: 40
|
||||||
|
radiusX: (pathView.height - 80) / 2
|
||||||
|
radiusY: (pathView.height - 80) / 2
|
||||||
|
direction: PathArc.Clockwise
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadData(data) {
|
|
||||||
custom_string = data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,7 +284,13 @@ void Router::handlePacket(const QByteArray &rawPacket) {
|
||||||
} else if (command == "KickPlayer") {
|
} else if (command == "KickPlayer") {
|
||||||
int i = jsonData.toInt();
|
int i = jsonData.toInt();
|
||||||
auto p = room->findPlayer(i);
|
auto p = room->findPlayer(i);
|
||||||
if (p && !room->isStarted()) room->removePlayer(p);
|
if (p && !room->isStarted()) {
|
||||||
|
room->removePlayer(p);
|
||||||
|
room->addRejectId(i);
|
||||||
|
QTimer::singleShot(30000, this, [=]() {
|
||||||
|
room->removeRejectId(i);
|
||||||
|
});
|
||||||
|
}
|
||||||
} else if (command == "Ready") {
|
} else if (command == "Ready") {
|
||||||
player->setReady(!player->isReady());
|
player->setReady(!player->isReady());
|
||||||
room->doBroadcastNotify(room->getPlayers(), "ReadyChanged",
|
room->doBroadcastNotify(room->getPlayers(), "ReadyChanged",
|
||||||
|
|
|
@ -125,6 +125,11 @@ void Room::addPlayer(ServerPlayer *player) {
|
||||||
if (!player)
|
if (!player)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (rejected_players.contains(player->getId())) {
|
||||||
|
player->doNotify("ErrorMsg", "rejected your demand of joining room");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 如果要加入的房间满员了,或者已经开战了,就不能再加入
|
// 如果要加入的房间满员了,或者已经开战了,就不能再加入
|
||||||
if (isFull() || gameStarted) {
|
if (isFull() || gameStarted) {
|
||||||
player->doNotify("ErrorMsg", "Room is full or already started!");
|
player->doNotify("ErrorMsg", "Room is full or already started!");
|
||||||
|
@ -322,6 +327,11 @@ void Room::addObserver(ServerPlayer *player) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rejected_players.contains(player->getId())) {
|
||||||
|
player->doNotify("ErrorMsg", "rejected your demand of joining room");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 向observers中追加player,并从大厅移除player,然后将player的room设为this
|
// 向observers中追加player,并从大厅移除player,然后将player的room设为this
|
||||||
observers.append(player);
|
observers.append(player);
|
||||||
player->setRoom(this);
|
player->setRoom(this);
|
||||||
|
@ -573,3 +583,12 @@ void Room::pushRequest(const QString &req) {
|
||||||
m_thread->pushRequest(QString("%1,%2").arg(QString::number(id), req));
|
m_thread->pushRequest(QString("%1,%2").arg(QString::number(id), req));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Room::addRejectId(int id) {
|
||||||
|
if (isLobby()) return;
|
||||||
|
rejected_players << id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Room::removeRejectId(int id) {
|
||||||
|
rejected_players.removeOne(id);
|
||||||
|
}
|
||||||
|
|
|
@ -63,6 +63,8 @@ class Room : public QObject {
|
||||||
void manuallyStart();
|
void manuallyStart();
|
||||||
void pushRequest(const QString &req);
|
void pushRequest(const QString &req);
|
||||||
|
|
||||||
|
void addRejectId(int id);
|
||||||
|
void removeRejectId(int id);
|
||||||
signals:
|
signals:
|
||||||
void abandoned();
|
void abandoned();
|
||||||
|
|
||||||
|
@ -82,6 +84,7 @@ class Room : public QObject {
|
||||||
QList<ServerPlayer *> players;
|
QList<ServerPlayer *> players;
|
||||||
QList<ServerPlayer *> observers;
|
QList<ServerPlayer *> observers;
|
||||||
QList<int> runned_players;
|
QList<int> runned_players;
|
||||||
|
QList<int> rejected_players;
|
||||||
int robot_id;
|
int robot_id;
|
||||||
bool gameStarted;
|
bool gameStarted;
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
|
|
|
@ -60,7 +60,7 @@ Server::Server(QObject *parent) : QObject(parent) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 30; i++) {
|
||||||
if (!this->isListening) {
|
if (!this->isListening) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue