UI commands (#17)
* add cardarea * move cards * add util * delaytrick * equiparea * var -> let * photo loop anim * setEmotion & damage * photo status * doIndicate * add property to ClientPlayer * todo: movecards, waiting * handle moveCards at client * ui - moveCards * modify to lua * move visible * adjust position of tablepile Co-authored-by: Notify-ctrl <notify-ctrl@qq.com>
BIN
image/anim/damage/0.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
image/anim/damage/1.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
image/anim/damage/2.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
image/anim/damage/3.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
image/anim/damage/4.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
image/anim/damage/5.png
Normal file
After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 321 B After Width: | Height: | Size: 321 B |
Before Width: | Height: | Size: 274 B After Width: | Height: | Size: 274 B |
Before Width: | Height: | Size: 380 B After Width: | Height: | Size: 380 B |
Before Width: | Height: | Size: 624 B After Width: | Height: | Size: 624 B |
Before Width: | Height: | Size: 512 B After Width: | Height: | Size: 512 B |
Before Width: | Height: | Size: 382 B After Width: | Height: | Size: 382 B |
Before Width: | Height: | Size: 284 B After Width: | Height: | Size: 284 B |
Before Width: | Height: | Size: 267 B After Width: | Height: | Size: 267 B |
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 406 B |
Before Width: | Height: | Size: 335 B After Width: | Height: | Size: 335 B |
Before Width: | Height: | Size: 538 B |
Before Width: | Height: | Size: 441 B |
Before Width: | Height: | Size: 619 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 658 B |
Before Width: | Height: | Size: 575 B |
Before Width: | Height: | Size: 553 B |
Before Width: | Height: | Size: 673 B |
Before Width: | Height: | Size: 442 B |
Before Width: | Height: | Size: 540 B |
Before Width: | Height: | Size: 378 B |
Before Width: | Height: | Size: 427 B |
Before Width: | Height: | Size: 441 B |
Before Width: | Height: | Size: 540 B |
Before Width: | Height: | Size: 436 B |
Before Width: | Height: | Size: 505 B |
Before Width: | Height: | Size: 490 B |
Before Width: | Height: | Size: 517 B |
Before Width: | Height: | Size: 398 B |
Before Width: | Height: | Size: 550 B |
Before Width: | Height: | Size: 576 B |
Before Width: | Height: | Size: 238 B After Width: | Height: | Size: 238 B |
Before Width: | Height: | Size: 273 B After Width: | Height: | Size: 273 B |
Before Width: | Height: | Size: 371 B After Width: | Height: | Size: 371 B |
Before Width: | Height: | Size: 500 B After Width: | Height: | Size: 500 B |
Before Width: | Height: | Size: 289 B After Width: | Height: | Size: 289 B |
Before Width: | Height: | Size: 755 B After Width: | Height: | Size: 755 B |
Before Width: | Height: | Size: 380 B After Width: | Height: | Size: 380 B |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
@ -1,3 +1,6 @@
|
|||
---@class Client
|
||||
---@field client fk.Client
|
||||
---@field players ClientPlayer[]
|
||||
Client = class('Client')
|
||||
|
||||
-- load client classes
|
||||
|
@ -23,6 +26,15 @@ function Client:initialize()
|
|||
self.players = {} -- ClientPlayer[]
|
||||
end
|
||||
|
||||
---@param id integer
|
||||
---@return ClientPlayer
|
||||
function Client:findPlayer(id)
|
||||
for _, p in ipairs(self.players) do
|
||||
if p.player:getId() == id then return p end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
fk.client_callback["Setup"] = function(jsonData)
|
||||
-- jsonData: [ int id, string screenName, string avatar ]
|
||||
local data = json.decode(jsonData)
|
||||
|
@ -31,6 +43,8 @@ fk.client_callback["Setup"] = function(jsonData)
|
|||
self:setId(id)
|
||||
self:setScreenName(name)
|
||||
self:setAvatar(avatar)
|
||||
Self = ClientPlayer:new(fk.Self)
|
||||
table.insert(ClientInstance.players, Self)
|
||||
end
|
||||
|
||||
fk.client_callback["AddPlayer"] = function(jsonData)
|
||||
|
@ -47,13 +61,13 @@ fk.client_callback["RemovePlayer"] = function(jsonData)
|
|||
-- jsonData: [ int id ]
|
||||
local data = json.decode(jsonData)
|
||||
local id = data[1]
|
||||
fk.ClientInstance:removePlayer(id)
|
||||
for _, p in ipairs(ClientInstance.players) do
|
||||
if p.player:getId() == id then
|
||||
table.removeOne(ClientInstance.players, p)
|
||||
break
|
||||
end
|
||||
end
|
||||
fk.ClientInstance:removePlayer(id)
|
||||
ClientInstance:notifyUI("RemovePlayer", jsonData)
|
||||
end
|
||||
|
||||
|
@ -61,20 +75,70 @@ fk.client_callback["ArrangeSeats"] = function(jsonData)
|
|||
local data = json.decode(jsonData)
|
||||
local n = #ClientInstance.players
|
||||
local players = {}
|
||||
local function findPlayer(id)
|
||||
for _, p in ipairs(ClientInstance.players) do
|
||||
if p.player:getId() == id then return p end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
for i = 1, n do
|
||||
table.insert(players, findPlayer(data[i]))
|
||||
table.insert(players, ClientInstance:findPlayer(data[i]))
|
||||
end
|
||||
ClientInstance.players = players
|
||||
|
||||
ClientInstance:notifyUI("ArrangeSeats", jsonData)
|
||||
end
|
||||
|
||||
fk.client_callback["PropertyUpdate"] = function(jsonData)
|
||||
-- jsonData: [ int id, string property_name, value ]
|
||||
local data = json.decode(jsonData)
|
||||
local id, name, value = data[1], data[2], data[3]
|
||||
ClientInstance:findPlayer(id)[name] = value
|
||||
ClientInstance:notifyUI("PropertyUpdate", jsonData)
|
||||
end
|
||||
|
||||
--- separated moves to many moves(one card per move)
|
||||
---@param moves CardsMoveStruct[]
|
||||
local function separateMoves(moves)
|
||||
local ret = {} ---@type CardsMoveInfo[]
|
||||
for _, move in ipairs(moves) do
|
||||
for _, info in ipairs(move.moveInfo) do
|
||||
table.insert(ret, {
|
||||
ids = {info.cardId},
|
||||
from = move.from,
|
||||
to = move.to,
|
||||
toArea = move.toArea,
|
||||
fromArea = info.fromArea,
|
||||
})
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--- merge separated moves (one fromArea per move)
|
||||
local function mergeMoves(moves)
|
||||
local ret = {}
|
||||
local temp = {}
|
||||
for _, move in ipairs(moves) do
|
||||
if temp[move.fromArea] == nil then
|
||||
temp[move.fromArea] = {
|
||||
ids = {},
|
||||
from = move.from,
|
||||
to = move.to,
|
||||
fromArea = move.fromArea,
|
||||
toArea = move.toArea
|
||||
}
|
||||
end
|
||||
table.insert(temp[move.fromArea].ids, move.ids[1])
|
||||
end
|
||||
for _, v in pairs(temp) do
|
||||
table.insert(ret, v)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
fk.client_callback["MoveCards"] = function(jsonData)
|
||||
-- jsonData: CardsMoveStruct[]
|
||||
local raw_moves = json.decode(jsonData)
|
||||
local separated = separateMoves(raw_moves)
|
||||
local merged = mergeMoves(separated)
|
||||
ClientInstance:notifyUI("MoveCards", json.encode(merged))
|
||||
end
|
||||
|
||||
-- Create ClientInstance (used by Lua)
|
||||
ClientInstance = Client:new()
|
||||
|
|
|
@ -9,3 +9,18 @@ function GetGeneralData(name)
|
|||
general.kingdom
|
||||
}
|
||||
end
|
||||
|
||||
function GetCardData(id)
|
||||
local card = Fk.cards[id]
|
||||
if card == nil then return json.encode{
|
||||
cid = id,
|
||||
known = false
|
||||
} end
|
||||
return json.encode{
|
||||
cid = id,
|
||||
name = card.name,
|
||||
number = card.number,
|
||||
suit = card:getSuitString(),
|
||||
color = card.color,
|
||||
}
|
||||
end
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
---@class ClientPlayer
|
||||
---@field player fk.Player
|
||||
---@field handcardNum integer
|
||||
---@field known_cards integer[]
|
||||
local ClientPlayer = Player:subclass("ClientPlayer")
|
||||
|
||||
function ClientPlayer:initialize(cp)
|
||||
self.player = cp
|
||||
self.handcardNum = 0
|
||||
self.known_cards = {}
|
||||
end
|
||||
|
||||
return ClientPlayer
|
||||
|
|
|
@ -74,4 +74,19 @@ function Card:initialize(name, suit, number, color)
|
|||
self.sub_type = Card.SubTypeNone
|
||||
end
|
||||
|
||||
function Card:getSuitString()
|
||||
local suit = self.suit
|
||||
if suit == Card.Spade then
|
||||
return "spade"
|
||||
elseif suit == Card.Heart then
|
||||
return "heart"
|
||||
elseif suit == Card.Club then
|
||||
return "club"
|
||||
elseif suit == Card.Diamond then
|
||||
return "diamond"
|
||||
else
|
||||
return "unknown"
|
||||
end
|
||||
end
|
||||
|
||||
return Card
|
||||
|
|
|
@ -17,3 +17,4 @@ end
|
|||
--debug.sethook(PrintWhenMethodCall, "c")
|
||||
|
||||
function p(v) print(inspect(v)) end
|
||||
function pt(t) for k,v in pairs(t)do print(k,v) end end
|
||||
|
|
|
@ -49,6 +49,23 @@ function table:removeOne(element)
|
|||
return false
|
||||
end
|
||||
|
||||
-- Note: only clone key and value, no metatable
|
||||
-- so dont use for class or instance
|
||||
---@generic T
|
||||
---@param self T
|
||||
---@return T
|
||||
function table.clone(self)
|
||||
local ret = {}
|
||||
for k, v in pairs(self) do
|
||||
if type(v) == "table" then
|
||||
ret[k] = table.clone(v)
|
||||
else
|
||||
ret[k] = v
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
---@class Sql
|
||||
Sql = {
|
||||
---@param filename string
|
||||
|
|
|
@ -219,6 +219,42 @@ function Room:getCardArea(cardId)
|
|||
return self.card_place[cardId] or Card.Unknown
|
||||
end
|
||||
|
||||
---@param players ServerPlayer[]
|
||||
---@param card_moves CardsMoveStruct[]
|
||||
---@param forceVisible boolean
|
||||
function Room:notifyMoveCards(players, card_moves, forceVisible)
|
||||
if players == nil or players == {} then players = self.players end
|
||||
for _, p in ipairs(players) do
|
||||
local arg = table.clone(card_moves)
|
||||
for _, move in ipairs(arg) do
|
||||
-- local to = self:getPlayerById(move.to)
|
||||
|
||||
-- forceVisible make the move visible
|
||||
-- FIXME: move.moveInfo is an array, fix this
|
||||
move.moveVisible = (forceVisible)
|
||||
-- if move is relevant to player, it should be open
|
||||
or ((move.from == p:getId()) or (move.to == p:getId() and move.toArea ~= Card.PlayerSpecial))
|
||||
-- cards move from/to equip/judge/discard/processing should be open
|
||||
or move.moveInfo.fromArea == Card.PlayerEquip
|
||||
or move.toArea == Card.PlayerEquip
|
||||
or move.moveInfo.fromArea == Card.PlayerJudge
|
||||
or move.toArea == Card.PlayerJudge
|
||||
or move.moveInfo.fromArea == Card.DiscardPile
|
||||
or move.toArea == Card.DiscardPile
|
||||
or move.moveInfo.fromArea == Card.Processing
|
||||
or move.toArea == Card.Processing
|
||||
-- TODO: PlayerSpecial
|
||||
|
||||
if not move.moveVisible then
|
||||
for _, info in ipairs(move.moveInfo) do
|
||||
info.cardId = -1
|
||||
end
|
||||
end
|
||||
end
|
||||
p:doNotify("MoveCards", json.encode(arg))
|
||||
end
|
||||
end
|
||||
|
||||
---@vararg CardsMoveInfo
|
||||
---@return boolean
|
||||
function Room:moveCards(...)
|
||||
|
@ -266,6 +302,8 @@ function Room:moveCards(...)
|
|||
return false
|
||||
end
|
||||
|
||||
self:notifyMoveCards(self.players, cardsMoveStructs)
|
||||
|
||||
for _, data in ipairs(cardsMoveStructs) do
|
||||
if #data.moveInfo > 0 then
|
||||
infoCheck(data)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---@alias CardsMoveInfo {ids: integer[], from: integer|null, to: integer|null, toArea: CardArea, moveReason: CardMoveReason, proposer: integer, skillName: string|null, moveVisible: boolean|null, specialName: string|null, specialVisible: boolean|null }
|
||||
---@alias MoveInfo {cardId: integer, fromArea: CardArea}
|
||||
---@alias CardsMoveStruct {moveInfo: {id: integer, fromArea: CardArea}[], from: integer|null, to: integer|null, toArea: CardArea, moveReason: CardMoveReason, proposer: integer|null, skillName: string|null, moveVisible: boolean|null, specialName: string|null, specialVisible: boolean|null, fromSpecialName: string|null }
|
||||
---@alias CardsMoveStruct {moveInfo: MoveInfo[], from: integer|null, to: integer|null, toArea: CardArea, moveReason: CardMoveReason, proposer: integer|null, skillName: string|null, moveVisible: boolean|null, specialName: string|null, specialVisible: boolean|null, fromSpecialName: string|null }
|
||||
|
||||
---@alias HpChangedData { num: integer, reason: string, skillName: string }
|
||||
---@alias HpLostData { num: integer, skillName: string }
|
||||
|
|
|
@ -31,6 +31,15 @@ GameRule = fk.CreateTriggerSkill{
|
|||
-- TODO: need a new function to call the UI
|
||||
local cardIds = room:getNCards(data.num)
|
||||
player:addCards(Player.Hand, cardIds)
|
||||
local move_to_notify = {} ---@type CardsMoveStruct
|
||||
move_to_notify.toArea = Card.PlayerHand
|
||||
move_to_notify.to = player:getId()
|
||||
move_to_notify.moveInfo = {}
|
||||
for _, id in ipairs(cardIds) do
|
||||
table.insert(move_to_notify.moveInfo,
|
||||
{ cardId = id, fromArea = Card.DrawPile })
|
||||
end
|
||||
room:notifyMoveCards(room.players, {move_to_notify})
|
||||
|
||||
for _, id in ipairs(cardIds) do
|
||||
room:setCardArea(id, Card.PlayerHand)
|
||||
|
@ -62,34 +71,31 @@ GameRule = fk.CreateTriggerSkill{
|
|||
error("You should never proceed PhaseNone")
|
||||
end,
|
||||
[Player.RoundStart] = function()
|
||||
print("Proceeding RoundStart.")
|
||||
|
||||
end,
|
||||
[Player.Start] = function()
|
||||
print("Proceeding Start.")
|
||||
|
||||
end,
|
||||
[Player.Judge] = function()
|
||||
print("Proceeding Judge.")
|
||||
|
||||
end,
|
||||
[Player.Draw] = function()
|
||||
print("Proceeding Draw.")
|
||||
room:drawCards(player, 2, self.name)
|
||||
end,
|
||||
[Player.Play] = function()
|
||||
print("Proceeding Play.")
|
||||
room:askForSkillInvoke(player, "rule")
|
||||
end,
|
||||
[Player.Discard] = function()
|
||||
print("Proceeding Discard.")
|
||||
local discardNum = #player:getCardIds(Player.Hand) - player:getMaxCards()
|
||||
if discardNum > 0 then
|
||||
room:askForDiscard(player, discardNum, discardNum, false, self.name)
|
||||
end
|
||||
end,
|
||||
[Player.Finish] = function()
|
||||
print("Proceeding Finish.")
|
||||
|
||||
end,
|
||||
[Player.NotActive] = function()
|
||||
print("Proceeding NotActive.")
|
||||
|
||||
end,
|
||||
})
|
||||
end,
|
||||
|
|
|
@ -17,6 +17,22 @@ Item {
|
|||
property alias promptText: prompt.text
|
||||
|
||||
// tmp
|
||||
Row {
|
||||
Button{text:"摸1牌"
|
||||
onClicked:{
|
||||
Logic.moveCards([{
|
||||
from:Logic.Player.DrawPile,
|
||||
to:Logic.Player.PlaceHand,
|
||||
cards:[1],
|
||||
}])
|
||||
}}
|
||||
Button{text:"弃1牌"
|
||||
onClicked:{Logic.moveCards([{
|
||||
to:Logic.Player.DrawPile,
|
||||
from:Logic.Player.PlaceHand,
|
||||
cards:[1],
|
||||
}])}}
|
||||
}
|
||||
Button {
|
||||
text: "quit"
|
||||
anchors.top: parent.top
|
||||
|
@ -145,7 +161,7 @@ Item {
|
|||
width: parent.width * 0.6
|
||||
height: 150
|
||||
x: parent.width * 0.2
|
||||
y: parent.height * 0.5
|
||||
y: parent.height * 0.6
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,9 @@ Item {
|
|||
property string suit: "club"
|
||||
property int number: 7
|
||||
property string name: "slash"
|
||||
property string subtype: ""
|
||||
property string color: "" // only use when suit is empty
|
||||
property string footnote: "曹操对刘备" // footnote, e.g. "A use card to B"
|
||||
property string footnote: "" // footnote, e.g. "A use card to B"
|
||||
property bool footnoteVisible: true
|
||||
property bool known: true // if false it only show a card back
|
||||
property bool enabled: true // if false the card will be grey
|
||||
|
@ -247,7 +248,7 @@ Item {
|
|||
function destroyOnStop()
|
||||
{
|
||||
root.moveFinished.connect(function(){
|
||||
destroy();
|
||||
root.destroy();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,15 +6,25 @@ RowLayout {
|
|||
id: root
|
||||
|
||||
property alias self: selfPhoto
|
||||
property alias handcardArea: handcardAreaItem
|
||||
property alias equipArea: selfPhoto.equipArea
|
||||
property alias delayedTrickArea: selfPhoto.delayedTrickArea
|
||||
property alias specialArea: selfPhoto.specialArea
|
||||
|
||||
Item {
|
||||
width: 40
|
||||
}
|
||||
|
||||
HandcardArea {
|
||||
id: handcardAreaItem
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: 130
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Photo {
|
||||
id: selfPhoto
|
||||
handcards: handcardAreaItem.length
|
||||
}
|
||||
|
||||
Item { width: 5 }
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import QtQuick 2.15
|
||||
import "../../util.js" as Utility
|
||||
|
||||
Item {
|
||||
property alias cards: cardArea.cards
|
||||
|
@ -68,12 +69,12 @@ Item {
|
|||
for (i = 0; i < cards.length; i++) {
|
||||
card = cards[i];
|
||||
if (card.selected)
|
||||
card.homeY -= 20;
|
||||
card.origY -= 20;
|
||||
}
|
||||
|
||||
if (animated) {
|
||||
for (i = 0; i < cards.length; i++)
|
||||
roomScene.cardItemGoBack(cards[i], true)
|
||||
cards[i].goBack(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
101
qml/Pages/RoomElement/IndicatorLine.qml
Normal file
|
@ -0,0 +1,101 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
Item {
|
||||
property point start: Qt.point(0, 0)
|
||||
property var end: []
|
||||
property alias running: pointToAnimation.running
|
||||
property color color: "#96943D"
|
||||
property real ratio: 0
|
||||
property int lineWidth: 6
|
||||
|
||||
signal finished()
|
||||
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
|
||||
Repeater {
|
||||
model: end
|
||||
|
||||
Rectangle {
|
||||
width: 6
|
||||
height: Math.sqrt(Math.pow(modelData.x - start.x, 2) + Math.pow(modelData.y - start.y, 2)) * ratio
|
||||
x: start.x
|
||||
y: start.y
|
||||
antialiasing: true
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: Qt.rgba(255, 255, 255, 0)
|
||||
}
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: Qt.rgba(200, 200, 200, 0.12)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 3
|
||||
height: parent.height
|
||||
antialiasing: true
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: Qt.rgba(255, 255, 255, 0)
|
||||
}
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: Qt.lighter(root.color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transform: Rotation {
|
||||
angle: 0
|
||||
|
||||
Component.onCompleted: {
|
||||
var dx = modelData.x - start.x;
|
||||
var dy = modelData.y - start.y;
|
||||
if (dx > 0) {
|
||||
angle = Math.atan2(dy, dx) / Math.PI * 180 - 90;
|
||||
} else if (dx < 0) {
|
||||
angle = Math.atan2(dy, dx) / Math.PI * 180 + 270;
|
||||
} else if (dy < 0) {
|
||||
angle = 180;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SequentialAnimation {
|
||||
id: pointToAnimation
|
||||
|
||||
PropertyAnimation {
|
||||
target: root
|
||||
property: "ratio"
|
||||
to: 1
|
||||
easing.type: Easing.OutCubic
|
||||
duration: 200
|
||||
}
|
||||
|
||||
PauseAnimation {
|
||||
duration: 200
|
||||
}
|
||||
|
||||
PropertyAnimation {
|
||||
target: root
|
||||
property: "opacity"
|
||||
to: 0
|
||||
easing.type: Easing.InQuart
|
||||
duration: 300
|
||||
}
|
||||
|
||||
onStopped: {
|
||||
root.visible = false;
|
||||
root.finished();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,7 +57,7 @@ Item {
|
|||
let items = [];
|
||||
for (let i = 0; i < outputs.length; i++) {
|
||||
if (_contains(outputs[i])) {
|
||||
let state = JSON.parse(Sanguosha.getCard4Qml(outputs[i]))
|
||||
let state = JSON.parse(Backend.getCardData(outputs[i]))
|
||||
state.x = parentPos.x;
|
||||
state.y = parentPos.y;
|
||||
state.opacity = 0;
|
||||
|
|
|
@ -14,7 +14,7 @@ Item {
|
|||
property string role: "unknown"
|
||||
property string kingdom: "qun"
|
||||
property string netstate: "online"
|
||||
property int handcards: 0
|
||||
property alias handcards: handcardAreaItem.length
|
||||
property int maxHp: 0
|
||||
property int hp: 0
|
||||
property int seatNumber: 1
|
||||
|
@ -24,10 +24,19 @@ Item {
|
|||
property bool chained: false
|
||||
property bool drank: false
|
||||
property bool isOwner: false
|
||||
property string status: "normal"
|
||||
|
||||
property alias handcardArea: handcardAreaItem
|
||||
property alias equipArea: equipAreaItem
|
||||
property alias delayedTrickArea: delayedTrickAreaItem
|
||||
property alias specialArea: handcardAreaItem
|
||||
|
||||
property alias progressBar: progressBar
|
||||
property alias progressTip: progressTip.text
|
||||
|
||||
property bool selectable: false
|
||||
property bool selected: false
|
||||
|
||||
Behavior on x {
|
||||
NumberAnimation { duration: 600; easing.type: Easing.InOutQuad }
|
||||
}
|
||||
|
@ -36,6 +45,14 @@ Item {
|
|||
NumberAnimation { duration: 600; easing.type: Easing.InOutQuad }
|
||||
}
|
||||
|
||||
PixmapAnimation {
|
||||
id: animFrame
|
||||
source: "selected"
|
||||
anchors.centerIn: parent
|
||||
loop: true
|
||||
scale: 1.1
|
||||
}
|
||||
|
||||
Image {
|
||||
id: back
|
||||
source: SkinBank.PHOTO_BACK_DIR + root.kingdom
|
||||
|
@ -108,6 +125,18 @@ Item {
|
|||
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
|
||||
|
@ -115,6 +144,13 @@ Item {
|
|||
x: 29; y: 5
|
||||
}
|
||||
|
||||
EquipArea {
|
||||
id: equipAreaItem
|
||||
|
||||
x: 31
|
||||
y: 139
|
||||
}
|
||||
|
||||
Image {
|
||||
id: chain
|
||||
visible: root.chained
|
||||
|
@ -244,6 +280,30 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
PixmapAnimation {
|
||||
id: animSelectable
|
||||
source: "selectable"
|
||||
anchors.centerIn: parent
|
||||
loop: true
|
||||
}
|
||||
|
||||
InvisibleCardArea {
|
||||
id: handcardAreaItem
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
DelayedTrickArea {
|
||||
id: delayedTrickAreaItem
|
||||
rows: 1
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 8
|
||||
}
|
||||
|
||||
InvisibleCardArea {
|
||||
id: defaultArea
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
onGeneralChanged: {
|
||||
if (!roomScene.isStarted) return;
|
||||
generalName.text = Backend.translate(general);
|
||||
|
|
|
@ -1 +1,65 @@
|
|||
|
||||
import QtQuick 2.15
|
||||
import ".."
|
||||
import "../../skin-bank.js" as SkinBank
|
||||
|
||||
Item {
|
||||
property alias rows: grid.rows
|
||||
property alias columns: grid.columns
|
||||
|
||||
InvisibleCardArea {
|
||||
id: area
|
||||
checkExisting: true
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: cards
|
||||
}
|
||||
|
||||
Grid {
|
||||
id: grid
|
||||
anchors.fill: parent
|
||||
rows: 100
|
||||
columns: 100
|
||||
|
||||
Repeater {
|
||||
model: cards
|
||||
|
||||
Image {
|
||||
source: SkinBank.DELAYED_TRICK_DIR + name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function add(inputs)
|
||||
{
|
||||
area.add(inputs);
|
||||
if (inputs instanceof Array) {
|
||||
cards.append(...inputs);
|
||||
} else {
|
||||
cards.append(inputs);
|
||||
}
|
||||
}
|
||||
|
||||
function remove(outputs)
|
||||
{
|
||||
let result = area.remove(outputs);
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
let item = result[i];
|
||||
for (let j = 0; j < cards.count; j++) {
|
||||
let icon = cards.get(j);
|
||||
if (icon.cid === item.cid) {
|
||||
cards.remove(j, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function updateCardPosition(animated)
|
||||
{
|
||||
area.updateCardPosition(animated);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1,120 @@
|
|||
import QtQuick 2.15
|
||||
import ".."
|
||||
import "../../skin-bank.js" as SkinBank
|
||||
|
||||
/* Layout of EquipArea:
|
||||
* | Treasure |
|
||||
| Weapon |
|
||||
| Armor |
|
||||
| +1 | -1 |
|
||||
+---------------+
|
||||
*/
|
||||
|
||||
Column {
|
||||
height: 88
|
||||
width: 138
|
||||
property int itemHeight: Math.floor(height / 4)
|
||||
property var items: [treasureItem, weaponItem, armorItem, defensiveHorseItem, offensiveHorseItem]
|
||||
property var subtypes: ["treasure", "weapon", "armor", "defensive_horse", "offensive_horse"]
|
||||
property int length: area.length
|
||||
|
||||
InvisibleCardArea {
|
||||
id: area
|
||||
checkExisting: true
|
||||
}
|
||||
|
||||
EquipItem {
|
||||
id: treasureItem
|
||||
width: parent.width
|
||||
height: itemHeight
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
EquipItem {
|
||||
id: weaponItem
|
||||
width: parent.width
|
||||
height: itemHeight
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
EquipItem {
|
||||
id: armorItem
|
||||
width: parent.width
|
||||
height: itemHeight
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
height: itemHeight
|
||||
|
||||
Item {
|
||||
width: Math.ceil(parent.width / 2)
|
||||
height: itemHeight
|
||||
|
||||
EquipItem {
|
||||
id: defensiveHorseItem
|
||||
width: parent.width
|
||||
height: itemHeight
|
||||
icon: "horse"
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: Math.floor(parent.width / 2)
|
||||
height: itemHeight
|
||||
|
||||
EquipItem {
|
||||
id: offensiveHorseItem
|
||||
width: parent.width
|
||||
height: itemHeight
|
||||
icon: "horse"
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function add(inputs)
|
||||
{
|
||||
area.add(inputs);
|
||||
|
||||
let card, item;
|
||||
if (inputs instanceof Array) {
|
||||
for (let i = 0; i < inputs.length; i++) {
|
||||
card = inputs[i];
|
||||
item = items[subtypes.indexOf(card.subtype)];
|
||||
item.setCard(card);
|
||||
item.show();
|
||||
}
|
||||
} else {
|
||||
card = inputs;
|
||||
item = items[subtypes.indexOf(card.subtype)];
|
||||
item.setCard(card);
|
||||
item.show();
|
||||
}
|
||||
}
|
||||
|
||||
function remove(outputs)
|
||||
{
|
||||
let result = area.remove(outputs);
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
let card = result[i];
|
||||
for (let j = 0; j < items.length; j++) {
|
||||
let item = items[j];
|
||||
if (item.cid === card.cid) {
|
||||
item.reset();
|
||||
item.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function updateCardPosition(animated)
|
||||
{
|
||||
area.updateCardPosition(animated);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
142
qml/Pages/RoomElement/PhotoElement/EquipItem.qml
Normal file
|
@ -0,0 +1,142 @@
|
|||
import QtQuick 2.15
|
||||
import ".."
|
||||
import "../../../util.js" as Utility
|
||||
import "../../skin-bank.js" as SkinBank
|
||||
|
||||
Item {
|
||||
property int cid: 0
|
||||
property string name: ""
|
||||
property string suit: ""
|
||||
property int number: 0
|
||||
|
||||
property string icon: ""
|
||||
property alias text: textItem.text
|
||||
|
||||
id: root
|
||||
|
||||
Image {
|
||||
id: iconItem
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
x: 3
|
||||
|
||||
source: icon ? SkinBank.EQUIP_ICON_DIR + icon : ""
|
||||
}
|
||||
|
||||
Image {
|
||||
id: suitItem
|
||||
anchors.right: parent.right
|
||||
source: suit ? SkinBank.CARD_SUIT_DIR + suit : ""
|
||||
width: implicitWidth / implicitHeight * height
|
||||
height: 16
|
||||
}
|
||||
|
||||
GlowText {
|
||||
id: numberItem
|
||||
visible: number > 0 && number < 14
|
||||
text: Utility.convertNumber(number)
|
||||
color: "white"
|
||||
font.family: "FZLiBian-S02"
|
||||
font.pixelSize: 16
|
||||
glow.color: "black"
|
||||
glow.spread: 0.75
|
||||
glow.radius: 2
|
||||
glow.samples: 4
|
||||
x: parent.width - 24
|
||||
y: 1
|
||||
}
|
||||
|
||||
GlowText {
|
||||
id: textItem
|
||||
font.family: "FZLiBian-S02"
|
||||
color: "white"
|
||||
font.pixelSize: 18
|
||||
glow.color: "black"
|
||||
glow.spread: 0.9
|
||||
glow.radius: 2
|
||||
glow.samples: 6
|
||||
anchors.left: iconItem.right
|
||||
anchors.leftMargin: -8
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
ParallelAnimation {
|
||||
id: showAnime
|
||||
|
||||
NumberAnimation {
|
||||
target: root
|
||||
property: "x"
|
||||
duration: 200
|
||||
easing.type: Easing.InOutQuad
|
||||
from: 10
|
||||
to: 0
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
target: root
|
||||
property: "opacity"
|
||||
duration: 200
|
||||
easing.type: Easing.InOutQuad
|
||||
from: 0
|
||||
to: 1
|
||||
}
|
||||
}
|
||||
|
||||
ParallelAnimation {
|
||||
id: hideAnime
|
||||
|
||||
NumberAnimation {
|
||||
target: root
|
||||
property: "x"
|
||||
duration: 200
|
||||
easing.type: Easing.InOutQuad
|
||||
from: 0
|
||||
to: 10
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
target: root
|
||||
property: "opacity"
|
||||
duration: 200
|
||||
easing.type: Easing.InOutQuad
|
||||
from: 1
|
||||
to: 0
|
||||
}
|
||||
}
|
||||
|
||||
function reset()
|
||||
{
|
||||
cid = 0;
|
||||
name = "";
|
||||
suit = "";
|
||||
number = 0;
|
||||
text = "";
|
||||
}
|
||||
|
||||
function setCard(card)
|
||||
{
|
||||
cid = card.cid;
|
||||
name = card.name;
|
||||
suit = card.suit;
|
||||
number = card.number;
|
||||
if (card.subtype === "defensive_horse") {
|
||||
text = "+1";
|
||||
icon = "horse";
|
||||
} else if (card.subtype === "offensive_horse") {
|
||||
text = "-1"
|
||||
icon = "horse";
|
||||
} else {
|
||||
text = name;
|
||||
icon = name;
|
||||
}
|
||||
}
|
||||
|
||||
function show()
|
||||
{
|
||||
showAnime.start();
|
||||
}
|
||||
|
||||
function hide()
|
||||
{
|
||||
hideAnime.start();
|
||||
}
|
||||
}
|
89
qml/Pages/RoomElement/PixmapAnimation.qml
Normal file
|
@ -0,0 +1,89 @@
|
|||
import QtQuick 2.15
|
||||
import Qt.labs.folderlistmodel 2.15
|
||||
import "../skin-bank.js" as SkinBank
|
||||
|
||||
Item {
|
||||
property string source: ""
|
||||
property int currentFrame: 0
|
||||
property alias interval: timer.interval
|
||||
property int loadedFrameCount: 0
|
||||
property bool autoStart: false
|
||||
property bool loop: false
|
||||
|
||||
signal loaded()
|
||||
signal started()
|
||||
signal finished()
|
||||
|
||||
id: root
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
|
||||
FolderListModel {
|
||||
id: fileModel
|
||||
folder: SkinBank.PIXANIM_DIR + source
|
||||
nameFilters: ["*.png"]
|
||||
showDirs: false
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: frames
|
||||
model: fileModel
|
||||
|
||||
Image {
|
||||
source: SkinBank.PIXANIM_DIR + root.source + "/" + index
|
||||
visible: false
|
||||
onStatusChanged: {
|
||||
if (status == Image.Ready) {
|
||||
loadedFrameCount++;
|
||||
if (loadedFrameCount == fileModel.count)
|
||||
root.loaded();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
if (autoStart)
|
||||
timer.start();
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 50
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if (currentFrame >= fileModel.count) {
|
||||
frames.itemAt(fileModel.count - 1).visible = false;
|
||||
if (loop) {
|
||||
currentFrame = 0;
|
||||
} else {
|
||||
timer.stop();
|
||||
root.finished();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentFrame > 0)
|
||||
frames.itemAt(currentFrame - 1).visible = false;
|
||||
frames.itemAt(currentFrame).visible = true;
|
||||
|
||||
currentFrame++;
|
||||
}
|
||||
}
|
||||
|
||||
function start()
|
||||
{
|
||||
if (loadedFrameCount == fileModel.count) {
|
||||
timer.start();
|
||||
} else {
|
||||
root.loaded.connect(function(){
|
||||
timer.start();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function stop()
|
||||
{
|
||||
timer.stop();
|
||||
}
|
||||
}
|
|
@ -26,9 +26,8 @@ Item {
|
|||
if (toVanish) {
|
||||
for (i = 0; i < discardedCards.length; i++) {
|
||||
card = discardedCards[i];
|
||||
card.homeOpacity = 0;
|
||||
// card.goBack(true);
|
||||
roomScene.cardItemGoBack(card, true)
|
||||
card.origOpacity = 0;
|
||||
card.goBack(true);
|
||||
card.destroyOnStop()
|
||||
}
|
||||
|
||||
|
@ -101,12 +100,12 @@ Item {
|
|||
let overflow = false;
|
||||
for (i = 0; i < cards.length; i++) {
|
||||
card = cards[i];
|
||||
card.homeX = i * card.width;
|
||||
if (card.homeX + card.width >= root.width) {
|
||||
card.origX = i * card.width;
|
||||
if (card.origX + card.width >= root.width) {
|
||||
overflow = true;
|
||||
break;
|
||||
}
|
||||
card.homeY = 0;
|
||||
card.origY = 0;
|
||||
}
|
||||
|
||||
if (overflow) {
|
||||
|
@ -115,8 +114,8 @@ Item {
|
|||
let spacing = xLimit / (cards.length - 1);
|
||||
for (i = 0; i < cards.length; i++) {
|
||||
card = cards[i];
|
||||
card.homeX = i * spacing;
|
||||
card.homeY = 0;
|
||||
card.origX = i * spacing;
|
||||
card.origY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,15 +123,13 @@ Item {
|
|||
let parentPos = roomScene.mapFromItem(root, 0, 0);
|
||||
for (i = 0; i < cards.length; i++) {
|
||||
card = cards[i];
|
||||
card.homeX += parentPos.x + offsetX;
|
||||
card.homeY += parentPos.y;
|
||||
card.origX += parentPos.x + offsetX;
|
||||
card.origY += parentPos.y;
|
||||
}
|
||||
|
||||
if (animated) {
|
||||
for (i = 0; i < cards.length; i++)
|
||||
// cards[i].goBack() // WTF
|
||||
// console.log(cards[i].homeOpacity)
|
||||
roomScene.cardItemGoBack(cards[i], true)
|
||||
cards[i].goBack(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
var Card = {
|
||||
Unknown : 0,
|
||||
PlayerHand : 1,
|
||||
PlayerEquip : 2,
|
||||
PlayerJudge : 3,
|
||||
PlayerSpecial : 4,
|
||||
Processing : 5,
|
||||
DrawPile : 6,
|
||||
DiscardPile : 7,
|
||||
Void : 8
|
||||
}
|
||||
|
||||
function arrangePhotos() {
|
||||
/* Layout of photos:
|
||||
* +---------------+
|
||||
|
@ -61,6 +73,134 @@ function replyToServer(jsonData) {
|
|||
ClientInstance.replyToServer("", jsonData);
|
||||
}
|
||||
|
||||
function getPhotoModel(id) {
|
||||
for (let i = 0; i < photoModel.count; i++) {
|
||||
let item = photoModel.get(i);
|
||||
if (item.id === id) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getPhoto(id) {
|
||||
for (let i = 0; i < photoModel.count; i++) {
|
||||
let item = photoModel.get(i);
|
||||
if (item.id === id) {
|
||||
return photos.itemAt(i);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getPhotoOrDashboard(id) {
|
||||
let photo = getPhoto(id);
|
||||
if (!photo) {
|
||||
if (id === Self.id)
|
||||
return dashboard;
|
||||
}
|
||||
return photo;
|
||||
}
|
||||
|
||||
function getAreaItem(area, id) {
|
||||
if (area === Card.DrawPile) {
|
||||
return drawPile;
|
||||
} else if (area === Card.DiscardPile || area === Card.Processing) {
|
||||
return tablePile;
|
||||
} else if (area === Card.AG) {
|
||||
return popupBox.item;
|
||||
}
|
||||
|
||||
let photo = getPhotoOrDashboard(id);
|
||||
if (!photo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (area === Card.PlayerHand) {
|
||||
return photo.handcardArea;
|
||||
} else if (area === Card.PlayerEquip)
|
||||
return photo.equipArea;
|
||||
else if (area === Card.PlayerJudge)
|
||||
return photo.delayedTrickArea;
|
||||
else if (area === Card.PlayerSpecial)
|
||||
return photo.specialArea;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function moveCards(moves) {
|
||||
for (let i = 0; i < moves.length; i++) {
|
||||
let move = moves[i];
|
||||
let from = getAreaItem(move.fromArea, move.from);
|
||||
let to = getAreaItem(move.toArea, move.to);
|
||||
if (!from || !to || from === to)
|
||||
continue;
|
||||
let items = from.remove(move.ids);
|
||||
if (items.length > 0)
|
||||
to.add(items);
|
||||
to.updateCardPosition(true);
|
||||
}
|
||||
}
|
||||
|
||||
function setEmotion(id, emotion) {
|
||||
let component = Qt.createComponent("RoomElement/PixmapAnimation.qml");
|
||||
if (component.status !== Component.Ready)
|
||||
return;
|
||||
|
||||
let photo = getPhoto(id);
|
||||
if (!photo) {
|
||||
if (id === dashboardModel.id) {
|
||||
photo = dashboard.self;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
let animation = component.createObject(photo, {source: emotion, anchors: {centerIn: photo}});
|
||||
animation.finished.connect(() => animation.destroy());
|
||||
animation.start();
|
||||
}
|
||||
|
||||
function changeHp(id, delta, losthp) {
|
||||
let photo = getPhoto(id);
|
||||
if (!photo) {
|
||||
if (id === dashboardModel.id) {
|
||||
photo = dashboard.self;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (delta < 0) {
|
||||
if (!losthp) {
|
||||
setEmotion(id, "damage")
|
||||
photo.tremble()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function doIndicate(from, tos) {
|
||||
let component = Qt.createComponent("RoomElement/IndicatorLine.qml");
|
||||
if (component.status !== Component.Ready)
|
||||
return;
|
||||
|
||||
let fromItem = getPhotoOrDashboard(from);
|
||||
let fromPos = mapFromItem(fromItem, fromItem.width / 2, fromItem.height / 2);
|
||||
|
||||
let end = [];
|
||||
for (let i = 0; i < tos.length; i++) {
|
||||
if (from === tos[i])
|
||||
continue;
|
||||
let toItem = getPhotoOrDashboard(tos[i]);
|
||||
let toPos = mapFromItem(toItem, toItem.width / 2, toItem.height / 2);
|
||||
end.push(toPos);
|
||||
}
|
||||
|
||||
let color = "#96943D";
|
||||
let line = component.createObject(roomScene, {start: fromPos, end: end, color: color});
|
||||
line.finished.connect(() => line.destroy());
|
||||
line.running = true;
|
||||
}
|
||||
|
||||
callbacks["AddPlayer"] = function(jsonData) {
|
||||
// jsonData: int id, string screenName, string avatar
|
||||
for (let i = 0; i < photoModel.count; i++) {
|
||||
|
@ -81,14 +221,11 @@ callbacks["AddPlayer"] = function(jsonData) {
|
|||
callbacks["RemovePlayer"] = function(jsonData) {
|
||||
// jsonData: int uid
|
||||
let uid = JSON.parse(jsonData)[0];
|
||||
for (let i = 0; i < photoModel.count; i++) {
|
||||
let item = photoModel.get(i);
|
||||
if (item.id === uid) {
|
||||
item.id = -1;
|
||||
item.screenName = "";
|
||||
item.general = "";
|
||||
return;
|
||||
}
|
||||
let model = getPhotoModel(uid);
|
||||
if (typeof(model) !== "undefined") {
|
||||
model.id = -1;
|
||||
model.screenName = "";
|
||||
model.general = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,12 +239,9 @@ callbacks["RoomOwner"] = function(jsonData) {
|
|||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < photoModel.count; i++) {
|
||||
let item = photoModel.get(i);
|
||||
if (item.id === uid) {
|
||||
item.isOwner = true;
|
||||
return;
|
||||
}
|
||||
let model = getPhotoModel(uid);
|
||||
if (typeof(model) !== "undefined") {
|
||||
model.isOwner = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,12 +258,9 @@ callbacks["PropertyUpdate"] = function(jsonData) {
|
|||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < photoModel.count; i++) {
|
||||
let item = photoModel.get(i);
|
||||
if (item.id === uid) {
|
||||
item[property_name] = value;
|
||||
return;
|
||||
}
|
||||
let model = getPhotoModel(uid);
|
||||
if (typeof(model) !== "undefined") {
|
||||
model[property_name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,12 +324,9 @@ callbacks["PlayerRunned"] = function(jsonData) {
|
|||
let runner = data[0];
|
||||
let robot = data[1];
|
||||
|
||||
let model;
|
||||
for (let i = 0; i < playerNum - 1; i++) {
|
||||
model = photoModel.get(i);
|
||||
if (model.id === runner) {
|
||||
model.id = robot;
|
||||
}
|
||||
let model = getPhotoModel(runner);
|
||||
if (typeof(model) !== "undefined") {
|
||||
model.id = robot;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,3 +369,9 @@ callbacks["AskForChoice"] = function(jsonData) {
|
|||
replyToServer(choices[box.result]);
|
||||
});
|
||||
}
|
||||
|
||||
callbacks["MoveCards"] = function(jsonData) {
|
||||
// jsonData: merged moves
|
||||
let moves = JSON.parse(jsonData);
|
||||
moveCards(moves);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
//var AppPath = "file://home/notify/develop/FreeKill";
|
||||
//var AppPath = "file:///home/notify/develop/FreeKill";
|
||||
var PHOTO_BACK_DIR = AppPath + "/image/photo/back/";
|
||||
var PHOTO_DIR = AppPath + "/image/photo/";
|
||||
var GENERAL_DIR = AppPath + "/image/generals/";
|
||||
var STATE_DIR = AppPath + "/image/photo/state/";
|
||||
var STATUS_DIR = AppPath + "/image/photo/status/";
|
||||
var ROLE_DIR = AppPath + "/image/photo/role/";
|
||||
var DEATH_DIR = AppPath + "/image/photo/death/";
|
||||
var MAGATAMA_DIR = AppPath + "/image/photo/magatama/";
|
||||
var CARD_DIR = AppPath + "/image/card/";
|
||||
var CARD_SUIT_DIR = AppPath + "/image/card/suit/";
|
||||
var DELAYED_TRICK_DIR = AppPath + "/image/card/delayedTrick/";
|
||||
var EQUIP_ICON_DIR = AppPath + "/image/card/equipIcon/";
|
||||
var PIXANIM_DIR = AppPath + "/image/anim/"
|
||||
|
|
21
qml/util.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
.pragma library
|
||||
|
||||
function convertNumber(number) {
|
||||
if (number === 1)
|
||||
return "A";
|
||||
if (number >= 2 && number <= 10)
|
||||
return number;
|
||||
if (number >= 11 && number <= 13) {
|
||||
const strs = ["J", "Q", "K"];
|
||||
return strs[number - 11];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Array.prototype.contains = function(element) {
|
||||
return this.indexOf(element) != -1;
|
||||
}
|
||||
|
||||
Array.prototype.prepend = function() {
|
||||
this.splice(0, 0, ...arguments);
|
||||
}
|
|
@ -85,20 +85,22 @@ bool QmlBackend::isDir(const QString &file) {
|
|||
return QFileInfo(file).isDir();
|
||||
}
|
||||
|
||||
#define CALLFUNC int err = lua_pcall(L, 1, 1, 0); \
|
||||
const char *result = lua_tostring(L, -1); \
|
||||
if (err) { \
|
||||
qDebug() << result; \
|
||||
lua_pop(L, 1); \
|
||||
return ""; \
|
||||
} \
|
||||
lua_pop(L, 1); \
|
||||
return QString(result); \
|
||||
|
||||
QString QmlBackend::translate(const QString &src) {
|
||||
lua_State *L = ClientInstance->getLuaState();
|
||||
lua_getglobal(L, "Translate");
|
||||
lua_pushstring(L, src.toUtf8().data());
|
||||
|
||||
int err = lua_pcall(L, 1, 1, 0);
|
||||
const char *result = lua_tostring(L, -1);
|
||||
if (err) {
|
||||
qDebug() << result;
|
||||
lua_pop(L, 1);
|
||||
return "";
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return QString(result);
|
||||
CALLFUNC
|
||||
}
|
||||
|
||||
QString QmlBackend::getGeneralData(const QString &general_name) {
|
||||
|
@ -106,13 +108,15 @@ QString QmlBackend::getGeneralData(const QString &general_name) {
|
|||
lua_getglobal(L, "GetGeneralData");
|
||||
lua_pushstring(L, general_name.toUtf8().data());
|
||||
|
||||
int err = lua_pcall(L, 1, 1, 0);
|
||||
const char *result = lua_tostring(L, -1);
|
||||
if (err) {
|
||||
qDebug() << result;
|
||||
lua_pop(L, 1);
|
||||
return "";
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return QString(result);
|
||||
CALLFUNC
|
||||
}
|
||||
|
||||
QString QmlBackend::getCardData(int id) {
|
||||
lua_State *L = ClientInstance->getLuaState();
|
||||
lua_getglobal(L, "GetCardData");
|
||||
lua_pushinteger(L, id);
|
||||
|
||||
CALLFUNC
|
||||
}
|
||||
|
||||
#undef CALLFUNC
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
// read data from lua, call lua functions
|
||||
Q_INVOKABLE QString translate(const QString &src);
|
||||
Q_INVOKABLE QString getGeneralData(const QString &general_name);
|
||||
Q_INVOKABLE QString getCardData(int id);
|
||||
|
||||
signals:
|
||||
void notifyUI(const QString &command, const QString &jsonData);
|
||||
|
|