mirror of
https://github.com/Qsgs-Fans/FreeKill.git
synced 2024-11-16 11:42:45 +08:00
220fb93b0e
Co-authored-by: YoumuKon <38815081+YoumuKon@users.noreply.github.com>
914 lines
20 KiB
QML
914 lines
20 KiB
QML
// SPDX-License-Identifier: GPL-3.0-or-later
|
||
|
||
import QtQuick
|
||
import Qt5Compat.GraphicalEffects
|
||
import QtQuick.Controls
|
||
import QtQuick.Layouts
|
||
import Fk
|
||
import Fk.PhotoElement
|
||
|
||
Item {
|
||
id: root
|
||
width: 175
|
||
height: 233
|
||
scale: 0.75
|
||
property int playerid: 0
|
||
property string general: ""
|
||
property string avatar: ""
|
||
property string deputyGeneral: ""
|
||
property string screenName: ""
|
||
property string role: "unknown"
|
||
property string kingdom: "qun"
|
||
property string netstate: "online"
|
||
property alias handcards: handcardAreaItem.length
|
||
property int maxHp: 0
|
||
property int hp: 0
|
||
property int shield: 0
|
||
property int seatNumber: 1
|
||
property bool dead: false
|
||
property bool dying: false
|
||
property bool faceup: true
|
||
property bool chained: false
|
||
property int drank: 0
|
||
property int rest: 0
|
||
property bool isOwner: false
|
||
property bool ready: false
|
||
property int winGame: 0
|
||
property int runGame: 0
|
||
property int totalGame: 0
|
||
property list<string> sealedSlots: []
|
||
|
||
property int distance: -1
|
||
property string status: "normal"
|
||
property int maxCard: 0
|
||
|
||
property alias handcardArea: handcardAreaItem
|
||
property alias equipArea: equipAreaItem
|
||
property alias areasSealed: equipAreaItem
|
||
property alias markArea: markAreaItem
|
||
property alias picMarkArea: picMarkAreaItem
|
||
property alias delayedTrickArea: delayedTrickAreaItem
|
||
property alias specialArea: specialAreaItem
|
||
|
||
property alias progressBar: progressBar
|
||
property alias progressTip: progressTip.text
|
||
|
||
property bool selectable: false
|
||
property bool selected: false
|
||
|
||
property bool playing: false
|
||
property bool surrendered: false
|
||
|
||
property var targetTip: []
|
||
onPlayingChanged: {
|
||
if (playing) {
|
||
animPlaying.start();
|
||
} else {
|
||
animPlaying.stop();
|
||
}
|
||
}
|
||
|
||
Behavior on x {
|
||
NumberAnimation { duration: 600; easing.type: Easing.InOutQuad }
|
||
}
|
||
|
||
Behavior on y {
|
||
NumberAnimation { duration: 600; easing.type: Easing.InOutQuad }
|
||
}
|
||
|
||
states: [
|
||
State { name: "normal" },
|
||
State { name: "candidate" }
|
||
//State { name: "playing" }
|
||
//State { name: "responding" },
|
||
//State { name: "sos" }
|
||
]
|
||
|
||
state: "normal"
|
||
transitions: [
|
||
Transition {
|
||
from: "*"; to: "normal"
|
||
ScriptAction {
|
||
script: {
|
||
animSelectable.stop();
|
||
animSelected.stop();
|
||
}
|
||
}
|
||
},
|
||
|
||
Transition {
|
||
from: "*"; to: "candidate"
|
||
ScriptAction {
|
||
script: {
|
||
animSelectable.start();
|
||
animSelected.start();
|
||
}
|
||
}
|
||
}
|
||
]
|
||
|
||
PixmapAnimation {
|
||
id: animPlaying
|
||
source: SkinBank.PIXANIM_DIR + "playing"
|
||
anchors.centerIn: parent
|
||
loop: true
|
||
scale: 1.1
|
||
visible: root.playing
|
||
}
|
||
|
||
PixmapAnimation {
|
||
id: animSelected
|
||
source: SkinBank.PIXANIM_DIR + "selected"
|
||
anchors.centerIn: parent
|
||
loop: true
|
||
scale: 1.1
|
||
visible: root.state === "candidate" && selected
|
||
}
|
||
|
||
Image {
|
||
id: back
|
||
source: SkinBank.getPhotoBack(root.kingdom)
|
||
}
|
||
|
||
Text {
|
||
id: generalName
|
||
x: 5
|
||
y: 28
|
||
font.family: fontLibian.name
|
||
font.pixelSize: 22
|
||
opacity: 0.9
|
||
horizontalAlignment: Text.AlignHCenter
|
||
lineHeight: 18
|
||
lineHeightMode: Text.FixedHeight
|
||
color: "white"
|
||
width: 24
|
||
wrapMode: Text.WrapAnywhere
|
||
text: ""
|
||
}
|
||
|
||
Text {
|
||
id: longGeneralName
|
||
x: 5
|
||
y: 6
|
||
font.family: fontLibian.name
|
||
font.pixelSize: 22
|
||
rotation: 90
|
||
transformOrigin: Item.BottomLeft
|
||
opacity: 0.9
|
||
horizontalAlignment: Text.AlignHCenter
|
||
lineHeight: 18
|
||
lineHeightMode: Text.FixedHeight
|
||
color: "white"
|
||
text: ""
|
||
}
|
||
|
||
HpBar {
|
||
id: hp
|
||
x: 8
|
||
value: root.hp
|
||
maxValue: root.maxHp
|
||
shieldNum: root.shield
|
||
anchors.bottom: parent.bottom
|
||
anchors.bottomMargin: 36
|
||
}
|
||
|
||
Item {
|
||
width: 138
|
||
height: 222
|
||
visible: false
|
||
id: generalImgItem
|
||
|
||
Image {
|
||
id: generalImage
|
||
width: deputyGeneral ? parent.width / 2 : parent.width
|
||
Behavior on width { NumberAnimation { duration: 100 } }
|
||
height: parent.height
|
||
smooth: true
|
||
fillMode: Image.PreserveAspectCrop
|
||
source: {
|
||
if (general === "") {
|
||
return "";
|
||
}
|
||
if (deputyGeneral) {
|
||
return SkinBank.getGeneralExtraPic(general, "dual/")
|
||
?? SkinBank.getGeneralPicture(general);
|
||
} else {
|
||
return SkinBank.getGeneralPicture(general)
|
||
}
|
||
}
|
||
}
|
||
|
||
Image {
|
||
id: deputyGeneralImage
|
||
anchors.left: generalImage.right
|
||
width: parent.width / 2
|
||
height: parent.height
|
||
smooth: true
|
||
fillMode: Image.PreserveAspectCrop
|
||
source: {
|
||
const general = deputyGeneral;
|
||
if (deputyGeneral != "") {
|
||
return SkinBank.getGeneralExtraPic(general, "dual/")
|
||
?? SkinBank.getGeneralPicture(general);
|
||
} else {
|
||
return "";
|
||
}
|
||
}
|
||
}
|
||
|
||
Image {
|
||
id: deputySplit
|
||
source: SkinBank.PHOTO_DIR + "deputy-split"
|
||
opacity: deputyGeneral ? 1 : 0
|
||
}
|
||
|
||
Text {
|
||
id: deputyGeneralName
|
||
anchors.left: generalImage.right
|
||
anchors.leftMargin: -14
|
||
y: 23
|
||
font.family: fontLibian.name
|
||
font.pixelSize: 22
|
||
opacity: 0.9
|
||
horizontalAlignment: Text.AlignHCenter
|
||
lineHeight: 18
|
||
lineHeightMode: Text.FixedHeight
|
||
color: "white"
|
||
width: 24
|
||
wrapMode: Text.WrapAnywhere
|
||
text: ""
|
||
style: Text.Outline
|
||
}
|
||
|
||
Text {
|
||
id: longDeputyGeneralName
|
||
anchors.left: generalImage.right
|
||
anchors.leftMargin: -14
|
||
y: 23
|
||
font.family: fontLibian.name
|
||
font.pixelSize: 22
|
||
rotation: 90
|
||
transformOrigin: Item.BottomLeft
|
||
opacity: 0.9
|
||
horizontalAlignment: Text.AlignHCenter
|
||
lineHeight: 18
|
||
lineHeightMode: Text.FixedHeight
|
||
color: "white"
|
||
width: 24
|
||
text: ""
|
||
style: Text.Outline
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
id: photoMask
|
||
x: 31
|
||
y: 5
|
||
width: 138
|
||
height: 222
|
||
radius: 8
|
||
visible: false
|
||
}
|
||
|
||
OpacityMask {
|
||
id: photoMaskEffect
|
||
anchors.fill: photoMask
|
||
source: generalImgItem
|
||
maskSource: photoMask
|
||
}
|
||
|
||
Colorize {
|
||
anchors.fill: photoMaskEffect
|
||
source: photoMaskEffect
|
||
saturation: 0
|
||
opacity: (root.dead || root.surrendered) ? 1 : 0
|
||
Behavior on opacity { NumberAnimation { duration: 300 } }
|
||
}
|
||
|
||
Rectangle {
|
||
x: 31
|
||
y: 5
|
||
width: 138
|
||
height: 222
|
||
radius: 8
|
||
|
||
// visible: root.drank > 0
|
||
color: "red"
|
||
opacity: (root.drank <= 0 ? 0 : 0.4) + Math.log(root.drank) * 0.12
|
||
Behavior on opacity { NumberAnimation { duration: 300 } }
|
||
}
|
||
|
||
ColumnLayout {
|
||
id: restRect
|
||
anchors.centerIn: photoMask
|
||
anchors.leftMargin: 20
|
||
visible: root.rest > 0
|
||
|
||
GlowText {
|
||
Layout.alignment: Qt.AlignCenter
|
||
text: luatr("resting...")
|
||
font.family: fontLibian.name
|
||
font.pixelSize: 40
|
||
font.bold: true
|
||
color: "#FEF7D6"
|
||
glow.color: "#845422"
|
||
glow.spread: 0.8
|
||
}
|
||
|
||
GlowText {
|
||
Layout.alignment: Qt.AlignCenter
|
||
visible: root.rest > 0 && root.rest < 999
|
||
text: root.rest
|
||
font.family: fontLibian.name
|
||
font.pixelSize: 34
|
||
font.bold: true
|
||
color: "#DBCC69"
|
||
glow.color: "#2E200F"
|
||
glow.spread: 0.6
|
||
}
|
||
|
||
GlowText {
|
||
Layout.alignment: Qt.AlignCenter
|
||
visible: root.rest > 0 && root.rest < 999
|
||
text: luatr("rest round num")
|
||
font.family: fontLibian.name
|
||
font.pixelSize: 28
|
||
color: "#F0E5D6"
|
||
glow.color: "#2E200F"
|
||
glow.spread: 0.6
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
id: winRateRect
|
||
width: 138; x: 31
|
||
anchors.bottom: parent.bottom
|
||
anchors.bottomMargin: 6
|
||
height: childrenRect.height + 8
|
||
color: "#CC3C3229"
|
||
radius: 8
|
||
border.color: "white"
|
||
border.width: 1
|
||
visible: screenName != "" && !roomScene.isStarted
|
||
|
||
Text {
|
||
y: 4
|
||
anchors.horizontalCenter: parent.horizontalCenter
|
||
font.pixelSize: 20
|
||
font.family: fontLibian.name
|
||
color: (totalGame > 0 && runGame / totalGame > 0.2) ? "red" : "white"
|
||
style: Text.Outline
|
||
text: {
|
||
if (totalGame === 0) {
|
||
return luatr("Newbie");
|
||
}
|
||
const winRate = (winGame / totalGame) * 100;
|
||
const runRate = (runGame / totalGame) * 100;
|
||
return luatr("Win=%1\nRun=%2\nTotal=%3")
|
||
.arg(winRate.toFixed(2))
|
||
.arg(runRate.toFixed(2))
|
||
.arg(totalGame);
|
||
}
|
||
}
|
||
}
|
||
|
||
Image {
|
||
anchors.bottom: winRateRect.top
|
||
anchors.right: parent.right
|
||
anchors.bottomMargin: -8
|
||
anchors.rightMargin: 4
|
||
source: SkinBank.PHOTO_DIR +
|
||
(isOwner ? "owner" : (ready ? "ready" : "notready"))
|
||
visible: screenName != "" && !roomScene.isStarted
|
||
}
|
||
|
||
Image {
|
||
visible: equipAreaItem.length > 0
|
||
source: SkinBank.PHOTO_DIR + "equipbg"
|
||
x: 31
|
||
y: 121
|
||
}
|
||
|
||
Image {
|
||
source: root.status != "normal" ? SkinBank.STATUS_DIR + root.status : ""
|
||
x: -6
|
||
}
|
||
|
||
Image {
|
||
id: turnedOver
|
||
visible: !root.faceup
|
||
source: SkinBank.PHOTO_DIR + "faceturned" + (config.heg ? '-heg' : '')
|
||
x: 29; y: 5
|
||
}
|
||
|
||
EquipArea {
|
||
id: equipAreaItem
|
||
|
||
x: 31
|
||
y: 157
|
||
}
|
||
|
||
Item {
|
||
id: specialAreaItem
|
||
|
||
x: 31
|
||
y: 139
|
||
|
||
InvisibleCardArea {
|
||
id: specialContainer
|
||
// checkExisting: true
|
||
}
|
||
|
||
function updatePileInfo(areaName) {
|
||
if (areaName.startsWith('#')) return;
|
||
const data = lcall("GetPile", root.playerid, areaName);
|
||
if (data.length === 0) {
|
||
root.markArea.removeMark(areaName);
|
||
} else {
|
||
root.markArea.setMark(areaName, data.length.toString());
|
||
}
|
||
}
|
||
|
||
function add(inputs, areaName) {
|
||
updatePileInfo(areaName);
|
||
specialContainer.add(inputs);
|
||
}
|
||
|
||
function remove(inputs, areaName) {
|
||
updatePileInfo(areaName);
|
||
return specialContainer.remove(inputs);
|
||
}
|
||
|
||
function updateCardPosition(a) {
|
||
specialContainer.updateCardPosition(a);
|
||
}
|
||
}
|
||
|
||
MarkArea {
|
||
id: markAreaItem
|
||
|
||
anchors.bottom: equipAreaItem.top
|
||
x: 31
|
||
}
|
||
|
||
Image {
|
||
id: chain
|
||
visible: root.chained
|
||
source: SkinBank.PHOTO_DIR + "chain"
|
||
anchors.horizontalCenter: parent.horizontalCenter
|
||
y: 72
|
||
}
|
||
|
||
Image {
|
||
// id: saveme
|
||
visible: (root.dead && !root.rest) || root.dying || root.surrendered
|
||
source: {
|
||
if (root.surrendered) {
|
||
return SkinBank.DEATH_DIR + "surrender";
|
||
} else if (root.dead) {
|
||
return SkinBank.getRoleDeathPic(root.role);
|
||
}
|
||
return SkinBank.DEATH_DIR + "saveme";
|
||
}
|
||
anchors.centerIn: photoMask
|
||
}
|
||
|
||
Image {
|
||
id: netstat
|
||
source: SkinBank.STATE_DIR + root.netstate
|
||
x: photoMask.x
|
||
y: photoMask.y
|
||
scale: 0.9
|
||
transformOrigin: Item.TopLeft
|
||
}
|
||
|
||
Image {
|
||
id: handcardNum
|
||
source: SkinBank.PHOTO_DIR + "handcard"
|
||
anchors.bottom: parent.bottom
|
||
anchors.bottomMargin: -6
|
||
x: -6
|
||
|
||
Text {
|
||
text: {
|
||
if (root.maxCard === root.hp || root.hp < 0) {
|
||
return root.handcards;
|
||
} else {
|
||
const maxCard = root.maxCard < 900 ? root.maxCard : "∞";
|
||
return root.handcards + "/" + maxCard;
|
||
}
|
||
}
|
||
font.family: fontLibian.name
|
||
font.pixelSize: (root.maxCard === root.hp || root.hp < 0 ) ? 32 : 27
|
||
//font.weight: 30
|
||
color: "white"
|
||
anchors.horizontalCenter: parent.horizontalCenter
|
||
anchors.bottom: parent.bottom
|
||
anchors.bottomMargin: 4
|
||
style: Text.Outline
|
||
}
|
||
}
|
||
|
||
TapHandler {
|
||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.NoButton
|
||
gesturePolicy: TapHandler.WithinBounds
|
||
|
||
onTapped: (p, btn) => {
|
||
if (btn === Qt.LeftButton || btn === Qt.NoButton) {
|
||
if (parent.state != "candidate" || !parent.selectable) {
|
||
return;
|
||
}
|
||
parent.selected = !parent.selected;
|
||
} else if (btn === Qt.RightButton) {
|
||
parent.showDetail();
|
||
}
|
||
}
|
||
|
||
onLongPressed: {
|
||
parent.showDetail();
|
||
}
|
||
}
|
||
|
||
RoleComboBox {
|
||
id: role
|
||
value: {
|
||
if (root.role === "hidden") return "hidden";
|
||
lcall("RoleVisibility", root.playerid) ? root.role : "unknown";
|
||
}
|
||
anchors.top: parent.top
|
||
anchors.topMargin: -4
|
||
anchors.right: parent.right
|
||
anchors.rightMargin: -4
|
||
}
|
||
|
||
LimitSkillArea {
|
||
id: limitSkills
|
||
anchors.top: parent.top
|
||
anchors.right: parent.right
|
||
anchors.topMargin: role.height + 2
|
||
anchors.rightMargin: 30
|
||
}
|
||
|
||
GlowText {
|
||
id: playerName
|
||
anchors.horizontalCenter: parent.horizontalCenter
|
||
anchors.top: parent.top
|
||
anchors.topMargin: 2
|
||
width: parent.width - role.width - hp.width - 20
|
||
|
||
font.pixelSize: 16
|
||
text: {
|
||
let ret = screenName;
|
||
if (config.blockedUsers?.includes(screenName))
|
||
ret = luatr("<Blocked> ") + ret;
|
||
return ret;
|
||
}
|
||
elide: root.playerid === Self.id ? Text.ElideNone : Text.ElideMiddle
|
||
horizontalAlignment: Qt.AlignHCenter
|
||
glow.radius: 8
|
||
}
|
||
|
||
Image {
|
||
visible: root.state === "candidate" && !selectable && !selected
|
||
source: SkinBank.PHOTO_DIR + "disable"
|
||
x: 31; y: -21
|
||
}
|
||
|
||
GlowText {
|
||
id: seatNum
|
||
visible: !progressBar.visible
|
||
anchors.horizontalCenter: parent.horizontalCenter
|
||
anchors.bottom: parent.bottom
|
||
anchors.bottomMargin: -32
|
||
property var seatChr: [
|
||
"一", "二", "三", "四", "五", "六",
|
||
"七", "八", "九", "十", "十一", "十二",
|
||
]
|
||
font.family: fontLi2.name
|
||
font.pixelSize: 32
|
||
text: seatChr[seatNumber - 1]
|
||
|
||
glow.color: "brown"
|
||
glow.spread: 0.2
|
||
glow.radius: 8
|
||
//glow.samples: 12
|
||
}
|
||
|
||
SequentialAnimation {
|
||
id: trembleAnimation
|
||
running: false
|
||
PropertyAnimation {
|
||
target: root
|
||
property: "x"
|
||
to: root.x - 20
|
||
easing.type: Easing.InQuad
|
||
duration: 100
|
||
}
|
||
PropertyAnimation {
|
||
target: root
|
||
property: "x"
|
||
to: root.x
|
||
easing.type: Easing.OutQuad
|
||
duration: 100
|
||
}
|
||
}
|
||
|
||
function tremble() {
|
||
trembleAnimation.start()
|
||
}
|
||
|
||
ProgressBar {
|
||
id: progressBar
|
||
width: parent.width
|
||
height: 4
|
||
anchors.bottom: parent.bottom
|
||
anchors.bottomMargin: -4
|
||
from: 0.0
|
||
to: 100.0
|
||
|
||
visible: false
|
||
NumberAnimation on value {
|
||
running: progressBar.visible
|
||
from: 100.0
|
||
to: 0.0
|
||
duration: config.roomTimeout * 1000
|
||
|
||
onFinished: {
|
||
progressBar.visible = false;
|
||
root.progressTip = "";
|
||
}
|
||
}
|
||
}
|
||
|
||
Image {
|
||
anchors.top: progressBar.bottom
|
||
anchors.topMargin: 1
|
||
source: SkinBank.PHOTO_DIR + "control/tip"
|
||
visible: progressTip.text != ""
|
||
Text {
|
||
id: progressTip
|
||
font.family: fontLibian.name
|
||
font.pixelSize: 18
|
||
x: 18
|
||
color: "white"
|
||
text: ""
|
||
}
|
||
}
|
||
|
||
PixmapAnimation {
|
||
id: animSelectable
|
||
source: SkinBank.PIXANIM_DIR + "selectable"
|
||
anchors.centerIn: parent
|
||
loop: true
|
||
visible: root.state === "candidate" && selectable
|
||
}
|
||
|
||
InvisibleCardArea {
|
||
id: handcardAreaItem
|
||
anchors.centerIn: parent
|
||
}
|
||
|
||
DelayedTrickArea {
|
||
id: delayedTrickAreaItem
|
||
anchors.bottom: parent.bottom
|
||
anchors.bottomMargin: 8
|
||
}
|
||
|
||
PicMarkArea {
|
||
id: picMarkAreaItem
|
||
|
||
anchors.top: parent.bottom
|
||
anchors.right: parent.right
|
||
anchors.topMargin: -4
|
||
}
|
||
|
||
InvisibleCardArea {
|
||
id: defaultArea
|
||
anchors.centerIn: parent
|
||
}
|
||
|
||
Rectangle {
|
||
id: chat
|
||
color: "#F2ECD7"
|
||
radius: 4
|
||
opacity: 0
|
||
width: parent.width
|
||
height: childrenRect.height + 8
|
||
property string text: ""
|
||
visible: false
|
||
Text {
|
||
width: parent.width - 8
|
||
x: 4
|
||
y: 4
|
||
text: parent.text
|
||
wrapMode: Text.WrapAnywhere
|
||
font.family: fontLibian.name
|
||
font.pixelSize: 20
|
||
}
|
||
SequentialAnimation {
|
||
id: chatAnim
|
||
PropertyAnimation {
|
||
target: chat
|
||
property: "opacity"
|
||
to: 0.9
|
||
duration: 200
|
||
}
|
||
NumberAnimation {
|
||
duration: 2500
|
||
}
|
||
PropertyAnimation {
|
||
target: chat
|
||
property: "opacity"
|
||
to: 0
|
||
duration: 150
|
||
}
|
||
onFinished: chat.visible = false;
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
color: "white"
|
||
height: 20
|
||
width: 20
|
||
visible: distance != -1
|
||
Text {
|
||
text: distance
|
||
anchors.centerIn: parent
|
||
}
|
||
}
|
||
|
||
RowLayout {
|
||
anchors.centerIn: parent
|
||
spacing: 5
|
||
|
||
Repeater {
|
||
model: root.targetTip
|
||
|
||
Item {
|
||
Layout.alignment: Qt.AlignHCenter
|
||
width: 30
|
||
|
||
GlowText {
|
||
anchors.centerIn: parent
|
||
visible: modelData.type === "normal"
|
||
text: Util.processPrompt(modelData.content)
|
||
font.family: fontLibian.name
|
||
color: "#F7F589"
|
||
font.pixelSize: 30
|
||
font.bold: true
|
||
glow.color: "black"
|
||
glow.spread: 0.3
|
||
glow.radius: 5
|
||
horizontalAlignment: Text.AlignHCenter
|
||
wrapMode: Text.WrapAnywhere
|
||
width: 30
|
||
}
|
||
|
||
Text {
|
||
anchors.centerIn: parent
|
||
visible: modelData.type === "warning"
|
||
font.family: fontLibian.name
|
||
font.pixelSize: 24
|
||
opacity: 0.9
|
||
horizontalAlignment: Text.AlignHCenter
|
||
lineHeight: 24
|
||
lineHeightMode: Text.FixedHeight
|
||
color: "#EAC28A"
|
||
width: 24
|
||
wrapMode: Text.WrapAnywhere
|
||
style: Text.Outline
|
||
styleColor: "#83231F"
|
||
text: Util.processPrompt(modelData.content)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
color: "#CC2E2C27"
|
||
radius: 6
|
||
border.color: "#A6967A"
|
||
border.width: 1
|
||
width: 44
|
||
height: 112
|
||
/* 有点小问题,因为绝大部分都是手机玩家我还是无脑放左
|
||
x: {
|
||
const roomX = mapToItem(roomScene, root.x, root.y).x;
|
||
if (roomX < 48) return 175;
|
||
return -44;
|
||
}
|
||
*/
|
||
x: -44
|
||
y: 128
|
||
visible: {
|
||
if (root.playerid === Self.id) return false;
|
||
if (root.handcards === 0) return false; // 优先绑定再判buddy,否则不会更新
|
||
if (!lcall("IsMyBuddy", Self.id, root.playerid) &&
|
||
!lcall("HasVisibleCard", Self.id, root.playerid)) return false;
|
||
return true;
|
||
}
|
||
|
||
Text {
|
||
x: 2; y: 2
|
||
width: 42
|
||
text: {
|
||
if (!parent.visible) return "";
|
||
const unused = root.handcards; // 绑定
|
||
const ids = lcall("GetPlayerHandcards", root.playerid);
|
||
const txt = [];
|
||
for (const cid of ids) {
|
||
if (txt.length >= 4) {
|
||
// txt.push(" ...");
|
||
txt.push("...");
|
||
break;
|
||
}
|
||
if (!lcall("CardVisibility", cid)) continue;
|
||
const data = lcall("GetCardData", cid);
|
||
let a = luatr(data.name);
|
||
/* if (a.length === 1) {
|
||
a = " " + a;
|
||
} else */
|
||
if (a.length >= 2) {
|
||
a = a.slice(0, 2);
|
||
}
|
||
txt.push(a);
|
||
}
|
||
|
||
if (txt.length < 5) {
|
||
const unknownCards = ids.length - txt.length;
|
||
for (let i = 0; i < unknownCards; i++) {
|
||
if (txt.length >= 4) {
|
||
txt.push("...");
|
||
break;
|
||
} else {
|
||
txt.push("?");
|
||
}
|
||
}
|
||
}
|
||
|
||
return txt.join("<br>");
|
||
}
|
||
color: "#E4D5A0"
|
||
font.family: fontLibian.name
|
||
font.pixelSize: 18
|
||
textFormat: Text.RichText
|
||
horizontalAlignment: Text.AlignHCenter
|
||
}
|
||
|
||
TapHandler {
|
||
onTapped: {
|
||
const params = { name: "hand_card" };
|
||
let data = lcall("GetPlayerHandcards", root.playerid);
|
||
data = data.filter((e) => lcall("CardVisibility", e));
|
||
|
||
params.ids = data;
|
||
|
||
// Just for using room's right drawer
|
||
roomScene.startCheat("../RoomElement/ViewPile", params);
|
||
}
|
||
}
|
||
}
|
||
|
||
onGeneralChanged: {
|
||
if (!roomScene.isStarted) return;
|
||
const text = luatr(general);
|
||
if (text.length > 6) {
|
||
generalName.text = "";
|
||
longGeneralName.text = text;
|
||
} else {
|
||
generalName.text = text;
|
||
longGeneralName.text = "";
|
||
}
|
||
}
|
||
|
||
onDeputyGeneralChanged: {
|
||
if (!roomScene.isStarted) return;
|
||
const text = luatr(deputyGeneral);
|
||
if (text.length > 6) {
|
||
deputyGeneralName.text = "";
|
||
longDeputyGeneralName.text = text;
|
||
} else {
|
||
deputyGeneralName.text = text;
|
||
longDeputyGeneralName.text = "";
|
||
}
|
||
}
|
||
|
||
function chat(msg) {
|
||
chat.text = msg;
|
||
chat.visible = true;
|
||
chatAnim.restart();
|
||
}
|
||
|
||
function updateLimitSkill(skill, time) {
|
||
limitSkills.update(skill, time);
|
||
}
|
||
|
||
function showDetail() {
|
||
if (playerid === 0 || playerid === -1) {
|
||
return;
|
||
}
|
||
|
||
roomScene.startCheat("PlayerDetail", { photo: this });
|
||
}
|
||
}
|