FreeKill/packages/standard/aux_skills.lua

270 lines
8.7 KiB
Lua

-- SPDX-License-Identifier: GPL-3.0-or-later
local discardSkill = fk.CreateActiveSkill{
name = "discard_skill",
card_filter = function(self, to_select, selected)
if #selected >= self.num then
return false
end
if Fk:currentRoom():getCardArea(to_select) == Card.PlayerSpecial then
local pile = ""
for p, t in pairs(Self.special_cards) do
if table.contains(t, to_select) then
pile = p
break
end
end
if not string.find(self.pattern or "", pile) then return false end
end
local checkpoint = true
local card = Fk:getCardById(to_select)
local status_skills = Fk:currentRoom().status_skills[ProhibitSkill] or Util.DummyTable
for _, skill in ipairs(status_skills) do
if skill:prohibitDiscard(Self, card) then
return false
end
end
if Fk.currentResponseReason == "game_rule" then
status_skills = Fk:currentRoom().status_skills[MaxCardsSkill] or Util.DummyTable
for _, skill in ipairs(status_skills) do
if skill:excludeFrom(Self, card) then
return false
end
end
end
if not self.include_equip then
checkpoint = checkpoint and (Fk:currentRoom():getCardArea(to_select) ~= Player.Equip)
end
if self.pattern and self.pattern ~= "" then
checkpoint = checkpoint and (Exppattern:Parse(self.pattern):match(card))
end
return checkpoint
end,
min_card_num = function(self) return self.min_num end,
max_card_num = function(self) return self.num end,
}
local chooseCardsSkill = fk.CreateActiveSkill{
name = "choose_cards_skill",
card_filter = function(self, to_select, selected)
if #selected >= self.num then
return false
end
if Fk:currentRoom():getCardArea(to_select) == Card.PlayerSpecial then
if not string.find(self.pattern or "", self.expand_pile or "") then return false end
end
local checkpoint = true
local card = Fk:getCardById(to_select)
if not self.include_equip then
checkpoint = checkpoint and (Fk:currentRoom():getCardArea(to_select) ~= Player.Equip)
end
if self.pattern and self.pattern ~= "" then
checkpoint = checkpoint and (Exppattern:Parse(self.pattern):match(card))
end
return checkpoint
end,
min_card_num = function(self) return self.min_num end,
max_card_num = function(self) return self.num end,
}
local choosePlayersSkill = fk.CreateActiveSkill{
name = "choose_players_skill",
card_filter = function(self, to_select)
return self.pattern ~= "" and Exppattern:Parse(self.pattern):match(Fk:getCardById(to_select))
end,
target_filter = function(self, to_select, selected, cards)
if self.pattern ~= "" and #cards == 0 then return end
if #selected < self.num then
return table.contains(self.targets, to_select)
end
end,
card_num = function(self) return self.pattern ~= "" and 1 or 0 end,
min_target_num = function(self) return self.min_num end,
max_target_num = function(self) return self.num end,
}
local exChooseSkill = fk.CreateActiveSkill{
name = "ex__choose_skill",
card_filter = function(self, to_select, selected)
if #selected >= self.max_card_num then return false end
if Fk:currentRoom():getCardArea(to_select) == Card.PlayerSpecial then
if not string.find(self.pattern or "", self.expand_pile or "") then return false end
end
local checkpoint = true
local card = Fk:getCardById(to_select)
if not self.include_equip then
checkpoint = checkpoint and (Fk:currentRoom():getCardArea(to_select) ~= Player.Equip)
end
if self.pattern and self.pattern ~= "" then
checkpoint = checkpoint and (Exppattern:Parse(self.pattern):match(card))
end
return checkpoint
end,
target_filter = function(self, to_select, selected, cards)
if self.pattern ~= "" and #cards < self.min_card_num then return end
if #selected < self.max_target_num then
return table.contains(self.targets, to_select)
end
end,
min_target_num = function(self) return self.min_target_num end,
max_target_num = function(self) return self.max_target_num end,
min_card_num = function(self) return self.min_card_num end,
max_card_num = function(self) return self.max_card_num end,
}
local maxCardsSkill = fk.CreateMaxCardsSkill{
name = "max_cards_skill",
global = true,
correct_func = function(self, player)
return
player:getMark(MarkEnum.AddMaxCards) +
player:getMark(MarkEnum.AddMaxCardsInTurn) -
player:getMark(MarkEnum.MinusMaxCards) -
player:getMark(MarkEnum.MinusMaxCardsInTurn)
end,
}
local choosePlayersToMoveCardInBoardSkill = fk.CreateActiveSkill{
name = "choose_players_to_move_card_in_board",
target_num = 2,
card_filter = function(self, to_select)
return false
end,
target_filter = function(self, to_select, selected, cards)
local target = Fk:currentRoom():getPlayerById(to_select)
if #selected > 0 then
return Fk:currentRoom():getPlayerById(selected[1]):canMoveCardsInBoardTo(target, self.flag, self.excludeIds)
end
local fromAreas = { Player.Equip, Player.Judge }
if self.flag == "e" then
fromAreas = { Player.Equip }
elseif self.flag == "j" then
fromAreas = { Player.Judge }
end
return #table.filter(target:getCardIds(fromAreas), function(id)
return not table.contains((type(self.excludeIds) == "table" and self.excludeIds or {}), id)
end) > 0
end,
}
local uncompulsoryInvalidity = fk.CreateInvaliditySkill {
name = "uncompulsory_invalidity",
global = true,
invalidity_func = function(self, from, skill)
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)
)
end
}
local revealProhibited = fk.CreateInvaliditySkill {
name = "reveal_prohibited",
global = true,
invalidity_func = function(self, from, skill)
local generals = {}
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)
end
end
end
if #generals == 0 then return false end
if type(from._fake_skills) == "table" and not table.contains(from._fake_skills, skill) then return false end
local sname = skill.name
for _, g in ipairs(generals) do
if g == "m" then
if from.general ~= "anjiang" then return false end
else
if from.deputyGeneral ~= "anjiang" then return false end
end
local generalName = g == "m" and from:getMark("__heg_general") or from:getMark("__heg_deputy")
local general = Fk.generals[generalName]
if table.contains(general:getSkillNameList(), sname) then
return true
end
end
return false
end
}
-- 亮将
local revealSkill = fk.CreateActiveSkill{
name = "reveal_skill",
prompt = "#reveal_skill",
interaction = function(self)
local choiceList = {}
if (Self.general == "anjiang" and not Self:prohibitReveal()) then
local general = Fk.generals[Self:getMark("__heg_general")]
for _, sname in ipairs(general:getSkillNameList()) do
local s = Fk.skills[sname]
if s.frequency == Skill.Compulsory and s.relate_to_place ~= "m" then
table.insert(choiceList, "revealMain")
break
end
end
end
if (Self.deputyGeneral == "anjiang" and not Self:prohibitReveal(true)) then
local general = Fk.generals[Self:getMark("__heg_deputy")]
for _, sname in ipairs(general:getSkillNameList()) do
local s = Fk.skills[sname]
if s.frequency == Skill.Compulsory and s.relate_to_place ~= "d" then
table.insert(choiceList, "revealDeputy")
break
end
end
end
if #choiceList == 0 then return false end
return UI.ComboBox { choices = choiceList}
end,
target_num = 0,
card_num = 0,
card_filter = Util.FalseFunc,
on_use = function(self, room, effect)
local player = room:getPlayerById(effect.from)
local choice = self.interaction.data
if not choice then return false
elseif choice == "revealMain" then player:revealGeneral(false)
elseif choice == "revealDeputy" then player:revealGeneral(true) end
end,
}
AuxSkills = {
discardSkill,
chooseCardsSkill,
choosePlayersSkill,
exChooseSkill,
maxCardsSkill,
choosePlayersToMoveCardInBoardSkill,
uncompulsoryInvalidity,
revealProhibited,
revealSkill
}