askForYiji (#318)
- 从Utility那里搬运了askForYiji和doYiji两个函数,负责分配 虽然暂时没实现单烧条,但先这么用着 - 修复了askForCardAndPlayers的选择中可以选择复数张牌的bug - 为prohibitDiscard添加了输入id选项
This commit is contained in:
parent
7779f06411
commit
6fbaf9d055
|
@ -205,8 +205,10 @@ Fk:loadTranslationTable({
|
||||||
["#AskForPeaches"] = "%src is dying, please use %arg Peach(es) to save him",
|
["#AskForPeaches"] = "%src is dying, please use %arg Peach(es) to save him",
|
||||||
["#AskForPeachesSelf"] = "You are dying, please use %arg Peach(es)/Alcohol to save yourself",
|
["#AskForPeachesSelf"] = "You are dying, please use %arg Peach(es)/Alcohol to save yourself",
|
||||||
|
|
||||||
["#AskForDiscard"] = "Please discard %arg cards (at least %arg2)",
|
["#AskForDiscard"] = "Please discard %arg cards (%arg2 at least)",
|
||||||
["#AskForCard"] = "Please choose %arg cards (at least %arg2)",
|
["#AskForCard"] = "Please choose %arg cards (%arg2 at least)",
|
||||||
|
["#AskForDistribution"] = "Please distribute cards (%arg at least , %arg2 total)",
|
||||||
|
["@DistributionTo"] = "",
|
||||||
["#askForPindian"] = "%arg: please choose a hand card for point fight",
|
["#askForPindian"] = "%arg: please choose a hand card for point fight",
|
||||||
["#StartPindianReason"] = "%from started point fight (%arg)",
|
["#StartPindianReason"] = "%from started point fight (%arg)",
|
||||||
["#ShowPindianCard"] = "The point fight card of %from is %card",
|
["#ShowPindianCard"] = "The point fight card of %from is %card",
|
||||||
|
|
|
@ -261,6 +261,8 @@ FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下
|
||||||
|
|
||||||
["#AskForDiscard"] = "请弃置 %arg 张牌,最少 %arg2 张",
|
["#AskForDiscard"] = "请弃置 %arg 张牌,最少 %arg2 张",
|
||||||
["#AskForCard"] = "请选择 %arg 张牌,最少 %arg2 张",
|
["#AskForCard"] = "请选择 %arg 张牌,最少 %arg2 张",
|
||||||
|
["#AskForDistribution"] = "请分配这些牌,至少 %arg 张,至多 %arg2 张",
|
||||||
|
["@DistributionTo"] = "",
|
||||||
["#askForPindian"] = "%arg:请选择一张手牌作为拼点牌",
|
["#askForPindian"] = "%arg:请选择一张手牌作为拼点牌",
|
||||||
["#StartPindianReason"] = "%from 由于 %arg 而发起拼点",
|
["#StartPindianReason"] = "%from 由于 %arg 而发起拼点",
|
||||||
["#ShowPindianCard"] = "%from 的拼点牌是 %card",
|
["#ShowPindianCard"] = "%from 的拼点牌是 %card",
|
||||||
|
|
|
@ -929,8 +929,12 @@ function Player:prohibitResponse(card)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- 确认玩家是否被禁止弃置特定牌。
|
--- 确认玩家是否被禁止弃置特定牌。
|
||||||
---@param card Card @ 特定的牌
|
---@param card Card|integer @ 特定的牌
|
||||||
function Player:prohibitDiscard(card)
|
function Player:prohibitDiscard(card)
|
||||||
|
if type(card) == "number" then
|
||||||
|
card = Fk:getCardById(card)
|
||||||
|
end
|
||||||
|
|
||||||
local status_skills = Fk:currentRoom().status_skills[ProhibitSkill] or Util.DummyTable
|
local status_skills = Fk:currentRoom().status_skills[ProhibitSkill] or Util.DummyTable
|
||||||
for _, skill in ipairs(status_skills) do
|
for _, skill in ipairs(status_skills) do
|
||||||
if skill:prohibitDiscard(self, card) then
|
if skill:prohibitDiscard(self, card) then
|
||||||
|
|
|
@ -208,8 +208,8 @@ function ActiveSkill:onEffect(room, cardEffectEvent) end
|
||||||
---@param cardEffectEvent CardEffectEvent | SkillEffectEvent
|
---@param cardEffectEvent CardEffectEvent | SkillEffectEvent
|
||||||
function ActiveSkill:onNullified(room, cardEffectEvent) end
|
function ActiveSkill:onNullified(room, cardEffectEvent) end
|
||||||
|
|
||||||
---@param selected integer[] @ ids of selected players
|
|
||||||
---@param selected_cards integer[] @ ids of selected cards
|
---@param selected_cards integer[] @ ids of selected cards
|
||||||
function ActiveSkill:prompt(selected, selected_cards) return "" end
|
---@param selected_targets integer[] @ ids of selected players
|
||||||
|
function ActiveSkill:prompt(selected_cards, selected_targets) return "" end
|
||||||
|
|
||||||
return ActiveSkill
|
return ActiveSkill
|
||||||
|
|
|
@ -43,8 +43,8 @@ function ViewAsSkill:beforeUse(player, cardUseStruct) end
|
||||||
---@param cardUseStruct CardUseStruct
|
---@param cardUseStruct CardUseStruct
|
||||||
function ViewAsSkill:afterUse(player, cardUseStruct) end
|
function ViewAsSkill:afterUse(player, cardUseStruct) end
|
||||||
|
|
||||||
---@param selected integer[] @ ids of selected players
|
|
||||||
---@param selected_cards integer[] @ ids of selected cards
|
---@param selected_cards integer[] @ ids of selected cards
|
||||||
function ViewAsSkill:prompt(selected, selected_cards) return "" end
|
---@param selected_targets integer[] @ ids of selected players
|
||||||
|
function ViewAsSkill:prompt(selected_cards, selected_targets) return "" end
|
||||||
|
|
||||||
return ViewAsSkill
|
return ViewAsSkill
|
||||||
|
|
|
@ -1366,6 +1366,94 @@ function Room:askForChooseCardsAndPlayers(player, minCardNum, maxCardNum, target
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- 询问将卡牌分配给任意角色。
|
||||||
|
---@param player ServerPlayer @ 要询问的玩家
|
||||||
|
---@param cards? integer[] @ 要分配的卡牌。默认拥有的所有牌
|
||||||
|
---@param targets? ServerPlayer[] @ 可以获得卡牌的角色。默认所有存活角色
|
||||||
|
---@param skillName? string @ 技能名,影响焦点信息。默认为“分配”
|
||||||
|
---@param minNum? integer @ 最少交出的卡牌数,默认0
|
||||||
|
---@param maxNum? integer @ 最多交出的卡牌数,默认所有牌
|
||||||
|
---@param prompt? string @ 询问提示信息
|
||||||
|
---@param expand_pile? string @ 可选私人牌堆名称,如要分配你武将牌上的牌请填写
|
||||||
|
---@param skipMove? boolean @ 是否跳过移动。默认不跳过
|
||||||
|
---@param single_max? integer|table @ 限制每人能获得的最大牌数。输入整数或(以角色id为键以整数为值)的表
|
||||||
|
---@return table<integer[]> @ 返回一个表,键为角色id,值为分配给其的牌id数组
|
||||||
|
function Room:askForYiji(player, cards, targets, skillName, minNum, maxNum, prompt, expand_pile, skipMove, single_max)
|
||||||
|
targets = targets or self.alive_players
|
||||||
|
cards = cards or player:getCardIds("he")
|
||||||
|
local _cards = table.simpleClone(cards)
|
||||||
|
targets = table.map(targets, Util.IdMapper)
|
||||||
|
self:sortPlayersByAction(targets)
|
||||||
|
skillName = skillName or "distribution_select_skill"
|
||||||
|
minNum = minNum or 0
|
||||||
|
maxNum = maxNum or #cards
|
||||||
|
local list = {}
|
||||||
|
for _, pid in ipairs(targets) do
|
||||||
|
list[pid] = {}
|
||||||
|
end
|
||||||
|
local toStr = function(int) return string.format("%d", int) end
|
||||||
|
local residueMap = {}
|
||||||
|
if type(single_max) == "table" then
|
||||||
|
for pid, v in pairs(single_max) do
|
||||||
|
residueMap[toStr(pid)] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local residue_sum = 0
|
||||||
|
local residue_num = type(single_max) == "number" and single_max or 9999
|
||||||
|
for _, pid in ipairs(targets) do
|
||||||
|
residueMap[toStr(pid)] = residueMap[toStr(pid)] or residue_num
|
||||||
|
residue_sum = residue_sum + residueMap[toStr(pid)]
|
||||||
|
end
|
||||||
|
minNum = math.min(minNum, #_cards, residue_sum)
|
||||||
|
local data = {
|
||||||
|
cards = _cards,
|
||||||
|
max_num = maxNum,
|
||||||
|
targets = targets,
|
||||||
|
residued_list = residueMap,
|
||||||
|
expand_pile = expand_pile
|
||||||
|
}
|
||||||
|
p(json.encode(residueMap))
|
||||||
|
|
||||||
|
while maxNum > 0 and #_cards > 0 do
|
||||||
|
data.max_num = maxNum
|
||||||
|
prompt = prompt or ("#AskForDistribution:::"..minNum..":"..maxNum)
|
||||||
|
local success, dat = self:askForUseActiveSkill(player, "distribution_select_skill", prompt, minNum == 0, data, true)
|
||||||
|
if success and dat then
|
||||||
|
local to = dat.targets[1]
|
||||||
|
local give_cards = dat.cards
|
||||||
|
for _, id in ipairs(give_cards) do
|
||||||
|
table.insert(list[to], id)
|
||||||
|
table.removeOne(_cards, id)
|
||||||
|
self:setCardMark(Fk:getCardById(id), "@DistributionTo", Fk:translate(self:getPlayerById(to).general))
|
||||||
|
end
|
||||||
|
minNum = math.max(0, minNum - #give_cards)
|
||||||
|
maxNum = maxNum - #give_cards
|
||||||
|
residueMap[toStr(to)] = residueMap[toStr(to)] - #give_cards
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, id in ipairs(cards) do
|
||||||
|
self:setCardMark(Fk:getCardById(id), "@DistributionTo", 0)
|
||||||
|
end
|
||||||
|
for _, pid in ipairs(targets) do
|
||||||
|
if minNum == 0 or #_cards == 0 then break end
|
||||||
|
local num = math.min(residueMap[toStr(pid)] or 0, minNum, #_cards)
|
||||||
|
if num > 0 then
|
||||||
|
for i = num, 1, -1 do
|
||||||
|
local c = table.remove(_cards, i)
|
||||||
|
table.insert(list[pid], c)
|
||||||
|
minNum = minNum - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not skipMove then
|
||||||
|
self:doYiji(self, list, player.id, skillName)
|
||||||
|
end
|
||||||
|
|
||||||
|
return list
|
||||||
|
end
|
||||||
--- 抽个武将
|
--- 抽个武将
|
||||||
---
|
---
|
||||||
--- 同getNCards,抽出来就没有了,所以记得放回去。
|
--- 同getNCards,抽出来就没有了,所以记得放回去。
|
||||||
|
@ -3009,6 +3097,65 @@ function Room:moveCardTo(card, to_place, target, reason, skill_name, special_nam
|
||||||
self:moveCards(table.unpack(movesSplitedByOwner))
|
self:moveCards(table.unpack(movesSplitedByOwner))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- 将一些卡牌同时分配给一些角色。
|
||||||
|
---@param room Room @ 房间
|
||||||
|
---@param list table<integer[]> @ 分配牌和角色的数据表,键为角色id,值为分配给其的牌id数组
|
||||||
|
---@param proposer? integer @ 操作者的id。默认为空
|
||||||
|
---@param skillName? string @ 技能名。默认为“分配”
|
||||||
|
---@return table<integer[]> @ 返回成功分配的卡牌
|
||||||
|
function Room:doYiji(room, list, proposer, skillName)
|
||||||
|
skillName = skillName or "distribution_skill"
|
||||||
|
local moveInfos = {}
|
||||||
|
local move_ids = {}
|
||||||
|
for to, cards in pairs(list) do
|
||||||
|
local toP = room:getPlayerById(to)
|
||||||
|
local handcards = toP:getCardIds("h")
|
||||||
|
cards = table.filter(cards, function (id) return not table.contains(handcards, id) end)
|
||||||
|
if #cards > 0 then
|
||||||
|
table.insertTable(move_ids, cards)
|
||||||
|
local moveMap = {}
|
||||||
|
local noFrom = {}
|
||||||
|
for _, id in ipairs(cards) do
|
||||||
|
local from = room.owner_map[id]
|
||||||
|
if from then
|
||||||
|
moveMap[from] = moveMap[from] or {}
|
||||||
|
table.insert(moveMap[from], id)
|
||||||
|
else
|
||||||
|
table.insert(noFrom, id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for from, _cards in pairs(moveMap) do
|
||||||
|
table.insert(moveInfos, {
|
||||||
|
ids = _cards,
|
||||||
|
moveInfo = table.map(_cards, function(id)
|
||||||
|
return {cardId = id, fromArea = room:getCardArea(id), fromSpecialName = room:getPlayerById(from):getPileNameOfId(id)}
|
||||||
|
end),
|
||||||
|
from = from,
|
||||||
|
to = to,
|
||||||
|
toArea = Card.PlayerHand,
|
||||||
|
moveReason = fk.ReasonGive,
|
||||||
|
proposer = proposer,
|
||||||
|
skillName = skillName,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
if #noFrom > 0 then
|
||||||
|
table.insert(moveInfos, {
|
||||||
|
ids = noFrom,
|
||||||
|
to = to,
|
||||||
|
toArea = Card.PlayerHand,
|
||||||
|
moveReason = fk.ReasonGive,
|
||||||
|
proposer = proposer,
|
||||||
|
skillName = skillName,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #moveInfos > 0 then
|
||||||
|
room:moveCards(table.unpack(moveInfos))
|
||||||
|
end
|
||||||
|
return move_ids
|
||||||
|
end
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
-- 其他游戏事件
|
-- 其他游戏事件
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
|
|
@ -78,8 +78,8 @@ local chooseCardsSkill = fk.CreateActiveSkill{
|
||||||
|
|
||||||
local choosePlayersSkill = fk.CreateActiveSkill{
|
local choosePlayersSkill = fk.CreateActiveSkill{
|
||||||
name = "choose_players_skill",
|
name = "choose_players_skill",
|
||||||
card_filter = function(self, to_select)
|
card_filter = function(self, to_select, selected)
|
||||||
return self.pattern ~= "" and Exppattern:Parse(self.pattern):match(Fk:getCardById(to_select))
|
return self.pattern ~= "" and Exppattern:Parse(self.pattern):match(Fk:getCardById(to_select)) and #selected == 0
|
||||||
end,
|
end,
|
||||||
target_filter = function(self, to_select, selected, cards)
|
target_filter = function(self, to_select, selected, cards)
|
||||||
if self.pattern ~= "" and #cards == 0 then return end
|
if self.pattern ~= "" and #cards == 0 then return end
|
||||||
|
@ -137,6 +137,21 @@ local maxCardsSkill = fk.CreateMaxCardsSkill{
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local distributionSelectSkill = fk.CreateActiveSkill{
|
||||||
|
name = "distribution_select_skill",
|
||||||
|
mute = true,
|
||||||
|
min_card_num = 1,
|
||||||
|
card_filter = function(self, to_select, selected)
|
||||||
|
return #selected < self.max_num and table.contains(self.cards, to_select)
|
||||||
|
end,
|
||||||
|
target_num = 1,
|
||||||
|
target_filter = function(self, to_select, selected, selected_cards)
|
||||||
|
return #selected == 0 and #selected_cards > 0 and table.contains(self.targets, to_select)
|
||||||
|
and #selected_cards <= (self.residued_list[string.format("%d", to_select)] or 0)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
local choosePlayersToMoveCardInBoardSkill = fk.CreateActiveSkill{
|
local choosePlayersToMoveCardInBoardSkill = fk.CreateActiveSkill{
|
||||||
name = "choose_players_to_move_card_in_board",
|
name = "choose_players_to_move_card_in_board",
|
||||||
target_num = 2,
|
target_num = 2,
|
||||||
|
@ -281,6 +296,7 @@ AuxSkills = {
|
||||||
chooseCardsSkill,
|
chooseCardsSkill,
|
||||||
choosePlayersSkill,
|
choosePlayersSkill,
|
||||||
exChooseSkill,
|
exChooseSkill,
|
||||||
|
distributionSelectSkill,
|
||||||
maxCardsSkill,
|
maxCardsSkill,
|
||||||
choosePlayersToMoveCardInBoardSkill,
|
choosePlayersToMoveCardInBoardSkill,
|
||||||
uncompulsoryInvalidity,
|
uncompulsoryInvalidity,
|
||||||
|
|
|
@ -192,6 +192,8 @@ Fk:loadTranslationTable({
|
||||||
["discard_skill"] = "Discard",
|
["discard_skill"] = "Discard",
|
||||||
["choose_cards_skill"] = "Choose card",
|
["choose_cards_skill"] = "Choose card",
|
||||||
["choose_players_skill"] = "Choose players",
|
["choose_players_skill"] = "Choose players",
|
||||||
|
["ex__choose_skill"] = "Choose",
|
||||||
|
["distribution_select_skill"] = "Distribute",
|
||||||
["choose_players_to_move_card_in_board"] = "Choose players",
|
["choose_players_to_move_card_in_board"] = "Choose players",
|
||||||
["reveal_skill"] = "Reveal",
|
["reveal_skill"] = "Reveal",
|
||||||
["#reveal_skill"] = "Choose a character to reveal",
|
["#reveal_skill"] = "Choose a character to reveal",
|
||||||
|
|
|
@ -519,6 +519,8 @@ Fk:loadTranslationTable{
|
||||||
["discard_skill"] = "弃牌",
|
["discard_skill"] = "弃牌",
|
||||||
["choose_cards_skill"] = "选牌",
|
["choose_cards_skill"] = "选牌",
|
||||||
["choose_players_skill"] = "选择角色",
|
["choose_players_skill"] = "选择角色",
|
||||||
|
["ex__choose_skill"] = "选择",
|
||||||
|
["distribution_select_skill"] = "分配",
|
||||||
["choose_players_to_move_card_in_board"] = "选择角色",
|
["choose_players_to_move_card_in_board"] = "选择角色",
|
||||||
["reveal_skill"] = "亮将",
|
["reveal_skill"] = "亮将",
|
||||||
["#reveal_skill"] = "选择一个武将亮将(点击左侧选择框展开)",
|
["#reveal_skill"] = "选择一个武将亮将(点击左侧选择框展开)",
|
||||||
|
|
|
@ -80,6 +80,7 @@ local control = fk.CreateActiveSkill{
|
||||||
-- ok = {10, 2},
|
-- ok = {10, 2},
|
||||||
-- })
|
-- })
|
||||||
-- room:swapSeat(from, to)
|
-- room:swapSeat(from, to)
|
||||||
|
-- p(room:askForYiji(from, from:getCardIds(Player.Hand), table.map(effect.tos, Util.Id2PlayerMapper), self.name, 2, 10, nil, false, nil, false, 3, true))
|
||||||
for _, pid in ipairs(effect.tos) do
|
for _, pid in ipairs(effect.tos) do
|
||||||
local to = room:getPlayerById(pid)
|
local to = room:getPlayerById(pid)
|
||||||
-- p(room:askForPoxi(from, "test", {
|
-- p(room:askForPoxi(from, "test", {
|
||||||
|
|
Loading…
Reference in New Issue