多后缀与bugFix (#321)
- 正式添加对多后缀标记的支持 - 添加了一点注释 - 搬运了moveCardIntoEquip和canMoveCardIntoEquip - 为选牌的默认prompt添加了目标 - 完善了朱雀羽扇的判定 - 修复了抽选武将牌堆时未删除已选武将的bug - 修复了maxCard标记不识别“-turn”以外标记的bug - 修复了obtaincard实际不能接受id数组的bug
This commit is contained in:
parent
6fbaf9d055
commit
380ca120e9
|
@ -1107,7 +1107,7 @@ callbacks["AskForCardChosen"] = (jsonData) => {
|
|||
const reason = data._reason;
|
||||
const prompt = data._prompt;
|
||||
if (prompt === "") {
|
||||
roomScene.promptText = luatr("#AskForChooseCard")
|
||||
roomScene.promptText = luatr(processPrompt("#AskForChooseCard:" + data._id))
|
||||
.arg(luatr(reason));
|
||||
} else {
|
||||
roomScene.setPrompt(processPrompt(prompt), true);
|
||||
|
@ -1139,7 +1139,7 @@ callbacks["AskForCardsChosen"] = (jsonData) => {
|
|||
const reason = data._reason;
|
||||
const prompt = data._prompt;
|
||||
if (prompt === "") {
|
||||
roomScene.promptText = luatr("#AskForChooseCards")
|
||||
roomScene.promptText = luatr(processPrompt("#AskForChooseCards:" + data._id))
|
||||
.arg(luatr(reason)).arg(min).arg(max);
|
||||
} else {
|
||||
roomScene.setPrompt(processPrompt(prompt), true);
|
||||
|
|
|
@ -378,6 +378,7 @@ fk.client_callback["AskForCardChosen"] = function(jsonData)
|
|||
judge = {}
|
||||
end
|
||||
ui_data = {
|
||||
_id = id,
|
||||
_reason = reason,
|
||||
card_data = {},
|
||||
_prompt = prompt,
|
||||
|
@ -413,6 +414,7 @@ fk.client_callback["AskForCardsChosen"] = function(jsonData)
|
|||
judge = {}
|
||||
end
|
||||
ui_data = {
|
||||
_id = id,
|
||||
_min = min,
|
||||
_max = max,
|
||||
_reason = reason,
|
||||
|
|
|
@ -185,12 +185,13 @@ Fk:loadTranslationTable({
|
|||
["AskForKingdom"] = "Choosing kingdom",
|
||||
["AskForPindian"] = "Point fight",
|
||||
["AskForMoveCardInBoard"] = "Moving cards",
|
||||
["replaceEquip"] = "Replacing Equip",
|
||||
["PlayCard"] = "Playing card",
|
||||
|
||||
["AskForCardChosen"] = "Choosing card",
|
||||
["AskForCardsChosen"] = "Choosing card",
|
||||
["#AskForChooseCard"] = "%1: please choose a card",
|
||||
["#AskForChooseCards"] = "%1: please choose %2~%3 cards",
|
||||
["#AskForChooseCard"] = "%1: please choose a card from %src",
|
||||
["#AskForChooseCards"] = "%1: please choose %2~%3 cards from %src",
|
||||
["$ChooseCard"] = "Choose a card",
|
||||
["$ChooseCards"] = "Choose %1~%2 cards",
|
||||
["$Hand"] = "Hand",
|
||||
|
@ -209,6 +210,7 @@ Fk:loadTranslationTable({
|
|||
["#AskForCard"] = "Please choose %arg cards (%arg2 at least)",
|
||||
["#AskForDistribution"] = "Please distribute cards (%arg at least , %arg2 total)",
|
||||
["@DistributionTo"] = "",
|
||||
["#replaceEquip"] = "Please Choose a Equip Card to be replaced",
|
||||
["#askForPindian"] = "%arg: please choose a hand card for point fight",
|
||||
["#StartPindianReason"] = "%from started point fight (%arg)",
|
||||
["#ShowPindianCard"] = "The point fight card of %from is %card",
|
||||
|
|
|
@ -239,12 +239,13 @@ FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下
|
|||
["AskForKingdom"] = "选择势力",
|
||||
["AskForPindian"] = "拼点",
|
||||
["AskForMoveCardInBoard"] = "移动卡牌",
|
||||
["replaceEquip"] = "替换装备",
|
||||
["PlayCard"] = "出牌",
|
||||
|
||||
["AskForCardChosen"] = "选牌",
|
||||
["AskForCardsChosen"] = "选牌",
|
||||
["#AskForChooseCard"] = "%1:请选择其一张卡牌",
|
||||
["#AskForChooseCards"] = "%1:请选择其%2至%3张卡牌",
|
||||
["#AskForChooseCard"] = "%1:请选择%src的一张卡牌",
|
||||
["#AskForChooseCards"] = "%1:请选择%src的%2至%3张卡牌",
|
||||
["$ChooseCard"] = "请选择一张卡牌",
|
||||
["$ChooseCards"] = "请选择%1至%2张卡牌",
|
||||
["$Hand"] = "手牌区",
|
||||
|
@ -263,6 +264,7 @@ FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下
|
|||
["#AskForCard"] = "请选择 %arg 张牌,最少 %arg2 张",
|
||||
["#AskForDistribution"] = "请分配这些牌,至少 %arg 张,至多 %arg2 张",
|
||||
["@DistributionTo"] = "",
|
||||
["#replaceEquip"] = "选择一张装备牌替换之",
|
||||
["#askForPindian"] = "%arg:请选择一张手牌作为拼点牌",
|
||||
["#StartPindianReason"] = "%from 由于 %arg 而发起拼点",
|
||||
["#ShowPindianCard"] = "%from 的拼点牌是 %card",
|
||||
|
|
|
@ -71,7 +71,7 @@ function General:__tostring()
|
|||
end
|
||||
|
||||
--- 为武将增加技能,需要注意增加其他武将技能时的处理方式。
|
||||
---@param skill Skill @ (单个)武将技能
|
||||
---@param skill Skill|string @ (单个)武将技能
|
||||
function General:addSkill(skill)
|
||||
if (type(skill) == "string") then
|
||||
table.insert(self.other_skills, skill)
|
||||
|
@ -82,7 +82,7 @@ function General:addSkill(skill)
|
|||
end
|
||||
|
||||
--- 为武将增加相关技能,需要注意增加其他武将技能时的处理方式。
|
||||
---@param skill Skill @ (单个)武将技能
|
||||
---@param skill Skill|string @ (单个)武将技能
|
||||
function General:addRelatedSkill(skill)
|
||||
if (type(skill) == "string") then
|
||||
table.insert(self.related_other_skills, skill)
|
||||
|
|
|
@ -475,9 +475,17 @@ end
|
|||
|
||||
--- 获取角色是否被移除。
|
||||
function Player:isRemoved()
|
||||
return self:getMark(MarkEnum.PlayerRemoved) ~= 0 or table.find(MarkEnum.TempMarkSuffix, function(s)
|
||||
return self:getMark(MarkEnum.PlayerRemoved .. s) ~= 0
|
||||
end)
|
||||
for mark, _ in pairs(self.mark) do
|
||||
if mark == MarkEnum.PlayerRemoved then return true end
|
||||
if mark:startsWith(MarkEnum.PlayerRemoved .. "-") then
|
||||
for _, suffix in ipairs(MarkEnum.TempMarkSuffix) do
|
||||
if mark:find(suffix, 1, true) then return true end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- return self:getMark(MarkEnum.PlayerRemoved) ~= 0 or table.find(MarkEnum.TempMarkSuffix, function(s)
|
||||
-- return self:getMark(MarkEnum.PlayerRemoved .. s) ~= 0
|
||||
-- end)
|
||||
end
|
||||
|
||||
--- 修改玩家与其他角色的固定距离。
|
||||
|
@ -950,13 +958,21 @@ function Player:prohibitReveal(isDeputy)
|
|||
if type(self:getMark(MarkEnum.RevealProhibited)) == "table" and table.contains(self:getMark(MarkEnum.RevealProhibited), place) then
|
||||
return true
|
||||
end
|
||||
for _, m in ipairs(table.map(MarkEnum.TempMarkSuffix, function(s)
|
||||
return self:getMark(MarkEnum.RevealProhibited .. s)
|
||||
end)) do
|
||||
if type(m) == "table" and table.contains(m, place) then
|
||||
return true
|
||||
|
||||
for mark, value in pairs(self.mark) do
|
||||
if mark:startsWith(MarkEnum.RevealProhibited .. "-") and type(value) == "table" then
|
||||
for _, suffix in ipairs(MarkEnum.TempMarkSuffix) do
|
||||
if mark:find(suffix, 1, true) then return true end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- for _, m in ipairs(table.map(MarkEnum.TempMarkSuffix, function(s)
|
||||
-- return self:getMark(MarkEnum.RevealProhibited .. s)
|
||||
-- end)) do
|
||||
-- if type(m) == "table" and table.contains(m, place) then
|
||||
-- return true
|
||||
-- end
|
||||
-- end
|
||||
return false
|
||||
end
|
||||
|
||||
|
@ -981,6 +997,21 @@ function Player:canPindian(to, ignoreFromKong, ignoreToKong)
|
|||
return true
|
||||
end
|
||||
|
||||
--- 判断一张牌能否移动至某角色的装备区
|
||||
---@param cardId integer @ 移动的牌
|
||||
---@param convert? boolean @ 是否可以替换装备(默认可以)
|
||||
---@return boolean
|
||||
function Player:canMoveCardIntoEquip(cardId, convert)
|
||||
convert = (convert == nil) and true or convert
|
||||
local card = Fk:getCardById(cardId)
|
||||
if not (card.sub_type >= 3 and card.sub_type <= 7) then return false end
|
||||
if self.dead or table.contains(self:getCardIds("e"), cardId) then return false end
|
||||
if self:hasEmptyEquipSlot(card.sub_type) or (#self:getEquipments(card.sub_type) > 0 and convert) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--转换技状态阳
|
||||
fk.SwitchYang = 0
|
||||
--转换技状态阴
|
||||
|
|
|
@ -155,21 +155,38 @@ function ActiveSkill:withinDistanceLimit(player, isattack, card, to)
|
|||
|
||||
local temp_suf = table.simpleClone(MarkEnum.TempMarkSuffix)
|
||||
local card_temp_suf = table.simpleClone(MarkEnum.CardTempMarkSuffix)
|
||||
table.insert(temp_suf, 1, "")
|
||||
table.insert(temp_suf, "-tmp")
|
||||
table.insert(card_temp_suf, 1, "")
|
||||
|
||||
---@param object Card|Player
|
||||
---@param markname string
|
||||
---@param suffixes string[]
|
||||
---@return boolean
|
||||
local function hasMark(object, markname, suffixes)
|
||||
if not object then return false end
|
||||
for mark, _ in pairs(object.mark) do
|
||||
if mark == markname then return true end
|
||||
if mark:startsWith(markname .. "-") then
|
||||
for _, suffix in ipairs(suffixes) do
|
||||
if mark:find(suffix, 1, true) then return true end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return (isattack and player:inMyAttackRange(to)) or
|
||||
(player:distanceTo(to) > 0 and player:distanceTo(to) <= self:getDistanceLimit(player, card, to)) or
|
||||
(card and table.find(card_temp_suf, function(s)
|
||||
return card:getMark(MarkEnum.BypassDistancesLimit .. s) ~= 0
|
||||
end)) or
|
||||
(table.find(temp_suf, function(s)
|
||||
return player:getMark(MarkEnum.BypassDistancesLimit .. s) ~= 0
|
||||
end)) or
|
||||
(to and (table.find(temp_suf, function(s)
|
||||
return to:getMark(MarkEnum.BypassDistancesLimitTo .. s) ~= 0
|
||||
end)))
|
||||
hasMark(card, MarkEnum.BypassDistancesLimit, card_temp_suf) or
|
||||
hasMark(player, MarkEnum.BypassDistancesLimit, temp_suf) or
|
||||
hasMark(to, MarkEnum.BypassDistancesLimitTo, temp_suf)
|
||||
-- (card and table.find(card_temp_suf, function(s)
|
||||
-- return card:getMark(MarkEnum.BypassDistancesLimit .. s) ~= 0
|
||||
-- end)) or
|
||||
-- (table.find(temp_suf, function(s)
|
||||
-- return player:getMark(MarkEnum.BypassDistancesLimit .. s) ~= 0
|
||||
-- end)) or
|
||||
-- (to and (table.find(temp_suf, function(s)
|
||||
-- return to:getMark(MarkEnum.BypassDistancesLimitTo .. s) ~= 0
|
||||
-- end)))
|
||||
end
|
||||
|
||||
--- Determine if selected cards and targets are valid for this skill
|
||||
|
|
|
@ -40,20 +40,37 @@ function UsableSkill:withinTimesLimit(player, scope, card, card_name, to)
|
|||
card_name = card_name or card.trueName
|
||||
local temp_suf = table.simpleClone(MarkEnum.TempMarkSuffix)
|
||||
local card_temp_suf = table.simpleClone(MarkEnum.CardTempMarkSuffix)
|
||||
table.insert(temp_suf, 1, "")
|
||||
table.insert(temp_suf, "-tmp")
|
||||
table.insert(card_temp_suf, 1, "")
|
||||
|
||||
---@param object Card|Player
|
||||
---@param markname string
|
||||
---@param suffixes string[]
|
||||
---@return boolean
|
||||
local function hasMark(object, markname, suffixes)
|
||||
if not object then return false end
|
||||
for mark, _ in pairs(object.mark) do
|
||||
if mark == markname then return true end
|
||||
if mark:startsWith(markname .. "-") then
|
||||
for _, suffix in ipairs(suffixes) do
|
||||
if mark:find(suffix, 1, true) then return true end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return player:usedCardTimes(card_name, scope) < self:getMaxUseTime(player, scope, card, to) or
|
||||
(card and table.find(card_temp_suf, function(s)
|
||||
return card:getMark(MarkEnum.BypassTimesLimit .. s) ~= 0
|
||||
end)) or
|
||||
(table.find(temp_suf, function(s)
|
||||
return player:getMark(MarkEnum.BypassTimesLimit .. s) ~= 0
|
||||
end)) or
|
||||
(to and (table.find(temp_suf, function(s)
|
||||
return to:getMark(MarkEnum.BypassTimesLimitTo .. s) ~= 0
|
||||
end)))
|
||||
hasMark(card, MarkEnum.BypassTimesLimit, card_temp_suf) or
|
||||
hasMark(player, MarkEnum.BypassTimesLimit, temp_suf) or
|
||||
hasMark(to, MarkEnum.BypassTimesLimitTo, temp_suf)
|
||||
-- (card and table.find(card_temp_suf, function(s)
|
||||
-- return card:getMark(MarkEnum.BypassTimesLimit .. s) ~= 0
|
||||
-- end)) or
|
||||
-- (table.find(temp_suf, function(s)
|
||||
-- return player:getMark(MarkEnum.BypassTimesLimit .. s) ~= 0
|
||||
-- end)) or
|
||||
-- (to and (table.find(temp_suf, function(s)
|
||||
-- return to:getMark(MarkEnum.BypassTimesLimitTo .. s) ~= 0
|
||||
-- end)))
|
||||
end
|
||||
|
||||
return UsableSkill
|
||||
|
|
|
@ -114,6 +114,73 @@ function fk.sorted_pairs(t, val_func, reverse)
|
|||
return iter, nil, 1
|
||||
end
|
||||
|
||||
-- frequenly used filter & map functions
|
||||
|
||||
--- 返回ID
|
||||
Util.IdMapper = function(e) return e.id end
|
||||
--- 根据卡牌ID返回卡牌
|
||||
Util.Id2CardMapper = function(id) return Fk:getCardById(id) end
|
||||
--- 根据玩家ID返回玩家
|
||||
Util.Id2PlayerMapper = function(id)
|
||||
return Fk:currentRoom():getPlayerById(id)
|
||||
end
|
||||
--- 返回武将名
|
||||
Util.NameMapper = function(e) return e.name end
|
||||
--- 根据武将名返回武将
|
||||
Util.Name2GeneralMapper = function(e) return Fk.generals[e] end
|
||||
--- 根据技能名返回技能
|
||||
Util.Name2SkillMapper = function(e) return Fk.skills[e] end
|
||||
--- 返回译文
|
||||
Util.TranslateMapper = function(str) return Fk:translate(str) end
|
||||
|
||||
-- for card preset
|
||||
|
||||
--- 全局卡牌(包括自己)的canUse
|
||||
Util.GlobalCanUse = function(self, player, card)
|
||||
local room = Fk:currentRoom()
|
||||
for _, p in ipairs(room.alive_players) do
|
||||
if not (card and player:isProhibited(p, card)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- AOE卡牌(不包括自己)的canUse
|
||||
Util.AoeCanUse = function(self, player, card)
|
||||
local room = Fk:currentRoom()
|
||||
for _, p in ipairs(room.alive_players) do
|
||||
if p ~= player and not (card and player:isProhibited(p, card)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- 全局卡牌(包括自己)的onUse
|
||||
Util.GlobalOnUse = function(self, room, cardUseEvent)
|
||||
if not cardUseEvent.tos or #TargetGroup:getRealTargets(cardUseEvent.tos) == 0 then
|
||||
cardUseEvent.tos = {}
|
||||
for _, player in ipairs(room:getAlivePlayers()) do
|
||||
if not room:getPlayerById(cardUseEvent.from):isProhibited(player, cardUseEvent.card) then
|
||||
TargetGroup:pushTargets(cardUseEvent.tos, player.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- AOE卡牌(不包括自己)的onUse
|
||||
Util.AoeOnUse = function(self, room, cardUseEvent)
|
||||
if not cardUseEvent.tos or #TargetGroup:getRealTargets(cardUseEvent.tos) == 0 then
|
||||
cardUseEvent.tos = {}
|
||||
for _, player in ipairs(room:getOtherPlayers(room:getPlayerById(cardUseEvent.from))) do
|
||||
if not room:getPlayerById(cardUseEvent.from):isProhibited(player, cardUseEvent.card) then
|
||||
TargetGroup:pushTargets(cardUseEvent.tos, player.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Table
|
||||
|
||||
---@param func fun(element, index, array)
|
||||
function table:forEach(func)
|
||||
for i, v in ipairs(self) do
|
||||
|
@ -164,66 +231,6 @@ function table:map(func)
|
|||
return ret
|
||||
end
|
||||
|
||||
-- frequenly used filter & map functions
|
||||
|
||||
--- 返回ID
|
||||
Util.IdMapper = function(e) return e.id end
|
||||
--- 根据卡牌ID返回卡牌
|
||||
Util.Id2CardMapper = function(id) return Fk:getCardById(id) end
|
||||
--- 根据玩家ID返回玩家
|
||||
Util.Id2PlayerMapper = function(id)
|
||||
return Fk:currentRoom():getPlayerById(id)
|
||||
end
|
||||
--- 返回武将名
|
||||
Util.NameMapper = function(e) return e.name end
|
||||
--- 根据武将名返回武将
|
||||
Util.Name2GeneralMapper = function(e) return Fk.generals[e] end
|
||||
--- 根据技能名返回技能
|
||||
Util.Name2SkillMapper = function(e) return Fk.skills[e] end
|
||||
--- 返回译文
|
||||
Util.TranslateMapper = function(str) return Fk:translate(str) end
|
||||
|
||||
-- for card preset
|
||||
Util.GlobalCanUse = function(self, player, card)
|
||||
local room = Fk:currentRoom()
|
||||
for _, p in ipairs(room.alive_players) do
|
||||
if not (card and player:isProhibited(p, card)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Util.AoeCanUse = function(self, player, card)
|
||||
local room = Fk:currentRoom()
|
||||
for _, p in ipairs(room.alive_players) do
|
||||
if p ~= player and not (card and player:isProhibited(p, card)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Util.GlobalOnUse = function(self, room, cardUseEvent)
|
||||
if not cardUseEvent.tos or #TargetGroup:getRealTargets(cardUseEvent.tos) == 0 then
|
||||
cardUseEvent.tos = {}
|
||||
for _, player in ipairs(room:getAlivePlayers()) do
|
||||
if not room:getPlayerById(cardUseEvent.from):isProhibited(player, cardUseEvent.card) then
|
||||
TargetGroup:pushTargets(cardUseEvent.tos, player.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Util.AoeOnUse = function(self, room, cardUseEvent)
|
||||
if not cardUseEvent.tos or #TargetGroup:getRealTargets(cardUseEvent.tos) == 0 then
|
||||
cardUseEvent.tos = {}
|
||||
for _, player in ipairs(room:getOtherPlayers(room:getPlayerById(cardUseEvent.from))) do
|
||||
if not room:getPlayerById(cardUseEvent.from):isProhibited(player, cardUseEvent.card) then
|
||||
TargetGroup:pushTargets(cardUseEvent.tos, player.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@generic T
|
||||
---@param self T[]
|
||||
---@return T[]
|
||||
|
|
|
@ -174,7 +174,7 @@ GameEvent.cleaners[GameEvent.Round] = function(self)
|
|||
p:setCardUseHistory("", 0, Player.HistoryRound)
|
||||
p:setSkillUseHistory("", 0, Player.HistoryRound)
|
||||
for name, _ in pairs(p.mark) do
|
||||
if name:endsWith("-round") then
|
||||
if name:find("-round", 1, true) then
|
||||
room:setPlayerMark(p, name, 0)
|
||||
end
|
||||
end
|
||||
|
@ -182,7 +182,7 @@ GameEvent.cleaners[GameEvent.Round] = function(self)
|
|||
|
||||
for cid, cmark in pairs(room.card_marks) do
|
||||
for name, _ in pairs(cmark) do
|
||||
if name:endsWith("-round") then
|
||||
if name:find("-round", 1, true) then
|
||||
room:setCardMark(Fk:getCardById(cid), name, 0)
|
||||
end
|
||||
end
|
||||
|
@ -249,7 +249,7 @@ GameEvent.cleaners[GameEvent.Turn] = function(self)
|
|||
p:setCardUseHistory("", 0, Player.HistoryTurn)
|
||||
p:setSkillUseHistory("", 0, Player.HistoryTurn)
|
||||
for name, _ in pairs(p.mark) do
|
||||
if name:endsWith("-turn") then
|
||||
if name:find("-turn", 1, true) then
|
||||
room:setPlayerMark(p, name, 0)
|
||||
end
|
||||
end
|
||||
|
@ -257,7 +257,7 @@ GameEvent.cleaners[GameEvent.Turn] = function(self)
|
|||
|
||||
for cid, cmark in pairs(room.card_marks) do
|
||||
for name, _ in pairs(cmark) do
|
||||
if name:endsWith("-turn") then
|
||||
if name:find("-turn", 1, true) then
|
||||
room:setCardMark(Fk:getCardById(cid), name, 0)
|
||||
end
|
||||
end
|
||||
|
@ -372,7 +372,7 @@ GameEvent.cleaners[GameEvent.Phase] = function(self)
|
|||
p:setCardUseHistory("", 0, Player.HistoryPhase)
|
||||
p:setSkillUseHistory("", 0, Player.HistoryPhase)
|
||||
for name, _ in pairs(p.mark) do
|
||||
if name:endsWith("-phase") then
|
||||
if name:find("-phase", 1, true) then
|
||||
room:setPlayerMark(p, name, 0)
|
||||
end
|
||||
end
|
||||
|
@ -380,7 +380,7 @@ GameEvent.cleaners[GameEvent.Phase] = function(self)
|
|||
|
||||
for cid, cmark in pairs(room.card_marks) do
|
||||
for name, _ in pairs(cmark) do
|
||||
if name:endsWith("-phase") then
|
||||
if name:find("-phase", 1, true) then
|
||||
room:setCardMark(Fk:getCardById(cid), name, 0)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -166,7 +166,7 @@ GameEvent.functions[GameEvent.MoveCards] = function(self)
|
|||
|
||||
local currentCard = Fk:getCardById(info.cardId)
|
||||
for name, _ in pairs(currentCard.mark) do
|
||||
if name:endsWith("-inhand") and
|
||||
if name:find("-inhand", 1, true) and
|
||||
realFromArea == Player.Hand and
|
||||
data.from
|
||||
then
|
||||
|
|
|
@ -1501,6 +1501,7 @@ end
|
|||
---@param name string @ 武将name,如找不到则查找truename,再找不到则返回nil
|
||||
---@return string? @ 抽出的武将名
|
||||
function Room:findGeneral(name)
|
||||
if not Fk.generals[name] then return nil end
|
||||
for i, g in ipairs(self.general_pile) do
|
||||
if g == name or Fk.generals[g].trueName == Fk.generals[name].trueName then
|
||||
return table.remove(self.general_pile, i)
|
||||
|
@ -1517,13 +1518,13 @@ function Room:findGenerals(func, n)
|
|||
n = n or 1
|
||||
local ret = {}
|
||||
local index = 1
|
||||
repeat
|
||||
while #ret < n and index <= #self.general_pile do
|
||||
if func(self.general_pile[index]) then
|
||||
table.insert(ret, table.remove(self.general_pile, index))
|
||||
else
|
||||
index = index + 1
|
||||
end
|
||||
until index >= #self.general_pile or #ret >= n
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
|
@ -2993,8 +2994,10 @@ end
|
|||
---@param proposer? integer @ 移动操作者的id
|
||||
function Room:obtainCard(player, cid, unhide, reason, proposer)
|
||||
if type(cid) ~= "number" then
|
||||
assert(cid and cid:isInstanceOf(Card))
|
||||
cid = cid:isVirtual() and cid.subcards or {cid.id}
|
||||
assert(cid and type(cid) == "table")
|
||||
if cid:isInstanceOf(Card) then
|
||||
cid = cid:isVirtual() and cid.subcards or {cid.id}
|
||||
end
|
||||
else
|
||||
cid = {cid}
|
||||
end
|
||||
|
@ -3156,6 +3159,37 @@ function Room:doYiji(room, list, proposer, skillName)
|
|||
return move_ids
|
||||
end
|
||||
|
||||
--- 将一张牌移动至某角色的装备区,若不合法则置入弃牌堆。目前没做相同副类别装备同时置入的适配(甘露神典韦)
|
||||
---@param target ServerPlayer @ 接受牌的角色
|
||||
---@param cards integer|integer[] @ 移动的牌
|
||||
---@param skillName? string @ 技能名
|
||||
---@param convert? boolean @ 是否可以替换装备(默认可以)
|
||||
---@param proposer? ServerPlayer @ 操作者
|
||||
function Room:moveCardIntoEquip(target, cards, skillName, convert, proposer)
|
||||
convert = (convert == nil) and true or convert
|
||||
skillName = skillName or ""
|
||||
cards = type(cards) == "table" and cards or {cards}
|
||||
local moves = {}
|
||||
for _, cardId in ipairs(cards) do
|
||||
local card = Fk:getCardById(cardId)
|
||||
local fromId = self.owner_map[cardId]
|
||||
local proposerId = proposer and proposer.id or nil
|
||||
if target:canMoveCardIntoEquip(cardId, convert) then
|
||||
if target:hasEmptyEquipSlot(card.sub_type) then
|
||||
table.insert(moves,{ids = {cardId}, from = fromId, to = target.id, toArea = Card.PlayerEquip, moveReason = fk.ReasonPut,skillName = skillName,proposer = proposerId})
|
||||
else
|
||||
local existingEquip = target:getEquipments(card.sub_type)
|
||||
local throw = #existingEquip == 1 and existingEquip[1] or
|
||||
self:askForCardChosen(proposer or target, target, {card_data = { {Util.convertSubtypeAndEquipSlot(card.sub_type),existingEquip} } }, "replaceEquip","#replaceEquip")
|
||||
table.insert(moves,{ids = {throw}, from = target.id, toArea = Card.DiscardPile, moveReason = fk.ReasonPutIntoDiscardPile, skillName = skillName,proposer = proposerId})
|
||||
table.insert(moves,{ids = {cardId}, from = fromId, to = target.id, toArea = Card.PlayerEquip, moveReason = fk.ReasonPut,skillName = skillName,proposer = proposerId})
|
||||
end
|
||||
else
|
||||
table.insert(moves,{ids = {cardId}, from = fromId, toArea = Card.DiscardPile, moveReason = fk.ReasonPutIntoDiscardPile,skillName = skillName})
|
||||
end
|
||||
end
|
||||
self:moveCards(table.unpack(moves))
|
||||
end
|
||||
------------------------------------------------------------------------
|
||||
-- 其他游戏事件
|
||||
------------------------------------------------------------------------
|
||||
|
|
|
@ -366,9 +366,12 @@ local fanSkill = fk.CreateTriggerSkill{
|
|||
card[k] = v
|
||||
end
|
||||
end
|
||||
if not data.card:isVirtual() then
|
||||
if data.card:isVirtual() then
|
||||
card.subcards = data.card.subcards
|
||||
else
|
||||
card.id = data.card.id
|
||||
end
|
||||
card.skillNames = data.card.skillNames
|
||||
card.skillName = "fan"
|
||||
data.card = card
|
||||
end,
|
||||
|
|
|
@ -129,11 +129,25 @@ local maxCardsSkill = fk.CreateMaxCardsSkill{
|
|||
name = "max_cards_skill",
|
||||
global = true,
|
||||
correct_func = function(self, player)
|
||||
local function getMark(markname)
|
||||
local v = 0
|
||||
for mark, value in pairs(player.mark) do
|
||||
if mark == markname then
|
||||
v = v + value
|
||||
elseif mark:startsWith(markname .. "-") then
|
||||
for _, suffix in ipairs(MarkEnum.TempMarkSuffix) do
|
||||
if mark:find(suffix, 1, true) then
|
||||
v = v + value
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return v
|
||||
end
|
||||
return
|
||||
player:getMark(MarkEnum.AddMaxCards) +
|
||||
player:getMark(MarkEnum.AddMaxCardsInTurn) -
|
||||
player:getMark(MarkEnum.MinusMaxCards) -
|
||||
player:getMark(MarkEnum.MinusMaxCardsInTurn)
|
||||
getMark(MarkEnum.AddMaxCards) -
|
||||
getMark(MarkEnum.MinusMaxCards)
|
||||
end,
|
||||
}
|
||||
|
||||
|
@ -181,15 +195,32 @@ local uncompulsoryInvalidity = fk.CreateInvaliditySkill {
|
|||
name = "uncompulsory_invalidity",
|
||||
global = true,
|
||||
invalidity_func = function(self, from, skill)
|
||||
---@param object Card|Player
|
||||
---@param markname string
|
||||
---@param suffixes string[]
|
||||
---@return boolean
|
||||
local function hasMark(object, markname, suffixes)
|
||||
if not object then return false end
|
||||
for mark, _ in pairs(object.mark) do
|
||||
if mark == markname then return true end
|
||||
if mark:startsWith(markname .. "-") then
|
||||
for _, suffix in ipairs(suffixes) do
|
||||
if mark:find(suffix, 1, true) then return true end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
return
|
||||
(skill.frequency ~= Skill.Compulsory and skill.frequency ~= Skill.Wake) and
|
||||
not (skill:isEquipmentSkill() or skill.name:endsWith("&")) and
|
||||
(
|
||||
from:getMark(MarkEnum.UncompulsoryInvalidity) ~= 0 or
|
||||
table.find(MarkEnum.TempMarkSuffix, function(s)
|
||||
return from:getMark(MarkEnum.UncompulsoryInvalidity .. s) ~= 0
|
||||
end)
|
||||
)
|
||||
hasMark(from, MarkEnum.UncompulsoryInvalidity, MarkEnum.TempMarkSuffix)
|
||||
-- (
|
||||
-- from:getMark(MarkEnum.UncompulsoryInvalidity) ~= 0 or
|
||||
-- table.find(MarkEnum.TempMarkSuffix, function(s)
|
||||
-- return from:getMark(MarkEnum.UncompulsoryInvalidity .. s) ~= 0
|
||||
-- end)
|
||||
-- )
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -201,15 +232,27 @@ local revealProhibited = fk.CreateInvaliditySkill {
|
|||
if type(from:getMark(MarkEnum.RevealProhibited)) == "table" then
|
||||
generals = from:getMark(MarkEnum.RevealProhibited)
|
||||
end
|
||||
for _, m in ipairs(table.map(MarkEnum.TempMarkSuffix, function(s)
|
||||
return from:getMark(MarkEnum.RevealProhibited .. s)
|
||||
end)) do
|
||||
if type(m) == "table" then
|
||||
for _, g in ipairs(m) do
|
||||
table.insertIfNeed(generals, g)
|
||||
|
||||
for mark, value in pairs(from.mark) do
|
||||
if mark:startsWith(MarkEnum.RevealProhibited .. "-") and type(value) == "table" then
|
||||
for _, suffix in ipairs(MarkEnum.TempMarkSuffix) do
|
||||
if mark:find(suffix, 1, true) then
|
||||
for _, g in ipairs(value) do
|
||||
table.insertIfNeed(generals, g)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- for _, m in ipairs(table.map(MarkEnum.TempMarkSuffix, function(s)
|
||||
-- return from:getMark(MarkEnum.RevealProhibited .. s)
|
||||
-- end)) do
|
||||
-- if type(m) == "table" then
|
||||
-- for _, g in ipairs(m) do
|
||||
-- table.insertIfNeed(generals, g)
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
if #generals == 0 then return false end
|
||||
local sname = skill.name
|
||||
|
|
|
@ -1132,9 +1132,17 @@ local role_getlogic = function()
|
|||
lord_general = lord_generals
|
||||
lord_generals = {lord_general}
|
||||
end
|
||||
|
||||
generals = table.filter(generals, function(g) return not table.contains(lord_generals, g) end)
|
||||
room:returnToGeneralPile(generals)
|
||||
local index = 1
|
||||
while index <= #room.general_pile do
|
||||
local ret = {}
|
||||
for _, gname in ipairs(lord_generals) do
|
||||
if room.general_pile[index] == gname or Fk.generals[room.general_pile[index]].trueName == Fk.generals[gname].trueName then
|
||||
table.insert(ret, table.remove(room.general_pile, index))
|
||||
end
|
||||
end
|
||||
if #ret == 0 then index = index + 1 end
|
||||
end
|
||||
|
||||
room:setPlayerGeneral(lord, lord_general, true)
|
||||
room:askForChooseKingdom({lord})
|
||||
|
@ -1216,14 +1224,24 @@ local role_getlogic = function()
|
|||
room:setPlayerGeneral(p, general, true, true)
|
||||
room:setDeputyGeneral(p, deputy)
|
||||
else
|
||||
table.insertTableIfNeed(selected, p.default_reply)
|
||||
room:setPlayerGeneral(p, p.default_reply[1], true, true)
|
||||
room:setDeputyGeneral(p, p.default_reply[2])
|
||||
end
|
||||
p.default_reply = ""
|
||||
end
|
||||
|
||||
generals = table.filter(generals, function(g) return not table.contains(selected, g) end)
|
||||
room:returnToGeneralPile(generals)
|
||||
local index = 1
|
||||
while index <= #room.general_pile do
|
||||
local ret = {}
|
||||
for _, gname in ipairs(selected) do
|
||||
if room.general_pile[index] == gname or Fk.generals[room.general_pile[index]].trueName == Fk.generals[gname].trueName then
|
||||
table.insert(ret, table.remove(room.general_pile, index))
|
||||
end
|
||||
end
|
||||
if #ret == 0 then index = index + 1 end
|
||||
end
|
||||
|
||||
room:askForChooseKingdom(nonlord)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue