Request (#7)
* cli * add timeout for class Room * request func, roomowner * request * corrent stupid Qml/JS * chooseGenerals * prepareForStart(part 1) * fix require grammar
This commit is contained in:
parent
58ea0ca80a
commit
7fd127b849
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
|
@ -1,7 +1,7 @@
|
||||||
Client = class('Client')
|
Client = class('Client')
|
||||||
|
|
||||||
-- load client classes
|
-- load client classes
|
||||||
ClientPlayer = require "client/clientplayer"
|
ClientPlayer = require "client.clientplayer"
|
||||||
|
|
||||||
freekill.client_callback = {}
|
freekill.client_callback = {}
|
||||||
|
|
||||||
|
|
|
@ -106,8 +106,8 @@ function Engine:getGeneralsRandomly(num, generalPool, except, filter)
|
||||||
except = except or {}
|
except = except or {}
|
||||||
|
|
||||||
local availableGenerals = {}
|
local availableGenerals = {}
|
||||||
for _, general in ipairs(generalPool) do
|
for _, general in pairs(generalPool) do
|
||||||
if not table.contains(except, general) and not (filter and filter(general)) then
|
if not table.contains(except, general.name) and not (filter and filter(general)) then
|
||||||
table.insert(availableGenerals, general)
|
table.insert(availableGenerals, general)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -117,9 +117,9 @@ function Engine:getGeneralsRandomly(num, generalPool, except, filter)
|
||||||
end
|
end
|
||||||
|
|
||||||
local result = {}
|
local result = {}
|
||||||
while num > 0 do
|
for i = 1, num do
|
||||||
local randomGeneral = math.random(1, #availableGenerals)
|
local randomGeneral = math.random(1, #availableGenerals)
|
||||||
table.insert(result, randomGeneral)
|
table.insert(result, availableGenerals[randomGeneral])
|
||||||
table.remove(availableGenerals, randomGeneral)
|
table.remove(availableGenerals, randomGeneral)
|
||||||
|
|
||||||
if #availableGenerals == 0 then
|
if #availableGenerals == 0 then
|
||||||
|
|
|
@ -13,7 +13,8 @@ function Player:initialize()
|
||||||
self.chained = false
|
self.chained = false
|
||||||
self.dying = false
|
self.dying = false
|
||||||
self.dead = false
|
self.dead = false
|
||||||
|
self.state = ""
|
||||||
|
|
||||||
self.playerSkills = {}
|
self.playerSkills = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,8 @@ FileIO = {
|
||||||
isDir = freekill.QmlBackend_isDir
|
isDir = freekill.QmlBackend_isDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
os.getms = freekill.GetMicroSecond
|
||||||
|
|
||||||
Stack = class("Stack")
|
Stack = class("Stack")
|
||||||
function Stack:initialize()
|
function Stack:initialize()
|
||||||
self.t = {}
|
self.t = {}
|
||||||
|
|
|
@ -8,7 +8,7 @@ package.path = package.path .. ";./lua/lib/?.lua"
|
||||||
class = require "middleclass"
|
class = require "middleclass"
|
||||||
json = require "json"
|
json = require "json"
|
||||||
require "sha256"
|
require "sha256"
|
||||||
Util = require "core/util"
|
Util = require "core.util"
|
||||||
math.randomseed(os.time())
|
math.randomseed(os.time())
|
||||||
|
|
||||||
DebugMode = true
|
DebugMode = true
|
||||||
|
@ -20,12 +20,12 @@ function pt(t)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- load core classes
|
-- load core classes
|
||||||
Engine = require "core/engine"
|
Engine = require "core.engine"
|
||||||
Package = require "core/package"
|
Package = require "core.package"
|
||||||
General = require "core/general"
|
General = require "core.general"
|
||||||
Card = require "core/card"
|
Card = require "core.card"
|
||||||
Skill = require "core/skill"
|
Skill = require "core.skill"
|
||||||
Player = require "core/player"
|
Player = require "core.player"
|
||||||
|
|
||||||
-- load packages
|
-- load packages
|
||||||
Fk = Engine:new()
|
Fk = Engine:new()
|
||||||
|
|
|
@ -25,30 +25,106 @@ function GameLogic:run()
|
||||||
self.room:adjustSeats()
|
self.room:adjustSeats()
|
||||||
|
|
||||||
self:chooseGenerals()
|
self:chooseGenerals()
|
||||||
self:startGame()
|
self:prepareForStart()
|
||||||
|
self:action()
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameLogic:assignRoles()
|
function GameLogic:assignRoles()
|
||||||
local n = #self.room.players
|
local room = self.room
|
||||||
|
local n = #room.players
|
||||||
local roles = self.role_table[n]
|
local roles = self.role_table[n]
|
||||||
table.shuffle(roles)
|
table.shuffle(roles)
|
||||||
|
|
||||||
for i = 1, n do
|
for i = 1, n do
|
||||||
local p = self.room.players[i]
|
local p = room.players[i]
|
||||||
p.role = roles[i]
|
p.role = roles[i]
|
||||||
if p.role == "lord" then
|
if p.role == "lord" then
|
||||||
self.room:broadcastProperty(p, "role")
|
room:broadcastProperty(p, "role")
|
||||||
else
|
else
|
||||||
self.room:notifyProperty(p, p, "role")
|
room:notifyProperty(p, p, "role")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameLogic:chooseGenerals()
|
function GameLogic:chooseGenerals()
|
||||||
|
local room = self.room
|
||||||
|
local function setPlayerGeneral(player, general)
|
||||||
|
if Fk.generals[general] == nil then return end
|
||||||
|
player.general = general
|
||||||
|
self.room:notifyProperty(player, player, "general")
|
||||||
|
end
|
||||||
|
local lord = room:getLord()
|
||||||
|
local lord_general = nil
|
||||||
|
if lord ~= nil then
|
||||||
|
local generals = Fk:getGeneralsRandomly(3)
|
||||||
|
for i = 1, #generals do
|
||||||
|
generals[i] = generals[i].name
|
||||||
|
end
|
||||||
|
lord_general = room:askForGeneral(lord, generals)
|
||||||
|
setPlayerGeneral(lord, lord_general)
|
||||||
|
room:broadcastProperty(lord, "general")
|
||||||
|
end
|
||||||
|
|
||||||
|
local nonlord = room:getOtherPlayers(lord)
|
||||||
|
local generals = Fk:getGeneralsRandomly(#nonlord * 3, Fk.generals, {lord_general})
|
||||||
|
table.shuffle(generals)
|
||||||
|
for _, p in ipairs(nonlord) do
|
||||||
|
local arg = {
|
||||||
|
(table.remove(generals, 1)).name,
|
||||||
|
(table.remove(generals, 1)).name,
|
||||||
|
(table.remove(generals, 1)).name,
|
||||||
|
}
|
||||||
|
p.request_data = json.encode(arg)
|
||||||
|
p.default_reply = arg[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
room:doBroadcastRequest("AskForGeneral", nonlord)
|
||||||
|
for _, p in ipairs(nonlord) do
|
||||||
|
if p.general == "" and p.reply_ready then
|
||||||
|
local general = json.decode(p.client_reply)[1]
|
||||||
|
setPlayerGeneral(p, general)
|
||||||
|
else
|
||||||
|
setPlayerGeneral(p, p.default_reply)
|
||||||
|
end
|
||||||
|
p.default_reply = ""
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameLogic:startGame()
|
function GameLogic:prepareForStart()
|
||||||
|
local room = self.room
|
||||||
|
local players = room.players
|
||||||
|
room.alive_players = players
|
||||||
|
for i = 1, #players - 1 do
|
||||||
|
players[i].next = players[i + 1]
|
||||||
|
end
|
||||||
|
players[#players].next = players[1]
|
||||||
|
|
||||||
|
for _, p in ipairs(players) do
|
||||||
|
assert(p.general ~= "")
|
||||||
|
local general = Fk.generals[p.general]
|
||||||
|
p.maxHp = general.maxHp
|
||||||
|
p.hp = general.hp
|
||||||
|
-- TODO: setup AI here
|
||||||
|
|
||||||
|
if p.role ~= "lord" then
|
||||||
|
room:broadcastProperty(p, "general")
|
||||||
|
elseif #players >= 5 then
|
||||||
|
p.maxHp = p.maxHp + 1
|
||||||
|
p.hp = p.hp + 1
|
||||||
|
end
|
||||||
|
room:broadcastProperty(p, "maxHp")
|
||||||
|
room:broadcastProperty(p, "hp")
|
||||||
|
|
||||||
|
-- TODO: add skills to player
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO: prepare drawPile
|
||||||
|
-- TODO: init cards in drawPile
|
||||||
|
|
||||||
|
-- TODO: init trigger table for self
|
||||||
|
end
|
||||||
|
|
||||||
|
function GameLogic:action()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,16 @@ local Room = class("Room")
|
||||||
function Room:initialize(_room)
|
function Room:initialize(_room)
|
||||||
self.room = _room
|
self.room = _room
|
||||||
self.players = {} -- ServerPlayer[]
|
self.players = {} -- ServerPlayer[]
|
||||||
self.gameFinished = false
|
self.alive_players = {}
|
||||||
|
self.game_finished = false
|
||||||
|
self.timeout = _room:getTimeout()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- When this function returns, the Room(C++) thread stopped.
|
-- When this function returns, the Room(C++) thread stopped.
|
||||||
function Room:run()
|
function Room:run()
|
||||||
for _, p in freekill.qlist(self.room:getPlayers()) do
|
for _, p in freekill.qlist(self.room:getPlayers()) do
|
||||||
local player = ServerPlayer:new(p)
|
local player = ServerPlayer:new(p)
|
||||||
|
player.state = p:getStateString()
|
||||||
table.insert(self.players, player)
|
table.insert(self.players, player)
|
||||||
self.server.players[player:getId()] = player
|
self.server.players[player:getId()] = player
|
||||||
end
|
end
|
||||||
|
@ -32,8 +35,55 @@ function Room:notifyProperty(p, player, property)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
function Room:doBroadcastNotify(command, jsonData)
|
function Room:doBroadcastNotify(command, jsonData, players)
|
||||||
self.room:doBroadcastNotify(self.room:getPlayers(), command, jsonData)
|
players = players or self.players
|
||||||
|
local tolist = freekill.SPlayerList()
|
||||||
|
for _, p in ipairs(players) do
|
||||||
|
tolist:append(p.serverplayer)
|
||||||
|
end
|
||||||
|
self.room:doBroadcastNotify(tolist, command, jsonData)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Room:doRequest(player, command, jsonData, wait)
|
||||||
|
if wait == nil then wait = true end
|
||||||
|
player:doRequest(command, jsonData, self.timeout)
|
||||||
|
|
||||||
|
if wait then
|
||||||
|
return player:waitForReply(self.timeout)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Room:doBroadcastRequest(command, players)
|
||||||
|
players = players or self.players
|
||||||
|
self:notifyMoveFocus(players, command)
|
||||||
|
for _, p in ipairs(players) do
|
||||||
|
self:doRequest(p, command, p.request_data, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
local remainTime = self.timeout
|
||||||
|
local currentTime = os.time()
|
||||||
|
local elapsed = 0
|
||||||
|
for _, p in ipairs(players) do
|
||||||
|
elapsed = os.time() - currentTime
|
||||||
|
remainTime = remainTime - elapsed
|
||||||
|
p:waitForReply(remainTime)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Room:notifyMoveFocus(players, command)
|
||||||
|
if (players.class) then
|
||||||
|
players = {players}
|
||||||
|
end
|
||||||
|
|
||||||
|
local ids = {}
|
||||||
|
for _, p in ipairs(players) do
|
||||||
|
table.insert(ids, p:getId())
|
||||||
|
end
|
||||||
|
|
||||||
|
self:doBroadcastNotify("MoveFocus", json.encode{
|
||||||
|
ids,
|
||||||
|
command
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
function Room:adjustSeats()
|
function Room:adjustSeats()
|
||||||
|
@ -64,8 +114,45 @@ function Room:adjustSeats()
|
||||||
self:doBroadcastNotify("ArrangeSeats", json.encode(player_circle))
|
self:doBroadcastNotify("ArrangeSeats", json.encode(player_circle))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Room:getLord()
|
||||||
|
local lord = self.players[1]
|
||||||
|
if lord.role == "lord" then return lord end
|
||||||
|
for _, p in ipairs(self.players) do
|
||||||
|
if p.role == "lord" then return p end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function Room:getOtherPlayers(expect)
|
||||||
|
local ret = {table.unpack(self.players)}
|
||||||
|
table.removeOne(ret, expect)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
function Room:askForGeneral(player, generals)
|
||||||
|
local command = "AskForGeneral"
|
||||||
|
self:notifyMoveFocus(player, command)
|
||||||
|
|
||||||
|
if #generals == 1 then return generals[1] end
|
||||||
|
local defaultChoice = generals[1]
|
||||||
|
|
||||||
|
if (player.state == "online") then
|
||||||
|
local result = self:doRequest(player, command, json.encode(generals))
|
||||||
|
if result == "" then
|
||||||
|
return defaultChoice
|
||||||
|
else
|
||||||
|
-- TODO: result is a JSON array
|
||||||
|
-- update here when choose multiple generals
|
||||||
|
return json.decode(result)[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return defaultChoice
|
||||||
|
end
|
||||||
|
|
||||||
function Room:gameOver()
|
function Room:gameOver()
|
||||||
self.gameFinished = true
|
self.game_finished = true
|
||||||
-- dosomething
|
-- dosomething
|
||||||
self.room:gameOver()
|
self.room:gameOver()
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
Server = class('Server')
|
Server = class('Server')
|
||||||
|
|
||||||
-- load server classes
|
-- load server classes
|
||||||
Room = require "server/room"
|
Room = require "server.room"
|
||||||
GameLogic = require "server/gamelogic"
|
GameLogic = require "server.gamelogic"
|
||||||
ServerPlayer = require "server/serverplayer"
|
ServerPlayer = require "server.serverplayer"
|
||||||
|
|
||||||
freekill.server_callback = {}
|
freekill.server_callback = {}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,14 @@ local ServerPlayer = Player:subclass("ServerPlayer")
|
||||||
function ServerPlayer:initialize(_self)
|
function ServerPlayer:initialize(_self)
|
||||||
Player.initialize(self)
|
Player.initialize(self)
|
||||||
self.serverplayer = _self
|
self.serverplayer = _self
|
||||||
|
|
||||||
|
self.next = nil
|
||||||
|
|
||||||
|
-- Below are for doBroadcastRequest
|
||||||
|
self.request_data = ""
|
||||||
|
self.client_reply = ""
|
||||||
|
self.default_reply = ""
|
||||||
|
self.reply_ready = false
|
||||||
end
|
end
|
||||||
|
|
||||||
function ServerPlayer:getId()
|
function ServerPlayer:getId()
|
||||||
|
@ -14,7 +22,23 @@ function ServerPlayer:doNotify(command, jsonData)
|
||||||
end
|
end
|
||||||
|
|
||||||
function ServerPlayer:doRequest(command, jsonData, timeout)
|
function ServerPlayer:doRequest(command, jsonData, timeout)
|
||||||
|
timeout = timeout or self.room.timeout
|
||||||
|
self.client_reply = ""
|
||||||
|
self.reply_ready = false
|
||||||
self.serverplayer:doRequest(command, jsonData, timeout)
|
self.serverplayer:doRequest(command, jsonData, timeout)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function ServerPlayer:waitForReply(timeout)
|
||||||
|
local result = ""
|
||||||
|
if timeout == nil then
|
||||||
|
result = self.serverplayer:waitForReply()
|
||||||
|
else
|
||||||
|
result = self.serverplayer:waitForReply(timeout)
|
||||||
|
end
|
||||||
|
self.request_data = ""
|
||||||
|
self.client_reply = result
|
||||||
|
if result ~= "" then self.reply_ready = true end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
return ServerPlayer
|
return ServerPlayer
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
local extension = Package:new("standard")
|
local extension = Package:new("standard")
|
||||||
extension.metadata = require "standard/metadata"
|
extension.metadata = require "standard.metadata"
|
||||||
|
|
||||||
Fk:loadTranslationTable{
|
Fk:loadTranslationTable{
|
||||||
["wei"] = "魏",
|
["wei"] = "魏",
|
||||||
|
|
|
@ -9,4 +9,5 @@ QtObject {
|
||||||
|
|
||||||
// Client data
|
// Client data
|
||||||
property int roomCapacity: 0
|
property int roomCapacity: 0
|
||||||
|
property int roomTimeout: 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,10 @@ callbacks["EnterLobby"] = function(jsonData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
callbacks["EnterRoom"] = function(jsonData) {
|
callbacks["EnterRoom"] = function(jsonData) {
|
||||||
config.roomCapacity = JSON.parse(jsonData)[0];
|
// jsonData: int capacity, int timeout
|
||||||
|
let data = JSON.parse(jsonData);
|
||||||
|
config.roomCapacity = data[0];
|
||||||
|
config.roomTimeout = data[1];
|
||||||
mainStack.push(room);
|
mainStack.push(room);
|
||||||
mainWindow.busy = false;
|
mainWindow.busy = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property bool enabled: true
|
||||||
|
property alias text: title.text
|
||||||
|
property alias textColor: title.color
|
||||||
|
property alias textFont: title.font
|
||||||
|
property alias backgroundColor: bg.color
|
||||||
|
property alias border: bg.border
|
||||||
|
property alias iconSource: icon.source
|
||||||
|
property int padding: 5
|
||||||
|
|
||||||
|
signal clicked
|
||||||
|
|
||||||
|
id: button
|
||||||
|
width: icon.width + title.implicitWidth + padding * 2
|
||||||
|
height: Math.max(icon.height, title.implicitHeight) + padding * 2
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: bg
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "black"
|
||||||
|
border.width: 2
|
||||||
|
border.color: "white"
|
||||||
|
opacity: 0.8
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "hovered"; when: mouse.containsMouse
|
||||||
|
PropertyChanges { target: bg; color: "white" }
|
||||||
|
PropertyChanges { target: title; color: "black" }
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "disabled"; when: !enabled
|
||||||
|
PropertyChanges { target: button; opacity: 0.2 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouse
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: parent.enabled
|
||||||
|
onReleased: if (parent.enabled) parent.clicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
x: padding
|
||||||
|
y: padding
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: icon
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: title
|
||||||
|
font.pixelSize: 18
|
||||||
|
// font.family: "WenQuanYi Micro Hei"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: ""
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,11 +13,9 @@ Item {
|
||||||
property bool isOwner: false
|
property bool isOwner: false
|
||||||
property bool isStarted: false
|
property bool isStarted: false
|
||||||
|
|
||||||
|
property alias popupBox: popupBox
|
||||||
|
|
||||||
// tmp
|
// tmp
|
||||||
Text {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text: "You are in room."
|
|
||||||
}
|
|
||||||
Button {
|
Button {
|
||||||
text: "quit"
|
text: "quit"
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
@ -28,7 +26,7 @@ Item {
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
text: "start game"
|
text: "start game"
|
||||||
visible: isOwner && !isStarted
|
visible: dashboardModel.isOwner && !isStarted
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,20 +71,20 @@ Item {
|
||||||
id: photos
|
id: photos
|
||||||
model: photoModel
|
model: photoModel
|
||||||
Photo {
|
Photo {
|
||||||
general: _general
|
general: model.general
|
||||||
screenName: _screenName
|
screenName: model.screenName
|
||||||
role: _role
|
role: model.role
|
||||||
kingdom: _kingdom
|
kingdom: model.kingdom
|
||||||
netstate: _netstate
|
netstate: model.netstate
|
||||||
maxHp: _maxHp
|
maxHp: model.maxHp
|
||||||
hp: _hp
|
hp: model.hp
|
||||||
seatNumber: _seatNumber
|
seatNumber: model.seatNumber
|
||||||
isDead: _isDead
|
isDead: model.isDead
|
||||||
dying: _dying
|
dying: model.dying
|
||||||
faceturned: _faceturned
|
faceturned: model.faceturned
|
||||||
chained: _chained
|
chained: model.chained
|
||||||
drank: _drank
|
drank: model.drank
|
||||||
isOwner: _isOwner
|
isOwner: model.isOwner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +127,30 @@ Item {
|
||||||
self.isOwner: dashboardModel.isOwner
|
self.isOwner: dashboardModel.isOwner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: popupBox
|
||||||
|
onSourceChanged: {
|
||||||
|
if (item === null)
|
||||||
|
return;
|
||||||
|
item.finished.connect(function(){
|
||||||
|
source = "";
|
||||||
|
});
|
||||||
|
item.widthChanged.connect(function(){
|
||||||
|
popupBox.moveToCenter();
|
||||||
|
});
|
||||||
|
item.heightChanged.connect(function(){
|
||||||
|
popupBox.moveToCenter();
|
||||||
|
});
|
||||||
|
moveToCenter();
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveToCenter()
|
||||||
|
{
|
||||||
|
item.x = Math.round((roomArea.width - item.width) / 2);
|
||||||
|
item.y = Math.round(roomArea.height * 0.67 - item.height / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
toast.show("Sucesessfully entered room.");
|
toast.show("Sucesessfully entered room.");
|
||||||
|
|
||||||
|
@ -157,20 +179,20 @@ Item {
|
||||||
photoModel.append({
|
photoModel.append({
|
||||||
id: -1,
|
id: -1,
|
||||||
index: i - 1, // For animating seat swap
|
index: i - 1, // For animating seat swap
|
||||||
_general: "",
|
general: "",
|
||||||
_screenName: "",
|
screenName: "",
|
||||||
_role: "unknown",
|
role: "unknown",
|
||||||
_kingdom: "qun",
|
kingdom: "qun",
|
||||||
_netstate: "online",
|
netstate: "online",
|
||||||
_maxHp: 0,
|
maxHp: 0,
|
||||||
_hp: 0,
|
hp: 0,
|
||||||
_seatNumber: i + 1,
|
seatNumber: i + 1,
|
||||||
_isDead: false,
|
isDead: false,
|
||||||
_dying: false,
|
dying: false,
|
||||||
_faceturned: false,
|
faceturned: false,
|
||||||
_chained: false,
|
chained: false,
|
||||||
_drank: false,
|
drank: false,
|
||||||
_isOwner: false
|
isOwner: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,9 @@ Item {
|
||||||
|
|
||||||
function remove(outputs)
|
function remove(outputs)
|
||||||
{
|
{
|
||||||
var result = [];
|
let result = [];
|
||||||
for (var i = 0; i < cards.length; i++) {
|
for (let i = 0; i < cards.length; i++) {
|
||||||
for (var j = 0; j < outputs.length; j++) {
|
for (let j = 0; j < outputs.length; j++) {
|
||||||
if (outputs[j] === cards[i].cid) {
|
if (outputs[j] === cards[i].cid) {
|
||||||
result.push(cards[i]);
|
result.push(cards[i]);
|
||||||
cards.splice(i, 1);
|
cards.splice(i, 1);
|
||||||
|
@ -37,9 +37,9 @@ Item {
|
||||||
|
|
||||||
function updateCardPosition(animated)
|
function updateCardPosition(animated)
|
||||||
{
|
{
|
||||||
var i, card;
|
let i, card;
|
||||||
|
|
||||||
var overflow = false;
|
let overflow = false;
|
||||||
for (i = 0; i < cards.length; i++) {
|
for (i = 0; i < cards.length; i++) {
|
||||||
card = cards[i];
|
card = cards[i];
|
||||||
card.origX = i * card.width;
|
card.origX = i * card.width;
|
||||||
|
@ -52,8 +52,8 @@ Item {
|
||||||
|
|
||||||
if (overflow) {
|
if (overflow) {
|
||||||
// TODO: Adjust cards in multiple lines if there are too many cards
|
// TODO: Adjust cards in multiple lines if there are too many cards
|
||||||
var xLimit = root.width - card.width;
|
let xLimit = root.width - card.width;
|
||||||
var spacing = xLimit / (cards.length - 1);
|
let spacing = xLimit / (cards.length - 1);
|
||||||
for (i = 0; i < cards.length; i++) {
|
for (i = 0; i < cards.length; i++) {
|
||||||
card = cards[i];
|
card = cards[i];
|
||||||
card.origX = i * spacing;
|
card.origX = i * spacing;
|
||||||
|
@ -61,7 +61,7 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var parentPos = roomScene.mapFromItem(root, 0, 0);
|
let parentPos = roomScene.mapFromItem(root, 0, 0);
|
||||||
for (i = 0; i < cards.length; i++) {
|
for (i = 0; i < cards.length; i++) {
|
||||||
card = cards[i];
|
card = cards[i];
|
||||||
card.origX += parentPos.x;
|
card.origX += parentPos.x;
|
||||||
|
|
|
@ -26,6 +26,7 @@ Item {
|
||||||
property bool footnoteVisible: true
|
property bool footnoteVisible: true
|
||||||
property bool known: true // if false it only show a card back
|
property bool known: true // if false it only show a card back
|
||||||
property bool enabled: true // if false the card will be grey
|
property bool enabled: true // if false the card will be grey
|
||||||
|
property alias card: cardItem
|
||||||
property alias glow: glowItem
|
property alias glow: glowItem
|
||||||
|
|
||||||
function getColor() {
|
function getColor() {
|
||||||
|
@ -38,9 +39,12 @@ Item {
|
||||||
property int cid: 0
|
property int cid: 0
|
||||||
property bool selectable: true
|
property bool selectable: true
|
||||||
property bool selected: false
|
property bool selected: false
|
||||||
|
property bool draggable: false
|
||||||
|
property bool autoBack: true
|
||||||
property int origX: 0
|
property int origX: 0
|
||||||
property int origY: 0
|
property int origY: 0
|
||||||
property real origOpacity: 0
|
property real origOpacity: 1
|
||||||
|
property bool isClicked: false
|
||||||
property bool moveAborted: false
|
property bool moveAborted: false
|
||||||
property alias goBackAnim: goBackAnimation
|
property alias goBackAnim: goBackAnimation
|
||||||
property int goBackDuration: 500
|
property int goBackDuration: 500
|
||||||
|
@ -71,6 +75,7 @@ Item {
|
||||||
source: known ? (name != "" ? SkinBank.CARD_DIR + name : "")
|
source: known ? (name != "" ? SkinBank.CARD_DIR + name : "")
|
||||||
: (SkinBank.CARD_DIR + "card-back")
|
: (SkinBank.CARD_DIR + "card-back")
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
@ -97,7 +102,7 @@ Item {
|
||||||
Image {
|
Image {
|
||||||
id: colorItem
|
id: colorItem
|
||||||
visible: known && suit == ""
|
visible: known && suit == ""
|
||||||
source: visible ? SkinBank.CARD_SUIT_DIR + "/" + color : ""
|
source: (visible && color != "") ? SkinBank.CARD_SUIT_DIR + "/" + color : ""
|
||||||
x: 1
|
x: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +131,41 @@ Item {
|
||||||
opacity: 0.7
|
opacity: 0.7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
drag.target: draggable ? parent : undefined
|
||||||
|
drag.axis: Drag.XAndYAxis
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
root.isClicked = mouse.isClick;
|
||||||
|
parent.released();
|
||||||
|
if (autoBack)
|
||||||
|
goBackAnimation.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
onEntered: {
|
||||||
|
parent.entered();
|
||||||
|
if (draggable) {
|
||||||
|
glow.visible = true;
|
||||||
|
root.z++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onExited: {
|
||||||
|
parent.exited();
|
||||||
|
if (draggable) {
|
||||||
|
glow.visible = false;
|
||||||
|
root.z--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
selected = selectable ? !selected : false;
|
||||||
|
parent.clicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ParallelAnimation {
|
ParallelAnimation {
|
||||||
id: goBackAnimation
|
id: goBackAnimation
|
||||||
|
|
||||||
|
@ -180,7 +220,7 @@ Item {
|
||||||
|
|
||||||
function toData()
|
function toData()
|
||||||
{
|
{
|
||||||
var data = {
|
let data = {
|
||||||
cid: cid,
|
cid: cid,
|
||||||
name: name,
|
name: name,
|
||||||
suit: suit,
|
suit: suit,
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import ".."
|
||||||
|
import "../skin-bank.js" as SkinBank
|
||||||
|
|
||||||
|
GraphicsBox {
|
||||||
|
property alias generalList: generalList
|
||||||
|
// property var generalList: []
|
||||||
|
property int choiceNum: 1
|
||||||
|
property var choices: []
|
||||||
|
property var selectedItem: []
|
||||||
|
property bool loaded: false
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: generalList
|
||||||
|
}
|
||||||
|
|
||||||
|
id: root
|
||||||
|
title.text: qsTr("Please choose ") + choiceNum + qsTr(" general(s)")
|
||||||
|
width: generalArea.width + body.anchors.leftMargin + body.anchors.rightMargin
|
||||||
|
height: body.implicitHeight + body.anchors.topMargin + body.anchors.bottomMargin
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: body
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 40
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: generalArea
|
||||||
|
width: (generalList.count >= 5 ? Math.ceil(generalList.count / 2) : Math.max(3, generalList.count)) * 97
|
||||||
|
height: generalList.count >= 5 ? 290 : 150
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: generalMagnetList
|
||||||
|
model: generalList.count
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 93
|
||||||
|
height: 130
|
||||||
|
x: (index % Math.ceil(generalList.count / (generalList.count >= 5 ? 2 : 1))) * 98 + (generalList.count >= 5 && index > generalList.count / 2 && generalList.count % 2 == 1 ? 50 : 0)
|
||||||
|
y: generalList.count < 5 ? 0 : (index < generalList.count / 2 ? 0 : 135)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: splitLine
|
||||||
|
width: parent.width - 80
|
||||||
|
height: 6
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
clip: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width
|
||||||
|
height: 165
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: resultArea
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: resultList
|
||||||
|
model: choiceNum
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: "#1D1E19"
|
||||||
|
radius: 3
|
||||||
|
width: 93
|
||||||
|
height: 130
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: buttonArea
|
||||||
|
width: parent.width
|
||||||
|
height: 40
|
||||||
|
|
||||||
|
MetroButton {
|
||||||
|
id: fightButton
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
text: qsTr("Fight")
|
||||||
|
width: 120
|
||||||
|
height: 35
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
onClicked: close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: generalCardList
|
||||||
|
model: generalList
|
||||||
|
|
||||||
|
GeneralCardItem {
|
||||||
|
name: model.name
|
||||||
|
selectable: true
|
||||||
|
draggable: true
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
let toSelect = true;
|
||||||
|
for (let i = 0; i < selectedItem.length; i++) {
|
||||||
|
if (selectedItem[i] === this) {
|
||||||
|
toSelect = false;
|
||||||
|
selectedItem.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (toSelect && selectedItem.length < choiceNum)
|
||||||
|
selectedItem.push(this);
|
||||||
|
updatePosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
if (!isClicked)
|
||||||
|
arrangeCards();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function arrangeCards()
|
||||||
|
{
|
||||||
|
let item, i;
|
||||||
|
|
||||||
|
selectedItem = [];
|
||||||
|
for (i = 0; i < generalList.count; i++) {
|
||||||
|
item = generalCardList.itemAt(i);
|
||||||
|
if (item.y > splitLine.y)
|
||||||
|
selectedItem.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedItem.sort((a, b) => a.x - b.x);
|
||||||
|
|
||||||
|
if (selectedItem.length > choiceNum)
|
||||||
|
selectedItem.splice(choiceNum, selectedItem.length - choiceNum);
|
||||||
|
|
||||||
|
updatePosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePosition()
|
||||||
|
{
|
||||||
|
choices = [];
|
||||||
|
let item, magnet, pos, i;
|
||||||
|
for (i = 0; i < selectedItem.length && i < resultList.count; i++) {
|
||||||
|
item = selectedItem[i];
|
||||||
|
choices.push(item.name);
|
||||||
|
magnet = resultList.itemAt(i);
|
||||||
|
pos = root.mapFromItem(resultArea, magnet.x, magnet.y);
|
||||||
|
if (item.origX !== pos.x || item.origY !== item.y) {
|
||||||
|
item.origX = pos.x;
|
||||||
|
item.origY = pos.y;
|
||||||
|
item.goBack(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fightButton.enabled = (choices.length == choiceNum);
|
||||||
|
|
||||||
|
for (i = 0; i < generalCardList.count; i++) {
|
||||||
|
item = generalCardList.itemAt(i);
|
||||||
|
if (selectedItem.indexOf(item) != -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
magnet = generalMagnetList.itemAt(i);
|
||||||
|
pos = root.mapFromItem(generalMagnetList.parent, magnet.x, magnet.y);
|
||||||
|
if (item.origX !== pos.x || item.origY !== item.y) {
|
||||||
|
item.origX = pos.x;
|
||||||
|
item.origY = pos.y;
|
||||||
|
item.goBack(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import "../skin-bank.js" as SkinBank
|
||||||
|
|
||||||
|
/* Layout of general card:
|
||||||
|
* +--------+
|
||||||
|
*kindom|wu 9999| <- hp
|
||||||
|
*name -|s |
|
||||||
|
* |q img |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* +--------+
|
||||||
|
* Inherit from CardItem to use common signal
|
||||||
|
*/
|
||||||
|
|
||||||
|
CardItem {
|
||||||
|
property string kingdom: "qun"
|
||||||
|
name: "caocao"
|
||||||
|
// description: Sanguosha.getGeneralDescription(name)
|
||||||
|
suit: ""
|
||||||
|
number: 0
|
||||||
|
footnote: ""
|
||||||
|
card.source: SkinBank.GENERAL_DIR + name
|
||||||
|
glow.color: "white" //Engine.kingdomColor[kingdom]
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property alias title: titleItem
|
||||||
|
signal accepted() //Read result
|
||||||
|
signal finished() //Close the box
|
||||||
|
|
||||||
|
id: root
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: background
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "#B0000000"
|
||||||
|
radius: 5
|
||||||
|
border.color: "#A6967A"
|
||||||
|
border.width: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
DropShadow {
|
||||||
|
source: background
|
||||||
|
anchors.fill: background
|
||||||
|
color: "#B0000000"
|
||||||
|
radius: 5
|
||||||
|
samples: 12
|
||||||
|
spread: 0.2
|
||||||
|
horizontalOffset: 5
|
||||||
|
verticalOffset: 4
|
||||||
|
transparentBorder: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: titleItem
|
||||||
|
color: "#E4D5A0"
|
||||||
|
font.pixelSize: 18
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 4
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
drag.target: parent
|
||||||
|
drag.axis: Drag.XAndYAxis
|
||||||
|
}
|
||||||
|
|
||||||
|
function close()
|
||||||
|
{
|
||||||
|
accepted();
|
||||||
|
finished();
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ Item {
|
||||||
{
|
{
|
||||||
cardArea.add(inputs);
|
cardArea.add(inputs);
|
||||||
if (inputs instanceof Array) {
|
if (inputs instanceof Array) {
|
||||||
for (var i = 0; i < inputs.length; i++)
|
for (let i = 0; i < inputs.length; i++)
|
||||||
filterInputCard(inputs[i]);
|
filterInputCard(inputs[i]);
|
||||||
} else {
|
} else {
|
||||||
filterInputCard(inputs);
|
filterInputCard(inputs);
|
||||||
|
@ -36,9 +36,9 @@ Item {
|
||||||
|
|
||||||
function remove(outputs)
|
function remove(outputs)
|
||||||
{
|
{
|
||||||
var result = cardArea.remove(outputs);
|
let result = cardArea.remove(outputs);
|
||||||
var card;
|
let card;
|
||||||
for (var i = 0; i < result.length; i++) {
|
for (let i = 0; i < result.length; i++) {
|
||||||
card = result[i];
|
card = result[i];
|
||||||
card.draggable = false;
|
card.draggable = false;
|
||||||
card.selectable = false;
|
card.selectable = false;
|
||||||
|
@ -49,7 +49,7 @@ Item {
|
||||||
|
|
||||||
function enableCards(cardIds)
|
function enableCards(cardIds)
|
||||||
{
|
{
|
||||||
var card, i;
|
let card, i;
|
||||||
for (i = 0; i < cards.length; i++) {
|
for (i = 0; i < cards.length; i++) {
|
||||||
card = cards[i];
|
card = cards[i];
|
||||||
card.selectable = cardIds.contains(card.cid);
|
card.selectable = cardIds.contains(card.cid);
|
||||||
|
@ -64,7 +64,7 @@ Item {
|
||||||
{
|
{
|
||||||
cardArea.updateCardPosition(false);
|
cardArea.updateCardPosition(false);
|
||||||
|
|
||||||
var i, card;
|
let i, card;
|
||||||
for (i = 0; i < cards.length; i++) {
|
for (i = 0; i < cards.length; i++) {
|
||||||
card = cards[i];
|
card = cards[i];
|
||||||
if (card.selected)
|
if (card.selected)
|
||||||
|
@ -81,8 +81,8 @@ Item {
|
||||||
{
|
{
|
||||||
area.updateCardPosition(true);
|
area.updateCardPosition(true);
|
||||||
|
|
||||||
for (var i = 0; i < cards.length; i++) {
|
for (let i = 0; i < cards.length; i++) {
|
||||||
var card = cards[i];
|
let card = cards[i];
|
||||||
if (card.selected) {
|
if (card.selected) {
|
||||||
if (!selectedCards.contains(card))
|
if (!selectedCards.contains(card))
|
||||||
selectCard(card);
|
selectCard(card);
|
||||||
|
@ -101,7 +101,7 @@ Item {
|
||||||
|
|
||||||
function unselectCard(card)
|
function unselectCard(card)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < selectedCards.length; i++) {
|
for (let i = 0; i < selectedCards.length; i++) {
|
||||||
if (selectedCards[i] === card) {
|
if (selectedCards[i] === card) {
|
||||||
selectedCards.splice(i, 1);
|
selectedCards.splice(i, 1);
|
||||||
cardSelected(card.cid, false);
|
cardSelected(card.cid, false);
|
||||||
|
@ -112,7 +112,7 @@ Item {
|
||||||
|
|
||||||
function unselectAll(exceptId) {
|
function unselectAll(exceptId) {
|
||||||
let card = undefined;
|
let card = undefined;
|
||||||
for (var i = 0; i < selectedCards.length; i++) {
|
for (let i = 0; i < selectedCards.length; i++) {
|
||||||
if (selectedCards[i].cid !== exceptId) {
|
if (selectedCards[i].cid !== exceptId) {
|
||||||
selectedCards[i].selected = false;
|
selectedCards[i].selected = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,9 +10,9 @@ Item {
|
||||||
|
|
||||||
function add(inputs)
|
function add(inputs)
|
||||||
{
|
{
|
||||||
var card;
|
let card;
|
||||||
if (inputs instanceof Array) {
|
if (inputs instanceof Array) {
|
||||||
for (var i = 0; i < inputs.length; i++) {
|
for (let i = 0; i < inputs.length; i++) {
|
||||||
card = inputs[i];
|
card = inputs[i];
|
||||||
pendingInput.push(card);
|
pendingInput.push(card);
|
||||||
cards.push(card.toData());
|
cards.push(card.toData());
|
||||||
|
@ -38,7 +38,7 @@ Item {
|
||||||
if (!checkExisting)
|
if (!checkExisting)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (var i = 0; i < cards.length; i++)
|
for (let i = 0; i < cards.length; i++)
|
||||||
{
|
{
|
||||||
if (cards[i].cid === cid)
|
if (cards[i].cid === cid)
|
||||||
return true;
|
return true;
|
||||||
|
@ -48,13 +48,13 @@ Item {
|
||||||
|
|
||||||
function remove(outputs)
|
function remove(outputs)
|
||||||
{
|
{
|
||||||
var component = Qt.createComponent("CardItem.qml");
|
let component = Qt.createComponent("CardItem.qml");
|
||||||
if (component.status !== Component.Ready)
|
if (component.status !== Component.Ready)
|
||||||
return [];
|
return [];
|
||||||
|
|
||||||
var parentPos = roomScene.mapFromItem(root, 0, 0);
|
let parentPos = roomScene.mapFromItem(root, 0, 0);
|
||||||
var card;
|
let card;
|
||||||
var items = [];
|
let items = [];
|
||||||
for (let i = 0; i < outputs.length; i++) {
|
for (let i = 0; i < outputs.length; i++) {
|
||||||
if (_contains(outputs[i])) {
|
if (_contains(outputs[i])) {
|
||||||
let state = JSON.parse(Sanguosha.getCard4Qml(outputs[i]))
|
let state = JSON.parse(Sanguosha.getCard4Qml(outputs[i]))
|
||||||
|
@ -82,10 +82,10 @@ Item {
|
||||||
|
|
||||||
function updateCardPosition(animated)
|
function updateCardPosition(animated)
|
||||||
{
|
{
|
||||||
var i, card;
|
let i, card;
|
||||||
|
|
||||||
if (animated) {
|
if (animated) {
|
||||||
var parentPos = roomScene.mapFromItem(root, 0, 0);
|
let parentPos = roomScene.mapFromItem(root, 0, 0);
|
||||||
for (i = 0; i < pendingInput.length; i++) {
|
for (i = 0; i < pendingInput.length; i++) {
|
||||||
card = pendingInput[i];
|
card = pendingInput[i];
|
||||||
card.origX = parentPos.x - card.width / 2 + ((i - pendingInput.length / 2) * 15);
|
card.origX = parentPos.x - card.width / 2 + ((i - pendingInput.length / 2) * 15);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtGraphicalEffects 1.15
|
import QtGraphicalEffects 1.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
import "PhotoElement"
|
import "PhotoElement"
|
||||||
import "../skin-bank.js" as SkinBank
|
import "../skin-bank.js" as SkinBank
|
||||||
|
|
||||||
|
@ -24,6 +25,9 @@ Item {
|
||||||
property bool drank: false
|
property bool drank: false
|
||||||
property bool isOwner: false
|
property bool isOwner: false
|
||||||
|
|
||||||
|
property alias progressBar: progressBar
|
||||||
|
property alias progressTip: progressTip.text
|
||||||
|
|
||||||
Behavior on x {
|
Behavior on x {
|
||||||
NumberAnimation { duration: 600; easing.type: Easing.InOutQuad }
|
NumberAnimation { duration: 600; easing.type: Easing.InOutQuad }
|
||||||
}
|
}
|
||||||
|
@ -95,6 +99,15 @@ Item {
|
||||||
visible: root.isDead
|
visible: root.isDead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottomMargin: 8
|
||||||
|
anchors.rightMargin: 4
|
||||||
|
source: SkinBank.PHOTO_DIR + (isOwner ? "owner" : "ready")
|
||||||
|
visible: screenName != "" && !roomScene.isStarted
|
||||||
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: turnedOver
|
id: turnedOver
|
||||||
visible: root.faceturned
|
visible: root.faceturned
|
||||||
|
@ -155,6 +168,7 @@ Item {
|
||||||
|
|
||||||
GlowText {
|
GlowText {
|
||||||
id: seatNum
|
id: seatNum
|
||||||
|
visible: !progressBar.visible
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: -32
|
anchors.bottomMargin: -32
|
||||||
|
@ -191,4 +205,42 @@ Item {
|
||||||
function tremble() {
|
function tremble() {
|
||||||
trembleAnimation.start()
|
trembleAnimation.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProgressBar {
|
||||||
|
id: progressBar
|
||||||
|
width: parent.width
|
||||||
|
height: 4
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: -4
|
||||||
|
from: 0.0
|
||||||
|
to: 100.0
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
NumberAnimation on value {
|
||||||
|
running: progressBar.visible
|
||||||
|
from: 100.0
|
||||||
|
to: 0.0
|
||||||
|
duration: config.roomTimeout * 1000
|
||||||
|
|
||||||
|
onFinished: {
|
||||||
|
progressBar.visible = false;
|
||||||
|
root.progressTip = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
anchors.top: progressBar.bottom
|
||||||
|
anchors.topMargin: 1
|
||||||
|
source: SkinBank.PHOTO_DIR + "control/tip"
|
||||||
|
visible: progressTip.text != ""
|
||||||
|
Text {
|
||||||
|
id: progressTip
|
||||||
|
font.family: "FZLiBian-S02"
|
||||||
|
font.pixelSize: 18
|
||||||
|
x: 18
|
||||||
|
color: "white"
|
||||||
|
text: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ Item {
|
||||||
running: true
|
running: true
|
||||||
triggeredOnStart: true
|
triggeredOnStart: true
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
var i, card;
|
let i, card;
|
||||||
if (toVanish) {
|
if (toVanish) {
|
||||||
for (i = 0; i < discardedCards.length; i++) {
|
for (i = 0; i < discardedCards.length; i++) {
|
||||||
card = discardedCards[i];
|
card = discardedCards[i];
|
||||||
|
@ -60,13 +60,13 @@ Item {
|
||||||
|
|
||||||
function remove(outputs)
|
function remove(outputs)
|
||||||
{
|
{
|
||||||
var i, j;
|
let i, j;
|
||||||
|
|
||||||
var result = area.remove(outputs);
|
let result = area.remove(outputs);
|
||||||
var vanished = [];
|
let vanished = [];
|
||||||
if (result.length < outputs.length) {
|
if (result.length < outputs.length) {
|
||||||
for (i = 0; i < outputs.length; i++) {
|
for (i = 0; i < outputs.length; i++) {
|
||||||
var exists = false;
|
let exists = false;
|
||||||
for (j = 0; j < result.length; j++) {
|
for (j = 0; j < result.length; j++) {
|
||||||
if (result[j].cid === outputs[i]) {
|
if (result[j].cid === outputs[i]) {
|
||||||
exists = true;
|
exists = true;
|
||||||
|
@ -96,9 +96,9 @@ Item {
|
||||||
if (cards.length <= 0)
|
if (cards.length <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var i, card;
|
let i, card;
|
||||||
|
|
||||||
var overflow = false;
|
let overflow = false;
|
||||||
for (i = 0; i < cards.length; i++) {
|
for (i = 0; i < cards.length; i++) {
|
||||||
card = cards[i];
|
card = cards[i];
|
||||||
card.homeX = i * card.width;
|
card.homeX = i * card.width;
|
||||||
|
@ -111,8 +111,8 @@ Item {
|
||||||
|
|
||||||
if (overflow) {
|
if (overflow) {
|
||||||
//@to-do: Adjust cards in multiple lines if there are too many cards
|
//@to-do: Adjust cards in multiple lines if there are too many cards
|
||||||
var xLimit = root.width - card.width;
|
let xLimit = root.width - card.width;
|
||||||
var spacing = xLimit / (cards.length - 1);
|
let spacing = xLimit / (cards.length - 1);
|
||||||
for (i = 0; i < cards.length; i++) {
|
for (i = 0; i < cards.length; i++) {
|
||||||
card = cards[i];
|
card = cards[i];
|
||||||
card.homeX = i * spacing;
|
card.homeX = i * spacing;
|
||||||
|
@ -120,8 +120,8 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var offsetX = Math.max(0, (root.width - cards.length * card.width) / 2);
|
let offsetX = Math.max(0, (root.width - cards.length * card.width) / 2);
|
||||||
var parentPos = roomScene.mapFromItem(root, 0, 0);
|
let parentPos = roomScene.mapFromItem(root, 0, 0);
|
||||||
for (i = 0; i < cards.length; i++) {
|
for (i = 0; i < cards.length; i++) {
|
||||||
card = cards[i];
|
card = cards[i];
|
||||||
card.homeX += parentPos.x + offsetX;
|
card.homeX += parentPos.x + offsetX;
|
||||||
|
|
|
@ -7,14 +7,14 @@ function arrangePhotos() {
|
||||||
* +---------------+
|
* +---------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var photoWidth = 175;
|
const photoWidth = 175;
|
||||||
var roomAreaPadding = 10;
|
const roomAreaPadding = 10;
|
||||||
var verticalPadding = Math.max(10, roomArea.width * 0.01);
|
let verticalPadding = Math.max(10, roomArea.width * 0.01);
|
||||||
var horizontalSpacing = Math.max(30, roomArea.height * 0.1);
|
let horizontalSpacing = Math.max(30, roomArea.height * 0.1);
|
||||||
var verticalSpacing = (roomArea.width - photoWidth * 7 - verticalPadding * 2) / 6;
|
let verticalSpacing = (roomArea.width - photoWidth * 7 - verticalPadding * 2) / 6;
|
||||||
|
|
||||||
// Position 1-7
|
// Position 1-7
|
||||||
var regions = [
|
const regions = [
|
||||||
{ x: verticalPadding + (photoWidth + verticalSpacing) * 6, y: roomAreaPadding + horizontalSpacing * 2 },
|
{ x: verticalPadding + (photoWidth + verticalSpacing) * 6, y: roomAreaPadding + horizontalSpacing * 2 },
|
||||||
{ x: verticalPadding + (photoWidth + verticalSpacing) * 5, y: roomAreaPadding + horizontalSpacing },
|
{ x: verticalPadding + (photoWidth + verticalSpacing) * 5, y: roomAreaPadding + horizontalSpacing },
|
||||||
{ x: verticalPadding + (photoWidth + verticalSpacing) * 4, y: roomAreaPadding },
|
{ x: verticalPadding + (photoWidth + verticalSpacing) * 4, y: roomAreaPadding },
|
||||||
|
@ -24,7 +24,7 @@ function arrangePhotos() {
|
||||||
{ x: verticalPadding, y: roomAreaPadding + horizontalSpacing * 2 },
|
{ x: verticalPadding, y: roomAreaPadding + horizontalSpacing * 2 },
|
||||||
];
|
];
|
||||||
|
|
||||||
var regularSeatIndex = [
|
const regularSeatIndex = [
|
||||||
[4],
|
[4],
|
||||||
[3, 5],
|
[3, 5],
|
||||||
[1, 4, 7],
|
[1, 4, 7],
|
||||||
|
@ -33,9 +33,9 @@ function arrangePhotos() {
|
||||||
[1, 2, 3, 5, 6, 7],
|
[1, 2, 3, 5, 6, 7],
|
||||||
[1, 2, 3, 4, 5, 6, 7],
|
[1, 2, 3, 4, 5, 6, 7],
|
||||||
];
|
];
|
||||||
var seatIndex = regularSeatIndex[playerNum - 2];
|
let seatIndex = regularSeatIndex[playerNum - 2];
|
||||||
|
|
||||||
var item, region, i;
|
let item, region, i;
|
||||||
|
|
||||||
for (i = 0; i < playerNum - 1; i++) {
|
for (i = 0; i < playerNum - 1; i++) {
|
||||||
item = photos.itemAt(i);
|
item = photos.itemAt(i);
|
||||||
|
@ -58,9 +58,8 @@ callbacks["AddPlayer"] = function(jsonData) {
|
||||||
let name = data[1];
|
let name = data[1];
|
||||||
let avatar = data[2];
|
let avatar = data[2];
|
||||||
item.id = uid;
|
item.id = uid;
|
||||||
item._screenName = name;
|
item.screenName = name;
|
||||||
item._general = avatar;
|
item.general = avatar;
|
||||||
photos.itemAt(i).tremble();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,19 +72,31 @@ callbacks["RemovePlayer"] = function(jsonData) {
|
||||||
let item = photoModel.get(i);
|
let item = photoModel.get(i);
|
||||||
if (item.id === uid) {
|
if (item.id === uid) {
|
||||||
item.id = -1;
|
item.id = -1;
|
||||||
item._screenName = "";
|
item.screenName = "";
|
||||||
item._general = "";
|
item.general = "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
callbacks["RoomOwner"] = function(jsonData) {
|
callbacks["RoomOwner"] = function(jsonData) {
|
||||||
// jsonData: int uid of the owner
|
// jsonData: int uid of the owner
|
||||||
toast.show(J)
|
let uid = JSON.parse(jsonData)[0];
|
||||||
|
|
||||||
|
if (dashboardModel.id === uid) {
|
||||||
|
dashboardModel.isOwner = true;
|
||||||
|
roomScene.dashboardModelChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < photoModel.count; i++) {
|
||||||
|
let item = photoModel.get(i);
|
||||||
|
if (item.id === uid) {
|
||||||
|
item.isOwner = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
callbacks["PropertyUpdate"] = function(jsonData) {
|
callbacks["PropertyUpdate"] = function(jsonData) {
|
||||||
// jsonData: int id, string property_name, value
|
// jsonData: int id, string property_name, value
|
||||||
|
@ -103,7 +114,7 @@ callbacks["PropertyUpdate"] = function(jsonData) {
|
||||||
for (let i = 0; i < photoModel.count; i++) {
|
for (let i = 0; i < photoModel.count; i++) {
|
||||||
let item = photoModel.get(i);
|
let item = photoModel.get(i);
|
||||||
if (item.id === uid) {
|
if (item.id === uid) {
|
||||||
item["_" + property_name] = value;
|
item[property_name] = value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,10 +123,11 @@ callbacks["PropertyUpdate"] = function(jsonData) {
|
||||||
callbacks["ArrangeSeats"] = function(jsonData) {
|
callbacks["ArrangeSeats"] = function(jsonData) {
|
||||||
// jsonData: seat order
|
// jsonData: seat order
|
||||||
let order = JSON.parse(jsonData);
|
let order = JSON.parse(jsonData);
|
||||||
|
roomScene.isStarted = true;
|
||||||
|
|
||||||
for (let i = 0; i < photoModel.count; i++) {
|
for (let i = 0; i < photoModel.count; i++) {
|
||||||
let item = photoModel.get(i);
|
let item = photoModel.get(i);
|
||||||
item._seatNumber = order.indexOf(item.id) + 1;
|
item.seatNumber = order.indexOf(item.id) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dashboardModel.seatNumber = order.indexOf(Self.id) + 1;
|
dashboardModel.seatNumber = order.indexOf(Self.id) + 1;
|
||||||
|
@ -134,3 +146,45 @@ callbacks["ArrangeSeats"] = function(jsonData) {
|
||||||
|
|
||||||
arrangePhotos();
|
arrangePhotos();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cancelAllFocus() {
|
||||||
|
let item;
|
||||||
|
for (let i = 0; i < playerNum - 1; i++) {
|
||||||
|
item = photos.itemAt(i);
|
||||||
|
item.progressBar.visible = false;
|
||||||
|
item.progressTip = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callbacks["MoveFocus"] = function(jsonData) {
|
||||||
|
// jsonData: int[] focuses, string command
|
||||||
|
cancelAllFocus();
|
||||||
|
let data = JSON.parse(jsonData);
|
||||||
|
let focuses = data[0];
|
||||||
|
let command = data[1];
|
||||||
|
|
||||||
|
let item, model;
|
||||||
|
for (let i = 0; i < playerNum - 1; i++) {
|
||||||
|
model = photoModel.get(i);
|
||||||
|
if (focuses.indexOf(model.id) != -1) {
|
||||||
|
item = photos.itemAt(i);
|
||||||
|
item.progressBar.visible = true;
|
||||||
|
item.progressTip = command + " thinking...";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callbacks["AskForGeneral"] = function(jsonData) {
|
||||||
|
// jsonData: string[] Generals
|
||||||
|
// TODO: choose multiple generals
|
||||||
|
let data = JSON.parse(jsonData);
|
||||||
|
roomScene.popupBox.source = "RoomElement/ChooseGeneralBox.qml";
|
||||||
|
let box = roomScene.popupBox.item;
|
||||||
|
box.choiceNum = 1;
|
||||||
|
box.accepted.connect(() => {
|
||||||
|
ClientInstance.replyToServer("AskForGeneral", JSON.stringify([box.choices[0]]));
|
||||||
|
});
|
||||||
|
for (let i = 0; i < data.length; i++)
|
||||||
|
box.generalList.append({ "name": data[i] });
|
||||||
|
box.updatePosition();
|
||||||
|
}
|
||||||
|
|
21
src/main.cpp
21
src/main.cpp
|
@ -3,32 +3,39 @@
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QGuiApplication app(argc, argv);
|
QCoreApplication *app;
|
||||||
QGuiApplication::setApplicationName("FreeKill");
|
QCoreApplication::setApplicationName("FreeKill");
|
||||||
QGuiApplication::setApplicationVersion("Alpha 0.0.1");
|
QCoreApplication::setApplicationVersion("Alpha 0.0.1");
|
||||||
|
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
parser.setApplicationDescription("FreeKill server");
|
parser.setApplicationDescription("FreeKill server");
|
||||||
parser.addHelpOption();
|
parser.addHelpOption();
|
||||||
parser.addVersionOption();
|
parser.addVersionOption();
|
||||||
parser.addOption({{"s", "server"}, "start server at <port>", "port"});
|
parser.addOption({{"s", "server"}, "start server at <port>", "port"});
|
||||||
parser.process(app);
|
QStringList cliOptions;
|
||||||
|
for (int i = 0; i < argc; i++)
|
||||||
|
cliOptions << argv[i];
|
||||||
|
|
||||||
|
parser.parse(cliOptions);
|
||||||
|
|
||||||
bool startServer = parser.isSet("server");
|
bool startServer = parser.isSet("server");
|
||||||
ushort serverPort = 9527;
|
ushort serverPort = 9527;
|
||||||
|
|
||||||
if (startServer) {
|
if (startServer) {
|
||||||
|
app = new QCoreApplication(argc, argv);
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
if (parser.value("server").toInt(&ok) && ok)
|
if (parser.value("server").toInt(&ok) && ok)
|
||||||
serverPort = parser.value("server").toInt();
|
serverPort = parser.value("server").toInt();
|
||||||
Server *server = new Server;
|
Server *server = new Server;
|
||||||
if (!server->listen(QHostAddress::Any, serverPort)) {
|
if (!server->listen(QHostAddress::Any, serverPort)) {
|
||||||
fprintf(stderr, "cannot listen on port %d!\n", serverPort);
|
fprintf(stderr, "cannot listen on port %d!\n", serverPort);
|
||||||
app.exit(1);
|
app->exit(1);
|
||||||
}
|
}
|
||||||
return app.exec();
|
return app->exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app = new QGuiApplication(argc, argv);
|
||||||
|
|
||||||
QQmlApplicationEngine *engine = new QQmlApplicationEngine;
|
QQmlApplicationEngine *engine = new QQmlApplicationEngine;
|
||||||
|
|
||||||
QmlBackend backend;
|
QmlBackend backend;
|
||||||
|
@ -44,7 +51,7 @@ int main(int argc, char *argv[])
|
||||||
engine->rootContext()->setContextProperty("Debugging", debugging);
|
engine->rootContext()->setContextProperty("Debugging", debugging);
|
||||||
engine->load("qml/main.qml");
|
engine->load("qml/main.qml");
|
||||||
|
|
||||||
int ret = app.exec();
|
int ret = app->exec();
|
||||||
|
|
||||||
// delete the engine first
|
// delete the engine first
|
||||||
// to avoid "TypeError: Cannot read property 'xxx' of null"
|
// to avoid "TypeError: Cannot read property 'xxx' of null"
|
||||||
|
|
|
@ -60,7 +60,7 @@ void Router::request(int type, const QString& command,
|
||||||
|
|
||||||
replyMutex.lock();
|
replyMutex.lock();
|
||||||
expectedReplyId = requestId;
|
expectedReplyId = requestId;
|
||||||
replyTimeout = 0;
|
replyTimeout = timeout;
|
||||||
requestStartTime = QDateTime::currentDateTime();
|
requestStartTime = QDateTime::currentDateTime();
|
||||||
m_reply = QString();
|
m_reply = QString();
|
||||||
replyMutex.unlock();
|
replyMutex.unlock();
|
||||||
|
@ -123,7 +123,7 @@ QString Router::waitForReply()
|
||||||
|
|
||||||
QString Router::waitForReply(int timeout)
|
QString Router::waitForReply(int timeout)
|
||||||
{
|
{
|
||||||
replyReadySemaphore.tryAcquire(1, timeout);
|
replyReadySemaphore.tryAcquire(1, timeout * 1000);
|
||||||
return m_reply;
|
return m_reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,6 @@ void Router::handlePacket(const QByteArray& rawPacket)
|
||||||
|
|
||||||
m_reply = jsonData;
|
m_reply = jsonData;
|
||||||
// TODO: callback?
|
// TODO: callback?
|
||||||
qDebug() << rawPacket << Qt::endl;
|
|
||||||
|
|
||||||
replyReadySemaphore.release();
|
replyReadySemaphore.release();
|
||||||
if (extraReplyReadySemaphore) {
|
if (extraReplyReadySemaphore) {
|
||||||
|
|
|
@ -8,7 +8,9 @@ Room::Room(Server* server)
|
||||||
server->nextRoomId++;
|
server->nextRoomId++;
|
||||||
this->server = server;
|
this->server = server;
|
||||||
setParent(server);
|
setParent(server);
|
||||||
|
owner = nullptr;
|
||||||
gameStarted = false;
|
gameStarted = false;
|
||||||
|
timeout = 15;
|
||||||
if (!isLobby()) {
|
if (!isLobby()) {
|
||||||
connect(this, &Room::playerAdded, server->lobby(), &Room::removePlayer);
|
connect(this, &Room::playerAdded, server->lobby(), &Room::removePlayer);
|
||||||
connect(this, &Room::playerRemoved, server->lobby(), &Room::addPlayer);
|
connect(this, &Room::playerRemoved, server->lobby(), &Room::addPlayer);
|
||||||
|
@ -76,7 +78,7 @@ void Room::setOwner(ServerPlayer *owner)
|
||||||
this->owner = owner;
|
this->owner = owner;
|
||||||
QJsonArray jsonData;
|
QJsonArray jsonData;
|
||||||
jsonData << owner->getId();
|
jsonData << owner->getId();
|
||||||
owner->doNotify("RoomOwner", QJsonDocument(jsonData).toJson());
|
doBroadcastNotify(players, "RoomOwner", QJsonDocument(jsonData).toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Room::addPlayer(ServerPlayer *player)
|
void Room::addPlayer(ServerPlayer *player)
|
||||||
|
@ -101,6 +103,7 @@ void Room::addPlayer(ServerPlayer *player)
|
||||||
// Second, let the player enter room and add other players
|
// Second, let the player enter room and add other players
|
||||||
jsonData = QJsonArray();
|
jsonData = QJsonArray();
|
||||||
jsonData << this->capacity;
|
jsonData << this->capacity;
|
||||||
|
jsonData << this->timeout;
|
||||||
player->doNotify("EnterRoom", QJsonDocument(jsonData).toJson());
|
player->doNotify("EnterRoom", QJsonDocument(jsonData).toJson());
|
||||||
|
|
||||||
foreach (ServerPlayer *p, getOtherPlayers(player)) {
|
foreach (ServerPlayer *p, getOtherPlayers(player)) {
|
||||||
|
@ -111,6 +114,12 @@ void Room::addPlayer(ServerPlayer *player)
|
||||||
player->doNotify("AddPlayer", QJsonDocument(jsonData).toJson());
|
player->doNotify("AddPlayer", QJsonDocument(jsonData).toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->owner != nullptr) {
|
||||||
|
jsonData = QJsonArray();
|
||||||
|
jsonData << this->owner->getId();
|
||||||
|
player->doNotify("RoomOwner", QJsonDocument(jsonData).toJson());
|
||||||
|
}
|
||||||
|
|
||||||
if (isFull())
|
if (isFull())
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
|
@ -150,11 +159,17 @@ QList<ServerPlayer *> Room::getOtherPlayers(ServerPlayer* expect) const
|
||||||
|
|
||||||
ServerPlayer *Room::findPlayer(int id) const
|
ServerPlayer *Room::findPlayer(int id) const
|
||||||
{
|
{
|
||||||
foreach (ServerPlayer *p, players) {
|
return server->findPlayer(id);
|
||||||
if (p->getId() == id)
|
}
|
||||||
return p;
|
|
||||||
}
|
int Room::getTimeout() const
|
||||||
return nullptr;
|
{
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Room::setTimeout(int timeout)
|
||||||
|
{
|
||||||
|
this->timeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Room::isStarted() const
|
bool Room::isStarted() const
|
||||||
|
|
|
@ -31,6 +31,9 @@ public:
|
||||||
QList<ServerPlayer *> getOtherPlayers(ServerPlayer *expect) const;
|
QList<ServerPlayer *> getOtherPlayers(ServerPlayer *expect) const;
|
||||||
ServerPlayer *findPlayer(int id) const;
|
ServerPlayer *findPlayer(int id) const;
|
||||||
|
|
||||||
|
int getTimeout() const;
|
||||||
|
void setTimeout(int timeout);
|
||||||
|
|
||||||
bool isStarted() const;
|
bool isStarted() const;
|
||||||
// ====================================}
|
// ====================================}
|
||||||
|
|
||||||
|
@ -64,6 +67,8 @@ private:
|
||||||
ServerPlayer *owner; // who created this room?
|
ServerPlayer *owner; // who created this room?
|
||||||
QList<ServerPlayer *> players;
|
QList<ServerPlayer *> players;
|
||||||
bool gameStarted;
|
bool gameStarted;
|
||||||
|
|
||||||
|
int timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _ROOM_H
|
#endif // _ROOM_H
|
||||||
|
|
|
@ -8,7 +8,7 @@ ServerPlayer::ServerPlayer(Room *room)
|
||||||
{
|
{
|
||||||
socket = nullptr;
|
socket = nullptr;
|
||||||
router = new Router(this, socket, Router::TYPE_SERVER);
|
router = new Router(this, socket, Router::TYPE_SERVER);
|
||||||
|
setState(Player::Online);
|
||||||
this->room = room;
|
this->room = room;
|
||||||
server = room->getServer();
|
server = room->getServer();
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,16 @@ void ServerPlayer::doRequest(const QString& command, const QString& jsonData, in
|
||||||
router->request(type, command, jsonData, timeout);
|
router->request(type, command, jsonData, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ServerPlayer::waitForReply()
|
||||||
|
{
|
||||||
|
return router->waitForReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ServerPlayer::waitForReply(int timeout)
|
||||||
|
{
|
||||||
|
return router->waitForReply(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
void ServerPlayer::doNotify(const QString& command, const QString& jsonData)
|
void ServerPlayer::doNotify(const QString& command, const QString& jsonData)
|
||||||
{
|
{
|
||||||
int type = Router::TYPE_NOTIFICATION | Router::SRC_SERVER | Router::DEST_CLIENT;
|
int type = Router::TYPE_NOTIFICATION | Router::SRC_SERVER | Router::DEST_CLIENT;
|
||||||
|
|
|
@ -24,6 +24,8 @@ public:
|
||||||
|
|
||||||
void doRequest(const QString &command,
|
void doRequest(const QString &command,
|
||||||
const QString &jsonData, int timeout = -1);
|
const QString &jsonData, int timeout = -1);
|
||||||
|
QString waitForReply(int timeout);
|
||||||
|
QString waitForReply();
|
||||||
void doNotify(const QString &command, const QString &jsonData);
|
void doNotify(const QString &command, const QString &jsonData);
|
||||||
|
|
||||||
void prepareForRequest(const QString &command,
|
void prepareForRequest(const QString &command,
|
||||||
|
|
|
@ -46,7 +46,9 @@ public:
|
||||||
void speak(const QString &message);
|
void speak(const QString &message);
|
||||||
|
|
||||||
void doRequest(const QString &command,
|
void doRequest(const QString &command,
|
||||||
const QString &json_data, int timeout = -1);
|
const QString &json_data, int timeout);
|
||||||
|
QString waitForReply();
|
||||||
|
QString waitForReply(int timeout);
|
||||||
void doNotify(const QString &command, const QString &json_data);
|
void doNotify(const QString &command, const QString &json_data);
|
||||||
|
|
||||||
void prepareForRequest(const QString &command, const QString &data);
|
void prepareForRequest(const QString &command, const QString &data);
|
||||||
|
|
|
@ -34,3 +34,15 @@ public:
|
||||||
%template(PlayerList) QList<const Player *>;
|
%template(PlayerList) QList<const Player *>;
|
||||||
%template(IntList) QList<int>;
|
%template(IntList) QList<int>;
|
||||||
%template(BoolList) QList<bool>;
|
%template(BoolList) QList<bool>;
|
||||||
|
|
||||||
|
%native(GetMicroSecond) int GetMicroSecond(lua_State *L);
|
||||||
|
%{
|
||||||
|
#include <sys/time.h>
|
||||||
|
static int GetMicroSecond(lua_State *L) {
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, nullptr);
|
||||||
|
long microsecond = tv.tv_sec * 1000000 + tv.tv_usec;
|
||||||
|
lua_pushnumber(L, microsecond);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
|
@ -71,6 +71,8 @@ public:
|
||||||
QList<ServerPlayer *> getPlayers() const;
|
QList<ServerPlayer *> getPlayers() const;
|
||||||
ServerPlayer *findPlayer(int id) const;
|
ServerPlayer *findPlayer(int id) const;
|
||||||
|
|
||||||
|
int getTimeout() const;
|
||||||
|
|
||||||
bool isStarted() const;
|
bool isStarted() const;
|
||||||
// ====================================}
|
// ====================================}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue