Card limitation (#111)

禁止使用打出弃置
Fk.currentResponseReason
FilterSkill加player参数
This commit is contained in:
notify 2023-04-10 15:55:06 +08:00 committed by GitHub
parent 9a951fdbfe
commit 533cc1a464
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 140 additions and 36 deletions

View File

@ -22,6 +22,10 @@ function Client:initialize()
end
self.client.callback = function(_self, command, jsonData)
local cb = fk.client_callback[command]
Fk.currentResponsePattern = nil
Fk.currentResponseReason = nil
if (type(cb) == "function") then
cb(jsonData)
else
@ -525,9 +529,21 @@ fk.client_callback["AskForUseActiveSkill"] = function(jsonData)
for k, v in pairs(extra_data) do
skill[k] = v
end
Fk.currentResponseReason = extra_data.skillName
ClientInstance:notifyUI("AskForUseActiveSkill", jsonData)
end
fk.client_callback["AskForUseCard"] = function(jsonData)
Fk.currentResponsePattern = json.decode(jsonData)[2]
ClientInstance:notifyUI("AskForUseCard", jsonData)
end
fk.client_callback["AskForResponseCard"] = function(jsonData)
Fk.currentResponsePattern = json.decode(jsonData)[2]
ClientInstance:notifyUI("AskForResponseCard", jsonData)
end
fk.client_callback["SetPlayerMark"] = function(jsonData)
-- jsonData: [ int id, string mark, int value ]
local data = json.decode(jsonData)

View File

@ -166,7 +166,30 @@ function CanUseCard(card, player)
end
end
local ret = c.skill:canUse(ClientInstance:getPlayerById(player), c)
player = ClientInstance:getPlayerById(player)
local ret = c.skill:canUse(player, c)
if ret then
local status_skills = Fk:currentRoom().status_skills[ProhibitSkill] or {}
for _, skill in ipairs(status_skills) do
if skill:prohibitUse(player, c) then
ret = false
break
end
end
end
return json.encode(ret)
end
function CardProhibitedUse(cid)
local c = Fk:getCardById(cid)
local ret = false
local status_skills = Fk:currentRoom().status_skills[ProhibitSkill] or {}
for _, skill in ipairs(status_skills) do
if skill:prohibitUse(Self, c) then
ret = true
break
end
end
return json.encode(ret)
end
@ -377,6 +400,19 @@ function SkillFitPattern(skill_name, pattern)
return json.encode(ret)
end
function CardProhibitedResponse(cid)
local c = Fk:getCardById(cid)
local ret = false
local status_skills = Fk:currentRoom().status_skills[ProhibitSkill] or {}
for _, skill in ipairs(status_skills) do
if skill:prohibitResponse(Self, c) then
ret = true
break
end
end
return json.encode(ret)
end
function SkillCanResponse(skill_name)
local skill = Fk.skills[skill_name]
local ret = false

View File

@ -20,6 +20,8 @@
---@field public translations table<string, table<string, string>> @ 翻译表
---@field public game_modes table<string, GameMode> @ 所有游戏模式
---@field public disabled_packs string[] @ 禁用的拓展包列表
---@field public currentResponsePattern string
---@field public currentResponseReason string
local Engine = class("Engine")
--- Engine的构造函数。
@ -376,12 +378,8 @@ function Engine:filterCard(id, player, data)
return
end
local skills = player:getAllSkills()
local filters = {}
for _, s in ipairs(skills) do
if s:isInstanceOf(FilterSkill) then
table.insert(filters, s)
end
end
local filters = self:currentRoom().status_skills[FilterSkill]
if #filters == 0 then
filtered_cards[id] = nil
return
@ -394,8 +392,8 @@ function Engine:filterCard(id, player, data)
end
for _, f in ipairs(filters) do
if f:cardFilter(card) then
local _card = f:viewAs(card)
if f:cardFilter(card, player) then
local _card = f:viewAs(card, player)
_card.id = id
_card.skillName = f.name
if modify and RoomInstance then

View File

@ -4,13 +4,13 @@
local FilterSkill = StatusSkill:subclass("FilterSkill")
---@param card Card
function FilterSkill:cardFilter(card)
function FilterSkill:cardFilter(card, player)
return false
end
---@param card Card
---@return Card
function FilterSkill:viewAs(card)
function FilterSkill:viewAs(card, player)
return nil
end

View File

@ -309,8 +309,8 @@ function fk.CreateTargetModSkill(spec)
end
---@class FilterSpec: StatusSkillSpec
---@field public card_filter fun(self: FilterSkill, card: Card)
---@field public view_as fun(self: FilterSkill, card: Card)
---@field public card_filter fun(self: FilterSkill, card: Card, player: Player)
---@field public view_as fun(self: FilterSkill, card: Card, player: Player)
---@param spec FilterSpec
---@return FilterSkill

View File

@ -832,7 +832,10 @@ function Room:askForUseActiveSkill(player, skill_name, prompt, cancelable, extra
local command = "AskForUseActiveSkill"
self:notifyMoveFocus(player, extra_data.skillName or skill_name) -- for display skill name instead of command name
local data = {skill_name, prompt, cancelable, json.encode(extra_data)}
Fk.currentResponseReason = extra_data.skillName
local result = self:doRequest(player, command, json.encode(data))
Fk.currentResponseReason = nil
if result == "" then
return false
@ -869,35 +872,52 @@ end
---@param prompt string @ 提示信息
---@return integer[] @ 弃掉的牌的id列表可能是空的
function Room:askForDiscard(player, minNum, maxNum, includeEquip, skillName, cancelable, pattern, prompt)
cancelable = cancelable or false
pattern = pattern or ""
local canDiscards = table.filter(
player:getCardIds{ Player.Hand, includeEquip and Player.Equip or nil }, function(id)
local checkpoint = true
local card = Fk:getCardById(id)
local status_skills = Fk:currentRoom().status_skills[ProhibitSkill] or {}
for _, skill in ipairs(status_skills) do
if skill:prohibitDiscard(player, card) then
return false
end
end
if pattern ~= "" then
checkpoint = checkpoint and (Exppattern:Parse(pattern):match(card))
end
return checkpoint
end
)
maxNum = math.min(#canDiscards, maxNum)
minNum = math.min(#canDiscards, minNum)
if minNum < 1 then
return nil
end
cancelable = cancelable or false
pattern = pattern or ""
local toDiscard = {}
local data = {
num = maxNum,
min_num = minNum,
include_equip = includeEquip,
reason = skillName,
skillName = skillName,
pattern = pattern,
}
local prompt = prompt or ("#AskForDiscard:::" .. maxNum .. ":" .. minNum)
local _, ret = self:askForUseActiveSkill(player, "discard_skill", prompt, cancelable, data)
if ret then
toDiscard = ret.cards
else
if cancelable then return {} end
local hands = player:getCardIds(Player.Hand)
if includeEquip then
table.insertTable(hands, player:getCardIds(Player.Equip))
end
for i = 1, minNum do
local randomId = hands[math.random(1, #hands)]
table.insert(toDiscard, randomId)
table.removeOne(hands, randomId)
end
toDiscard = table.random(canDiscards, minNum)
end
self:throwCard(toDiscard, skillName, player, player)
@ -962,7 +982,7 @@ function Room:askForCard(player, minNum, maxNum, includeEquip, skillName, cancel
num = maxNum,
min_num = minNum,
include_equip = includeEquip,
reason = skillName,
skillName = skillName,
pattern = pattern,
expand_pile = expand_pile,
}
@ -1302,7 +1322,11 @@ function Room:askForUseCard(player, card_name, pattern, prompt, cancelable, extr
return askForUseCardData.result
else
local data = {card_name, pattern, prompt, cancelable, extra_data}
Fk.currentResponsePattern = pattern
local result = self:doRequest(player, command, json.encode(data))
Fk.currentResponsePattern = nil
if result ~= "" then
return self:handleUseCardReply(player, result)
end
@ -1338,7 +1362,11 @@ function Room:askForResponse(player, card_name, pattern, prompt, cancelable, ext
return eventData.result
else
local data = {card_name, pattern, prompt, cancelable, extra_data}
Fk.currentResponsePattern = pattern
local result = self:doRequest(player, command, json.encode(data))
Fk.currentResponsePattern = nil
if result ~= "" then
local use = self:handleUseCardReply(player, result)
if use then
@ -1375,7 +1403,11 @@ function Room:askForNullification(players, card_name, pattern, prompt, cancelabl
self:doBroadcastNotify("WaitForNullification", "")
local data = {card_name, pattern, prompt, cancelable, extra_data}
Fk.currentResponsePattern = pattern
local winner = self:doRaceRequest(command, players, json.encode(data))
Fk.currentResponsePattern = nil
if winner then
local result = winner.client_reply
return self:handleUseCardReply(winner, result)

View File

@ -8,12 +8,21 @@ local discardSkill = fk.CreateActiveSkill{
end
local checkpoint = true
local card = Fk:getCardById(to_select)
local status_skills = Fk:currentRoom().status_skills[ProhibitSkill] or {}
for _, skill in ipairs(status_skills) do
if skill:prohibitDiscard(Self, card) then
return false
end
end
if not self.include_equip then
checkpoint = checkpoint and (Fk:currentRoom():getCardArea(to_select) ~= Player.Equip)
end
if self.pattern ~= "" then
checkpoint = checkpoint and (Exppattern:Parse(self.pattern):match(Fk:getCardById(to_select)))
checkpoint = checkpoint and (Exppattern:Parse(self.pattern):match(card))
end
return checkpoint
end,

View File

@ -311,4 +311,6 @@ Fk:loadTranslationTable{
["discard_skill"] = "弃牌",
["choose_cards_skill"] = "选牌",
["choose_players_skill"] = "选择角色",
["game_rule"] = "弃牌阶段",
}

View File

@ -143,18 +143,32 @@ RowLayout {
// If cname is set, we are responding card.
function enableCards(cname) {
const cardValid = (cid, cname) => {
let ret = JSON.parse(Backend.callLuaFunction(
"CardFitPattern", [cid, cname]));
if (ret) {
if (roomScene.respond_play) {
ret = ret && !JSON.parse(Backend.callLuaFunction(
"CardProhibitedResponse", [cid]));
} else {
ret = ret && !JSON.parse(Backend.callLuaFunction(
"CardProhibitedUse", [cid]));
}
}
return ret;
}
if (cname) {
let ids = [], cards = handcardAreaItem.cards;
for (let i = 0; i < cards.length; i++) {
if (JSON.parse(Backend.callLuaFunction("CardFitPattern", [cards[i].cid, cname])))
if (cardValid(cards[i].cid, cname)) {
ids.push(cards[i].cid);
}
}
cards = selfPhoto.equipArea.getAllCards();
cards.forEach(c => {
if (JSON.parse(Backend.callLuaFunction(
"CardFitPattern",
[c.cid, cname]
))) {
if (cardValid(c.cid, cname)) {
ids.push(c.cid);
if (!expanded_piles["_equip"]) {
expandPile("_equip");
@ -169,10 +183,7 @@ RowLayout {
pile_list = pile_list.split(",");
for (let pile_name of pile_list) {
pile_data[pile_name] && pile_data[pile_name].forEach(cid => {
if (JSON.parse(Backend.callLuaFunction(
"CardFitPattern",
[cid, cname]
))) {
if (cardValid(cid, cname)) {
ids.push(cid);
if (!expanded_piles[pile_name]) {
expandPile(pile_name);