Bugfix (#206)
* 修cost_data * 修cardMark,仍需自动清理措施 * 修锁视技( **重要!使用牌之前会根据锁视技重新决定使用的卡牌!!**)
This commit is contained in:
parent
6c0d5433c6
commit
c3fd8fc9a5
|
@ -159,6 +159,7 @@ Item {
|
||||||
|
|
||||||
if (dashboard.pending_skill !== "")
|
if (dashboard.pending_skill !== "")
|
||||||
dashboard.stopPending();
|
dashboard.stopPending();
|
||||||
|
dashboard.updateHandcards();
|
||||||
dashboard.disableAllCards();
|
dashboard.disableAllCards();
|
||||||
dashboard.disableSkills();
|
dashboard.disableSkills();
|
||||||
dashboard.retractAllPiles();
|
dashboard.retractAllPiles();
|
||||||
|
@ -176,6 +177,7 @@ Item {
|
||||||
ScriptAction {
|
ScriptAction {
|
||||||
script: {
|
script: {
|
||||||
skillInteraction.sourceComponent = undefined;
|
skillInteraction.sourceComponent = undefined;
|
||||||
|
dashboard.updateHandcards();
|
||||||
dashboard.enableCards();
|
dashboard.enableCards();
|
||||||
dashboard.enableSkills();
|
dashboard.enableSkills();
|
||||||
progress.visible = true;
|
progress.visible = true;
|
||||||
|
@ -191,6 +193,7 @@ Item {
|
||||||
ScriptAction {
|
ScriptAction {
|
||||||
script: {
|
script: {
|
||||||
skillInteraction.sourceComponent = undefined;
|
skillInteraction.sourceComponent = undefined;
|
||||||
|
dashboard.updateHandcards();
|
||||||
dashboard.enableCards(responding_card);
|
dashboard.enableCards(responding_card);
|
||||||
dashboard.enableSkills(responding_card, respond_play);
|
dashboard.enableSkills(responding_card, respond_play);
|
||||||
autoPending = false;
|
autoPending = false;
|
||||||
|
@ -205,6 +208,7 @@ Item {
|
||||||
ScriptAction {
|
ScriptAction {
|
||||||
script: {
|
script: {
|
||||||
skillInteraction.sourceComponent = undefined;
|
skillInteraction.sourceComponent = undefined;
|
||||||
|
dashboard.updateHandcards();
|
||||||
dashboard.disableAllCards();
|
dashboard.disableAllCards();
|
||||||
dashboard.disableSkills();
|
dashboard.disableSkills();
|
||||||
progress.visible = true;
|
progress.visible = true;
|
||||||
|
|
|
@ -622,6 +622,33 @@ callbacks["PropertyUpdate"] = (jsonData) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callbacks["UpdateCard"] = (j) => {
|
||||||
|
const id = parseInt(j);
|
||||||
|
let card;
|
||||||
|
roomScene.tableCards.forEach((v) => {
|
||||||
|
if (v.cid === id) {
|
||||||
|
card = v;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!card) {
|
||||||
|
roomScene.dashboard.handcardArea.cards.forEach((v) => {
|
||||||
|
if (v.cid === id) {
|
||||||
|
card = v;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!card) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = JSON.parse(Backend.callLuaFunction("GetCardData", [id]));
|
||||||
|
card.setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
callbacks["StartGame"] = (jsonData) => {
|
callbacks["StartGame"] = (jsonData) => {
|
||||||
roomScene.isStarted = true;
|
roomScene.isStarted = true;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
import Qt5Compat.GraphicalEffects
|
import Qt5Compat.GraphicalEffects
|
||||||
import Fk
|
import Fk
|
||||||
|
|
||||||
|
@ -33,6 +34,7 @@ Item {
|
||||||
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 card: cardItem
|
||||||
property alias glow: glowItem
|
property alias glow: glowItem
|
||||||
|
property var mark: ({})
|
||||||
|
|
||||||
function getColor() {
|
function getColor() {
|
||||||
if (suit != "")
|
if (suit != "")
|
||||||
|
@ -161,6 +163,57 @@ Item {
|
||||||
//glow.samples: 12
|
//glow.samples: 12
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: cardMarkDelegate
|
||||||
|
Item {
|
||||||
|
width: root.width / 2
|
||||||
|
height: 16
|
||||||
|
Rectangle {
|
||||||
|
id: mark_rect
|
||||||
|
width: mark_text.width + 12
|
||||||
|
height: 16
|
||||||
|
// color: "#A50330"
|
||||||
|
radius: 4
|
||||||
|
// border.color: "snow"
|
||||||
|
// border.width: 1
|
||||||
|
gradient: Gradient {
|
||||||
|
orientation: Gradient.Horizontal
|
||||||
|
GradientStop { position: 0.7; color: "#A50330" }
|
||||||
|
GradientStop { position: 1.0; color: "transparent" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
id: mark_text
|
||||||
|
x: 2
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.family: fontLibian.name
|
||||||
|
font.letterSpacing: -0.6
|
||||||
|
text: {
|
||||||
|
let ret = Backend.translate(modelData.k);
|
||||||
|
if (!modelData.k.startsWith("@@")) {
|
||||||
|
ret += modelData.v.toString();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
color: "white"
|
||||||
|
style: Text.Outline
|
||||||
|
styleColor: "purple"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
width: root.width
|
||||||
|
y: 60
|
||||||
|
columns: 2
|
||||||
|
rowSpacing: 1
|
||||||
|
columnSpacing: 0
|
||||||
|
Repeater {
|
||||||
|
model: mark
|
||||||
|
delegate: cardMarkDelegate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: !root.selectable
|
visible: !root.selectable
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -266,6 +319,7 @@ Item {
|
||||||
color = data.color;
|
color = data.color;
|
||||||
subtype = data.subtype ? data.subtype : "";
|
subtype = data.subtype ? data.subtype : "";
|
||||||
virt_name = data.virt_name ? data.virt_name : "";
|
virt_name = data.virt_name ? data.virt_name : "";
|
||||||
|
mark = data.mark ?? {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function toData()
|
function toData()
|
||||||
|
@ -278,6 +332,7 @@ Item {
|
||||||
color: color,
|
color: color,
|
||||||
subtype: subtype,
|
subtype: subtype,
|
||||||
virt_name: virt_name,
|
virt_name: virt_name,
|
||||||
|
mark: mark,
|
||||||
};
|
};
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -405,6 +405,14 @@ RowLayout {
|
||||||
self.tremble();
|
self.tremble();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateHandcards() {
|
||||||
|
Backend.callLuaFunction("FilterMyHandcards", []);
|
||||||
|
handcardAreaItem.cards.forEach(v => {
|
||||||
|
const data = JSON.parse(Backend.callLuaFunction("GetCardData", [v.cid]));
|
||||||
|
v.setData(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
unSelectAll();
|
unSelectAll();
|
||||||
disableSkills();
|
disableSkills();
|
||||||
|
|
|
@ -52,6 +52,9 @@ function Client:initialize()
|
||||||
self.status_skills[class] = {table.unpack(skills)}
|
self.status_skills[class] = {table.unpack(skills)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.skill_costs = {}
|
||||||
|
self.card_marks = {}
|
||||||
|
self.filtered_cards = {}
|
||||||
self.disabled_packs = {}
|
self.disabled_packs = {}
|
||||||
self.disabled_generals = {}
|
self.disabled_generals = {}
|
||||||
end
|
end
|
||||||
|
@ -657,11 +660,9 @@ fk.client_callback["SetCardMark"] = function(jsonData)
|
||||||
-- jsonData: [ int id, string mark, int value ]
|
-- jsonData: [ int id, string mark, int value ]
|
||||||
local data = json.decode(jsonData)
|
local data = json.decode(jsonData)
|
||||||
local card, mark, value = data[1], data[2], data[3]
|
local card, mark, value = data[1], data[2], data[3]
|
||||||
ClientInstance:getCardById(card):setMark(mark, value)
|
Fk:getCardById(card):setMark(mark, value)
|
||||||
|
|
||||||
if string.sub(mark, 1, 1) == "@" then
|
ClientInstance:notifyUI("UpdateCard", tostring(card))
|
||||||
ClientInstance:notifyUI("SetCardMark", jsonData)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
fk.client_callback["Chat"] = function(jsonData)
|
fk.client_callback["Chat"] = function(jsonData)
|
||||||
|
|
|
@ -81,6 +81,14 @@ function GetCardData(id)
|
||||||
cid = id,
|
cid = id,
|
||||||
known = false
|
known = false
|
||||||
} end
|
} end
|
||||||
|
local mark = {}
|
||||||
|
for k, v in pairs(card.mark) do
|
||||||
|
if k and k:startsWith("@") and v and v ~= 0 then
|
||||||
|
table.insert(mark, {
|
||||||
|
k = k, v = v,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
local ret = {
|
local ret = {
|
||||||
cid = id,
|
cid = id,
|
||||||
name = card.name,
|
name = card.name,
|
||||||
|
@ -88,6 +96,7 @@ function GetCardData(id)
|
||||||
number = card.number,
|
number = card.number,
|
||||||
suit = card:getSuitString(),
|
suit = card:getSuitString(),
|
||||||
color = card:getColorString(),
|
color = card:getColorString(),
|
||||||
|
mark = mark,
|
||||||
subtype = cardSubtypeStrings[card.sub_type]
|
subtype = cardSubtypeStrings[card.sub_type]
|
||||||
}
|
}
|
||||||
if card.skillName ~= "" then
|
if card.skillName ~= "" then
|
||||||
|
@ -605,4 +614,8 @@ function SetPlayerGameData(pid, data)
|
||||||
p.player:setGameData(table.unpack(data))
|
p.player:setGameData(table.unpack(data))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function FilterMyHandcards()
|
||||||
|
Self:filterHandcards()
|
||||||
|
end
|
||||||
|
|
||||||
dofile "lua/client/i18n/init.lua"
|
dofile "lua/client/i18n/init.lua"
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
---@field public mark table<string, integer> @ 当前拥有的所有标记,用烂了
|
---@field public mark table<string, integer> @ 当前拥有的所有标记,用烂了
|
||||||
---@field public subcards integer[] @ 子卡ID表
|
---@field public subcards integer[] @ 子卡ID表
|
||||||
---@field public skillName string @ 虚拟牌的技能名 for virtual cards
|
---@field public skillName string @ 虚拟牌的技能名 for virtual cards
|
||||||
|
---@field private _skillName string
|
||||||
---@field public skillNames string[] @ 虚拟牌的技能名们(一张虚拟牌可能有多个技能名,如芳魂、龙胆、朱雀羽扇)
|
---@field public skillNames string[] @ 虚拟牌的技能名们(一张虚拟牌可能有多个技能名,如芳魂、龙胆、朱雀羽扇)
|
||||||
---@field public skill Skill @ 技能(用于实现卡牌效果)
|
---@field public skill Skill @ 技能(用于实现卡牌效果)
|
||||||
---@field public special_skills string[] | nil @ 衍生技能,如重铸
|
---@field public special_skills string[] | nil @ 衍生技能,如重铸
|
||||||
|
@ -94,18 +95,27 @@ function Card:initialize(name, suit, number, color)
|
||||||
-- self.package = nil
|
-- self.package = nil
|
||||||
self.id = 0
|
self.id = 0
|
||||||
self.type = 0
|
self.type = 0
|
||||||
self.sub_type = Card.SubTypeNone
|
self.sub_type = Card.SubtypeNone
|
||||||
-- self.skill = nil
|
-- self.skill = nil
|
||||||
self.subcards = {}
|
self.subcards = {}
|
||||||
-- self.skillName = nil
|
-- self.skillName = nil
|
||||||
self._skillName = ""
|
self._skillName = ""
|
||||||
self.skillNames = {}
|
self.skillNames = {}
|
||||||
self.mark = {}
|
-- self.mark = {} -- 这个视情况了,只有虚拟牌才有真正的self.mark,真牌的话挂在currentRoom
|
||||||
end
|
end
|
||||||
|
|
||||||
function Card:__index(k)
|
function Card:__index(k)
|
||||||
if k == "skillName" then
|
if k == "skillName" then
|
||||||
return self._skillName
|
return self._skillName
|
||||||
|
elseif k == "mark" then
|
||||||
|
if not self:isVirtual() then
|
||||||
|
local mark_tab = Fk:currentRoom().card_marks
|
||||||
|
mark_tab[self.id] = mark_tab[self.id] or {}
|
||||||
|
return mark_tab[self.id]
|
||||||
|
else
|
||||||
|
self.mark = {}
|
||||||
|
return self.mark
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -322,6 +332,15 @@ function Card:removeMark(mark, count)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- 为卡牌设置Mark至指定数量。
|
--- 为卡牌设置Mark至指定数量。
|
||||||
|
---
|
||||||
|
--- 关于标记的说明:
|
||||||
|
---
|
||||||
|
--- * @开头的为可见标记,其余为隐藏标记。
|
||||||
|
--- * -turn结尾、-phase结尾、-round结尾的如同玩家标记一样在这个时机自动清理。
|
||||||
|
--- * -noclear结尾的表示不要自动清理。
|
||||||
|
--- * 默认的自动清理策略是当卡牌离开手牌区后清除所有的标记。
|
||||||
|
--- * -turn之类的后缀会覆盖默认清理的方式。
|
||||||
|
--- * (TODO: 以上皆为画饼)
|
||||||
---@param mark string @ 标记
|
---@param mark string @ 标记
|
||||||
---@param count integer @ 为标记删除的数量
|
---@param count integer @ 为标记删除的数量
|
||||||
function Card:setMark(mark, count)
|
function Card:setMark(mark, count)
|
||||||
|
@ -335,7 +354,11 @@ end
|
||||||
---@param mark string @ 标记
|
---@param mark string @ 标记
|
||||||
---@return integer
|
---@return integer
|
||||||
function Card:getMark(mark)
|
function Card:getMark(mark)
|
||||||
return (self.mark[mark] or 0)
|
local ret = (self.mark[mark] or 0)
|
||||||
|
if (not self:isVirtual()) and next(self.mark) == nil then
|
||||||
|
self.mark = nil
|
||||||
|
end
|
||||||
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
--- 判定卡牌是否拥有对应的Mark。
|
--- 判定卡牌是否拥有对应的Mark。
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
---@field public game_modes table<string, GameMode> @ 所有游戏模式
|
---@field public game_modes table<string, GameMode> @ 所有游戏模式
|
||||||
---@field public currentResponsePattern string @ 要求用牌的种类(如要求用特定花色的桃···)
|
---@field public currentResponsePattern string @ 要求用牌的种类(如要求用特定花色的桃···)
|
||||||
---@field public currentResponseReason string @ 要求用牌的原因(如濒死,被特定牌指定,使用特定技能···)
|
---@field public currentResponseReason string @ 要求用牌的原因(如濒死,被特定牌指定,使用特定技能···)
|
||||||
|
---@field public filtered_cards table<integer, Card> @ 被锁视技影响的卡牌
|
||||||
local Engine = class("Engine")
|
local Engine = class("Engine")
|
||||||
|
|
||||||
--- Engine的构造函数。
|
--- Engine的构造函数。
|
||||||
|
@ -57,6 +58,7 @@ end
|
||||||
local _foreign_keys = {
|
local _foreign_keys = {
|
||||||
"currentResponsePattern",
|
"currentResponsePattern",
|
||||||
"currentResponseReason",
|
"currentResponseReason",
|
||||||
|
"filtered_cards",
|
||||||
}
|
}
|
||||||
|
|
||||||
function Engine:__index(k)
|
function Engine:__index(k)
|
||||||
|
@ -381,8 +383,6 @@ function Engine:getAllCardIds(except)
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
local filtered_cards = {}
|
|
||||||
|
|
||||||
--- 根据id返回相应的卡牌。
|
--- 根据id返回相应的卡牌。
|
||||||
---@param id integer @ 牌的id
|
---@param id integer @ 牌的id
|
||||||
---@param ignoreFilter boolean @ 是否要无视掉锁定视为技,直接获得真牌
|
---@param ignoreFilter boolean @ 是否要无视掉锁定视为技,直接获得真牌
|
||||||
|
@ -390,7 +390,7 @@ local filtered_cards = {}
|
||||||
function Engine:getCardById(id, ignoreFilter)
|
function Engine:getCardById(id, ignoreFilter)
|
||||||
local ret = self.cards[id]
|
local ret = self.cards[id]
|
||||||
if not ignoreFilter then
|
if not ignoreFilter then
|
||||||
ret = filtered_cards[id] or self.cards[id]
|
ret = self.filtered_cards[id] or self.cards[id]
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
@ -402,14 +402,14 @@ end
|
||||||
function Engine:filterCard(id, player, data)
|
function Engine:filterCard(id, player, data)
|
||||||
local card = self:getCardById(id, true)
|
local card = self:getCardById(id, true)
|
||||||
if player == nil then
|
if player == nil then
|
||||||
filtered_cards[id] = nil
|
self.filtered_cards[id] = nil
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local skills = player:getAllSkills()
|
local skills = player:getAllSkills()
|
||||||
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
|
||||||
filtered_cards[id] = nil
|
self.filtered_cards[id] = nil
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -446,11 +446,11 @@ function Engine:filterCard(id, player, data)
|
||||||
if card == nil then
|
if card == nil then
|
||||||
card = self:getCardById(id)
|
card = self:getCardById(id)
|
||||||
end
|
end
|
||||||
filtered_cards[id] = card
|
self.filtered_cards[id] = card
|
||||||
end
|
end
|
||||||
|
|
||||||
if modify then
|
if modify then
|
||||||
filtered_cards[id] = nil
|
self.filtered_cards[id] = nil
|
||||||
data.card = card
|
data.card = card
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
|
@ -344,6 +344,12 @@ function Player:getHandcardNum()
|
||||||
return #self:getCardIds(Player.Hand)
|
return #self:getCardIds(Player.Hand)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Player:filterHandcards()
|
||||||
|
for _, id in ipairs(self:getCardIds(Player.Hand)) do
|
||||||
|
Fk:filterCard(id, self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- 检索玩家装备区是否存在对应类型的装备。
|
--- 检索玩家装备区是否存在对应类型的装备。
|
||||||
---@param cardSubtype CardSubtype @ 卡牌子类
|
---@param cardSubtype CardSubtype @ 卡牌子类
|
||||||
---@return integer|null @ 返回卡牌ID或nil
|
---@return integer|null @ 返回卡牌ID或nil
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
-- Note: these files are not used by FreeKill.
|
-- Note: these files are not used by FreeKill.
|
||||||
-- Just for convenience when using sumneko.lua
|
-- Just for convenience when using sumneko.lua
|
||||||
|
|
||||||
|
---@alias null nil
|
||||||
|
|
||||||
---@class fk
|
---@class fk
|
||||||
---FreeKill's lua API
|
---FreeKill's lua API
|
||||||
fk = {}
|
fk = {}
|
||||||
|
@ -35,3 +37,8 @@ function fk.QmlBackend_exists(file)end
|
||||||
|
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function fk.QmlBackend_isDir(file)end
|
function fk.QmlBackend_isDir(file)end
|
||||||
|
|
||||||
|
function fk.qCritical(msg) end
|
||||||
|
function fk.qInfo(msg) end
|
||||||
|
function fk.qDebug(msg) end
|
||||||
|
function fk.qWarning(msg) end
|
||||||
|
|
|
@ -14,6 +14,9 @@ function FPlayer:getScreenName()end
|
||||||
---@return string avatar
|
---@return string avatar
|
||||||
function FPlayer:getAvatar()end
|
function FPlayer:getAvatar()end
|
||||||
|
|
||||||
|
---@class fk.ServerPlayer : fk.Player
|
||||||
|
FServerPlayer = {}
|
||||||
|
|
||||||
--- Send a request to client, and allow client to reply within *timeout* seconds.
|
--- Send a request to client, and allow client to reply within *timeout* seconds.
|
||||||
---
|
---
|
||||||
--- *timeout* must not be negative or **nil**.
|
--- *timeout* must not be negative or **nil**.
|
||||||
|
@ -34,3 +37,9 @@ function FServerPlayer:waitForReply(timeout)end
|
||||||
---@param command string
|
---@param command string
|
||||||
---@param jsonData string
|
---@param jsonData string
|
||||||
function FServerPlayer:doNotify(command,jsonData)end
|
function FServerPlayer:doNotify(command,jsonData)end
|
||||||
|
|
||||||
|
function FServerPlayer:setBusy(_) end
|
||||||
|
function FServerPlayer:isBusy(_) end
|
||||||
|
function FServerPlayer:setThinking(_) end
|
||||||
|
|
||||||
|
function FServerPlayer:getState() end
|
||||||
|
|
|
@ -119,7 +119,9 @@ GameEvent.functions[GameEvent.MoveCards] = function(self)
|
||||||
self:doBroadcastNotify("UpdateDrawPile", #self.draw_pile)
|
self:doBroadcastNotify("UpdateDrawPile", #self.draw_pile)
|
||||||
end
|
end
|
||||||
|
|
||||||
Fk:filterCard(info.cardId, self:getPlayerById(data.to))
|
if not (data.to and data.toArea ~= Card.PlayerHand) then
|
||||||
|
Fk:filterCard(info.cardId, self:getPlayerById(data.to))
|
||||||
|
end
|
||||||
|
|
||||||
local currentCard = Fk:getCardById(info.cardId)
|
local currentCard = Fk:getCardById(info.cardId)
|
||||||
if
|
if
|
||||||
|
|
|
@ -52,6 +52,7 @@ local sendCardEmotionAndLog = function(room, cardUseEvent)
|
||||||
Fk:filterCard(_card.id, room:getPlayerById(from), temp)
|
Fk:filterCard(_card.id, room:getPlayerById(from), temp)
|
||||||
card = temp.card
|
card = temp.card
|
||||||
end
|
end
|
||||||
|
cardUseEvent.card = card
|
||||||
|
|
||||||
playCardEmotionAndSound(room, room:getPlayerById(from), card)
|
playCardEmotionAndSound(room, room:getPlayerById(from), card)
|
||||||
room:doAnimate("Indicate", {
|
room:doAnimate("Indicate", {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
---@field public request_queue table<userdata, table>
|
---@field public request_queue table<userdata, table>
|
||||||
---@field public request_self table<integer, integer>
|
---@field public request_self table<integer, integer>
|
||||||
---@field public skill_costs table<string, any> @ 存放skill.cost_data用
|
---@field public skill_costs table<string, any> @ 存放skill.cost_data用
|
||||||
|
---@field public card_marks table<integer, any> @ 存放card.mark之用
|
||||||
local Room = class("Room")
|
local Room = class("Room")
|
||||||
|
|
||||||
-- load classes used by the game
|
-- load classes used by the game
|
||||||
|
@ -88,6 +89,8 @@ function Room:initialize(_room)
|
||||||
self.request_queue = {}
|
self.request_queue = {}
|
||||||
self.request_self = {}
|
self.request_self = {}
|
||||||
self.skill_costs = {}
|
self.skill_costs = {}
|
||||||
|
self.card_marks = {}
|
||||||
|
self.filtered_cards = {}
|
||||||
|
|
||||||
self.settings = json.decode(self.room:settings())
|
self.settings = json.decode(self.room:settings())
|
||||||
self.disabled_packs = self.settings.disabledPack
|
self.disabled_packs = self.settings.disabledPack
|
||||||
|
@ -465,11 +468,13 @@ end
|
||||||
---@param value integer @ 要设为的值,其实也可以设为字符串
|
---@param value integer @ 要设为的值,其实也可以设为字符串
|
||||||
function Room:setCardMark(card, mark, value)
|
function Room:setCardMark(card, mark, value)
|
||||||
card:setMark(mark, value)
|
card:setMark(mark, value)
|
||||||
self:doBroadcastNotify("SetCardMark", json.encode{
|
if not card:isVirtual() then
|
||||||
card.id,
|
self:doBroadcastNotify("SetCardMark", json.encode{
|
||||||
mark,
|
card.id,
|
||||||
value
|
mark,
|
||||||
})
|
value
|
||||||
|
})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- 将一张卡牌的mark标记增加count个。
|
--- 将一张卡牌的mark标记增加count个。
|
||||||
|
@ -1168,7 +1173,7 @@ function Room:askForCard(player, minNum, maxNum, includeEquip, skillName, cancel
|
||||||
if includeEquip then
|
if includeEquip then
|
||||||
table.insertTable(hands, player:getCardIds(Player.Equip))
|
table.insertTable(hands, player:getCardIds(Player.Equip))
|
||||||
end
|
end
|
||||||
for i = 1, minNum do
|
for _ = 1, minNum do
|
||||||
local randomId = hands[math.random(1, #hands)]
|
local randomId = hands[math.random(1, #hands)]
|
||||||
table.insert(chosenCards, randomId)
|
table.insert(chosenCards, randomId)
|
||||||
table.removeOne(hands, randomId)
|
table.removeOne(hands, randomId)
|
||||||
|
@ -1371,7 +1376,7 @@ end
|
||||||
---@param prompt string|null @ 观星框的标题(暂时雪藏)
|
---@param prompt string|null @ 观星框的标题(暂时雪藏)
|
||||||
---@param noPut boolean|null @ 是否进行放置牌操作
|
---@param noPut boolean|null @ 是否进行放置牌操作
|
||||||
---@param areaNames string[]|null @ 左侧提示信息
|
---@param areaNames string[]|null @ 左侧提示信息
|
||||||
---@return table<top|bottom, cardId[]>
|
---@return table<"top"|"bottom", integer[]>
|
||||||
function Room:askForGuanxing(player, cards, top_limit, bottom_limit, customNotify, noPut, areaNames)
|
function Room:askForGuanxing(player, cards, top_limit, bottom_limit, customNotify, noPut, areaNames)
|
||||||
-- 这一大堆都是来提前报错的
|
-- 这一大堆都是来提前报错的
|
||||||
top_limit = top_limit or Util.DummyTable
|
top_limit = top_limit or Util.DummyTable
|
||||||
|
@ -1441,10 +1446,10 @@ end
|
||||||
--- 询问玩家任意交换几堆牌堆。
|
--- 询问玩家任意交换几堆牌堆。
|
||||||
---
|
---
|
||||||
---@param player ServerPlayer @ 要询问的玩家
|
---@param player ServerPlayer @ 要询问的玩家
|
||||||
---@param piles table<cardIds, cardId[]> @ 卡牌id列表的列表,也就是……几堆牌堆的集合
|
---@param piles table<cardIds, integer[]> @ 卡牌id列表的列表,也就是……几堆牌堆的集合
|
||||||
---@param piles_name string[] @ 牌堆名,必须一一对应,否则统一替换为“牌堆X”
|
---@param piles_name string[] @ 牌堆名,必须一一对应,否则统一替换为“牌堆X”
|
||||||
---@param customNotify string|null @ 自定义读条操作提示
|
---@param customNotify string|null @ 自定义读条操作提示
|
||||||
---@return table<cardIds, cardId[]>
|
---@return table<cardIds, integer[]>
|
||||||
function Room:askForExchange(player, piles, piles_name, customNotify)
|
function Room:askForExchange(player, piles, piles_name, customNotify)
|
||||||
local command = "AskForExchange"
|
local command = "AskForExchange"
|
||||||
piles_name = piles_name or Util.DummyTable
|
piles_name = piles_name or Util.DummyTable
|
||||||
|
@ -1775,7 +1780,7 @@ end
|
||||||
---@param skillName string @ 技能名
|
---@param skillName string @ 技能名
|
||||||
---@param flag string|null @ 限定可移动的区域,值为nil(装备区和判定区)、‘e’或‘j’
|
---@param flag string|null @ 限定可移动的区域,值为nil(装备区和判定区)、‘e’或‘j’
|
||||||
---@param moveFrom ServerPlayer|null @ 是否只是目标1移动给目标2
|
---@param moveFrom ServerPlayer|null @ 是否只是目标1移动给目标2
|
||||||
---@return cardId
|
---@return integer
|
||||||
function Room:askForMoveCardInBoard(player, targetOne, targetTwo, skillName, flag, moveFrom)
|
function Room:askForMoveCardInBoard(player, targetOne, targetTwo, skillName, flag, moveFrom)
|
||||||
if flag then
|
if flag then
|
||||||
assert(flag == "e" or flag == "j")
|
assert(flag == "e" or flag == "j")
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
-- 为纯lua的测试环境捏一个虚拟的fk以便于测试
|
||||||
|
|
||||||
|
local fk = {}
|
||||||
|
|
||||||
|
local os, io = os, io
|
||||||
|
|
||||||
|
-- 这下Linux专用了
|
||||||
|
function fk.QmlBackend_ls(dir)
|
||||||
|
local f = io.popen("ls " .. dir)
|
||||||
|
return f:read("*a"):split("\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
function fk.QmlBackend_isDir(dir)
|
||||||
|
local f = io.popen("if [ -d " .. dir .. " ]; then echo OK; fi")
|
||||||
|
return f:read("*a"):startsWith("OK")
|
||||||
|
end
|
||||||
|
|
||||||
|
function fk.QmlBackend_exists(dir)
|
||||||
|
local f = io.popen("if [ -e " .. dir .. " ]; then echo OK; fi")
|
||||||
|
return f:read("*a"):startsWith("OK")
|
||||||
|
end
|
||||||
|
|
||||||
|
return fk
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
||||||
|
local exp1 = Exppattern:Parse("slash,jink")
|
||||||
|
local exp2 = Exppattern:Parse("peach,jink")
|
||||||
|
local exp3 = Exppattern:Parse(".|.|.|.|.|trick")
|
||||||
|
local exp4 = Exppattern:Parse("peach,ex_nihilo")
|
||||||
|
|
||||||
|
local slash = Fk:cloneCard("slash")
|
||||||
|
|
||||||
|
TestExppattern = {
|
||||||
|
testMatchExp = function()
|
||||||
|
assert(exp1:matchExp(exp2))
|
||||||
|
end,
|
||||||
|
|
||||||
|
testEasyMatchCard = function()
|
||||||
|
assert(exp1:match(slash))
|
||||||
|
assert(not exp2:match(slash))
|
||||||
|
end,
|
||||||
|
|
||||||
|
testMatchWithType = function()
|
||||||
|
assert(not exp3:matchExp(exp1))
|
||||||
|
assert(exp3:matchExp(exp4))
|
||||||
|
end,
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
-- Run tests with `lua5.4 test/lua/run.lua`
|
||||||
|
|
||||||
|
---@diagnostic disable: lowercase-global
|
||||||
|
|
||||||
|
package.path = package.path .. ";./test/lua/lib/?.lua"
|
||||||
|
|
||||||
|
lu = require('luaunit')
|
||||||
|
local os = os
|
||||||
|
fk = require('fk')
|
||||||
|
|
||||||
|
dofile 'lua/freekill.lua'
|
||||||
|
dofile 'test/lua/pattern.lua'
|
||||||
|
|
||||||
|
os.exit( lu.LuaUnit.run() )
|
Loading…
Reference in New Issue