Qmlfix (#152)
- 战报自动滚动 - 长按手牌显示提示 - 选将阶段可查看技能 - 减小延时锦囊的尺寸 - 在转圈界面显示提示文本 - 手气卡机制
This commit is contained in:
parent
fc3a7dbda7
commit
ce2cae0aa5
|
@ -32,6 +32,7 @@ cp ../server/init.sql assets/res/server
|
||||||
cp ../LICENSE assets/res
|
cp ../LICENSE assets/res
|
||||||
cp ../zh_CN.qm assets/res
|
cp ../zh_CN.qm assets/res
|
||||||
cp ../fk_ver assets/res
|
cp ../fk_ver assets/res
|
||||||
|
cp ../waiting_tips.txt assets/res
|
||||||
|
|
||||||
# Due to Qt Android's bug, we need make sure every directory has a subfile (not subdir)
|
# Due to Qt Android's bug, we need make sure every directory has a subfile (not subdir)
|
||||||
function fixDir() {
|
function fixDir() {
|
||||||
|
|
|
@ -31,6 +31,7 @@ Fk:loadTranslationTable{
|
||||||
["Player num"] = "玩家数目",
|
["Player num"] = "玩家数目",
|
||||||
["Select general num"] = "选将数目",
|
["Select general num"] = "选将数目",
|
||||||
["Operation timeout"] = "操作时长(秒)",
|
["Operation timeout"] = "操作时长(秒)",
|
||||||
|
["Luck Card Times"] = "手气卡次数",
|
||||||
["Game Mode"] = "游戏模式",
|
["Game Mode"] = "游戏模式",
|
||||||
["Enable free assign"] = "自由选将",
|
["Enable free assign"] = "自由选将",
|
||||||
["Enable deputy general"] = "启用副将机制",
|
["Enable deputy general"] = "启用副将机制",
|
||||||
|
@ -128,10 +129,13 @@ FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下
|
||||||
["$ChooseGeneral"] = "请选择 %1 名武将",
|
["$ChooseGeneral"] = "请选择 %1 名武将",
|
||||||
["Same General Convert"] = "替换武将",
|
["Same General Convert"] = "替换武将",
|
||||||
["Fight"] = "出战",
|
["Fight"] = "出战",
|
||||||
|
["Show General Detail"] = "查看技能",
|
||||||
|
|
||||||
["#PlayCard"] = "出牌阶段,请使用一张牌",
|
["#PlayCard"] = "出牌阶段,请使用一张牌",
|
||||||
["#AskForGeneral"] = "请选择 1 名武将",
|
["#AskForGeneral"] = "请选择 1 名武将",
|
||||||
["#AskForSkillInvoke"] = "你想发动技能“%1”吗?",
|
["#AskForSkillInvoke"] = "你想发动技能“%1”吗?",
|
||||||
|
["#AskForLuckCard"] = "你想使用手气卡吗?还可以使用 %1 次,剩余手气卡∞张",
|
||||||
|
["AskForLuckCard"] = "手气卡",
|
||||||
["#AskForChoice"] = "%1:请选择",
|
["#AskForChoice"] = "%1:请选择",
|
||||||
["#choose-trigger"] = "请选择一项技能发动",
|
["#choose-trigger"] = "请选择一项技能发动",
|
||||||
["trigger"] = "选择技能",
|
["trigger"] = "选择技能",
|
||||||
|
|
|
@ -1,35 +1,113 @@
|
||||||
-- SPDX-License-Identifier: GPL-3.0-or-later
|
-- SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
local function drawInit(room, player, n)
|
||||||
|
-- TODO: need a new function to call the UI
|
||||||
|
local cardIds = room:getNCards(n)
|
||||||
|
player:addCards(Player.Hand, cardIds)
|
||||||
|
for _, id in ipairs(cardIds) do
|
||||||
|
Fk:filterCard(id, player)
|
||||||
|
end
|
||||||
|
local move_to_notify = {} ---@type CardsMoveStruct
|
||||||
|
move_to_notify.toArea = Card.PlayerHand
|
||||||
|
move_to_notify.to = player.id
|
||||||
|
move_to_notify.moveInfo = {}
|
||||||
|
move_to_notify.moveReason = fk.ReasonDraw
|
||||||
|
for _, id in ipairs(cardIds) do
|
||||||
|
table.insert(move_to_notify.moveInfo,
|
||||||
|
{ cardId = id, fromArea = Card.DrawPile })
|
||||||
|
end
|
||||||
|
room:notifyMoveCards(nil, {move_to_notify})
|
||||||
|
|
||||||
|
for _, id in ipairs(cardIds) do
|
||||||
|
room:setCardArea(id, Card.PlayerHand, player.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function discardInit(room, player)
|
||||||
|
local cardIds = player:getCardIds(Player.Hand)
|
||||||
|
player:removeCards(Player.Hand, cardIds)
|
||||||
|
table.insertTable(room.draw_pile, cardIds)
|
||||||
|
for _, id in ipairs(cardIds) do
|
||||||
|
Fk:filterCard(id, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
local move_to_notify = {} ---@type CardsMoveStruct
|
||||||
|
move_to_notify.from = player.id
|
||||||
|
move_to_notify.toArea = Card.DrawPile
|
||||||
|
move_to_notify.moveInfo = {}
|
||||||
|
move_to_notify.moveReason = fk.ReasonJustMove
|
||||||
|
for _, id in ipairs(cardIds) do
|
||||||
|
table.insert(move_to_notify.moveInfo,
|
||||||
|
{ cardId = id, fromArea = Card.PlayerHand })
|
||||||
|
end
|
||||||
|
room:notifyMoveCards(nil, {move_to_notify})
|
||||||
|
|
||||||
|
for _, id in ipairs(cardIds) do
|
||||||
|
room:setCardArea(id, Card.DrawPile, nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
GameEvent.functions[GameEvent.DrawInitial] = function(self)
|
GameEvent.functions[GameEvent.DrawInitial] = function(self)
|
||||||
local room = self.room
|
local room = self.room
|
||||||
|
|
||||||
|
local luck_data = {
|
||||||
|
drawInit = drawInit,
|
||||||
|
discardInit = discardInit,
|
||||||
|
playerList = table.map(room.alive_players, Util.IdMapper),
|
||||||
|
}
|
||||||
|
|
||||||
for _, player in ipairs(room.alive_players) do
|
for _, player in ipairs(room.alive_players) do
|
||||||
local draw_data = { num = 4 }
|
local draw_data = { num = 4 }
|
||||||
room.logic:trigger(fk.DrawInitialCards, player, draw_data)
|
room.logic:trigger(fk.DrawInitialCards, player, draw_data)
|
||||||
|
luck_data[player.id] = draw_data
|
||||||
|
luck_data[player.id].luckTime = room.settings.luckTime
|
||||||
|
if player.id < 0 then -- Robot
|
||||||
|
luck_data[player.id].luckTime = 0
|
||||||
|
end
|
||||||
if draw_data.num > 0 then
|
if draw_data.num > 0 then
|
||||||
-- TODO: need a new function to call the UI
|
drawInit(room, player, draw_data.num)
|
||||||
local cardIds = room:getNCards(draw_data.num)
|
|
||||||
player:addCards(Player.Hand, cardIds)
|
|
||||||
for _, id in ipairs(cardIds) do
|
|
||||||
Fk:filterCard(id, player)
|
|
||||||
end
|
|
||||||
local move_to_notify = {} ---@type CardsMoveStruct
|
|
||||||
move_to_notify.toArea = Card.PlayerHand
|
|
||||||
move_to_notify.to = player.id
|
|
||||||
move_to_notify.moveInfo = {}
|
|
||||||
move_to_notify.moveReason = fk.ReasonDraw
|
|
||||||
for _, id in ipairs(cardIds) do
|
|
||||||
table.insert(move_to_notify.moveInfo,
|
|
||||||
{ cardId = id, fromArea = Card.DrawPile })
|
|
||||||
end
|
|
||||||
room:notifyMoveCards(nil, {move_to_notify})
|
|
||||||
|
|
||||||
for _, id in ipairs(cardIds) do
|
|
||||||
room:setCardArea(id, Card.PlayerHand, player.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
room.logic:trigger(fk.AfterDrawInitialCards, player, data)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if room.settings.luckTime <= 0 then
|
||||||
|
for _, player in ipairs(room.alive_players) do
|
||||||
|
local draw_data = luck_data[player.id]
|
||||||
|
draw_data.luckTime = nil
|
||||||
|
room.logic:trigger(fk.AfterDrawInitialCards, player, data)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
room:setTag("LuckCardData", luck_data)
|
||||||
|
room:notifyMoveFocus(room.alive_players, "AskForLuckCard")
|
||||||
|
room:doBroadcastNotify("AskForLuckCard", room.settings.luckTime or 4)
|
||||||
|
|
||||||
|
local remainTime = room.timeout
|
||||||
|
local currentTime = os.time()
|
||||||
|
local elapsed = 0
|
||||||
|
|
||||||
|
while true do
|
||||||
|
elapsed = os.time() - currentTime
|
||||||
|
if remainTime - elapsed <= 0 then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
if table.every(room:getTag("LuckCardData").playerList, function(id)
|
||||||
|
return room:getTag("LuckCardData")[id].luckTime == 0
|
||||||
|
end) then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
coroutine.yield("__handleRequest", (remainTime - elapsed) * 1000)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, player in ipairs(room.alive_players) do
|
||||||
|
local draw_data = luck_data[player.id]
|
||||||
|
draw_data.luckTime = nil
|
||||||
|
room.logic:trigger(fk.AfterDrawInitialCards, player, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
room:removeTag("LuckCardData")
|
||||||
end
|
end
|
||||||
|
|
||||||
GameEvent.functions[GameEvent.Round] = function(self)
|
GameEvent.functions[GameEvent.Round] = function(self)
|
||||||
|
|
|
@ -85,6 +85,27 @@ request_handlers["prelight"] = function(room, id, reqlist)
|
||||||
p:prelightSkill(reqlist[3], reqlist[4] == "true")
|
p:prelightSkill(reqlist[3], reqlist[4] == "true")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
request_handlers["luckcard"] = function(room, id, reqlist)
|
||||||
|
local p = room:getPlayerById(id)
|
||||||
|
local cancel = reqlist[3] == "false"
|
||||||
|
local luck_data = room:getTag("LuckCardData")
|
||||||
|
local pdata = luck_data[id]
|
||||||
|
|
||||||
|
if not cancel then
|
||||||
|
pdata.luckTime = pdata.luckTime - 1
|
||||||
|
luck_data.discardInit(room, p)
|
||||||
|
luck_data.drawInit(room, p, pdata.num)
|
||||||
|
else
|
||||||
|
pdata.luckTime = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
if pdata.luckTime > 0 then
|
||||||
|
p:doNotify("AskForLuckCard", pdata.luckTime)
|
||||||
|
end
|
||||||
|
|
||||||
|
room:setTag("LuckCardData", luck_data)
|
||||||
|
end
|
||||||
|
|
||||||
request_handlers["changeself"] = function(room, id, reqlist)
|
request_handlers["changeself"] = function(room, id, reqlist)
|
||||||
local p = room:getPlayerById(id)
|
local p = room:getPlayerById(id)
|
||||||
local toId = tonumber(reqlist[3])
|
local toId = tonumber(reqlist[3])
|
||||||
|
@ -107,7 +128,8 @@ request_handlers["changeself"] = function(room, id, reqlist)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
local function requestLoop(self, rest_time)
|
local function requestLoop(self)
|
||||||
|
local rest_time = 0
|
||||||
while true do
|
while true do
|
||||||
local ret = false
|
local ret = false
|
||||||
local request = self.room:fetchRequest()
|
local request = self.room:fetchRequest()
|
||||||
|
@ -122,7 +144,7 @@ local function requestLoop(self, rest_time)
|
||||||
-- otherwise CPU usage will be 100% (infinite yield <-> resume loop)
|
-- otherwise CPU usage will be 100% (infinite yield <-> resume loop)
|
||||||
fk.QThread_msleep(10)
|
fk.QThread_msleep(10)
|
||||||
end
|
end
|
||||||
coroutine.yield(ret)
|
rest_time = coroutine.yield(ret)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,8 @@ function Room:initialize(_room)
|
||||||
local main_co = coroutine.create(function()
|
local main_co = coroutine.create(function()
|
||||||
self:run()
|
self:run()
|
||||||
end)
|
end)
|
||||||
local request_co = coroutine.create(function(rest)
|
local request_co = coroutine.create(function()
|
||||||
self:requestLoop(rest)
|
self:requestLoop()
|
||||||
end)
|
end)
|
||||||
local ret, err_msg, rest_time = true, true
|
local ret, err_msg, rest_time = true, true
|
||||||
while not self.game_finished do
|
while not self.game_finished do
|
||||||
|
@ -642,8 +642,7 @@ function Room:doRaceRequest(command, players, jsonData)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
coroutine.yield("__handleRequest", remainTime - elapsed)
|
coroutine.yield("__handleRequest", (remainTime - elapsed) * 1000)
|
||||||
fk.QThread_msleep(10)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, p in ipairs(self.players) do
|
for _, p in ipairs(self.players) do
|
||||||
|
@ -2525,7 +2524,7 @@ function Room:gameOver(winner)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.room:gameOver()
|
self.room:gameOver()
|
||||||
coroutine.yield("__handleRequest")
|
coroutine.yield("__handleRequest", 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param card Card
|
---@param card Card
|
||||||
|
|
|
@ -25,6 +25,7 @@ QtObject {
|
||||||
property var disabledGenerals: []
|
property var disabledGenerals: []
|
||||||
|
|
||||||
property int preferredTimeout
|
property int preferredTimeout
|
||||||
|
property int preferredLuckTime
|
||||||
|
|
||||||
// Player property of client
|
// Player property of client
|
||||||
property string serverAddr
|
property string serverAddr
|
||||||
|
@ -60,6 +61,7 @@ QtObject {
|
||||||
bgmVolume = conf.bgmVolume ?? 50.;
|
bgmVolume = conf.bgmVolume ?? 50.;
|
||||||
disableMsgAudio = conf.disableMsgAudio ?? false;
|
disableMsgAudio = conf.disableMsgAudio ?? false;
|
||||||
preferredTimeout = conf.preferredTimeout ?? 15;
|
preferredTimeout = conf.preferredTimeout ?? 15;
|
||||||
|
preferredLuckTime = conf.preferredLuckTime ?? 0;
|
||||||
disabledGenerals = conf.disabledGenerals ?? [];
|
disabledGenerals = conf.disabledGenerals ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +85,7 @@ QtObject {
|
||||||
conf.bgmVolume = bgmVolume;
|
conf.bgmVolume = bgmVolume;
|
||||||
conf.disableMsgAudio = disableMsgAudio;
|
conf.disableMsgAudio = disableMsgAudio;
|
||||||
conf.preferredTimeout = preferredTimeout;
|
conf.preferredTimeout = preferredTimeout;
|
||||||
|
conf.preferredLuckTime = preferredLuckTime;
|
||||||
conf.disabledGenerals = disabledGenerals;
|
conf.disabledGenerals = disabledGenerals;
|
||||||
|
|
||||||
Backend.saveConf(JSON.stringify(conf, undefined, 2));
|
Backend.saveConf(JSON.stringify(conf, undefined, 2));
|
||||||
|
|
|
@ -5,15 +5,12 @@ import QtQuick.Controls
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: root
|
id: root
|
||||||
//property alias font: textEdit.font
|
|
||||||
//property alias text: textEdit.text
|
|
||||||
//property alias color: textEdit.color
|
|
||||||
//property alias textFormat: textEdit.textFormat
|
|
||||||
|
|
||||||
//flickableDirection: Flickable.VerticalFlick
|
|
||||||
//contentWidth: textEdit.width
|
|
||||||
//contentHeight: textEdit.height
|
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
highlight: Rectangle { color: "#EEEEEE"; radius: 5 }
|
||||||
|
highlightMoveDuration: 500
|
||||||
|
|
||||||
ScrollBar.vertical: ScrollBar {
|
ScrollBar.vertical: ScrollBar {
|
||||||
parent: root.parent
|
parent: root.parent
|
||||||
anchors.top: root.top
|
anchors.top: root.top
|
||||||
|
@ -30,17 +27,27 @@ ListView {
|
||||||
clip: true
|
clip: true
|
||||||
readOnly: true
|
readOnly: true
|
||||||
selectByKeyboard: true
|
selectByKeyboard: true
|
||||||
selectByMouse: true
|
selectByMouse: false
|
||||||
wrapMode: TextEdit.WrapAnywhere
|
wrapMode: TextEdit.WrapAnywhere
|
||||||
textFormat: TextEdit.RichText
|
textFormat: TextEdit.RichText
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
|
|
||||||
|
TapHandler {
|
||||||
|
onTapped: root.currentIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Return to Bottom"
|
||||||
|
visible: root.currentIndex !== logModel.count - 1
|
||||||
|
onClicked: root.currentIndex = logModel.count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function append(text) {
|
function append(text) {
|
||||||
let autoScroll = atYEnd;
|
let autoScroll = root.currentIndex === logModel.count - 1;
|
||||||
logModel.append({ logText: text });
|
logModel.append({ logText: text });
|
||||||
if (autoScroll && contentHeight > contentY + height) {
|
if (autoScroll) {
|
||||||
contentY = contentHeight - height;
|
root.currentIndex = logModel.count - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,23 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Switch {
|
Switch {
|
||||||
id: freeAssignCheck
|
id: freeAssignCheck
|
||||||
checked: Debugging ? true : false
|
checked: Debugging ? true : false
|
||||||
|
@ -136,6 +153,7 @@ ColumnLayout {
|
||||||
gameMode: config.preferedMode,
|
gameMode: config.preferedMode,
|
||||||
disabledPack: config.disabledPack,
|
disabledPack: config.disabledPack,
|
||||||
generalNum: config.preferredGeneralNum,
|
generalNum: config.preferredGeneralNum,
|
||||||
|
luckTime: config.preferredLuckTime,
|
||||||
disabledGenerals,
|
disabledGenerals,
|
||||||
}])
|
}])
|
||||||
);
|
);
|
||||||
|
|
|
@ -46,6 +46,7 @@ Item {
|
||||||
property bool selected: false
|
property bool selected: false
|
||||||
property bool draggable: false
|
property bool draggable: false
|
||||||
property bool autoBack: true
|
property bool autoBack: true
|
||||||
|
property bool showDetail: false
|
||||||
property int origX: 0
|
property int origX: 0
|
||||||
property int origY: 0
|
property int origY: 0
|
||||||
property real origOpacity: 1
|
property real origOpacity: 1
|
||||||
|
@ -67,6 +68,11 @@ Item {
|
||||||
signal generalChanged() // For choose general freely
|
signal generalChanged() // For choose general freely
|
||||||
signal hoverChanged(bool enter)
|
signal hoverChanged(bool enter)
|
||||||
|
|
||||||
|
onRightClicked: {
|
||||||
|
if (!showDetail) return;
|
||||||
|
roomScene.startCheat("RoomElement/Cheat/CardDetail.qml", { card: this });
|
||||||
|
}
|
||||||
|
|
||||||
RectangularGlow {
|
RectangularGlow {
|
||||||
id: glowItem
|
id: glowItem
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
id: root
|
||||||
|
anchors.fill: parent
|
||||||
|
property var extra_data: ({})
|
||||||
|
|
||||||
|
signal finish()
|
||||||
|
|
||||||
|
contentHeight: details.height
|
||||||
|
ScrollBar.vertical: ScrollBar {}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: details
|
||||||
|
width: parent.width - 40
|
||||||
|
x: 20
|
||||||
|
|
||||||
|
// TODO: player details
|
||||||
|
Text {
|
||||||
|
id: screenName
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: 18
|
||||||
|
}
|
||||||
|
|
||||||
|
TextEdit {
|
||||||
|
id: skillDesc
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: 18
|
||||||
|
|
||||||
|
readOnly: true
|
||||||
|
selectByKeyboard: true
|
||||||
|
selectByMouse: false
|
||||||
|
wrapMode: TextEdit.WordWrap
|
||||||
|
textFormat: TextEdit.RichText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onExtra_dataChanged: {
|
||||||
|
const card = extra_data.card;
|
||||||
|
if (!card) return;
|
||||||
|
const name = card.virt_name ? card.virt_name : card.name;
|
||||||
|
screenName.text = Backend.translate(name);
|
||||||
|
skillDesc.text = Backend.translate(":" + name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
id: root
|
||||||
|
anchors.fill: parent
|
||||||
|
property var extra_data: ({})
|
||||||
|
|
||||||
|
signal finish()
|
||||||
|
|
||||||
|
contentHeight: details.height
|
||||||
|
ScrollBar.vertical: ScrollBar {}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: details
|
||||||
|
width: parent.width - 40
|
||||||
|
x: 20
|
||||||
|
|
||||||
|
TextEdit {
|
||||||
|
id: skillDesc
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: 18
|
||||||
|
|
||||||
|
readOnly: true
|
||||||
|
selectByKeyboard: true
|
||||||
|
selectByMouse: false
|
||||||
|
wrapMode: TextEdit.WordWrap
|
||||||
|
textFormat: TextEdit.RichText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onExtra_dataChanged: {
|
||||||
|
if (!extra_data.generals) return;
|
||||||
|
skillDesc.text = "";
|
||||||
|
|
||||||
|
extra_data.generals.forEach((g) => {
|
||||||
|
let data = JSON.parse(Backend.callLuaFunction("GetGeneralDetail", [g]));
|
||||||
|
skillDesc.append(Backend.translate(data.kingdom) + " " + Backend.translate(g) + " " + data.hp + "/" + data.maxHp);
|
||||||
|
data.skill.forEach(t => {
|
||||||
|
skillDesc.append("<b>" + Backend.translate(t.name) + "</b>: " + t.description)
|
||||||
|
});
|
||||||
|
data.related_skill.forEach(t => {
|
||||||
|
skillDesc.append("<font color=\"purple\"><b>" + Backend.translate(t.name) + "</b>: " + t.description + "</font>")
|
||||||
|
});
|
||||||
|
skillDesc.append("\n");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,8 @@ Flickable {
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: details
|
id: details
|
||||||
width: parent.width - 16
|
width: parent.width - 40
|
||||||
|
x: 20
|
||||||
|
|
||||||
// TODO: player details
|
// TODO: player details
|
||||||
Text {
|
Text {
|
||||||
|
|
|
@ -106,6 +106,16 @@ GraphicsBox {
|
||||||
|
|
||||||
onClicked: close();
|
onClicked: close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetroButton {
|
||||||
|
id: detailBtn
|
||||||
|
enabled: choices.length > 0
|
||||||
|
text: Backend.translate("Show General Detail")
|
||||||
|
onClicked: roomScene.startCheat(
|
||||||
|
"RoomElement/Cheat/GeneralDetail.qml",
|
||||||
|
{ generals: choices }
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,6 +189,7 @@ GraphicsBox {
|
||||||
item.goBack(true);
|
item.goBack(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
root.choicesChanged();
|
||||||
|
|
||||||
fightButton.enabled = (choices.length == choiceNum);
|
fightButton.enabled = (choices.length == choiceNum);
|
||||||
|
|
||||||
|
@ -201,10 +212,10 @@ GraphicsBox {
|
||||||
if (JSON.parse(Backend.callLuaFunction(
|
if (JSON.parse(Backend.callLuaFunction(
|
||||||
"GetSameGenerals", [generalList.get(i).name])
|
"GetSameGenerals", [generalList.get(i).name])
|
||||||
).length > 0) {
|
).length > 0) {
|
||||||
convertBtn.visible = true;
|
convertBtn.enabled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
convertBtn.visible = false;
|
convertBtn.enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ CardItem {
|
||||||
color: "white"
|
color: "white"
|
||||||
font.family: fontLibian.name
|
font.family: fontLibian.name
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
lineHeight: Math.max(1.4 - lineCount / 10, 0.6)
|
lineHeight: Math.max(1.4 - lineCount / 8, 0.6)
|
||||||
style: Text.Outline
|
style: Text.Outline
|
||||||
wrapMode: Text.WrapAnywhere
|
wrapMode: Text.WrapAnywhere
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ Item {
|
||||||
card.autoBack = true;
|
card.autoBack = true;
|
||||||
card.draggable = true;
|
card.draggable = true;
|
||||||
card.selectable = false;
|
card.selectable = false;
|
||||||
|
card.showDetail = true;
|
||||||
card.clicked.connect(adjustCards);
|
card.clicked.connect(adjustCards);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ Item {
|
||||||
card = result[i];
|
card = result[i];
|
||||||
card.draggable = false;
|
card.draggable = false;
|
||||||
card.selectable = false;
|
card.selectable = false;
|
||||||
|
card.showDetail = false;
|
||||||
card.selectedChanged.disconnect(adjustCards);
|
card.selectedChanged.disconnect(adjustCards);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -511,7 +511,6 @@ Item {
|
||||||
|
|
||||||
DelayedTrickArea {
|
DelayedTrickArea {
|
||||||
id: delayedTrickAreaItem
|
id: delayedTrickAreaItem
|
||||||
rows: 1
|
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: 8
|
anchors.bottomMargin: 8
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,6 @@ import ".."
|
||||||
import "../../skin-bank.js" as SkinBank
|
import "../../skin-bank.js" as SkinBank
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property alias rows: grid.rows
|
|
||||||
property alias columns: grid.columns
|
|
||||||
|
|
||||||
InvisibleCardArea {
|
InvisibleCardArea {
|
||||||
id: area
|
id: area
|
||||||
checkExisting: true
|
checkExisting: true
|
||||||
|
@ -17,16 +14,17 @@ Item {
|
||||||
id: cards
|
id: cards
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid {
|
Row {
|
||||||
id: grid
|
id: grid
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
rows: 100
|
spacing: -4
|
||||||
columns: 100
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: cards
|
model: cards
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
height: 55 * 0.8
|
||||||
|
width: 47 * 0.8
|
||||||
source: SkinBank.DELAYED_TRICK_DIR + name
|
source: SkinBank.DELAYED_TRICK_DIR + name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,18 @@ function doOkButton() {
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (roomScene.extra_data.luckCard) {
|
||||||
|
okButton.enabled = false;
|
||||||
|
ClientInstance.notifyServer("PushRequest", [
|
||||||
|
"luckcard", true
|
||||||
|
].join(","));
|
||||||
|
|
||||||
|
if (roomScene.extra_data.time == 1) {
|
||||||
|
roomScene.state = "notactive";
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
replyToServer("1");
|
replyToServer("1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +115,13 @@ function doCancelButton() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (roomScene.extra_data.luckCard) {
|
||||||
|
ClientInstance.notifyServer("PushRequest", [
|
||||||
|
"luckcard", false
|
||||||
|
].join(","));
|
||||||
|
roomScene.state = "notactive";
|
||||||
|
return;
|
||||||
|
}
|
||||||
replyToServer("__cancel");
|
replyToServer("__cancel");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1060,3 +1079,17 @@ callbacks["ChangeSelf"] = (j) => {
|
||||||
}
|
}
|
||||||
changeSelf(data);
|
changeSelf(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callbacks["AskForLuckCard"] = (j) => {
|
||||||
|
// jsonData: int time
|
||||||
|
const time = parseInt(j);
|
||||||
|
roomScene.promptText = Backend.translate("#AskForLuckCard").arg(time);
|
||||||
|
roomScene.state = "replying";
|
||||||
|
roomScene.extra_data = {
|
||||||
|
luckCard: true,
|
||||||
|
time: time,
|
||||||
|
};
|
||||||
|
roomScene.okCancel.visible = true;
|
||||||
|
roomScene.okButton.enabled = true;
|
||||||
|
roomScene.cancelButton.enabled = true;
|
||||||
|
}
|
||||||
|
|
|
@ -151,10 +151,13 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "FK联机交流群:531553435"
|
text: "常用联机IP:175.178.66.93\nFK联机交流群:531553435"
|
||||||
font.pixelSize: 20
|
font.pixelSize: 20
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 20
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 20
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------Disappear--------------
|
//--------------------Disappear--------------
|
||||||
|
|
39
qml/main.qml
39
qml/main.qml
|
@ -15,6 +15,7 @@ Window {
|
||||||
minimumHeight: 90
|
minimumHeight: 90
|
||||||
title: "FreeKill v" + FkVersion
|
title: "FreeKill v" + FkVersion
|
||||||
property var callbacks: Logic.callbacks
|
property var callbacks: Logic.callbacks
|
||||||
|
property var tipList: []
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: mainWindow
|
id: mainWindow
|
||||||
|
@ -67,10 +68,45 @@ Item {
|
||||||
onBusyChanged: busyText = "";
|
onBusyChanged: busyText = "";
|
||||||
|
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
|
id: busyIndicator
|
||||||
running: true
|
running: true
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: mainWindow.busy === true
|
visible: mainWindow.busy === true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.top: busyIndicator.bottom
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.topMargin: 8
|
||||||
|
visible: mainWindow.busy === true
|
||||||
|
|
||||||
|
property int idx: 1
|
||||||
|
text: tipList[idx - 1] ?? ""
|
||||||
|
color: "#F0E5DA"
|
||||||
|
font.pixelSize: 20
|
||||||
|
font.family: fontLibian.name
|
||||||
|
style: Text.Outline
|
||||||
|
styleColor: "#3D2D1C"
|
||||||
|
textFormat: Text.RichText
|
||||||
|
width: parent.width * 0.7
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
|
||||||
|
onVisibleChanged: idx = 0;
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
running: parent.visible
|
||||||
|
interval: 3600
|
||||||
|
repeat: true
|
||||||
|
onTriggered: {
|
||||||
|
const oldIdx = parent.idx;
|
||||||
|
while (parent.idx === oldIdx) {
|
||||||
|
parent.idx = Math.floor(Math.random() * tipList.length) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
visible: mainWindow.busy === true && mainWindow.busyText !== ""
|
visible: mainWindow.busy === true && mainWindow.busyText !== ""
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
@ -247,6 +283,9 @@ Item {
|
||||||
width = config.winWidth;
|
width = config.winWidth;
|
||||||
height = config.winHeight;
|
height = config.winHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tips = Backend.loadTips();
|
||||||
|
tipList = tips.trim().split("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
onClosing: {
|
onClosing: {
|
||||||
|
|
|
@ -231,6 +231,18 @@ QString QmlBackend::loadConf() {
|
||||||
return conf.readAll();
|
return conf.readAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QmlBackend::loadTips() {
|
||||||
|
QFile conf("waiting_tips.txt");
|
||||||
|
if (!conf.exists()) {
|
||||||
|
conf.open(QIODevice::WriteOnly);
|
||||||
|
static const char *init_conf = "转啊~ 转啊~";
|
||||||
|
conf.write(init_conf);
|
||||||
|
return init_conf;
|
||||||
|
}
|
||||||
|
conf.open(QIODevice::ReadOnly);
|
||||||
|
return conf.readAll();
|
||||||
|
}
|
||||||
|
|
||||||
void QmlBackend::saveConf(const QString &conf) {
|
void QmlBackend::saveConf(const QString &conf) {
|
||||||
QFile c("freekill.client.config.json");
|
QFile c("freekill.client.config.json");
|
||||||
c.open(QIODevice::WriteOnly);
|
c.open(QIODevice::WriteOnly);
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE QString pubEncrypt(const QString &key, const QString &data);
|
Q_INVOKABLE QString pubEncrypt(const QString &key, const QString &data);
|
||||||
Q_INVOKABLE QString loadConf();
|
Q_INVOKABLE QString loadConf();
|
||||||
|
Q_INVOKABLE QString loadTips();
|
||||||
Q_INVOKABLE void saveConf(const QString &conf);
|
Q_INVOKABLE void saveConf(const QString &conf);
|
||||||
|
|
||||||
Q_INVOKABLE void replyDelayTest(const QString &screenName, const QString &cipher);
|
Q_INVOKABLE void replyDelayTest(const QString &screenName, const QString &cipher);
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
在对局中长按他人武将牌可以查看其技能哦
|
||||||
|
长按手牌可以查看这张卡牌的详细信息
|
||||||
|
在大厅界面点击左上角的头像可以进行各种设置
|
||||||
|
在聊天中输入$zhiheng:1试试看?
|
||||||
|
在聊天中输入$~caocao试试看?
|
||||||
|
不要为了一个战功,放弃你的队友,你不是一个人在战斗。
|
||||||
|
转啊~ 转啊~
|
||||||
|
给FreeKill的GitHub仓库点一个star吧!
|
||||||
|
你可以在武将一览界面禁将,在你创建的房间中禁用武将不会出现在选将框。
|
||||||
|
如果你遇到了bug,请截图并反馈给开发者
|
||||||
|
如果你想要制作FK的mod,需要先学习Lua语言
|
||||||
|
目光所及短寸吾才之间满腹狭目之阿瞒有我见袁本良计初只能窥取冀州便是底竟不从易成略在胸如反掌之良计速出吾才满目光所及腹袁本初竟短寸之间不从之
|
||||||
|
吔!
|
||||||
|
想要参与到FK的开发工作中?那么就从制作自己的Mod开始吧!
|
||||||
|
在游戏的一些地方,长按可以显示该元素的详情。如果你用的是电脑版的话可以用鼠标右键代替长按。
|
||||||
|
注意:官方不支持任何形式的账号交易行为,请妥善保管好您的账号密码。请勿与他人共享账号。因账号交易、共享引起的账号争议官方均不受理。
|
||||||
|
如果牌不好的话,就请辱骂GK的发牌员吧
|
||||||
|
行动前请三思,需要先明确全场所有人的技能与卡牌的效果,再去做出决定。
|
||||||
|
神曰:“MBKS”
|
||||||
|
正在匹配势均力敌的对手…… 匹配到界徐盛
|
||||||
|
先喝酒还是先上刀,这是个值得考虑的问题
|
||||||
|
在抱怨FK只有标准包?那么去试着参与联机吧
|
||||||
|
如果在牌局内想查看技能,可以长按想要看技能的角色
|
||||||
|
FK的开服很简单,只要单机启动就可以当做服务器使用了
|
||||||
|
用Linux也能搭建FK服务器,起始页推荐的联机IP就是跑在Linux服务器上的
|
||||||
|
我们的游戏正在蒸蒸日上哦~
|
Loading…
Reference in New Issue