Invoke choice (#10)

* define askforskillinvoke

* states of room

* askForSkillInvoke

* askForChoice

Co-authored-by: Notify-ctrl <notify-ctrl@qq.com>
This commit is contained in:
Notify-ctrl 2022-04-02 15:11:13 +08:00 committed by GitHub
parent 4e25c032e6
commit c230d675ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 231 additions and 23 deletions

View File

@ -49,10 +49,9 @@ end
---@param data any # useful data of the event ---@param data any # useful data of the event
---@return boolean # returns true if trigger is broken ---@return boolean # returns true if trigger is broken
function TriggerSkill:trigger(event, target, player, data) function TriggerSkill:trigger(event, target, player, data)
print(string.format("%s triggered: event=%d", self.name, event)) if player.room:askForSkillInvoke(player, self.name) then
--if player.room:askForSkillInvoke(self.name) then return self:use(event, target, player, data)
-- return self:use(event, target, player, data) end
--end
return false return false
end end

View File

@ -249,7 +249,7 @@ function GameLogic:trigger(event, target, data)
end end
while #skill_names > 0 do while #skill_names > 0 do
local skill_name = room:askForChoice(player, skill_names) local skill_name = room:askForChoice(player, skill_names, "trigger")
local skill = triggerables[table.indexOf(skill_names, skill_name)] local skill = triggerables[table.indexOf(skill_names, skill_name)]
broken = skill:trigger(event, target, player, data) broken = skill:trigger(event, target, player, data)
if broken then break end if broken then break end

View File

@ -220,8 +220,28 @@ end
---@param player ServerPlayer ---@param player ServerPlayer
---@param choices string[] ---@param choices string[]
function Room:askForChoice(player, choices) ---@param skill_name string
return choices[1] function Room:askForChoice(player, choices, skill_name, data)
if #choices == 1 then return choices[1] end
local command = "AskForChoice"
self:notifyMoveFocus(player, skill_name)
local result = self:doRequest(player, command, json.encode{
choices, skill_name
})
if result == "" then result = choices[1] end
return result
end
---@param player ServerPlayer
---@param skill_name string
---@return boolean
function Room:askForSkillInvoke(player, skill_name, data)
local command = "AskForSkillInvoke"
self:notifyMoveFocus(player, skill_name)
local invoked = false
local result = self:doRequest(player, command, skill_name)
if result ~= "" then invoked = true end
return invoked
end end
fk.room_callback["QuitRoom"] = function(jsonData) fk.room_callback["QuitRoom"] = function(jsonData)

View File

@ -10,4 +10,13 @@ GameRule = fk.CreateTriggerSkill{
return (target == player) or (target == nil) return (target == player) or (target == nil)
end, end,
on_trigger = function(self, event, target, player, data)
if player == nil then return false end
local room = player.room
if player.room:askForSkillInvoke(player, self.name) then
-- do something
end
return false
end,
} }

View File

