mirror of
https://github.com/Qsgs-Fans/FreeKill.git
synced 2024-11-15 19:22:25 +08:00
Enhancement (#362)
1. 新增隐藏礼物选项
2. 无效技能ui显示🔒
3. 过期房间字符串显示删除线
5. 按钮键长按查看技能详情
6. 筛选房间功能
7. “禁用lua扩展”禁用
8. 调整服务器“从收藏移除”的ui,改为三点展开
9. 调整红温缩进
10. 房间内限制玩家名称长度(自己除外)
11. 玩家详情显示判定区
12. 房间内一览
13. 武将一览语音键增加按钮复制代码与文本(长按复制代码),悬停显示
14. 手牌排序多选:(默认)类型、点数、花色
15. 技能次数提示,指定为正数或0显示
16. 修复ArrangeCardsBox的报错
17. 手牌拖拽排序
18. 武将技能按顺序添加
This commit is contained in:
parent
3d942a24b0
commit
e8aacf1888
|
@ -56,11 +56,8 @@ Flickable {
|
|||
skillDesc.append(ret)
|
||||
}
|
||||
data.skill.forEach(t => {
|
||||
skillDesc.append("<b>" + luatr(t.name) + "</b>: " + t.description)
|
||||
});
|
||||
data.related_skill.forEach(t => {
|
||||
skillDesc.append("<font color=\"purple\"><b>" + luatr(t.name) +
|
||||
"</b>: " + t.description + "</font>")
|
||||
skillDesc.append((t.is_related_skill ? "<font color=\"purple\"><b>" : "<b>") + luatr(t.name) +
|
||||
"</b>: " + t.description + (t.is_related_skill ? "</font>" : ""));
|
||||
});
|
||||
skillDesc.append("\n");
|
||||
});
|
||||
|
|
|
@ -212,5 +212,17 @@ Flickable {
|
|||
skillDesc.append("--------------------");
|
||||
skillDesc.append("<b>" + luatr(t.name) + "</b>: " + luatr(":" + t.name));
|
||||
});
|
||||
|
||||
const judge = leval(
|
||||
`(function()
|
||||
local p = ClientInstance:getPlayerById(${id})
|
||||
return p.player_cards[Player.Judge]
|
||||
end)()`
|
||||
);
|
||||
judge.forEach(cid => {
|
||||
const t = lcall("GetCardData", cid);
|
||||
skillDesc.append("--------------------");
|
||||
skillDesc.append("<b>" + luatr(t.name) + "</b>: " + luatr(":" + t.name));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ ListView {
|
|||
}
|
||||
|
||||
Button {
|
||||
text: "Return to Bottom"
|
||||
text: luatr("Return to Bottom")
|
||||
visible: root.currentIndex !== logModel.count - 1
|
||||
onClicked: root.currentIndex = logModel.count - 1;
|
||||
}
|
||||
|
|
|
@ -20,12 +20,14 @@ QtObject {
|
|||
property string preferedMode
|
||||
property int preferedPlayerNum
|
||||
property int preferredGeneralNum
|
||||
property var preferredFilter
|
||||
property string ladyImg
|
||||
property real bgmVolume
|
||||
property bool disableMsgAudio
|
||||
property bool hideUseless
|
||||
property bool hideObserverChatter
|
||||
property bool rotateTableCard
|
||||
property bool hidePresents
|
||||
// property list<string> disabledGenerals: []
|
||||
// property list<var> disableGeneralSchemes: []
|
||||
// property int disableSchemeIdx: 0
|
||||
|
@ -126,6 +128,13 @@ QtObject {
|
|||
preferedMode = conf.preferedMode ?? "aaa_role_mode";
|
||||
preferedPlayerNum = conf.preferedPlayerNum ?? 2;
|
||||
preferredGeneralNum = conf.preferredGeneralNum ?? 3;
|
||||
preferredFilter = conf.preferredFilter ?? {
|
||||
name: "", // 房间名
|
||||
id: "", // 房间ID
|
||||
modes : [], // 游戏模式
|
||||
full : 2, // 满员,0满,1未满,2不限
|
||||
hasPassword : 2, // 密码,0有,1无,2不限
|
||||
};
|
||||
ladyImg = conf.ladyImg ?? AppPath + "/image/lady";
|
||||
Backend.volume = conf.effectVolume ?? 50.;
|
||||
bgmVolume = conf.bgmVolume ?? 50.;
|
||||
|
@ -133,6 +142,7 @@ QtObject {
|
|||
hideUseless = conf.hideUseless ?? false;
|
||||
hideObserverChatter = conf.hideObserverChatter ?? false;
|
||||
rotateTableCard = conf.rotateTableCard ?? false;
|
||||
hidePresents = conf.hidePresents ?? false;
|
||||
preferredTimeout = conf.preferredTimeout ?? 15;
|
||||
preferredLuckTime = conf.preferredLuckTime ?? 0;
|
||||
firstRun = conf.firstRun ?? true;
|
||||
|
@ -165,6 +175,7 @@ QtObject {
|
|||
// conf.disabledPack = disabledPack;
|
||||
conf.preferedMode = preferedMode;
|
||||
conf.preferedPlayerNum = preferedPlayerNum;
|
||||
conf.preferredFilter = preferredFilter;
|
||||
conf.ladyImg = ladyImg;
|
||||
conf.preferredGeneralNum = preferredGeneralNum;
|
||||
conf.effectVolume = Backend.volume;
|
||||
|
@ -173,6 +184,7 @@ QtObject {
|
|||
conf.hideUseless = hideUseless;
|
||||
conf.hideObserverChatter = hideObserverChatter;
|
||||
conf.rotateTableCard = rotateTableCard;
|
||||
conf.hidePresents = hidePresents;
|
||||
conf.preferredTimeout = preferredTimeout;
|
||||
conf.preferredLuckTime = preferredLuckTime;
|
||||
conf.firstRun = firstRun;
|
||||
|
|
|
@ -70,5 +70,13 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: luatr("Hide presents")
|
||||
checked: config.hidePresents
|
||||
onCheckedChanged: {
|
||||
config.hidePresents = checked;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
288
Fk/LobbyElement/FilterRoom.qml
Normal file
288
Fk/LobbyElement/FilterRoom.qml
Normal file
|
@ -0,0 +1,288 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
Flickable {
|
||||
id: root
|
||||
height: parent.height
|
||||
width: layout.width
|
||||
anchors.fill: parent
|
||||
anchors.margins: 16
|
||||
clip: true
|
||||
contentWidth: layout.width
|
||||
contentHeight: layout.height
|
||||
ScrollBar.vertical: ScrollBar {}
|
||||
ScrollBar.horizontal: ScrollBar {} // considering long game mode name
|
||||
|
||||
signal finished()
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.top: parent.top
|
||||
|
||||
Item { Layout.fillHeight: true }
|
||||
|
||||
// roomId, roomName, gameMode, playerNum, capacity, hasPassword, outdated
|
||||
|
||||
GridLayout {
|
||||
columns: 2
|
||||
|
||||
// roomName
|
||||
RowLayout {
|
||||
anchors.rightMargin: 8
|
||||
spacing: 16
|
||||
Text {
|
||||
text: luatr("Room Name")
|
||||
font.bold: true
|
||||
font.pixelSize: 14
|
||||
}
|
||||
TextField {
|
||||
id: name
|
||||
maximumLength: 64
|
||||
font.pixelSize: 18
|
||||
Layout.rightMargin: 16
|
||||
Layout.fillWidth: true
|
||||
text: config.preferredFilter.name
|
||||
}
|
||||
}
|
||||
|
||||
// roomId
|
||||
RowLayout {
|
||||
anchors.rightMargin: 8
|
||||
spacing: 16
|
||||
Text {
|
||||
text: luatr("Room ID")
|
||||
font.bold: true
|
||||
font.pixelSize: 14
|
||||
}
|
||||
TextField {
|
||||
id: id
|
||||
maximumLength: 64
|
||||
font.pixelSize: 18
|
||||
Layout.rightMargin: 16
|
||||
Layout.fillWidth: true
|
||||
text: config.preferredFilter.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// gameMode
|
||||
ButtonGroup {
|
||||
id: childModes
|
||||
exclusive: false
|
||||
checkState: parentModeBox.checkState
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: parentModeBox
|
||||
text: luatr("Game Mode")
|
||||
font.bold: true
|
||||
checkState: childModes.checkState
|
||||
}
|
||||
GridLayout {
|
||||
columns: 6
|
||||
|
||||
Repeater {
|
||||
id: modes
|
||||
model: ListModel {
|
||||
id: gameModeList
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: name
|
||||
checked: config.preferredFilter.modes.includes(name)
|
||||
leftPadding: indicator.width
|
||||
ButtonGroup.group: childModes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.rightMargin: 8
|
||||
// spacing: 64
|
||||
// Layout.fillWidth: true
|
||||
|
||||
// full
|
||||
Column {
|
||||
ButtonGroup {
|
||||
id: childFull
|
||||
exclusive: false
|
||||
checkState: parentFullBox.checkState
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: parentFullBox
|
||||
text: luatr("Room Fullness")
|
||||
font.bold: true
|
||||
checkState: childFull.checkState
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
columns: 6
|
||||
|
||||
Repeater {
|
||||
id: fullStates
|
||||
model: ["Full", "Not Full"]
|
||||
|
||||
CheckBox {
|
||||
text: luatr(modelData)
|
||||
checked: config.preferredFilter.full === index
|
||||
leftPadding: indicator.width
|
||||
ButtonGroup.group: childFull
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hasPassword
|
||||
Column {
|
||||
ButtonGroup {
|
||||
id: childPw
|
||||
exclusive: false
|
||||
checkState: parentPwBox.checkState
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: parentPwBox
|
||||
text: luatr("Room Password")
|
||||
font.bold: true
|
||||
checkState: childPw.checkState
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
columns: 6
|
||||
|
||||
Repeater {
|
||||
id: pwStates
|
||||
model: ["Has Password", "No Password"]
|
||||
|
||||
CheckBox {
|
||||
text: luatr(modelData)
|
||||
checked: config.preferredFilter.hasPassword === index
|
||||
leftPadding: indicator.width
|
||||
ButtonGroup.group: childPw
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: luatr("Clear")
|
||||
onClicked: {
|
||||
opTimer.start();
|
||||
config.preferredFilter = {
|
||||
name: "",
|
||||
id: "",
|
||||
modes : [],
|
||||
full : 2,
|
||||
hasPassword : 2,
|
||||
}
|
||||
config.preferredFilterChanged();
|
||||
ClientInstance.notifyServer("RefreshRoomList", "");
|
||||
lobby_dialog.item.finished();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: luatr("Filter")
|
||||
// width: 200
|
||||
// enabled: !opTimer.running
|
||||
onClicked: {
|
||||
// opTimer.start();
|
||||
filterRoom();
|
||||
root.finished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// capacity
|
||||
/*
|
||||
Column {
|
||||
ButtonGroup {
|
||||
id: childCapacity
|
||||
exclusive: false
|
||||
checkState: parentCapacityBox.checkState
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: parentCapacityBox
|
||||
text: luatr("Room Capacity")
|
||||
font.bold: true
|
||||
checkState: childCapacity.checkState
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
columns: 6
|
||||
|
||||
Repeater {
|
||||
id: capacityStates
|
||||
model: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
||||
|
||||
CheckBox {
|
||||
text: modelData
|
||||
checked: false
|
||||
leftPadding: indicator.width
|
||||
ButtonGroup.group: childCapacity
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Component.onCompleted: {
|
||||
const mode_data = lcall("GetGameModes");
|
||||
mode_data.forEach(d => {
|
||||
gameModeList.append(d);
|
||||
});
|
||||
}
|
||||
}
|
||||
function filterRoom() {
|
||||
let f = config.preferredFilter;
|
||||
|
||||
f.name = name.text;
|
||||
f.id = id.text;
|
||||
|
||||
// mode
|
||||
let modeList = [];
|
||||
if (parentModeBox.checkState === Qt.PartiallyChecked) {
|
||||
for (let index = 0; index < modes.count; index++) {
|
||||
var tCheckBox = modes.itemAt(index)
|
||||
if (tCheckBox.checked) {modeList.push(tCheckBox.text)}
|
||||
}
|
||||
}
|
||||
f.modes = modeList;
|
||||
|
||||
f.full = parentFullBox.checkState === Qt.PartiallyChecked ? (fullStates.itemAt(0).checked ? 0 : 1) : 2;
|
||||
f.hasPassword = parentPwBox.checkState === Qt.PartiallyChecked ? (pwStates.itemAt(0).checked ? 0 : 1) : 2;
|
||||
|
||||
// capacity
|
||||
/*
|
||||
let capacityList = [];
|
||||
if (parentCapacityBox.checkState === Qt.PartiallyChecked) {
|
||||
for (let index = 0; index < capacityStates.count; index++) {
|
||||
var nCheckBox = capacityStates.itemAt(index)
|
||||
if (nCheckBox.checked) {capacityList.push(parseInt(nCheckBox.text))}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
config.preferredFilterChanged();
|
||||
|
||||
for (let i = roomModel.count - 1; i >= 0; i--) {
|
||||
const r = roomModel.get(i);
|
||||
if ((name.text !== '' && !r.roomName.includes(name.text))
|
||||
|| (id.text !== '' && !r.roomId.toString().includes(id.text))
|
||||
|| (modeList.length > 0 && !modeList.includes(luatr(r.gameMode)))
|
||||
|| (f.full !== 2 &&
|
||||
(f.full === 0 ? r.playerNum < r.capacity : r.playerNum >= r.capacity))
|
||||
|| (f.hasPassword !== 2 &&
|
||||
(f.hasPassword === 0 ? !r.hasPassword : r.hasPassword))
|
||||
// || (capacityList.length > 0 && !capacityList.includes(r.capacity))
|
||||
) {
|
||||
roomModel.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,9 +22,11 @@ Flickable {
|
|||
anchors.top: parent.top
|
||||
anchors.topMargin: 8
|
||||
|
||||
/*
|
||||
Switch {
|
||||
text: luatr("Disable Extension")
|
||||
}
|
||||
*/
|
||||
|
||||
RowLayout {
|
||||
Text {
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
module Fk.LobbyElement
|
||||
AudioSetting 1.0 AudioSetting.qml
|
||||
BanGeneralSetting 1.0 BanGeneralSetting.qml
|
||||
BGSetting 1.0 BGSetting.qml
|
||||
CreateRoom 1.0 CreateRoom.qml
|
||||
EditProfile 1.0 EditProfile.qml
|
||||
FilterRoom 1.0 FilterRoom.qml
|
||||
PersonalSettings 1.0 PersonalSettings.qml
|
||||
RoomGeneralSettings 1.0 RoomGeneralSettings.qml
|
||||
RoomPackageSettings 1.0 RoomPackageSettings.qml
|
||||
|
|
|
@ -8,6 +8,7 @@ import Fk.RoomElement
|
|||
|
||||
Item {
|
||||
id: root
|
||||
objectName: "CardsOverview"
|
||||
|
||||
property bool loaded: false
|
||||
|
||||
|
@ -196,6 +197,7 @@ Item {
|
|||
property var cards
|
||||
function updateCard() {
|
||||
const data = lcall("GetCardData", cid);
|
||||
detailFlickable.contentY = 0; // 重置滚动条
|
||||
const suitTable = {
|
||||
spade: "♠", heart: '<font color="red">♥</font>',
|
||||
club: "♣", diamond: '<font color="red">♦</font>',
|
||||
|
@ -234,6 +236,7 @@ Item {
|
|||
}
|
||||
|
||||
Flickable {
|
||||
id: detailFlickable
|
||||
flickableDirection: Flickable.VerticalFlick
|
||||
contentHeight: detailLayout.height
|
||||
width: parent.width - 40
|
||||
|
@ -323,6 +326,7 @@ Item {
|
|||
Button {
|
||||
text: luatr("Quit")
|
||||
anchors.right: parent.right
|
||||
visible: mainStack.currentItem.objectName === "CardsOverview"
|
||||
onClicked: {
|
||||
mainStack.pop();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import "RoomLogic.js" as RoomLogic
|
|||
|
||||
Item {
|
||||
id: root
|
||||
objectName: "GeneralsOverview"
|
||||
|
||||
property bool loaded: false
|
||||
property int stat: 0 // 0=normal 1=banPkg 2=banChara
|
||||
|
@ -165,6 +166,7 @@ Item {
|
|||
return luatr("BanGeneral");
|
||||
}
|
||||
enabled: stat !== 1
|
||||
visible: mainStack.currentItem.objectName === "GeneralsOverview"
|
||||
onClicked: {
|
||||
if (stat === 0) {
|
||||
stat = 2;
|
||||
|
@ -182,6 +184,7 @@ Item {
|
|||
return luatr("BanPackage");
|
||||
}
|
||||
enabled: stat !== 2
|
||||
visible: mainStack.currentItem.objectName === "GeneralsOverview"
|
||||
onClicked: {
|
||||
if (stat === 0) {
|
||||
stat = 1;
|
||||
|
@ -194,6 +197,7 @@ Item {
|
|||
ToolButton {
|
||||
text: luatr("Quit")
|
||||
font.pixelSize: 20
|
||||
visible: mainStack.currentItem.objectName === "GeneralsOverview"
|
||||
onClicked: {
|
||||
mainStack.pop();
|
||||
config.saveConf();
|
||||
|
@ -283,9 +287,9 @@ Item {
|
|||
const gdata = lcall("GetGeneralData", modelData);
|
||||
const pack = gdata.package;
|
||||
if (s.banPkg[pack]) {
|
||||
if (s.banPkg[pack].includes(modelData)) return '启用';
|
||||
if (s.banPkg[pack].includes(modelData)) return luatr('Enable');
|
||||
} else {
|
||||
if (!!s.normalPkg[pack]?.includes(modelData)) return '禁';
|
||||
if (!!s.normalPkg[pack]?.includes(modelData)) return luatr('Prohibit');
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
|
@ -370,17 +374,9 @@ Item {
|
|||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: {
|
||||
const orig = '$' + name + (idx ? idx.toString() : "");
|
||||
const orig_trans = luatr(orig);
|
||||
|
||||
// try general specific
|
||||
const orig_g = '$' + name + '_' + detailGeneralCard.name
|
||||
const orig = '$' + name + (specific ? '_' + detailGeneralCard.name : "")
|
||||
+ (idx ? idx.toString() : "");
|
||||
const orig_g_trans = luatr(orig_g);
|
||||
|
||||
if (orig_g_trans !== orig_g) {
|
||||
return orig_g_trans;
|
||||
}
|
||||
const orig_trans = luatr(orig);
|
||||
|
||||
if (orig_trans !== orig) {
|
||||
return orig_trans;
|
||||
|
@ -396,10 +392,51 @@ Item {
|
|||
callbacks["LogEvent"]({
|
||||
type: "PlaySkillSound",
|
||||
name: name,
|
||||
general: detailGeneralCard.name,
|
||||
general: specific ? detailGeneralCard.name : null, // 分化特别和一般
|
||||
i: idx,
|
||||
});
|
||||
}
|
||||
|
||||
onPressAndHold: {
|
||||
Backend.copyToClipboard('$' + name + (specific ? '_' + detailGeneralCard.name : "")
|
||||
+ (idx ? idx.toString() : "") + ':');
|
||||
toast.show(luatr("Audio Code Copy Success"));
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Layout.preferredWidth: 32
|
||||
Layout.preferredHeight: 32
|
||||
visible: parent.hovered
|
||||
text: "⋮"
|
||||
onClicked: {
|
||||
if (skillAudioMenu.visible){
|
||||
skillAudioMenu.close();
|
||||
} else {
|
||||
skillAudioMenu.open();
|
||||
}
|
||||
}
|
||||
Menu {
|
||||
id: skillAudioMenu
|
||||
MenuItem {
|
||||
text: luatr("Copy Audio Code")
|
||||
onTriggered: {
|
||||
Backend.copyToClipboard('$' + name + (specific ? '_' + detailGeneralCard.name : "")
|
||||
+ (idx ? idx.toString() : "") + ':');
|
||||
toast.show(luatr("Audio Code Copy Success"));
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
text: luatr("Copy Audio Text")
|
||||
onTriggered: {
|
||||
Backend.copyToClipboard(luatr('$' + name + (specific ? '_' + detailGeneralCard.name : "")
|
||||
+ (idx ? idx.toString() : "")));
|
||||
toast.show(luatr("Audio Text Copy Success"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -427,7 +464,7 @@ Item {
|
|||
|
||||
if (Backend.exists(fname)) {
|
||||
ret = true;
|
||||
audioModel.append({ name: skill, idx: i });
|
||||
audioModel.append({ name: skill, idx: i, specific: true });
|
||||
} else {
|
||||
if (i > 0) break;
|
||||
}
|
||||
|
@ -445,7 +482,7 @@ Item {
|
|||
skill + (i !== 0 ? i.toString() : "") + ".mp3";
|
||||
|
||||
if (Backend.exists(fname)) {
|
||||
audioModel.append({ name: skill, idx: i });
|
||||
audioModel.append({ name: skill, idx: i, specific: false});
|
||||
} else {
|
||||
if (i > 0) break;
|
||||
}
|
||||
|
@ -465,6 +502,7 @@ Item {
|
|||
|
||||
function updateGeneral() {
|
||||
detailGeneralCard.name = general;
|
||||
detailFlickable.contentY = 0; // 重置滚动条
|
||||
const data = lcall("GetGeneralDetail", general);
|
||||
generalText.clear();
|
||||
audioModel.clear();
|
||||
|
@ -479,14 +517,8 @@ Item {
|
|||
}
|
||||
|
||||
data.skill.forEach(t => {
|
||||
generalText.append("<b>" + luatr(t.name) +
|
||||
"</b>: " + t.description);
|
||||
|
||||
addSkillAudio(t.name);
|
||||
});
|
||||
data.related_skill.forEach(t => {
|
||||
generalText.append("<font color=\"purple\"><b>" + luatr(t.name) +
|
||||
"</b>: " + t.description + "</font>");
|
||||
generalText.append((t.is_related_skill ? "<font color=\"purple\"><b>" : "<b>") + luatr(t.name) +
|
||||
"</b>: " + t.description + (t.is_related_skill ? "</font>" : ""));
|
||||
|
||||
addSkillAudio(t.name);
|
||||
});
|
||||
|
@ -521,6 +553,8 @@ Item {
|
|||
wrapMode: Text.WordWrap
|
||||
textFormat: TextEdit.RichText
|
||||
font.pixelSize: 16
|
||||
lineHeight: 21
|
||||
lineHeightMode: Text.FixedHeight
|
||||
function trans(str) {
|
||||
const ret = luatr(str);
|
||||
if (ret === str) {
|
||||
|
@ -530,13 +564,18 @@ Item {
|
|||
}
|
||||
text: {
|
||||
const general = generalDetail.general;
|
||||
return [
|
||||
luatr(lcall("GetGeneralData", general).package),
|
||||
const gdata = lcall("GetGeneralData", general);
|
||||
let ret = [
|
||||
luatr(gdata.package),
|
||||
luatr("Title") + trans("#" + general),
|
||||
luatr("Designer") + trans("designer:" + general),
|
||||
luatr("Voice Actor") + trans("cv:" + general),
|
||||
luatr("Illustrator") + trans("illustrator:" + general),
|
||||
].join("<br>");
|
||||
if (gdata.hidden) {
|
||||
ret += "<br><font color=\"grey\">" + luatr("Hidden General") + "</font>";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -547,6 +586,7 @@ Item {
|
|||
|
||||
Button {
|
||||
text: luatr("Set as Avatar")
|
||||
visible: mainStack.currentItem.objectName === "GeneralsOverview"
|
||||
enabled: detailGeneralCard.name !== "" && !opTimer.running
|
||||
&& Self.avatar !== detailGeneralCard.name
|
||||
onClicked: {
|
||||
|
@ -562,6 +602,7 @@ Item {
|
|||
}
|
||||
|
||||
Flickable {
|
||||
id: detailFlickable
|
||||
flickableDirection: Flickable.VerticalFlick
|
||||
contentHeight: detailLayout.height
|
||||
width: parent.width - 40 - generalInfo.width
|
||||
|
@ -628,6 +669,44 @@ Item {
|
|||
Backend.playSound("./packages/" + extension + "/audio/death/"
|
||||
+ general);
|
||||
}
|
||||
|
||||
onPressAndHold: {
|
||||
Backend.copyToClipboard("$~" + generalDetail.general);
|
||||
toast.show(luatr("Audio Code Copy Success"));
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Layout.preferredWidth: 32
|
||||
Layout.preferredHeight: 32
|
||||
visible: parent.hovered
|
||||
text: "⋮"
|
||||
onClicked: {
|
||||
if (deathAudioMenu.visible){
|
||||
deathAudioMenu.close();
|
||||
} else {
|
||||
deathAudioMenu.open();
|
||||
}
|
||||
}
|
||||
Menu {
|
||||
id: deathAudioMenu
|
||||
MenuItem {
|
||||
text: luatr("Copy Audio Code")
|
||||
onTriggered: {
|
||||
Backend.copyToClipboard("$~" + generalDetail.general);
|
||||
toast.show(luatr("Audio Code Copy Success"));
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
text: luatr("Copy Audio Text")
|
||||
onTriggered: {
|
||||
Backend.copyToClipboard(luatr("~" + generalDetail.general));
|
||||
toast.show(luatr("Audio Text Copy Success"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,6 +102,32 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
x: parent.width - 32
|
||||
y: parent.height / 2 - 8
|
||||
Layout.preferredWidth: 32
|
||||
Layout.preferredHeight: 32
|
||||
visible: !!favorite
|
||||
text: "⋮"
|
||||
onClicked: {
|
||||
if (menu.visible){
|
||||
menu.close();
|
||||
} else {
|
||||
menu.open();
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: menu
|
||||
MenuItem {
|
||||
text: qsTr("Remove from Favorites")
|
||||
onTriggered: {
|
||||
removeFavorite(addr, port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
x: 6
|
||||
height: parent.height
|
||||
|
@ -125,7 +151,7 @@ Item {
|
|||
height: childrenRect.height
|
||||
width: serverList.width
|
||||
Text {
|
||||
text: "已收藏服务器与公共服务器列表"
|
||||
text: qsTr("List of Favorites and Public Servers")
|
||||
font.pixelSize: 18
|
||||
x: 32; y: 8
|
||||
}
|
||||
|
@ -170,14 +196,14 @@ Item {
|
|||
id: addressEdit
|
||||
maximumLength: 64
|
||||
Layout.fillWidth: true
|
||||
placeholderText: "服务器地址"
|
||||
placeholderText: qsTr("Server Address")
|
||||
text: selectedServer?.addr ?? ""
|
||||
}
|
||||
TextField {
|
||||
id: portEdit
|
||||
maximumLength: 6
|
||||
Layout.fillWidth: true
|
||||
placeholderText: "端口"
|
||||
placeholderText: qsTr("Port")
|
||||
text: selectedServer?.port ?? ""
|
||||
}
|
||||
Flickable {
|
||||
|
@ -199,21 +225,21 @@ Item {
|
|||
id: usernameEdit
|
||||
maximumLength: 32
|
||||
Layout.fillWidth: true
|
||||
placeholderText: "用户名"
|
||||
placeholderText: qsTr("Username")
|
||||
text: selectedServer?.username ?? ""
|
||||
}
|
||||
TextField {
|
||||
id: passwordEdit
|
||||
maximumLength: 32
|
||||
Layout.fillWidth: true
|
||||
placeholderText: "密码"
|
||||
placeholderText: qsTr("Password")
|
||||
passwordCharacter: "*"
|
||||
echoMode: TextInput.Password
|
||||
text: selectedServer?.password ?? ""
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: "登录(首次登录自动注册)"
|
||||
text: qsTr("LOGIN (Auto-registration)")
|
||||
Layout.fillWidth: true
|
||||
enabled: !!(addressEdit.text && portEdit.text &&
|
||||
usernameEdit.text && passwordEdit.text)
|
||||
|
@ -237,9 +263,9 @@ Item {
|
|||
}
|
||||
}
|
||||
Button {
|
||||
text: "从收藏夹删除"
|
||||
text: qsTr("Remove from Favorites")
|
||||
Layout.fillWidth: true
|
||||
visible: !!(selectedServer?.favorite)
|
||||
visible: false // !!(selectedServer?.favorite) // 暂时禁用
|
||||
onClicked: {
|
||||
removeFavorite(selectedServer.addr, selectedServer.port);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ Item {
|
|||
text: roomName
|
||||
// color: outdated ? "gray" : "black"
|
||||
font.pixelSize: 16
|
||||
font.strikeout: outdated
|
||||
// elide: Label.ElideRight
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
|
@ -44,6 +45,7 @@ Item {
|
|||
Text {
|
||||
id: roomIdText
|
||||
text: luatr(gameMode) + ' #' + roomId
|
||||
font.strikeout: outdated
|
||||
anchors.top: roomNameText.bottom
|
||||
anchors.left: roomNameText.left
|
||||
}
|
||||
|
@ -119,7 +121,7 @@ Item {
|
|||
text: "在未来的版本中这一块区域将增加更多实用的功能,<br>"+
|
||||
"例如直接查看房间的各种配置信息<br>"+
|
||||
"以及更多与禁将有关的实用功能!"+
|
||||
"<font color='gray'>注:绿色按钮为试做型UI 后面优化</font>"
|
||||
"<font color='gray'>注:灰色按钮为试做型UI 后面优化</font>"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
|
||||
|
@ -195,6 +197,13 @@ Item {
|
|||
ClientInstance.notifyServer("RefreshRoomList", "");
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: luatr("Filter")
|
||||
onClicked: {
|
||||
lobby_dialog.sourceComponent = Qt.createComponent("../LobbyElement/FilterRoom.qml"); //roomFilterDialog;
|
||||
lobby_drawer.open();
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: luatr("Create Room")
|
||||
onClicked: {
|
||||
|
@ -313,7 +322,7 @@ Item {
|
|||
}
|
||||
}
|
||||
Button {
|
||||
text: luatr("Scenarios Overview")
|
||||
text: luatr("Modes Overview")
|
||||
onClicked: {
|
||||
mainStack.push(mainWindow.modesOverviewPage);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ Item {
|
|||
property int padding: 5
|
||||
|
||||
signal clicked
|
||||
signal rightClicked
|
||||
|
||||
id: button
|
||||
width: icon.width + title.implicitWidth + padding * 2
|
||||
|
@ -44,7 +45,19 @@ Item {
|
|||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.NoButton
|
||||
gesturePolicy: TapHandler.WithinBounds
|
||||
|
||||
onTapped: if (parent.enabled) parent.clicked()
|
||||
onTapped: (p, btn) => {
|
||||
if (parent.enabled) {
|
||||
if (btn === Qt.LeftButton || btn === Qt.NoButton) {
|
||||
parent.clicked();
|
||||
} else if (btn === Qt.RightButton) {
|
||||
parent.rightClicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onLongPressed: {
|
||||
parent.rightClicked();
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
|
|
|
@ -5,6 +5,7 @@ import QtQuick.Layouts
|
|||
import QtQuick.Controls
|
||||
|
||||
Item {
|
||||
objectName: "ModesOverview"
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
|
@ -30,6 +31,7 @@ Item {
|
|||
TapHandler {
|
||||
onTapped: {
|
||||
listView.currentIndex = index;
|
||||
detailFlickable.contentY = 0; // 重置滚动条
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +42,7 @@ Item {
|
|||
Layout.fillHeight: true
|
||||
color: "#88EEEEEE"
|
||||
Flickable {
|
||||
id: detailFlickable
|
||||
width: parent.width - 16
|
||||
height: parent.height - 16
|
||||
anchors.centerIn: parent
|
||||
|
@ -62,6 +65,7 @@ Item {
|
|||
Button {
|
||||
text: luatr("Quit")
|
||||
anchors.bottom: parent.bottom
|
||||
visible: mainStack.currentItem.objectName === "ModesOverview"
|
||||
onClicked: {
|
||||
mainStack.pop();
|
||||
}
|
||||
|
@ -72,5 +76,6 @@ Item {
|
|||
for (let d of mode_data) {
|
||||
modeList.append(d);
|
||||
}
|
||||
listView.currentIndex = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,11 +100,12 @@ Item {
|
|||
Menu {
|
||||
id: menuContainer
|
||||
y: menuButton.height - 12
|
||||
width: 100
|
||||
width: parent.width * 1.8
|
||||
|
||||
MenuItem {
|
||||
id: quitButton
|
||||
text: luatr("Quit")
|
||||
icon.source: AppPath + "/image/modmaker/back"
|
||||
onClicked: {
|
||||
if (config.replaying) {
|
||||
Backend.controlReplayer("shutdown");
|
||||
|
@ -117,10 +118,57 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
id: volumeButton
|
||||
text: luatr("Audio Settings")
|
||||
icon.source: AppPath + "/image/button/tileicon/configure"
|
||||
onClicked: {
|
||||
volumeDialog.open();
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
title: luatr("Overview")
|
||||
icon.source: AppPath + "/image/button/tileicon/rule_summary"
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.color: palette.windowText
|
||||
MenuItem {
|
||||
id: generalButton
|
||||
text: luatr("Generals Overview")
|
||||
icon.source: AppPath + "/image/button/tileicon/general_overview"
|
||||
onClicked: {
|
||||
overviewLoader.overviewType = "Generals";
|
||||
overviewDialog.open();
|
||||
overviewLoader.item.loadPackages();
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
id: cardslButton
|
||||
text: luatr("Cards Overview")
|
||||
icon.source: AppPath + "/image/button/tileicon/card_overview"
|
||||
onClicked: {
|
||||
overviewLoader.overviewType = "Cards";
|
||||
overviewDialog.open();
|
||||
overviewLoader.item.loadPackages();
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
id: modesButton
|
||||
text: luatr("Modes Overview")
|
||||
icon.source: AppPath + "/image/misc/paper"
|
||||
onClicked: {
|
||||
overviewLoader.overviewType = "Modes";
|
||||
overviewDialog.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
id: surrenderButton
|
||||
enabled: !config.observing && !config.replaying
|
||||
enabled: !config.observing && !config.replaying && isStarted
|
||||
text: luatr("Surrender")
|
||||
icon.source: AppPath + "/image/misc/surrender"
|
||||
onClicked: {
|
||||
const photo = getPhoto(Self.id);
|
||||
if (isStarted && !(photo.dead && photo.rest <= 0)) {
|
||||
|
@ -130,21 +178,13 @@ Item {
|
|||
luatr('Surrender is disabled in this mode');
|
||||
} else {
|
||||
surrenderDialog.informativeText = surrenderCheck
|
||||
.map(str => `${luatr(str.text)}(${str.passed ? '√' : '×'})`)
|
||||
.map(str => `${luatr(str.text)}(${str.passed ? '✓' : '✗'})`)
|
||||
.join('<br>');
|
||||
}
|
||||
surrenderDialog.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
id: volumeButton
|
||||
text: luatr("Audio Settings")
|
||||
onClicked: {
|
||||
volumeDialog.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,7 +508,68 @@ Item {
|
|||
MetroButton {
|
||||
text: luatr("Sort Cards")
|
||||
textFont.pixelSize: 28
|
||||
onClicked: Logic.resortHandcards();
|
||||
onClicked: {
|
||||
if (lcall("CanSortHandcards", Self.id)) {
|
||||
let sortMethods = [];
|
||||
for (let index = 0; index < sortMenuRepeater.count; index++) {
|
||||
var tCheckBox = sortMenuRepeater.itemAt(index)
|
||||
sortMethods.push(tCheckBox.checked)
|
||||
}
|
||||
Logic.sortHandcards(sortMethods);
|
||||
}
|
||||
}
|
||||
|
||||
onRightClicked: {
|
||||
if (sortMenu.visible) {
|
||||
sortMenu.close();
|
||||
} else {
|
||||
sortMenu.open();
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: sortMenu
|
||||
x: parent.width
|
||||
y: -25
|
||||
width: parent.width * 2
|
||||
background: Rectangle {
|
||||
color: "black"
|
||||
border.width: 3
|
||||
border.color: "white"
|
||||
opacity: 0.8
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: sortMenuRepeater
|
||||
model: ["Sort by Type", "Sort by Number", "Sort by Suit"]
|
||||
|
||||
CheckBox {
|
||||
id: control
|
||||
text: "<font color='white'>" + luatr(modelData) + "</font>"
|
||||
checked: modelData === "Sort by Type"
|
||||
font.pixelSize: 20
|
||||
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 26
|
||||
implicitHeight: 26
|
||||
x: control.leftPadding
|
||||
y: control.height / 2 - height / 2
|
||||
radius: 3
|
||||
border.color: "white"
|
||||
|
||||
Rectangle {
|
||||
width: 14
|
||||
height: 14
|
||||
x: 6
|
||||
y: 6
|
||||
radius: 2
|
||||
color: control.down ? "#17a81a" : "#21be2b"
|
||||
visible: control.checked
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MetroButton {
|
||||
text: luatr("Chat")
|
||||
|
@ -994,6 +1095,28 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Popup {
|
||||
id: overviewDialog
|
||||
width: realMainWin.width * 0.75
|
||||
height: realMainWin.height * 0.75
|
||||
anchors.centerIn: parent
|
||||
background: Rectangle {
|
||||
color: "#EEEEEEEE"
|
||||
radius: 5
|
||||
border.color: "#A6967A"
|
||||
border.width: 1
|
||||
}
|
||||
Loader {
|
||||
id: overviewLoader
|
||||
property string overviewType: "Generals"
|
||||
anchors.centerIn: parent
|
||||
width: parent.width / mainWindow.scale
|
||||
height: parent.height / mainWindow.scale
|
||||
scale: mainWindow.scale
|
||||
source: AppPath + "/Fk/Pages/" + overviewType + "Overview.qml"
|
||||
}
|
||||
}
|
||||
|
||||
GlowText {
|
||||
anchors.centerIn: dashboard
|
||||
visible: Logic.getPhoto(Self.id).rest > 0 && !config.observing
|
||||
|
@ -1127,6 +1250,8 @@ Item {
|
|||
const general = luatr(data.general);
|
||||
|
||||
if (msg.startsWith("!")) {
|
||||
if (config.hidePresents)
|
||||
return true;
|
||||
const splited = msg.split(":");
|
||||
const type = splited[0].slice(1);
|
||||
switch (type) {
|
||||
|
|
|
@ -297,13 +297,27 @@ function moveCards(moves) {
|
|||
}
|
||||
}
|
||||
|
||||
const suitInteger = {
|
||||
spade: 1, heart: 3,
|
||||
club: 2, diamond: 4,
|
||||
}
|
||||
|
||||
|
||||
function resortHandcards() {
|
||||
function sortHandcards(sortMethods) {
|
||||
if (!dashboard.handcardArea.cards.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cardType = sortMethods[0];
|
||||
const cardNum = sortMethods[1];
|
||||
const cardSuit = sortMethods[2];
|
||||
|
||||
if (!cardType && !cardNum && !cardSuit) {
|
||||
return;
|
||||
}
|
||||
|
||||
let sortOutputs = [];
|
||||
let sortedStatus = [];
|
||||
|
||||
const subtypeString2Number = {
|
||||
["none"]: Card.SubtypeNone,
|
||||
["delayed_trick"]: Card.SubtypeDelayedTrick,
|
||||
|
@ -318,7 +332,11 @@ function resortHandcards() {
|
|||
return c.cid;
|
||||
})
|
||||
|
||||
dashboard.handcardArea.cards.sort((prev, next) => {
|
||||
let sortedByType = true;
|
||||
let handcards
|
||||
if (cardType) {
|
||||
handcards = dashboard.handcardArea.cards.slice(0);
|
||||
handcards.sort((prev, next) => {
|
||||
if (prev.footnote === next.footnote) {
|
||||
if (prev.type === next.type) {
|
||||
const prevSubtypeNumber = subtypeString2Number[prev.subtype];
|
||||
|
@ -345,24 +363,30 @@ function resortHandcards() {
|
|||
}
|
||||
});
|
||||
|
||||
// Check if the cards are sorted by type
|
||||
let i = 0;
|
||||
let resort = true;
|
||||
dashboard.handcardArea.cards.forEach(c => {
|
||||
handcards.every(c => {
|
||||
if (hand[i] !== c.cid) {
|
||||
resort = false;
|
||||
return;
|
||||
sortedByType = false;
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
return true;
|
||||
})
|
||||
sortOutputs.push(handcards);
|
||||
sortedStatus.push(sortedByType);
|
||||
}
|
||||
|
||||
if (resort) {
|
||||
dashboard.handcardArea.cards.sort((prev, next) => {
|
||||
let sortedByNum = true;
|
||||
if (cardNum) {
|
||||
handcards = dashboard.handcardArea.cards.slice(0);
|
||||
handcards.sort((prev, next) => {
|
||||
if (prev.footnote === next.footnote) {
|
||||
if (prev.number === next.number) { // 按点数排
|
||||
if (prev.suit === next.suit) {
|
||||
if (prev.number === next.number) {
|
||||
if (suitInteger[prev.suit] === suitInteger[next.suit]) {
|
||||
return prev.cid - next.cid;
|
||||
} else {
|
||||
return prev.suit - next.suit;
|
||||
return suitInteger[prev.suit] - suitInteger[next.suit];
|
||||
}
|
||||
} else {
|
||||
return prev.number - next.number;
|
||||
|
@ -371,8 +395,61 @@ function resortHandcards() {
|
|||
return prev.footnote > next.footnote ? 1 : -1;
|
||||
}
|
||||
});
|
||||
|
||||
let i = 0;
|
||||
handcards.every(c => {
|
||||
if (hand[i] !== c.cid) {
|
||||
sortedByNum = false;
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
return true;
|
||||
})
|
||||
sortOutputs.push(handcards);
|
||||
sortedStatus.push(sortedByNum);
|
||||
}
|
||||
|
||||
let sortedBySuit = true;
|
||||
if (cardSuit) {
|
||||
handcards = dashboard.handcardArea.cards.slice(0);
|
||||
handcards.sort((prev, next) => {
|
||||
if (prev.footnote === next.footnote) {
|
||||
if (suitInteger[prev.suit] === suitInteger[next.suit]) {
|
||||
if (prev.number === next.number) {
|
||||
return prev.cid - next.cid;
|
||||
} else {
|
||||
return prev.number - next.number;
|
||||
}
|
||||
} else {
|
||||
return suitInteger[prev.suit] - suitInteger[next.suit];
|
||||
}
|
||||
} else {
|
||||
return prev.footnote > next.footnote ? 1 : -1;
|
||||
}
|
||||
});
|
||||
|
||||
let i = 0;
|
||||
handcards.every(c => {
|
||||
if (hand[i] !== c.cid) {
|
||||
sortedBySuit = false;
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
return true;
|
||||
})
|
||||
sortOutputs.push(handcards);
|
||||
sortedStatus.push(sortedBySuit);
|
||||
}
|
||||
let output
|
||||
for (let i = 0; i < sortedStatus.length; i++) {
|
||||
if (sortedStatus[i]) {
|
||||
let j = i < sortedStatus.length - 1 ? i + 1 : 0;
|
||||
output = sortOutputs[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!output) output = sortOutputs[0];
|
||||
dashboard.handcardArea.cards = output;
|
||||
dashboard.handcardArea.updateCardPosition(true);
|
||||
}
|
||||
|
||||
|
@ -933,6 +1010,18 @@ callbacks["UpdateCard"] = (j) => {
|
|||
card.setData(lcall("GetCardData", id));
|
||||
}
|
||||
|
||||
callbacks["UpdateSkill"] = (j) => {
|
||||
const all_skills = [roomScene.dashboard.skillButtons, roomScene.dashboard.notActiveButtons];
|
||||
for (const skills of all_skills) {
|
||||
for (let i = 0; i < skills.count; i++) {
|
||||
const item = skills.itemAt(i);
|
||||
const dat = lcall("GetSkillStatus", item.orig);
|
||||
item.locked = dat.locked;
|
||||
item.times = dat.times;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callbacks["StartGame"] = (jsonData) => {
|
||||
roomScene.isStarted = true;
|
||||
|
||||
|
|
|
@ -82,8 +82,7 @@ GraphicsBox {
|
|||
}
|
||||
|
||||
Row {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 32
|
||||
|
||||
MetroButton {
|
||||
|
|
|
@ -69,7 +69,7 @@ Item {
|
|||
signal rightClicked()
|
||||
signal doubleClicked()
|
||||
signal thrown()
|
||||
signal released()
|
||||
signal released(var card)
|
||||
signal entered()
|
||||
signal exited()
|
||||
signal moveFinished()
|
||||
|
@ -287,7 +287,7 @@ Item {
|
|||
|
||||
onGrabChanged: (transtition, point) => {
|
||||
if (transtition !== PointerDevice.UngrabExclusive) return;
|
||||
parent.released();
|
||||
parent.released(root);
|
||||
if (autoBack)
|
||||
goBackAnimation.start();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ RowLayout {
|
|||
property int selected_card: -1
|
||||
|
||||
property alias skillButtons: skillPanel.skill_buttons
|
||||
property alias notActiveButtons: skillPanel.not_active_buttons
|
||||
|
||||
property var expanded_piles: ({}) // name -> int[]
|
||||
property var extra_cards: []
|
||||
|
|
|
@ -13,6 +13,7 @@ Item {
|
|||
property alias style: textItem.style
|
||||
property alias styleColor: textItem.styleColor
|
||||
property alias wrapMode: textItem.wrapMode
|
||||
property alias elide: textItem.elide
|
||||
property alias lineHeight: textItem.lineHeight
|
||||
property alias glow: glowItem
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ Item {
|
|||
property alias cards: cardArea.cards
|
||||
property alias length: cardArea.length
|
||||
property var selectedCards: []
|
||||
property var movepos
|
||||
|
||||
signal cardSelected(int cardId, bool selected)
|
||||
|
||||
|
@ -32,9 +33,11 @@ Item {
|
|||
function filterInputCard(card)
|
||||
{
|
||||
card.autoBack = true;
|
||||
card.draggable = true;
|
||||
card.draggable = lcall("CanSortHandcards", Self.id);
|
||||
card.selectable = false;
|
||||
card.clicked.connect(adjustCards);
|
||||
card.released.connect(updateCardReleased);
|
||||
card.xChanged.connect(updateCardDragging);
|
||||
}
|
||||
|
||||
function remove(outputs)
|
||||
|
@ -46,6 +49,8 @@ Item {
|
|||
card.draggable = false;
|
||||
card.selectable = false;
|
||||
card.selectedChanged.disconnect(adjustCards);
|
||||
card.released.disconnect(updateCardReleased);
|
||||
card.xChanged.disconnect(updateCardDragging);
|
||||
card.prohibitReason = "";
|
||||
}
|
||||
return result;
|
||||
|
@ -84,6 +89,49 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
function updateCardDragging()
|
||||
{
|
||||
let _card, c;
|
||||
let index;
|
||||
for (index = 0; index < cards.length; index++) {
|
||||
c = cards[index];
|
||||
if (c.dragging) {
|
||||
_card = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!_card) return;
|
||||
_card.goBackAnim.stop();
|
||||
_card.opacity = 0.8
|
||||
|
||||
let card;
|
||||
movepos = null;
|
||||
for (let i = 0; i < cards.length; i++) {
|
||||
card = cards[i];
|
||||
if (card.dragging) continue;
|
||||
|
||||
if (card.x > _card.x) {
|
||||
movepos = i - (index < i ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (movepos == null) { // 最右
|
||||
movepos = cards.length;
|
||||
}
|
||||
}
|
||||
|
||||
function updateCardReleased(_card)
|
||||
{
|
||||
let i;
|
||||
if (movepos != null) {
|
||||
i = cards.indexOf(_card);
|
||||
cards.splice(i, 1);
|
||||
cards.splice(movepos, 0, _card);
|
||||
movepos = null;
|
||||
}
|
||||
updateCardPosition(true);
|
||||
}
|
||||
|
||||
function adjustCards()
|
||||
{
|
||||
area.updateCardPosition(true);
|
||||
|
|
|
@ -566,6 +566,7 @@ Item {
|
|||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 2
|
||||
width: parent.width - role.width - hp.width - 20
|
||||
|
||||
font.pixelSize: 16
|
||||
text: {
|
||||
|
@ -574,7 +575,8 @@ Item {
|
|||
ret = luatr("<Blocked> ") + ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
elide: root.playerid === Self.id ? Text.ElideNone : Text.ElideMiddle
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
glow.radius: 8
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ Flickable {
|
|||
id: root
|
||||
property alias skill_buttons: skill_buttons
|
||||
property alias prelight_buttons: prelight_buttons
|
||||
property alias not_active_buttons: not_active_buttons
|
||||
|
||||
clip: true
|
||||
contentWidth: panel.width
|
||||
|
@ -91,6 +92,7 @@ Flickable {
|
|||
columnSpacing: 2
|
||||
rowSpacing: 2
|
||||
Repeater {
|
||||
id: not_active_buttons
|
||||
model: not_active_skills
|
||||
onItemAdded: parent.forceLayout()
|
||||
SkillButton {
|
||||
|
|
|
@ -11,6 +11,8 @@ Item {
|
|||
property string orig: ""
|
||||
property bool pressed: false
|
||||
property bool prelighted: false
|
||||
property bool locked: false
|
||||
property int times: -1
|
||||
|
||||
onEnabledChanged: {
|
||||
if (!enabled)
|
||||
|
@ -86,6 +88,76 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
source: AppPath + "/image/button/skill/locked.png"
|
||||
scale: 0.8
|
||||
z: 2
|
||||
visible: root.locked
|
||||
opacity: 0.8
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 12
|
||||
height: 12
|
||||
visible: root.times > -1
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: type === "notactive" ? -13 : 5
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 5
|
||||
|
||||
Rectangle {
|
||||
width: Math.max(15, 1.4 * count.contentWidth)
|
||||
height: 15
|
||||
radius: width * 0.5
|
||||
x: (parent.width - width) / 2
|
||||
y: -1.5
|
||||
color: "transparent"
|
||||
border.color: "#D2AD4A"
|
||||
border.width: 1.1
|
||||
}
|
||||
|
||||
Text {
|
||||
id: count
|
||||
anchors.centerIn: parent
|
||||
font.pixelSize: 16
|
||||
font.family: fontLibian.name
|
||||
font.bold: true
|
||||
text: root.times
|
||||
z: 1.5
|
||||
}
|
||||
|
||||
Glow {
|
||||
source: count
|
||||
anchors.fill: count
|
||||
color: "black"
|
||||
spread: 0.3
|
||||
radius: 5
|
||||
}
|
||||
|
||||
LinearGradient {
|
||||
anchors.fill: count
|
||||
z: 3
|
||||
source: count
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: "#FEF7C2"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 0.8
|
||||
color: "#D2AD4A"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: "#BE9878"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.NoButton
|
||||
onTapped: (p, btn) => {
|
||||
|
@ -95,6 +167,10 @@ Item {
|
|||
skillDetail.open();
|
||||
}
|
||||
}
|
||||
|
||||
onLongPressed: {
|
||||
skillDetail.open();
|
||||
}
|
||||
}
|
||||
|
||||
Popup {
|
||||
|
|
BIN
image/misc/paper.png
Normal file
BIN
image/misc/paper.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 752 B |
BIN
image/misc/surrender.png
Normal file
BIN
image/misc/surrender.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
1
include
1
include
|
@ -1 +0,0 @@
|
|||
Subproject commit 4fd2070d099d1f967d1070d72beb0fae2cb6e4be
|
|
@ -227,6 +227,10 @@
|
|||
<source>Edit Server</source>
|
||||
<translation>编辑服务器</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>List of Favorites and Public Servers</source>
|
||||
<translation>已收藏服务器与公共服务器列表</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Refresh List</source>
|
||||
<translation>刷新列表</translation>
|
||||
|
@ -239,6 +243,14 @@
|
|||
<source>Go Back</source>
|
||||
<translation>返回</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server Address</source>
|
||||
<translation>服务器地址</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Port</source>
|
||||
<translation>端口</translation>
|
||||
</message>
|
||||
|
||||
<message>
|
||||
<source>@VersionMismatch</source>
|
||||
|
@ -286,6 +298,14 @@
|
|||
<source>Delete Server</source>
|
||||
<translation>删除服务器</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>LOGIN (Auto-registration)</source>
|
||||
<translation>登录(首次登录自动注册)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove from Favorites</source>
|
||||
<translation>从收藏夹删除</translation>
|
||||
</message>
|
||||
</context>
|
||||
|
||||
<context>
|
||||
|
@ -549,8 +569,7 @@
|
|||
<source>tutor_msg_3</source>
|
||||
<translation>新月杀本身默认只含标准包!<br>
|
||||
想要体验更多武将,就要通过联机获取!<br>
|
||||
在主界面点击“加入服务器” -> 添加服务器。<br>
|
||||
(目前推荐的服务器IP是175.178.66.93)</translation>
|
||||
在主界面点击“加入服务器” -> 进入公共服务器或添加新服务器。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>tutor_msg_4</source>
|
||||
|
@ -561,8 +580,8 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>tutor_msg_5</source>
|
||||
<translation>更多指引可以去查阅下载链接附送的pdf。
|
||||
这些pdf都是由开发者们编写的,不仅能让你快速掌握游戏的深入玩法,
|
||||
<translation>更多指引可以去查阅新月之书:<a href="https://fkbook-all-in-one.readthedocs.io">https://fkbook-all-in-one.readthedocs.io</a><br>。
|
||||
这些文档都是由开发者们编写的,不仅能让你快速掌握游戏的深入玩法,
|
||||
还可以告诉你关于开设私服、制作拓展之类的知识。</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
Loading…
Reference in New Issue
Block a user