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
---@return boolean # returns true if trigger is broken
function TriggerSkill:trigger(event, target, player, data)
print(string.format("%s triggered: event=%d", self.name, event))
--if player.room:askForSkillInvoke(self.name) then
-- return self:use(event, target, player, data)
--end
if player.room:askForSkillInvoke(player, self.name) then
return self:use(event, target, player, data)
end
return false
end

View File

@ -249,7 +249,7 @@ function GameLogic:trigger(event, target, data)
end
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)]
broken = skill:trigger(event, target, player, data)
if broken then break end

View File

@ -220,8 +220,28 @@ end
---@param player ServerPlayer
---@param choices string[]
function Room:askForChoice(player, choices)
return choices[1]
---@param skill_name string
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
fk.room_callback["QuitRoom"] = function(jsonData)

View File

@ -10,4 +10,13 @@ GameRule = fk.CreateTriggerSkill{
return (target == player) or (target == nil)
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 alias popupBox: popupBox
property alias promptText: prompt.text
// tmp
Button {
text: "quit"
anchors.bottom: parent.bottom
anchors.top: parent.top
anchors.right: parent.right
onClicked: {
ClientInstance.clearPlayers();
ClientInstance.notifyServer("QuitRoom", "[]");
@ -30,22 +32,60 @@ Item {
anchors.centerIn: parent
}
// For debugging
RowLayout {
visible: Debugging ? true : false
width: parent.width
TextField {
id: lua
Layout.fillWidth: true
text: "print \"Hello world.\""
}
Button {
text: "DoLuaScript"
onClicked: {
ClientInstance.notifyServer("DoLuaScript", JSON.stringify([lua.text]));
states: [
State { name: "notactive" }, // Normal status
State { name: "playing" }, // Playing cards in playing phase
State { name: "responding" }, // all requests need to operate dashboard
State { name: "replying" } // requests only operate a popup window
]
state: "notactive"
transitions: [
Transition {
from: "*"; to: "notactive"
ScriptAction {
script: {
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:
* +---------------------+
@ -127,6 +167,74 @@ Item {
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 {
id: popupBox
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) {
// jsonData: int id, string screenName, string avatar
for (let i = 0; i < photoModel.count; i++) {
@ -178,13 +191,38 @@ callbacks["AskForGeneral"] = function(jsonData) {
// jsonData: string[] Generals
// TODO: choose multiple generals
let data = JSON.parse(jsonData);
roomScene.promptText = "Please choose 1 general";
roomScene.state = "replying";
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]]));
replyToServer(JSON.stringify([box.choices[0]]));
});
for (let i = 0; i < data.length; i++)
box.generalList.append({ "name": data[i] });
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]);
});
}