@ -14,11 +14,13 @@ Item {
property bool isStarted: false property bool isStarted: false
property alias popupBox: popupBox property alias popupBox: popupBox
property alias promptText: prompt.text
// tmp // tmp
Button { Button {
text: "quit" text: "quit"
anchors.bottom: parent.bottom anchors.top: parent.top
anchors.right: parent.right
onClicked: { onClicked: {
ClientInstance.clearPlayers(); ClientInstance.clearPlayers();
ClientInstance.notifyServer("QuitRoom", "[]"); ClientInstance.notifyServer("QuitRoom", "[]");
@ -30,22 +32,60 @@ Item {
anchors.centerIn: parent anchors.centerIn: parent
} }
// For debugging states: [
RowLayout { State { name: "notactive" }, // Normal status
visible: Debugging ? true : false State { name: "playing" }, // Playing cards in playing phase
width: parent.width State { name: "responding" }, // all requests need to operate dashboard
TextField { State { name: "replying" } // requests only operate a popup window
id: lua ]
Layout.fillWidth: true state: "notactive"
text: "print \"Hello world.\"" transitions: [
} Transition {
Button { from: "*"; to: "notactive"
text: "DoLuaScript" ScriptAction {
onClicked: { script: {
ClientInstance.notifyServer("DoLuaScript", JSON.stringify([lua.text])); promptText = "";
progress.visible = false;
okCancel.visible = false;
endPhaseButton.visible = false;
if (popupBox.item != null) {
popupBox.item.finished();
}
}
}
},
Transition {
from: "*"; to: "playing"
ScriptAction {
script: {
progress.visible = true;
okCancel.visible = true;
endPhaseButton.visible = true;
}
}
},
Transition {
from: "*"; to: "responding"
ScriptAction {
script: {
progress.visible = true;
okCancel.visible = true;
}
}
},
Transition {
from: "*"; to: "replying"
ScriptAction {
script: {
progress.visible = true;
}
} }
} }
} ]
/* Layout: /* Layout:
* +---------------------+ * +---------------------+
@ -127,6 +167,74 @@ Item {
self.isOwner: dashboardModel.isOwner self.isOwner: dashboardModel.isOwner
} }
Item {
id: controls
anchors.bottom: dashboard.top
anchors.bottomMargin: -40
width: roomScene.width
Text {
id: prompt
visible: progress.visible
anchors.bottom: progress.top
anchors.bottomMargin: 8
anchors.horizontalCenter: progress.horizontalCenter
}
ProgressBar {
id: progress
width: parent.width * 0.6
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: okCancel.top
anchors.bottomMargin: 8
from: 0.0
to: 100.0
visible: false
NumberAnimation on value {
running: progress.visible
from: 100.0
to: 0.0
duration: config.roomTimeout * 1000
onFinished: {
roomScene.state = "notactive"
}
}
}
Row {
id: okCancel
anchors.bottom: parent.bottom
anchors.horizontalCenter: progress.horizontalCenter
spacing: 20
visible: false
Button {
id: okButton
text: "OK"
onClicked: Logic.doOkButton();
}
Button {
id: cancelButton
text: "Cancel"
onClicked: Logic.doCancelButton();
}
}
Button {
id: endPhaseButton
text: "End"
anchors.bottom: parent.bottom
anchors.bottomMargin: 40
anchors.right: parent.right
anchors.rightMargin: 30
visible: false;
onClicked: Logic.doCancelButton();
}
}
Loader { Loader {
id: popupBox id: popupBox
onSourceChanged: { onSourceChanged: {

View File

@ -0,0 +1,34 @@
import QtQuick 2.15
import ".."
GraphicsBox {
property var options: []
property string skill_name: ""
property int result
id: root
title.text: skill_name + ": Please choose"
width: Math.max(140, body.width + 20)
height: body.height + title.height + 20
Column {
id: body
x: 10
y: title.height + 5
spacing: 10
Repeater {
model: options
MetroButton {
text: modelData
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
result = index;
root.close();
}
}
}
}
}

View File

@ -48,6 +48,19 @@ function arrangePhotos() {
} }
} }
function doOkButton() {
replyToServer("1");
}
function doCancelButton() {
replyToServer("");
}
function replyToServer(jsonData) {
roomScene.state = "notactive";
ClientInstance.replyToServer("", jsonData);
}
callbacks["AddPlayer"] = function(jsonData) { callbacks["AddPlayer"] = function(jsonData) {
// jsonData: int id, string screenName, string avatar // jsonData: int id, string screenName, string avatar
for (let i = 0; i < photoModel.count; i++) { for (let i = 0; i < photoModel.count; i++) {
@ -178,13 +191,38 @@ callbacks["AskForGeneral"] = function(jsonData) {
// jsonData: string[] Generals // jsonData: string[] Generals
// TODO: choose multiple generals // TODO: choose multiple generals
let data = JSON.parse(jsonData); let data = JSON.parse(jsonData);
roomScene.promptText = "Please choose 1 general";
roomScene.state = "replying";
roomScene.popupBox.source = "RoomElement/ChooseGeneralBox.qml"; roomScene.popupBox.source = "RoomElement/ChooseGeneralBox.qml";
let box = roomScene.popupBox.item; let box = roomScene.popupBox.item;
box.choiceNum = 1; box.choiceNum = 1;
box.accepted.connect(() => { box.accepted.connect(() => {
ClientInstance.replyToServer("AskForGeneral", JSON.stringify([box.choices[0]])); replyToServer(JSON.stringify([box.choices[0]]));
}); });
for (let i = 0; i < data.length; i++) for (let i = 0; i < data.length; i++)
box.generalList.append({ "name": data[i] }); box.generalList.append({ "name": data[i] });
box.updatePosition(); box.updatePosition();
} }
callbacks["AskForSkillInvoke"] = function(jsonData) {
// jsonData: string name
roomScene.promptText = "Do you want to invoke '" + jsonData + "' ?";
roomScene.state = "responding";
}
callbacks["AskForChoice"] = function(jsonData) {
// jsonData: [ string[] choices, string skill ]
// TODO: multiple choices, e.g. benxi_ol
let data = JSON.parse(jsonData);
let choices = data[0];
let skill_name = data[1];
roomScene.promptText = skill_name + ": Please make choice";
roomScene.state = "replying";
roomScene.popupBox.source = "RoomElement/ChoiceBox.qml";
let box = roomScene.popupBox.item;
box.options = choices;
box.skill_name = skill_name;
box.accepted.connect(() => {
replyToServer(choices[box.result]);
});
}