Modify game core (#294)
- 新增船新“休整”机制; - 修改作废逻辑,并可在当前响应读条禁用该技能(出牌阶段空闲时间点尚未完成限制); - 修复锁视技的相关bug,其cardFilter新增标识是否为判定的参数; - 将护甲扣减融合进体力扣减流程,为伤害流程增加“虚拟伤害”概念,为伤害流程增加“造成过伤害”标识id以供记录搜索使用; - 为变将新增可删除副将。 --------- Co-authored-by: notify <notify-ctrl@qq.com>
This commit is contained in:
parent
94c1107c2e
commit
cec18e0614
|
@ -0,0 +1,20 @@
|
||||||
|
import QtQuick
|
||||||
|
import Fk
|
||||||
|
|
||||||
|
Image {
|
||||||
|
property string general
|
||||||
|
|
||||||
|
width: 64
|
||||||
|
height: 64
|
||||||
|
source: SkinBank.getGeneralExtraPic(general, "avatar/") ?? SkinBank.getGeneralPicture(general)
|
||||||
|
// sourceSize.width: 250
|
||||||
|
// sourceSize.height: 292
|
||||||
|
property bool useSmallPic: !!SkinBank.getGeneralExtraPic(general, "avatar/")
|
||||||
|
sourceClipRect: useSmallPic ? undefined : Qt.rect(61, 0, 128, 128)
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,238 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Fk.Pages
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
property bool isLobby: false
|
||||||
|
|
||||||
|
function append(chatter, data) {
|
||||||
|
let general = data.general;
|
||||||
|
let avatar;
|
||||||
|
if (general == "__server") {
|
||||||
|
general = "";
|
||||||
|
avatar = "__server"
|
||||||
|
} else if (!roomScene.getPhoto(data.sender)) {
|
||||||
|
avatar = "__observer";
|
||||||
|
}
|
||||||
|
chatLogBox.append({
|
||||||
|
avatar: data.general || roomScene.getPhoto(data.sender)?.general || avatar || "unknown",
|
||||||
|
general: general,
|
||||||
|
msg: data.msg,
|
||||||
|
userName: data.userName,
|
||||||
|
time: data.time,
|
||||||
|
isSelf: data.sender === Self.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadSkills() {
|
||||||
|
for (let i = 1; i <= 16; i++) {
|
||||||
|
skills.append({ name: "fastchat_m", idx: i });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: opTimer
|
||||||
|
interval: 1500
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: avatarDelegate
|
||||||
|
Item {
|
||||||
|
width: chatLogBox.width
|
||||||
|
height: childrenRect.height
|
||||||
|
Avatar {
|
||||||
|
id: avatarPic
|
||||||
|
width: 36
|
||||||
|
height: 36
|
||||||
|
general: avatar
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 8
|
||||||
|
anchors.left: isSelf ? undefined : parent.left
|
||||||
|
anchors.right: !isSelf ? undefined : parent.right
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: unameLbl
|
||||||
|
anchors.left: isSelf ? undefined : avatarPic.right
|
||||||
|
anchors.right: !isSelf ? undefined : avatarPic.left
|
||||||
|
anchors.margins: 6
|
||||||
|
font.pixelSize: 14
|
||||||
|
text: userName + (general ? (" (" + Backend.translate(general) + ")") : "")
|
||||||
|
+ ' <font color="grey">[' + time + "]</font>"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.left: isSelf ? undefined : avatarPic.right
|
||||||
|
anchors.right: !isSelf ? undefined : avatarPic.left
|
||||||
|
anchors.margins: 4
|
||||||
|
anchors.top: unameLbl.bottom
|
||||||
|
width: Math.min(parent.width - 80, childrenRect.width + 12)
|
||||||
|
height: childrenRect.height + 12
|
||||||
|
radius: 8
|
||||||
|
color: isSelf ? "lightgreen" : "lightsteelblue"
|
||||||
|
Text {
|
||||||
|
width: Math.min(contentWidth, parent.parent.width - 80 - 12)
|
||||||
|
x: 6; y: 6
|
||||||
|
text: msg
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
font.family: fontLibian.name
|
||||||
|
font.pixelSize: 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TapHandler {
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.NoButton
|
||||||
|
gesturePolicy: TapHandler.WithinBounds
|
||||||
|
onTapped: chatLogBox.currentIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
LogEdit {
|
||||||
|
id: chatLogBox
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 10
|
||||||
|
delegate: avatarDelegate
|
||||||
|
//font.pixelSize: 14
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: emojiSelector
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 120
|
||||||
|
cellHeight: 48
|
||||||
|
cellWidth: 48
|
||||||
|
model: 59
|
||||||
|
visible: false
|
||||||
|
clip: true
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
Image {
|
||||||
|
height: 32; width: 32
|
||||||
|
anchors.centerIn: parent
|
||||||
|
source: "../../image/emoji/" + index
|
||||||
|
}
|
||||||
|
onClicked: chatEdit.insert(chatEdit.cursorPosition, "{emoji" + index + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: soundSelector
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 180
|
||||||
|
visible: false
|
||||||
|
clip: true
|
||||||
|
ScrollBar.vertical: ScrollBar {}
|
||||||
|
model: ListModel {
|
||||||
|
id: skills
|
||||||
|
}
|
||||||
|
// onVisibleChanged: {skills.clear(); loadSkills();}
|
||||||
|
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
width: soundSelector.width
|
||||||
|
height: 30
|
||||||
|
text: Backend.translate("$" + name + (idx ? idx.toString() : ""))
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
opTimer.start();
|
||||||
|
const general = roomScene.getPhoto(Self.id).general;
|
||||||
|
let skill = "fastchat_m";
|
||||||
|
if (general !== "") {
|
||||||
|
const data = JSON.parse(Backend.callLuaFunction("GetGeneralDetail", [general]));
|
||||||
|
const gender = data.gender;
|
||||||
|
if (gender !== 1) {
|
||||||
|
skill = "fastchat_f";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClientInstance.notifyServer(
|
||||||
|
"Chat",
|
||||||
|
JSON.stringify({
|
||||||
|
type: isLobby ? 1 : 2,
|
||||||
|
msg: "$" + skill + ":" + idx
|
||||||
|
})
|
||||||
|
);
|
||||||
|
soundSelector.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 28
|
||||||
|
color: "#040403"
|
||||||
|
radius: 3
|
||||||
|
border.width: 1
|
||||||
|
border.color: "#A6967A"
|
||||||
|
|
||||||
|
TextInput {
|
||||||
|
id: chatEdit
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 6
|
||||||
|
color: "white"
|
||||||
|
clip: true
|
||||||
|
font.pixelSize: 14
|
||||||
|
maximumLength: 300
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (text != "") {
|
||||||
|
ClientInstance.notifyServer(
|
||||||
|
"Chat",
|
||||||
|
JSON.stringify({
|
||||||
|
type: isLobby ? 1 : 2,
|
||||||
|
msg: text
|
||||||
|
})
|
||||||
|
);
|
||||||
|
text = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MetroButton {
|
||||||
|
id: soundBtn
|
||||||
|
text: "🗨️"
|
||||||
|
visible: !isLobby
|
||||||
|
enabled: !opTimer.running;
|
||||||
|
onClicked: {
|
||||||
|
emojiSelector.visible = false;
|
||||||
|
soundSelector.visible = !soundSelector.visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MetroButton {
|
||||||
|
id: emojiBtn
|
||||||
|
text: "😃"
|
||||||
|
onClicked: {
|
||||||
|
soundSelector.visible = false;
|
||||||
|
emojiSelector.visible = !emojiSelector.visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MetroButton {
|
||||||
|
text: "✔️"
|
||||||
|
enabled: !opTimer.running;
|
||||||
|
onClicked: {
|
||||||
|
opTimer.start();
|
||||||
|
chatEdit.accepted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
loadSkills();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ Rectangle {
|
||||||
property bool isLobby: false
|
property bool isLobby: false
|
||||||
|
|
||||||
function append(chatter) {
|
function append(chatter) {
|
||||||
chatLogBox.append(chatter)
|
chatLogBox.append({ logText: chatter })
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadSkills() {
|
function loadSkills() {
|
||||||
|
|
|
@ -33,6 +33,8 @@ ListView {
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
|
|
||||||
TapHandler {
|
TapHandler {
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.NoButton
|
||||||
|
gesturePolicy: TapHandler.WithinBounds
|
||||||
onTapped: root.currentIndex = index;
|
onTapped: root.currentIndex = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,9 +45,9 @@ ListView {
|
||||||
onClicked: root.currentIndex = logModel.count - 1;
|
onClicked: root.currentIndex = logModel.count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function append(text) {
|
function append(data) {
|
||||||
const autoScroll = root.currentIndex === logModel.count - 1;
|
const autoScroll = root.currentIndex === logModel.count - 1;
|
||||||
logModel.append({ logText: text });
|
logModel.append(data);
|
||||||
if (autoScroll) {
|
if (autoScroll) {
|
||||||
root.currentIndex = logModel.count - 1;
|
root.currentIndex = logModel.count - 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
module Fk.Common
|
module Fk.Common
|
||||||
ChatBox 1.0 ChatBox.qml
|
ChatBox 1.0 ChatBox.qml
|
||||||
LogEdit 1.0 LogEdit.qml
|
LogEdit 1.0 LogEdit.qml
|
||||||
|
Avatar 1.0 Avatar.qml
|
||||||
|
AvatarChatBox 1.0 AvatarChatBox.qml
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Fk
|
import Fk
|
||||||
|
import Fk.Common
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
@ -20,19 +21,10 @@ Item {
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Item { Layout.preferredWidth: 16 }
|
Item { Layout.preferredWidth: 16 }
|
||||||
|
|
||||||
Image {
|
Avatar {
|
||||||
Layout.preferredWidth: 64
|
Layout.preferredWidth: 64
|
||||||
Layout.preferredHeight: 64
|
Layout.preferredHeight: 64
|
||||||
source: SkinBank.getGeneralExtraPic(Self.avatar, "avatar/") ?? SkinBank.getGeneralPicture(Self.avatar)
|
general: Self.avatar
|
||||||
// sourceSize.width: 250
|
|
||||||
// sourceSize.height: 292
|
|
||||||
sourceClipRect: sourceSize.width > 200 ? Qt.rect(61, 0, 128, 128) : undefined
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: "transparent"
|
|
||||||
border.width: 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { Layout.preferredWidth: 8 }
|
Item { Layout.preferredWidth: 8 }
|
||||||
|
|
|
@ -5,6 +5,7 @@ import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Dialogs
|
import QtQuick.Dialogs
|
||||||
import Fk
|
import Fk
|
||||||
|
import Fk.Common
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
@ -59,21 +60,13 @@ Item {
|
||||||
width: root.width
|
width: root.width
|
||||||
height: 64
|
height: 64
|
||||||
|
|
||||||
Image {
|
Avatar {
|
||||||
id: generalPic
|
id: generalPic
|
||||||
|
width: 48; height: 48
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.margins: 8
|
anchors.margins: 8
|
||||||
width: 48
|
general: general
|
||||||
height: 48
|
|
||||||
source: SkinBank.getGeneralExtraPic(general, "avatar/") ?? SkinBank.getGeneralPicture(general)
|
|
||||||
sourceClipRect: sourceSize.width > 200 ? Qt.rect(61, 0, 128, 128) : undefined
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: "transparent"
|
|
||||||
border.width: 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
|
|
@ -392,6 +392,7 @@ Item {
|
||||||
faceup: model.faceup
|
faceup: model.faceup
|
||||||
chained: model.chained
|
chained: model.chained
|
||||||
drank: model.drank
|
drank: model.drank
|
||||||
|
rest: model.rest
|
||||||
isOwner: model.isOwner
|
isOwner: model.isOwner
|
||||||
ready: model.ready
|
ready: model.ready
|
||||||
surrendered: model.surrendered
|
surrendered: model.surrendered
|
||||||
|
@ -855,7 +856,7 @@ Item {
|
||||||
}
|
}
|
||||||
Item {
|
Item {
|
||||||
visible: !config.replaying
|
visible: !config.replaying
|
||||||
ChatBox {
|
AvatarChatBox {
|
||||||
id: chat
|
id: chat
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
|
@ -1121,7 +1122,7 @@ Item {
|
||||||
if (raw.msg.startsWith("$")) {
|
if (raw.msg.startsWith("$")) {
|
||||||
if (specialChat(pid, raw, raw.msg.slice(1))) return;
|
if (specialChat(pid, raw, raw.msg.slice(1))) return;
|
||||||
}
|
}
|
||||||
chat.append(msg);
|
chat.append(msg, raw);
|
||||||
const photo = Logic.getPhoto(pid);
|
const photo = Logic.getPhoto(pid);
|
||||||
if (photo === undefined) {
|
if (photo === undefined) {
|
||||||
const user = raw.userName;
|
const user = raw.userName;
|
||||||
|
@ -1176,10 +1177,11 @@ Item {
|
||||||
Backend.playSound("./packages/" + extension + "/audio/death/" + g);
|
Backend.playSound("./packages/" + extension + "/audio/death/" + g);
|
||||||
|
|
||||||
const m = Backend.translate("~" + g);
|
const m = Backend.translate("~" + g);
|
||||||
|
data.msg = m;
|
||||||
if (general === "")
|
if (general === "")
|
||||||
chat.append(`[${time}] ${userName}: ${m}`);
|
chat.append(`[${time}] ${userName}: ${m}`, data);
|
||||||
else
|
else
|
||||||
chat.append(`[${time}] ${userName}(${general}): ${m}`);
|
chat.append(`[${time}] ${userName}(${general}): ${m}`, data);
|
||||||
|
|
||||||
const photo = Logic.getPhoto(pid);
|
const photo = Logic.getPhoto(pid);
|
||||||
if (photo === undefined) {
|
if (photo === undefined) {
|
||||||
|
@ -1205,10 +1207,11 @@ Item {
|
||||||
}));
|
}));
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
const m = Backend.translate("$" + skill + (gene ? "_" + gene : "") + (idx ? idx.toString() : ""));
|
const m = Backend.translate("$" + skill + (gene ? "_" + gene : "") + (idx ? idx.toString() : ""));
|
||||||
|
data.msg = m;
|
||||||
if (general === "")
|
if (general === "")
|
||||||
chat.append(`[${time}] ${userName}: ${m}`);
|
chat.append(`[${time}] ${userName}: ${m}`, data);
|
||||||
else
|
else
|
||||||
chat.append(`[${time}] ${userName}(${general}): ${m}`);
|
chat.append(`[${time}] ${userName}(${general}): ${m}`, data)
|
||||||
|
|
||||||
const photo = Logic.getPhoto(pid);
|
const photo = Logic.getPhoto(pid);
|
||||||
if (photo === undefined) {
|
if (photo === undefined) {
|
||||||
|
@ -1224,12 +1227,17 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addToLog(msg) {
|
function addToLog(msg) {
|
||||||
log.append(msg);
|
log.append({ logText: msg });
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendDanmaku(msg) {
|
function sendDanmaku(msg) {
|
||||||
danmaku.sendLog(msg);
|
danmaku.sendLog(msg);
|
||||||
chat.append(msg);
|
chat.append(null, {
|
||||||
|
msg: msg,
|
||||||
|
general: "__server", // FIXME: 基于默认读取貂蝉的数据
|
||||||
|
userName: "",
|
||||||
|
time: "Server",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showDistance(show) {
|
function showDistance(show) {
|
||||||
|
@ -1327,6 +1335,7 @@ Item {
|
||||||
faceup: true,
|
faceup: true,
|
||||||
chained: false,
|
chained: false,
|
||||||
drank: 0,
|
drank: 0,
|
||||||
|
rest: 0,
|
||||||
isOwner: false,
|
isOwner: false,
|
||||||
ready: false,
|
ready: false,
|
||||||
surrendered: false,
|
surrendered: false,
|
||||||
|
|
|
@ -1319,6 +1319,7 @@ callbacks["AskForUseCard"] = (jsonData) => {
|
||||||
const pattern = data[1];
|
const pattern = data[1];
|
||||||
const prompt = data[2];
|
const prompt = data[2];
|
||||||
const extra_data = data[4];
|
const extra_data = data[4];
|
||||||
|
const disabledSkillNames = data[5];
|
||||||
if (extra_data != null) {
|
if (extra_data != null) {
|
||||||
if (extra_data.effectTo !== Self.id && roomScene.skippedUseEventId.find(id => id === extra_data.useEventId)) {
|
if (extra_data.effectTo !== Self.id && roomScene.skippedUseEventId.find(id => id === extra_data.useEventId)) {
|
||||||
doCancelButton();
|
doCancelButton();
|
||||||
|
@ -1336,6 +1337,7 @@ callbacks["AskForUseCard"] = (jsonData) => {
|
||||||
}
|
}
|
||||||
roomScene.responding_card = pattern;
|
roomScene.responding_card = pattern;
|
||||||
roomScene.respond_play = false;
|
roomScene.respond_play = false;
|
||||||
|
disabledSkillNames && (dashboard.disabledSkillNames = disabledSkillNames);
|
||||||
roomScene.state = "responding";
|
roomScene.state = "responding";
|
||||||
okButton.enabled = false;
|
okButton.enabled = false;
|
||||||
cancelButton.enabled = true;
|
cancelButton.enabled = true;
|
||||||
|
@ -1347,6 +1349,7 @@ callbacks["AskForResponseCard"] = (jsonData) => {
|
||||||
const cardname = data[0];
|
const cardname = data[0];
|
||||||
const pattern = data[1];
|
const pattern = data[1];
|
||||||
const prompt = data[2];
|
const prompt = data[2];
|
||||||
|
const disabledSkillNames = data[5];
|
||||||
|
|
||||||
if (prompt === "") {
|
if (prompt === "") {
|
||||||
roomScene.promptText = Backend.translate("#AskForResponseCard")
|
roomScene.promptText = Backend.translate("#AskForResponseCard")
|
||||||
|
@ -1356,6 +1359,7 @@ callbacks["AskForResponseCard"] = (jsonData) => {
|
||||||
}
|
}
|
||||||
roomScene.responding_card = pattern;
|
roomScene.responding_card = pattern;
|
||||||
roomScene.respond_play = true;
|
roomScene.respond_play = true;
|
||||||
|
disabledSkillNames && (dashboard.disabledSkillNames = disabledSkillNames);
|
||||||
roomScene.state = "responding";
|
roomScene.state = "responding";
|
||||||
okButton.enabled = false;
|
okButton.enabled = false;
|
||||||
cancelButton.enabled = true;
|
cancelButton.enabled = true;
|
||||||
|
|
|
@ -19,6 +19,8 @@ RowLayout {
|
||||||
|
|
||||||
property var expanded_piles: ({}) // name -> int[]
|
property var expanded_piles: ({}) // name -> int[]
|
||||||
|
|
||||||
|
property var disabledSkillNames: []
|
||||||
|
|
||||||
signal cardSelected(var card)
|
signal cardSelected(var card)
|
||||||
|
|
||||||
Item { width: 5 }
|
Item { width: 5 }
|
||||||
|
@ -454,6 +456,11 @@ RowLayout {
|
||||||
// if cname is presented, we are responding use or play.
|
// if cname is presented, we are responding use or play.
|
||||||
for (let i = 0; i < skillButtons.count; i++) {
|
for (let i = 0; i < skillButtons.count; i++) {
|
||||||
const item = skillButtons.itemAt(i);
|
const item = skillButtons.itemAt(i);
|
||||||
|
if (disabledSkillNames.includes(item.orig)) {
|
||||||
|
item.enabled = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const fitpattern = JSON.parse(Backend.callLuaFunction("SkillFitPattern", [item.orig, cname]));
|
const fitpattern = JSON.parse(Backend.callLuaFunction("SkillFitPattern", [item.orig, cname]));
|
||||||
const canresp = JSON.parse(Backend.callLuaFunction("SkillCanResponse", [item.orig, cardResponsing]));
|
const canresp = JSON.parse(Backend.callLuaFunction("SkillCanResponse", [item.orig, cardResponsing]));
|
||||||
item.enabled = fitpattern && canresp;
|
item.enabled = fitpattern && canresp;
|
||||||
|
@ -462,11 +469,17 @@ RowLayout {
|
||||||
}
|
}
|
||||||
for (let i = 0; i < skillButtons.count; i++) {
|
for (let i = 0; i < skillButtons.count; i++) {
|
||||||
const item = skillButtons.itemAt(i);
|
const item = skillButtons.itemAt(i);
|
||||||
|
if (disabledSkillNames.includes(item.orig)) {
|
||||||
|
item.enabled = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
item.enabled = JSON.parse(Backend.callLuaFunction("ActiveCanUse", [item.orig]));
|
item.enabled = JSON.parse(Backend.callLuaFunction("ActiveCanUse", [item.orig]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function disableSkills() {
|
function disableSkills() {
|
||||||
|
disabledSkillNames = [];
|
||||||
for (let i = 0; i < skillButtons.count; i++)
|
for (let i = 0; i < skillButtons.count; i++)
|
||||||
skillButtons.itemAt(i).enabled = false;
|
skillButtons.itemAt(i).enabled = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Qt5Compat.GraphicalEffects
|
import Qt5Compat.GraphicalEffects
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
import Fk
|
import Fk
|
||||||
import Fk.PhotoElement
|
import Fk.PhotoElement
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ Item {
|
||||||
property bool faceup: true
|
property bool faceup: true
|
||||||
property bool chained: false
|
property bool chained: false
|
||||||
property int drank: 0
|
property int drank: 0
|
||||||
|
property int rest: 0
|
||||||
property bool isOwner: false
|
property bool isOwner: false
|
||||||
property bool ready: false
|
property bool ready: false
|
||||||
property int winGame: 0
|
property int winGame: 0
|
||||||
|
@ -269,6 +271,45 @@ Item {
|
||||||
opacity: 0.4 + Math.log(root.drank) * 0.12
|
opacity: 0.4 + Math.log(root.drank) * 0.12
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: restRect
|
||||||
|
anchors.centerIn: photoMask
|
||||||
|
anchors.leftMargin: 20
|
||||||
|
visible: root.rest > 0
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
text: "休整中"
|
||||||
|
font.family: fontLibian.name
|
||||||
|
font.pixelSize: 40
|
||||||
|
color: "white"
|
||||||
|
style: Text.Outline
|
||||||
|
textFormat: Text.RichText
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
visible: root.rest > 0 && root.rest < 999
|
||||||
|
text: root.rest
|
||||||
|
font.family: fontLibian.name
|
||||||
|
font.pixelSize: 30
|
||||||
|
color: "white"
|
||||||
|
style: Text.Outline
|
||||||
|
textFormat: Text.RichText
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
visible: root.rest > 0 && root.rest < 999
|
||||||
|
text: "轮次"
|
||||||
|
font.family: fontLibian.name
|
||||||
|
font.pixelSize: 28
|
||||||
|
color: "white"
|
||||||
|
style: Text.Outline
|
||||||
|
textFormat: Text.RichText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: winRateRect
|
id: winRateRect
|
||||||
width: 138; x: 31
|
width: 138; x: 31
|
||||||
|
@ -389,7 +430,7 @@ Item {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
// id: saveme
|
// id: saveme
|
||||||
visible: root.dead || root.dying || root.surrendered
|
visible: (root.dead && !root.rest) || root.dying || root.surrendered
|
||||||
source: {
|
source: {
|
||||||
if (root.dead) {
|
if (root.dead) {
|
||||||
return SkinBank.getRoleDeathPic(root.role);
|
return SkinBank.getRoleDeathPic(root.role);
|
||||||
|
|
|
@ -455,12 +455,12 @@ end
|
||||||
---@param player Player @ 和这张牌扯上关系的那名玩家
|
---@param player Player @ 和这张牌扯上关系的那名玩家
|
||||||
---@param data any @ 随意,目前只用到JudgeStruct,为了影响判定牌
|
---@param data any @ 随意,目前只用到JudgeStruct,为了影响判定牌
|
||||||
function Engine:filterCard(id, player, data)
|
function Engine:filterCard(id, player, data)
|
||||||
local card = self:getCardById(id, true)
|
|
||||||
if player == nil then
|
if player == nil then
|
||||||
self.filtered_cards[id] = nil
|
self.filtered_cards[id] = nil
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local skills = player:getAllSkills()
|
|
||||||
|
local card = self:getCardById(id, true)
|
||||||
local filters = self:currentRoom().status_skills[FilterSkill] or Util.DummyTable
|
local filters = self:currentRoom().status_skills[FilterSkill] or Util.DummyTable
|
||||||
|
|
||||||
if #filters == 0 then
|
if #filters == 0 then
|
||||||
|
@ -475,7 +475,7 @@ function Engine:filterCard(id, player, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, f in ipairs(filters) do
|
for _, f in ipairs(filters) do
|
||||||
if f:cardFilter(card, player) then
|
if f:cardFilter(card, player, type(data) == "table" and data.isJudgeEvent) then
|
||||||
local _card = f:viewAs(card, player)
|
local _card = f:viewAs(card, player)
|
||||||
_card.id = id
|
_card.id = id
|
||||||
_card.skillName = f.name
|
_card.skillName = f.name
|
||||||
|
|
|
@ -27,10 +27,14 @@ end
|
||||||
---@param victim ServerPlayer @ 死者
|
---@param victim ServerPlayer @ 死者
|
||||||
---@return string @ 胜者阵营
|
---@return string @ 胜者阵营
|
||||||
function GameMode:getWinner(victim)
|
function GameMode:getWinner(victim)
|
||||||
|
if victim.rest > 0 then
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
local room = victim.room
|
local room = victim.room
|
||||||
local winner = ""
|
local winner = ""
|
||||||
local alive = table.filter(room.alive_players, function(p)
|
local alive = table.filter(room.players, function(p)
|
||||||
return not p.surrendered
|
return not p.surrendered and not (p.dead and p.rest == 0)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if victim.role == "lord" then
|
if victim.role == "lord" then
|
||||||
|
|
|
@ -86,6 +86,7 @@ function Player:initialize()
|
||||||
self.dying = false
|
self.dying = false
|
||||||
self.dead = false
|
self.dead = false
|
||||||
self.drank = 0
|
self.drank = 0
|
||||||
|
self.rest = 0
|
||||||
|
|
||||||
self.player_skills = {}
|
self.player_skills = {}
|
||||||
self.derivative_skills = {}
|
self.derivative_skills = {}
|
||||||
|
@ -570,9 +571,9 @@ end
|
||||||
---@param ignoreRemoved? boolean @ 忽略被移除
|
---@param ignoreRemoved? boolean @ 忽略被移除
|
||||||
---@param num? integer @ 第几个,默认1
|
---@param num? integer @ 第几个,默认1
|
||||||
---@return ServerPlayer
|
---@return ServerPlayer
|
||||||
function Player:getNextAlive(ignoreRemoved, num)
|
function Player:getNextAlive(ignoreRemoved, num, ignoreRest)
|
||||||
if #Fk:currentRoom().alive_players == 0 then
|
if #Fk:currentRoom().alive_players == 0 then
|
||||||
return self
|
return self.rest > 0 and self.next.rest > 0 and self.next or self
|
||||||
end
|
end
|
||||||
local doNotIgnore = not ignoreRemoved
|
local doNotIgnore = not ignoreRemoved
|
||||||
if doNotIgnore and table.every(Fk:currentRoom().alive_players, function(p) return p:isRemoved() end) then
|
if doNotIgnore and table.every(Fk:currentRoom().alive_players, function(p) return p:isRemoved() end) then
|
||||||
|
@ -583,7 +584,7 @@ function Player:getNextAlive(ignoreRemoved, num)
|
||||||
num = num or 1
|
num = num or 1
|
||||||
for _ = 1, num do
|
for _ = 1, num do
|
||||||
ret = ret.next
|
ret = ret.next
|
||||||
while ret.dead or (doNotIgnore and ret:isRemoved()) do
|
while (ret.dead and not ignoreRest) or (doNotIgnore and ret:isRemoved()) do
|
||||||
ret = ret.next
|
ret = ret.next
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
local FilterSkill = StatusSkill:subclass("FilterSkill")
|
local FilterSkill = StatusSkill:subclass("FilterSkill")
|
||||||
|
|
||||||
---@param card Card
|
---@param card Card
|
||||||
function FilterSkill:cardFilter(card, player)
|
function FilterSkill:cardFilter(card, player, isJudgeEvent)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -135,4 +135,6 @@ fk.BeforePropertyChange = 92
|
||||||
fk.PropertyChange = 93
|
fk.PropertyChange = 93
|
||||||
fk.AfterPropertyChange = 94
|
fk.AfterPropertyChange = 94
|
||||||
|
|
||||||
|
fk.AfterPlayerRevived = 95
|
||||||
|
|
||||||
fk.NumOfEvents = 96
|
fk.NumOfEvents = 96
|
||||||
|
|
|
@ -53,7 +53,11 @@ GameEvent.functions[GameEvent.Death] = function(self)
|
||||||
local room = self.room
|
local room = self.room
|
||||||
local victim = room:getPlayerById(deathStruct.who)
|
local victim = room:getPlayerById(deathStruct.who)
|
||||||
victim.dead = true
|
victim.dead = true
|
||||||
victim._splayer:setDied(true)
|
|
||||||
|
if victim.rest <= 0 then
|
||||||
|
victim._splayer:setDied(true)
|
||||||
|
end
|
||||||
|
|
||||||
table.removeOne(room.alive_players, victim)
|
table.removeOne(room.alive_players, victim)
|
||||||
|
|
||||||
local logic = room.logic
|
local logic = room.logic
|
||||||
|
@ -65,22 +69,26 @@ GameEvent.functions[GameEvent.Death] = function(self)
|
||||||
type = "#KillPlayer",
|
type = "#KillPlayer",
|
||||||
to = {killer.id},
|
to = {killer.id},
|
||||||
from = victim.id,
|
from = victim.id,
|
||||||
arg = victim.role,
|
arg = (victim.rest > 0 and 'unknown' or victim.role),
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
room:sendLog{
|
room:sendLog{
|
||||||
type = "#KillPlayerWithNoKiller",
|
type = "#KillPlayerWithNoKiller",
|
||||||
from = victim.id,
|
from = victim.id,
|
||||||
arg = victim.role,
|
arg = (victim.rest > 0 and 'unknown' or victim.role),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
room:sendLogEvent("Death", {to = victim.id})
|
room:sendLogEvent("Death", {to = victim.id})
|
||||||
|
|
||||||
room:broadcastProperty(victim, "role")
|
if victim.rest == 0 then
|
||||||
|
room:broadcastProperty(victim, "role")
|
||||||
|
end
|
||||||
room:broadcastProperty(victim, "dead")
|
room:broadcastProperty(victim, "dead")
|
||||||
|
|
||||||
victim.drank = 0
|
victim.drank = 0
|
||||||
room:broadcastProperty(victim, "drank")
|
room:broadcastProperty(victim, "drank")
|
||||||
|
victim.shield = 0
|
||||||
|
room:broadcastProperty(victim, "shield")
|
||||||
|
|
||||||
logic:trigger(fk.GameOverJudge, victim, deathStruct)
|
logic:trigger(fk.GameOverJudge, victim, deathStruct)
|
||||||
logic:trigger(fk.Death, victim, deathStruct)
|
logic:trigger(fk.Death, victim, deathStruct)
|
||||||
|
@ -88,3 +96,23 @@ GameEvent.functions[GameEvent.Death] = function(self)
|
||||||
|
|
||||||
logic:trigger(fk.Deathed, victim, deathStruct)
|
logic:trigger(fk.Deathed, victim, deathStruct)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
GameEvent.functions[GameEvent.Revive] = function(self)
|
||||||
|
local room = self.room
|
||||||
|
local player, sendLog, reason = table.unpack(self.data)
|
||||||
|
|
||||||
|
if not player.dead then return end
|
||||||
|
room:setPlayerProperty(player, "dead", false)
|
||||||
|
player._splayer:setDied(false)
|
||||||
|
room:setPlayerProperty(player, "dying", false)
|
||||||
|
room:setPlayerProperty(player, "hp", player.maxHp)
|
||||||
|
table.insertIfNeed(room.alive_players, player)
|
||||||
|
|
||||||
|
sendLog = (sendLog == nil) and true or sendLog
|
||||||
|
if sendLog then
|
||||||
|
room:sendLog { type = "#Revive", from = player.id }
|
||||||
|
end
|
||||||
|
|
||||||
|
reason = reason or ""
|
||||||
|
room.logic:trigger(fk.AfterPlayerRevived, player, { reason = reason })
|
||||||
|
end
|
||||||
|
|
|
@ -161,8 +161,8 @@ GameEvent.functions[GameEvent.Round] = function(self)
|
||||||
p = room.current
|
p = room.current
|
||||||
GameEvent(GameEvent.Turn, p):exec()
|
GameEvent(GameEvent.Turn, p):exec()
|
||||||
if room.game_finished then break end
|
if room.game_finished then break end
|
||||||
room.current = room.current:getNextAlive(true)
|
room.current = room.current:getNextAlive(true, nil, true)
|
||||||
until p.seat >= p:getNextAlive(true).seat
|
until p.seat >= p:getNextAlive(true, nil, true).seat
|
||||||
|
|
||||||
logic:trigger(fk.RoundEnd, p)
|
logic:trigger(fk.RoundEnd, p)
|
||||||
end
|
end
|
||||||
|
@ -194,6 +194,15 @@ GameEvent.prepare_funcs[GameEvent.Turn] = function(self)
|
||||||
local logic = room.logic
|
local logic = room.logic
|
||||||
local player = room.current
|
local player = room.current
|
||||||
|
|
||||||
|
if player.rest > 0 and player.rest < 999 then
|
||||||
|
room:setPlayerRest(player, player.rest - 1)
|
||||||
|
if player.rest == 0 and player.dead then
|
||||||
|
room:revivePlayer(player, true, "rest")
|
||||||
|
else
|
||||||
|
room:delay(50)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if player.dead then return true end
|
if player.dead then return true end
|
||||||
|
|
||||||
room:sendLog{ type = "$AppendSeparator" }
|
room:sendLog{ type = "$AppendSeparator" }
|
||||||
|
@ -312,9 +321,9 @@ GameEvent.functions[GameEvent.Phase] = function(self)
|
||||||
local result = room:doRequest(player, "PlayCard", player.id)
|
local result = room:doRequest(player, "PlayCard", player.id)
|
||||||
if result == "" then break end
|
if result == "" then break end
|
||||||
|
|
||||||
local use = room:handleUseCardReply(player, result)
|
local useResult = room:handleUseCardReply(player, result)
|
||||||
if use then
|
if type(useResult) == "table" then
|
||||||
room:useCard(use)
|
room:useCard(useResult)
|
||||||
end
|
end
|
||||||
|
|
||||||
if player._play_phase_end then
|
if player._play_phase_end then
|
||||||
|
|
|
@ -48,37 +48,50 @@ GameEvent.functions[GameEvent.ChangeHp] = function(self)
|
||||||
damageEvent = damageStruct,
|
damageEvent = damageStruct,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if reason == "damage" then
|
||||||
|
data.shield_lost = math.min(-num, player.shield)
|
||||||
|
data.num = num + data.shield_lost
|
||||||
|
end
|
||||||
|
|
||||||
if logic:trigger(fk.BeforeHpChanged, player, data) then
|
if logic:trigger(fk.BeforeHpChanged, player, data) then
|
||||||
logic:breakEvent(false)
|
logic:breakEvent(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
assert(not (data.reason == "recover" and data.num < 0))
|
if reason == "damage" and data.shield_lost > 0 and not damageStruct.isVirtualDMG then
|
||||||
player.hp = math.min(player.hp + data.num, player.maxHp)
|
room:changeShield(player, -data.shield_lost)
|
||||||
room:broadcastProperty(player, "hp")
|
end
|
||||||
|
|
||||||
if reason == "damage" then
|
if reason == "damage" then
|
||||||
sendDamageLog(room, damageStruct)
|
sendDamageLog(room, damageStruct)
|
||||||
elseif reason == "loseHp" then
|
|
||||||
room:sendLog{
|
|
||||||
type = "#LoseHP",
|
|
||||||
from = player.id,
|
|
||||||
arg = 0 - num,
|
|
||||||
}
|
|
||||||
room:sendLogEvent("LoseHP", {})
|
|
||||||
elseif reason == "recover" then
|
|
||||||
room:sendLog{
|
|
||||||
type = "#HealHP",
|
|
||||||
from = player.id,
|
|
||||||
arg = num,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
room:sendLog{
|
if not (reason == "damage" and (data.num == 0 or damageStruct.isVirtualDMG)) then
|
||||||
type = "#ShowHPAndMaxHP",
|
assert(not (data.reason == "recover" and data.num < 0))
|
||||||
from = player.id,
|
player.hp = math.min(player.hp + data.num, player.maxHp)
|
||||||
arg = player.hp,
|
room:broadcastProperty(player, "hp")
|
||||||
arg2 = player.maxHp,
|
|
||||||
}
|
if reason == "loseHp" then
|
||||||
|
room:sendLog{
|
||||||
|
type = "#LoseHP",
|
||||||
|
from = player.id,
|
||||||
|
arg = 0 - num,
|
||||||
|
}
|
||||||
|
room:sendLogEvent("LoseHP", {})
|
||||||
|
elseif reason == "recover" then
|
||||||
|
room:sendLog{
|
||||||
|
type = "#HealHP",
|
||||||
|
from = player.id,
|
||||||
|
arg = num,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
room:sendLog{
|
||||||
|
type = "#ShowHPAndMaxHP",
|
||||||
|
from = player.id,
|
||||||
|
arg = player.hp,
|
||||||
|
arg2 = player.maxHp,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
logic:trigger(fk.HpChanged, player, data)
|
logic:trigger(fk.HpChanged, player, data)
|
||||||
|
|
||||||
|
@ -124,10 +137,12 @@ GameEvent.functions[GameEvent.Damage] = function(self)
|
||||||
|
|
||||||
local stages = {
|
local stages = {
|
||||||
{fk.PreDamage, damageStruct.from},
|
{fk.PreDamage, damageStruct.from},
|
||||||
{fk.DamageCaused, damageStruct.from},
|
|
||||||
{fk.DamageInflicted, damageStruct.to},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if not damageStruct.isVirtualDMG then
|
||||||
|
table.insertTable(stages, { { fk.DamageCaused, damageStruct.from }, { fk.DamageInflicted, damageStruct.to } })
|
||||||
|
end
|
||||||
|
|
||||||
for _, struct in ipairs(stages) do
|
for _, struct in ipairs(stages) do
|
||||||
local event, player = table.unpack(struct)
|
local event, player = table.unpack(struct)
|
||||||
if logic:trigger(event, player, damageStruct) or damageStruct.damage < 1 then
|
if logic:trigger(event, player, damageStruct) or damageStruct.damage < 1 then
|
||||||
|
@ -141,6 +156,9 @@ GameEvent.functions[GameEvent.Damage] = function(self)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
damageStruct.dealtRecorderId = room.logic.specific_events_id[GameEvent.Damage]
|
||||||
|
room.logic.specific_events_id[GameEvent.Damage] = room.logic.specific_events_id[GameEvent.Damage] + 1
|
||||||
|
|
||||||
if damageStruct.card and damageStruct.damage > 0 then
|
if damageStruct.card and damageStruct.damage > 0 then
|
||||||
local parentUseData = logic:getCurrentEvent():findParent(GameEvent.UseCard)
|
local parentUseData = logic:getCurrentEvent():findParent(GameEvent.UseCard)
|
||||||
if parentUseData then
|
if parentUseData then
|
||||||
|
@ -155,23 +173,16 @@ GameEvent.functions[GameEvent.Damage] = function(self)
|
||||||
damageStruct.to:setChainState(false)
|
damageStruct.to:setChainState(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 先扣减护甲,再扣体力值
|
if not room:changeHp(
|
||||||
local shield_to_lose = math.min(damageStruct.damage, damageStruct.to.shield)
|
damageStruct.to,
|
||||||
room:changeShield(damageStruct.to, -shield_to_lose)
|
-damageStruct.damage,
|
||||||
|
"damage",
|
||||||
if shield_to_lose < damageStruct.damage then
|
damageStruct.skillName,
|
||||||
if not room:changeHp(
|
damageStruct) then
|
||||||
damageStruct.to,
|
logic:breakEvent(false)
|
||||||
shield_to_lose - damageStruct.damage,
|
|
||||||
"damage",
|
|
||||||
damageStruct.skillName,
|
|
||||||
damageStruct) then
|
|
||||||
logic:breakEvent(false)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
sendDamageLog(room, damageStruct)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
stages = {
|
stages = {
|
||||||
{fk.Damage, damageStruct.from},
|
{fk.Damage, damageStruct.from},
|
||||||
{fk.Damaged, damageStruct.to},
|
{fk.Damaged, damageStruct.to},
|
||||||
|
@ -201,9 +212,15 @@ GameEvent.exit_funcs[GameEvent.Damage] = function(self)
|
||||||
type = "#ChainDamage",
|
type = "#ChainDamage",
|
||||||
from = p.id
|
from = p.id
|
||||||
}
|
}
|
||||||
local dmg = table.simpleClone(damageStruct)
|
local dmg = {
|
||||||
dmg.to = p
|
from = damageStruct.from,
|
||||||
dmg.chain = true
|
to = p,
|
||||||
|
damage = damageStruct.damage,
|
||||||
|
card = damageStruct.card,
|
||||||
|
skillName = damageStruct.skillName,
|
||||||
|
chain = true,
|
||||||
|
}
|
||||||
|
|
||||||
room:damage(dmg)
|
room:damage(dmg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,6 +14,7 @@ dofile "lua/server/events/hp.lua"
|
||||||
|
|
||||||
GameEvent.Dying = 6
|
GameEvent.Dying = 6
|
||||||
GameEvent.Death = 7
|
GameEvent.Death = 7
|
||||||
|
GameEvent.Revive = 22
|
||||||
dofile "lua/server/events/death.lua"
|
dofile "lua/server/events/death.lua"
|
||||||
|
|
||||||
GameEvent.MoveCards = 8
|
GameEvent.MoveCards = 8
|
||||||
|
@ -64,6 +65,7 @@ local eventTranslations = {
|
||||||
[GameEvent.ChangeMaxHp] = "GameEvent.ChangeMaxHp",
|
[GameEvent.ChangeMaxHp] = "GameEvent.ChangeMaxHp",
|
||||||
[GameEvent.Dying] = "GameEvent.Dying",
|
[GameEvent.Dying] = "GameEvent.Dying",
|
||||||
[GameEvent.Death] = "GameEvent.Death",
|
[GameEvent.Death] = "GameEvent.Death",
|
||||||
|
[GameEvent.Revive] = "GameEvent.Revive",
|
||||||
[GameEvent.MoveCards] = "GameEvent.MoveCards",
|
[GameEvent.MoveCards] = "GameEvent.MoveCards",
|
||||||
[GameEvent.UseCard] = "GameEvent.UseCard",
|
[GameEvent.UseCard] = "GameEvent.UseCard",
|
||||||
[GameEvent.RespondCard] = "GameEvent.RespondCard",
|
[GameEvent.RespondCard] = "GameEvent.RespondCard",
|
||||||
|
|
|
@ -5,6 +5,8 @@ GameEvent.functions[GameEvent.Judge] = function(self)
|
||||||
local room = self.room
|
local room = self.room
|
||||||
local logic = room.logic
|
local logic = room.logic
|
||||||
local who = data.who
|
local who = data.who
|
||||||
|
|
||||||
|
data.isJudgeEvent = true
|
||||||
logic:trigger(fk.StartJudge, who, data)
|
logic:trigger(fk.StartJudge, who, data)
|
||||||
data.card = data.card or Fk:getCardById(room:getNCards(1)[1])
|
data.card = data.card or Fk:getCardById(room:getNCards(1)[1])
|
||||||
|
|
||||||
|
|
|
@ -39,28 +39,33 @@ GameEvent.functions[GameEvent.ChangeProperty] = function(self)
|
||||||
room:setPlayerProperty(player, "general", data.general)
|
room:setPlayerProperty(player, "general", data.general)
|
||||||
end
|
end
|
||||||
|
|
||||||
if data.deputyGeneral and data.deputyGeneral ~= "" and data.deputyGeneral ~= player.deputyGeneral then
|
if data.deputyGeneral and data.deputyGeneral ~= player.deputyGeneral then
|
||||||
local originalDeputy = Fk.generals[player.deputyGeneral] or Fk.generals["blank_shibing"]
|
local originalDeputy = Fk.generals[player.deputyGeneral] or Fk.generals["blank_shibing"]
|
||||||
local originalSkills = originalDeputy and originalDeputy:getSkillNameList() or Util.DummyTable
|
local originalSkills = originalDeputy and originalDeputy:getSkillNameList() or Util.DummyTable
|
||||||
table.insertTableIfNeed(skills, table.map(originalSkills, function(e)
|
table.insertTableIfNeed(skills, table.map(originalSkills, function(e)
|
||||||
return "-" .. e
|
return "-" .. e
|
||||||
end))
|
end))
|
||||||
local newDeputy = Fk.generals[data.deputyGeneral] or Fk.generals["blank_shibing"]
|
|
||||||
for _, name in ipairs(newDeputy:getSkillNameList()) do
|
if data.deputyGeneral ~= "" then
|
||||||
local s = Fk.skills[name]
|
local newDeputy = Fk.generals[data.deputyGeneral] or Fk.generals["blank_shibing"]
|
||||||
if not s.relate_to_place or s.relate_to_place == "d" then
|
for _, name in ipairs(newDeputy:getSkillNameList()) do
|
||||||
table.insertIfNeed(skills, name)
|
local s = Fk.skills[name]
|
||||||
|
if not s.relate_to_place or s.relate_to_place == "d" then
|
||||||
|
table.insertIfNeed(skills, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if data.sendLog then
|
||||||
|
room:sendLog{
|
||||||
|
type = "#ChangeHero",
|
||||||
|
from = player.id,
|
||||||
|
arg = player.deputyGeneral,
|
||||||
|
arg2 = data.deputyGeneral,
|
||||||
|
arg3 = "deputyGeneral",
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if data.sendLog then
|
|
||||||
room:sendLog{
|
|
||||||
type = "#ChangeHero",
|
|
||||||
from = player.id,
|
|
||||||
arg = player.deputyGeneral,
|
|
||||||
arg2 = data.deputyGeneral,
|
|
||||||
arg3 = "deputyGeneral",
|
|
||||||
}
|
|
||||||
end
|
|
||||||
data.results["deputyChange"] = {player.deputyGeneral, data.deputyGeneral}
|
data.results["deputyChange"] = {player.deputyGeneral, data.deputyGeneral}
|
||||||
room:setPlayerProperty(player, "deputyGeneral", data.deputyGeneral)
|
room:setPlayerProperty(player, "deputyGeneral", data.deputyGeneral)
|
||||||
end
|
end
|
||||||
|
|
|
@ -152,10 +152,18 @@ GameEvent.functions[GameEvent.MoveCards] = function(self)
|
||||||
room:doBroadcastNotify("UpdateDrawPile", #room.draw_pile)
|
room:doBroadcastNotify("UpdateDrawPile", #room.draw_pile)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not (data.to and data.toArea ~= Card.PlayerHand) then
|
local beforeCard = Fk:getCardById(info.cardId)
|
||||||
Fk:filterCard(info.cardId, room:getPlayerById(data.to))
|
if
|
||||||
|
realFromArea == Player.Equip and
|
||||||
|
beforeCard.type == Card.TypeEquip and
|
||||||
|
data.from ~= nil and
|
||||||
|
beforeCard.equip_skill
|
||||||
|
then
|
||||||
|
beforeCard:onUninstall(room, room:getPlayerById(data.from))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Fk:filterCard(info.cardId, room:getPlayerById(data.to))
|
||||||
|
|
||||||
local currentCard = Fk:getCardById(info.cardId)
|
local currentCard = Fk:getCardById(info.cardId)
|
||||||
for name, _ in pairs(currentCard.mark) do
|
for name, _ in pairs(currentCard.mark) do
|
||||||
if name:endsWith("-inhand") and
|
if name:endsWith("-inhand") and
|
||||||
|
@ -174,15 +182,6 @@ GameEvent.functions[GameEvent.MoveCards] = function(self)
|
||||||
then
|
then
|
||||||
currentCard:onInstall(room, room:getPlayerById(data.to))
|
currentCard:onInstall(room, room:getPlayerById(data.to))
|
||||||
end
|
end
|
||||||
|
|
||||||
if
|
|
||||||
realFromArea == Player.Equip and
|
|
||||||
currentCard.type == Card.TypeEquip and
|
|
||||||
data.from ~= nil and
|
|
||||||
currentCard.equip_skill
|
|
||||||
then
|
|
||||||
currentCard:onUninstall(room, room:getPlayerById(data.from))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -155,13 +155,29 @@ local sendCardEmotionAndLog = function(room, cardUseEvent)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
GameEvent.functions[GameEvent.UseCard] = function(self)
|
||||||
|
local cardUseEvent = table.unpack(self.data)
|
||||||
|
local room = self.room
|
||||||
|
local logic = room.logic
|
||||||
|
|
||||||
|
if cardUseEvent.card.skill then
|
||||||
|
cardUseEvent.card.skill:onUse(room, cardUseEvent)
|
||||||
|
end
|
||||||
|
|
||||||
|
sendCardEmotionAndLog(room, cardUseEvent)
|
||||||
|
|
||||||
|
room:moveCardTo(cardUseEvent.card, Card.Processing, nil, fk.ReasonUse)
|
||||||
|
|
||||||
|
local card = cardUseEvent.card
|
||||||
|
local useCardIds = card:isVirtual() and card.subcards or { card.id }
|
||||||
if #useCardIds == 0 then return end
|
if #useCardIds == 0 then return end
|
||||||
if cardUseEvent.tos and #cardUseEvent.tos > 0 and #cardUseEvent.tos <= 2 then
|
if cardUseEvent.tos and #cardUseEvent.tos > 0 and #cardUseEvent.tos <= 2 then
|
||||||
local tos = table.map(cardUseEvent.tos, function(e) return e[1] end)
|
local tos = table.map(cardUseEvent.tos, function(e) return e[1] end)
|
||||||
room:sendFootnote(useCardIds, {
|
room:sendFootnote(useCardIds, {
|
||||||
type = "##UseCardTo",
|
type = "##UseCardTo",
|
||||||
from = from,
|
from = cardUseEvent.from,
|
||||||
to = tos,
|
to = tos,
|
||||||
})
|
})
|
||||||
if card:isVirtual() then
|
if card:isVirtual() then
|
||||||
|
@ -170,26 +186,12 @@ local sendCardEmotionAndLog = function(room, cardUseEvent)
|
||||||
else
|
else
|
||||||
room:sendFootnote(useCardIds, {
|
room:sendFootnote(useCardIds, {
|
||||||
type = "##UseCard",
|
type = "##UseCard",
|
||||||
from = from,
|
from = cardUseEvent.from,
|
||||||
})
|
})
|
||||||
if card:isVirtual() then
|
if card:isVirtual() then
|
||||||
room:sendCardVirtName(useCardIds, card.name)
|
room:sendCardVirtName(useCardIds, card.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
GameEvent.functions[GameEvent.UseCard] = function(self)
|
|
||||||
local cardUseEvent = table.unpack(self.data)
|
|
||||||
local room = self.room
|
|
||||||
local logic = room.logic
|
|
||||||
|
|
||||||
room:moveCardTo(cardUseEvent.card, Card.Processing, nil, fk.ReasonUse)
|
|
||||||
|
|
||||||
if cardUseEvent.card.skill then
|
|
||||||
cardUseEvent.card.skill:onUse(room, cardUseEvent)
|
|
||||||
end
|
|
||||||
|
|
||||||
sendCardEmotionAndLog(room, cardUseEvent)
|
|
||||||
|
|
||||||
if logic:trigger(fk.PreCardUse, room:getPlayerById(cardUseEvent.from), cardUseEvent) then
|
if logic:trigger(fk.PreCardUse, room:getPlayerById(cardUseEvent.from), cardUseEvent) then
|
||||||
logic:breakEvent()
|
logic:breakEvent()
|
||||||
|
|
|
@ -23,6 +23,9 @@ function GameLogic:initialize(room)
|
||||||
self.all_game_events = {}
|
self.all_game_events = {}
|
||||||
self.event_recorder = {}
|
self.event_recorder = {}
|
||||||
self.current_event_id = 0
|
self.current_event_id = 0
|
||||||
|
self.specific_events_id = {
|
||||||
|
[GameEvent.Damage] = 0,
|
||||||
|
}
|
||||||
|
|
||||||
self.role_table = {
|
self.role_table = {
|
||||||
{ "lord" },
|
{ "lord" },
|
||||||
|
|
|
@ -1913,10 +1913,13 @@ function Room:handleUseCardReply(player, data)
|
||||||
end
|
end
|
||||||
use.card = c
|
use.card = c
|
||||||
|
|
||||||
skill:beforeUse(player, use)
|
|
||||||
|
|
||||||
self:useSkill(player, skill, Util.DummyFunc)
|
self:useSkill(player, skill, Util.DummyFunc)
|
||||||
|
|
||||||
|
local rejectSkillName = skill:beforeUse(player, use)
|
||||||
|
if type(rejectSkillName) == "string" then
|
||||||
|
return rejectSkillName
|
||||||
|
end
|
||||||
|
|
||||||
return use
|
return use
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2007,17 +2010,29 @@ function Room:askForUseCard(player, card_name, pattern, prompt, cancelable, extr
|
||||||
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit .. "-tmp", 0)
|
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit .. "-tmp", 0)
|
||||||
return askForUseCardData.result
|
return askForUseCardData.result
|
||||||
else
|
else
|
||||||
local data = {card_name, pattern, prompt, cancelable, extra_data}
|
local useResult
|
||||||
|
local disabledSkillNames = {}
|
||||||
|
|
||||||
Fk.currentResponsePattern = pattern
|
repeat
|
||||||
local result = self:doRequest(player, command, json.encode(data))
|
useResult = nil
|
||||||
Fk.currentResponsePattern = nil
|
local data = {card_name, pattern, prompt, cancelable, extra_data, disabledSkillNames}
|
||||||
|
|
||||||
if result ~= "" then
|
Fk.currentResponsePattern = pattern
|
||||||
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit .. "-tmp", 0)
|
local result = self:doRequest(player, command, json.encode(data))
|
||||||
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit .. "-tmp", 0)
|
Fk.currentResponsePattern = nil
|
||||||
return self:handleUseCardReply(player, result)
|
|
||||||
end
|
if result ~= "" then
|
||||||
|
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit .. "-tmp", 0)
|
||||||
|
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit .. "-tmp", 0)
|
||||||
|
useResult = self:handleUseCardReply(player, result)
|
||||||
|
|
||||||
|
if type(useResult) == "string" and useResult ~= "" then
|
||||||
|
table.insertIfNeed(disabledSkillNames, useResult)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
until type(useResult) ~= "string"
|
||||||
|
|
||||||
|
return useResult
|
||||||
end
|
end
|
||||||
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit .. "-tmp", 0)
|
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit .. "-tmp", 0)
|
||||||
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit .. "-tmp", 0)
|
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit .. "-tmp", 0)
|
||||||
|
@ -2056,17 +2071,28 @@ function Room:askForResponse(player, card_name, pattern, prompt, cancelable, ext
|
||||||
if eventData.result then
|
if eventData.result then
|
||||||
return eventData.result
|
return eventData.result
|
||||||
else
|
else
|
||||||
local data = {card_name, pattern, prompt, cancelable, extra_data}
|
local useResult
|
||||||
|
local disabledSkillNames = {}
|
||||||
|
|
||||||
Fk.currentResponsePattern = pattern
|
repeat
|
||||||
local result = self:doRequest(player, command, json.encode(data))
|
useResult = nil
|
||||||
Fk.currentResponsePattern = nil
|
local data = {card_name, pattern, prompt, cancelable, extra_data, disabledSkillNames}
|
||||||
|
|
||||||
if result ~= "" then
|
Fk.currentResponsePattern = pattern
|
||||||
local use = self:handleUseCardReply(player, result)
|
local result = self:doRequest(player, command, json.encode(data))
|
||||||
if use then
|
Fk.currentResponsePattern = nil
|
||||||
return use.card
|
|
||||||
|
if result ~= "" then
|
||||||
|
useResult = self:handleUseCardReply(player, result)
|
||||||
|
|
||||||
|
if type(useResult) == "string" and useResult ~= "" then
|
||||||
|
table.insertIfNeed(disabledSkillNames, useResult)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
until type(useResult) ~= "string"
|
||||||
|
|
||||||
|
if useResult then
|
||||||
|
return useResult.card
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
|
@ -2094,20 +2120,31 @@ function Room:askForNullification(players, card_name, pattern, prompt, cancelabl
|
||||||
prompt = prompt or ""
|
prompt = prompt or ""
|
||||||
pattern = pattern or card_name
|
pattern = pattern or card_name
|
||||||
|
|
||||||
self:notifyMoveFocus(self.alive_players, card_name)
|
local useResult
|
||||||
self:doBroadcastNotify("WaitForNullification", "")
|
local disabledSkillNames = {}
|
||||||
|
|
||||||
local data = {card_name, pattern, prompt, cancelable, extra_data}
|
repeat
|
||||||
|
useResult = nil
|
||||||
|
self:notifyMoveFocus(self.alive_players, card_name)
|
||||||
|
self:doBroadcastNotify("WaitForNullification", "")
|
||||||
|
|
||||||
Fk.currentResponsePattern = pattern
|
local data = {card_name, pattern, prompt, cancelable, extra_data, disabledSkillNames}
|
||||||
local winner = self:doRaceRequest(command, players, json.encode(data))
|
|
||||||
|
|
||||||
if winner then
|
Fk.currentResponsePattern = pattern
|
||||||
local result = winner.client_reply
|
local winner = self:doRaceRequest(command, players, json.encode(data))
|
||||||
return self:handleUseCardReply(winner, result)
|
|
||||||
end
|
if winner then
|
||||||
Fk.currentResponsePattern = nil
|
local result = winner.client_reply
|
||||||
return nil
|
useResult = self:handleUseCardReply(winner, result)
|
||||||
|
|
||||||
|
if type(useResult) == "string" and useResult ~= "" then
|
||||||
|
table.insertIfNeed(disabledSkillNames, useResult)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Fk.currentResponsePattern = nil
|
||||||
|
until type(useResult) ~= "string"
|
||||||
|
|
||||||
|
return useResult
|
||||||
end
|
end
|
||||||
|
|
||||||
-- AG(a.k.a. Amazing Grace) functions
|
-- AG(a.k.a. Amazing Grace) functions
|
||||||
|
@ -2409,9 +2446,8 @@ local onAim = function(room, cardUseEvent, aimEventCollaborators)
|
||||||
|
|
||||||
firstTarget = false
|
firstTarget = false
|
||||||
|
|
||||||
if room.logic:trigger(stage, (stage == fk.TargetSpecifying or stage == fk.TargetSpecified) and room:getPlayerById(aimStruct.from) or room:getPlayerById(aimStruct.to), aimStruct) then
|
room.logic:trigger(stage, (stage == fk.TargetSpecifying or stage == fk.TargetSpecified) and room:getPlayerById(aimStruct.from) or room:getPlayerById(aimStruct.to), aimStruct)
|
||||||
return false
|
|
||||||
end
|
|
||||||
AimGroup:removeDeadTargets(room, aimStruct)
|
AimGroup:removeDeadTargets(room, aimStruct)
|
||||||
|
|
||||||
local aimEventTargetGroup = aimStruct.targetGroup
|
local aimEventTargetGroup = aimStruct.targetGroup
|
||||||
|
@ -3292,19 +3328,9 @@ function Room:useSkill(player, skill, effect_cb)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param player ServerPlayer
|
---@param player ServerPlayer
|
||||||
---@param sendLog? boolean
|
---@param sendLog? bool
|
||||||
function Room:revivePlayer(player, sendLog)
|
function Room:revivePlayer(player, sendLog, reason)
|
||||||
if not player.dead then return end
|
return execGameEvent(GameEvent.Revive, player, sendLog, reason)
|
||||||
self:setPlayerProperty(player, "dead", false)
|
|
||||||
player._splayer:setDied(false)
|
|
||||||
self:setPlayerProperty(player, "dying", false)
|
|
||||||
self:setPlayerProperty(player, "hp", player.maxHp)
|
|
||||||
table.insertIfNeed(self.alive_players, player)
|
|
||||||
|
|
||||||
sendLog = (sendLog == nil) and true or sendLog
|
|
||||||
if sendLog then
|
|
||||||
self:sendLog { type = "#Revive", from = player.id }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param room Room
|
---@param room Room
|
||||||
|
@ -3573,4 +3599,9 @@ function Room:resumePlayerArea(player, playerSlots)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Room:setPlayerRest(player, roundNum)
|
||||||
|
player.rest = roundNum
|
||||||
|
self:broadcastProperty(player, "rest")
|
||||||
|
end
|
||||||
|
|
||||||
return Room
|
return Room
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
--- 描述和一次体力变化有关的数据
|
--- 描述和一次体力变化有关的数据
|
||||||
---@class HpChangedData
|
---@class HpChangedData
|
||||||
---@field public num integer @ 体力变化量,可能是正数或者负数
|
---@field public num integer @ 体力变化量,可能是正数或者负数
|
||||||
|
---@field public shield_lost integer|nil
|
||||||
---@field public reason string @ 体力变化原因
|
---@field public reason string @ 体力变化原因
|
||||||
---@field public skillName string @ 引起体力变化的技能名
|
---@field public skillName string @ 引起体力变化的技能名
|
||||||
---@field public damageEvent? DamageStruct @ 引起这次体力变化的伤害数据
|
---@field public damageEvent? DamageStruct @ 引起这次体力变化的伤害数据
|
||||||
|
|
|
@ -82,7 +82,7 @@ GameRule = fk.CreateTriggerSkill{
|
||||||
end,
|
end,
|
||||||
[fk.BuryVictim] = function()
|
[fk.BuryVictim] = function()
|
||||||
player:bury()
|
player:bury()
|
||||||
if room.tag["SkipNormalDeathProcess"] then
|
if room.tag["SkipNormalDeathProcess"] or player.rest > 0 then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local damage = data.damage
|
local damage = data.damage
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
|
@ -423,6 +423,31 @@ local jijiang = fk.CreateViewAsSkill{
|
||||||
c.skillName = self.name
|
c.skillName = self.name
|
||||||
return c
|
return c
|
||||||
end,
|
end,
|
||||||
|
before_use = function(self, player, use)
|
||||||
|
local room = player.room
|
||||||
|
if use.tos then
|
||||||
|
room:doIndicate(player.id, TargetGroup:getRealTargets(use.tos))
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, p in ipairs(room:getOtherPlayers(player)) do
|
||||||
|
if p.kingdom == "shu" then
|
||||||
|
local cardResponded = room:askForResponse(p, "slash", "slash", "#jijiang-ask:" .. player.id, true)
|
||||||
|
if cardResponded then
|
||||||
|
room:responseCard({
|
||||||
|
from = p.id,
|
||||||
|
card = cardResponded,
|
||||||
|
skipDrop = true,
|
||||||
|
})
|
||||||
|
|
||||||
|
use.card = cardResponded
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
room:setPlayerMark(player, "jijiang-failed-phase", 1)
|
||||||
|
return self.name
|
||||||
|
end,
|
||||||
enabled_at_play = function(self, player)
|
enabled_at_play = function(self, player)
|
||||||
return player:getMark("jijiang-failed-phase") == 0 and not table.every(Fk:currentRoom().alive_players, function(p)
|
return player:getMark("jijiang-failed-phase") == 0 and not table.every(Fk:currentRoom().alive_players, function(p)
|
||||||
return p == player or p.kingdom ~= "shu"
|
return p == player or p.kingdom ~= "shu"
|
||||||
|
@ -434,51 +459,6 @@ local jijiang = fk.CreateViewAsSkill{
|
||||||
end)
|
end)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
local jijiangResponse = fk.CreateTriggerSkill{
|
|
||||||
name = "#jijiangResponse",
|
|
||||||
events = {fk.PreCardUse, fk.PreCardRespond},
|
|
||||||
mute = true,
|
|
||||||
priority = 10,
|
|
||||||
can_trigger = function(self, event, target, player, data)
|
|
||||||
return target == player and player:hasSkill(self.name, true) and table.contains(data.card.skillNames, "jijiang")
|
|
||||||
end,
|
|
||||||
on_cost = function(self, event, target, player, data)
|
|
||||||
local room = player.room
|
|
||||||
room:doIndicate(player.id, TargetGroup:getRealTargets(data.tos))
|
|
||||||
return true
|
|
||||||
end,
|
|
||||||
on_use = function(self, event, target, player, data)
|
|
||||||
local room = player.room
|
|
||||||
for _, p in ipairs(room:getOtherPlayers(player)) do
|
|
||||||
if p.kingdom == "shu" then
|
|
||||||
local cardResponded = room:askForResponse(p, "slash", "slash", "#jijiang-ask:" .. player.id, true)
|
|
||||||
if cardResponded then
|
|
||||||
room:responseCard({
|
|
||||||
from = p.id,
|
|
||||||
card = cardResponded,
|
|
||||||
skipDrop = true,
|
|
||||||
})
|
|
||||||
|
|
||||||
data.card = cardResponded
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if event == fk.PreCardUse and player.phase == Player.Play then
|
|
||||||
room:setPlayerMark(player, "jijiang-failed-phase", 1)
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end,
|
|
||||||
refresh_events = {fk.CardUsing},
|
|
||||||
can_refresh = function(self, event, target, player, data)
|
|
||||||
return target == player and player:hasSkill(self.name, true) and player:getMark("jijiang-failed-phase") > 0
|
|
||||||
end,
|
|
||||||
on_refresh = function(self, event, target, player, data)
|
|
||||||
player.room:setPlayerMark(player, "jijiang-failed-phase", 0)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
jijiang:addRelatedSkill(jijiangResponse)
|
|
||||||
|
|
||||||
local liubei = General:new(extension, "liubei", "shu", 4)
|
local liubei = General:new(extension, "liubei", "shu", 4)
|
||||||
liubei:addSkill(rende)
|
liubei:addSkill(rende)
|
||||||
|
|
|
@ -338,6 +338,7 @@ local test_feichu = fk.CreateActiveSkill{
|
||||||
room:abortPlayerArea(from, eqipSlots)
|
room:abortPlayerArea(from, eqipSlots)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
local test2 = General(extension, "mouxusheng", "wu", 4, 4, General.Female)
|
local test2 = General(extension, "mouxusheng", "wu", 4, 4, General.Female)
|
||||||
test2.shield = 3
|
test2.shield = 3
|
||||||
test2.hidden = true
|
test2.hidden = true
|
||||||
|
|
Loading…
Reference in New Issue