Enhancement (#292)

1. 卡牌一览中音效播放(装备牌鸽)
2. 修改游戏桌面菜单式样,增加音量
3. 卡牌使用时prompt
4. 比较角色性别是否相同
5. 修一些函数提示
6. getEventsOfScope找不到start_event直接返回
7. 应用all_card_types
8. 修改askForCard的默认返回值
9. 增加装备牌技能触发log
10. phase_state初始化
11. 额外阶段走phaseChanging
12. 亮将增加一个时机并做调整(但还是不对……)
13. 标准包和军争篇增加卡牌prompt,修改描述
14. 运用一些Util,hasSkill精简
15. 修改一些神秘英语单词,水

---------

Signed-off-by: Mechanel <nyutanislavsky@qq.com>
This commit is contained in:
Nyutanislavsky 2023-12-09 21:57:47 +08:00 committed by GitHub
parent 8df1985b99
commit 5abbdc9b23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 666 additions and 324 deletions

View File

@ -226,8 +226,9 @@ Item {
} }
detailCard.known = true; detailCard.known = true;
cardText.clear(); cardText.clear();
audioRow.clear();
cardText.append(Backend.translate(":" + data.name)); cardText.append(Backend.translate(":" + data.name));
addCardAudio(data)
const skills = JSON.parse(Backend.callLuaFunction const skills = JSON.parse(Backend.callLuaFunction
("GetCardSpecialSkills", [cid])); ("GetCardSpecialSkills", [cid]));
if (skills.length > 0) { if (skills.length > 0) {
@ -287,6 +288,35 @@ Item {
textFormat: TextEdit.RichText textFormat: TextEdit.RichText
font.pixelSize: 16 font.pixelSize: 16
} }
GridLayout {
columns: 2
Repeater {
model: ListModel {
id: audioRow
}
Button {
Layout.fillWidth: true
contentItem: Text {
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: {
if (gender === "male") {
return Backend.translate("Male Audio");
} else {
return Backend.translate("Female Audio");
}
}
font.pixelSize: 14
}
onClicked: {
const data = JSON.parse(Backend.callLuaFunction("GetCardData", [cardDetail.cid]));
Backend.playSound("./packages/" + extension + "/audio/card/" + gender + "/" + data.name);
}
}
}
}
} }
} }
} }
@ -299,6 +329,29 @@ Item {
} }
} }
function addCardAudio(card) {
const extension = card.extension;
const orig_extension = Backend.callLuaFunction("GetCardExtensionByName", [card.name]);
let fname = AppPath + "/packages/" + extension + "/audio/card/male/" + card.name + ".mp3";
if (Backend.exists(fname)) {
audioRow.append( {gender: "male", extension: extension} );
} else {
fname = AppPath + "/packages/" + orig_extension + "/audio/card/male/" + card.name + ".mp3";
if (Backend.exists(fname)) {
audioRow.append( {gender: "male", extension: orig_extension} );
}
}
fname = AppPath + "/packages/" + extension + "/audio/card/female/" + card.name + ".mp3";
if (Backend.exists(fname)) {
audioRow.append( {gender: "female", extension: extension} );
}else {
fname = AppPath + "/packages/" + orig_extension + "/audio/card/female/" + card.name + ".mp3";
if (Backend.exists(fname)) {
audioRow.append( {gender: "female", extension: orig_extension} );
}
}
}
function loadPackages() { function loadPackages() {
if (loaded) return; if (loaded) return;
const packs = JSON.parse(Backend.callLuaFunction("GetAllCardPack", [])); const packs = JSON.parse(Backend.callLuaFunction("GetAllCardPack", []));

View File

@ -81,104 +81,140 @@ Item {
} }
} }
// tmp ToolButton {
Button {
id: menuButton id: menuButton
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 12
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 10 anchors.rightMargin: 36
text: Backend.translate("Menu") icon.source: AppPath + "/image/modmaker/menu"
z: 2 icon.width: 36
icon.height: 36
onClicked: { onClicked: {
menuContainer.visible || menuContainer.open(); if (menuContainer.visible){
menuContainer.close();
} else {
menuContainer.open();
}
} }
}
Menu { background.implicitWidth: 60
id: menuContainer background.implicitHeight: 60
x: parent.width - menuButton.width - menuContainer.width - 17
width: menuRow.width
height: menuRow.height
verticalPadding: 0
spacing: 7
z: 2
Row { Menu {
id: menuRow id: menuContainer
spacing: 7 y: menuButton.height - 12
width: 115
Button { height: menuRow.height
id: surrenderButton verticalPadding: 0
enabled: !config.observing && !config.replaying spacing: 15
text: Backend.translate("Surrender") z: 2
onClicked: { background: Rectangle {
if (isStarted && !getPhoto(Self.id).dead) { implicitWidth: 200
const surrenderCheck = JSON.parse(Backend.callLuaFunction('CheckSurrenderAvailable', [miscStatus.playedTime])); implicitHeight: 40
if (!surrenderCheck.length) { color: "transparent"
surrenderDialog.informativeText = Backend.translate('Surrender is disabled in this mode'); border.color: "transparent"
} else {
surrenderDialog.informativeText = surrenderCheck.map(str => `${Backend.translate(str.text)}${str.passed ? '√' : '×'}`).join('<br>');
}
surrenderDialog.open();
}
}
} }
MessageDialog { Column {
id: surrenderDialog id: menuRow
title: Backend.translate("Surrender") width: menuContainer.width
informativeText: '' Layout.fillWidth: true
buttons: MessageDialog.Ok | MessageDialog.Cancel spacing: 7
onButtonClicked: function (button, role) {
switch (button) {
case MessageDialog.Ok: {
const surrenderCheck = JSON.parse(Backend.callLuaFunction('CheckSurrenderAvailable', [miscStatus.playedTime]));
if (surrenderCheck.length && !surrenderCheck.find(check => !check.passed)) {
ClientInstance.notifyServer("PushRequest", [
"surrender", true
]);
}
surrenderDialog.close();
break;
}
case MessageDialog.Cancel: {
surrenderDialog.close();
}
}
}
}
Button { Button {
id: quitButton id: quitButton
text: Backend.translate("Quit") text: Backend.translate("Quit")
onClicked: { font.pixelSize: 28
if (config.replaying) { Layout.fillWidth: true
Backend.controlReplayer("shutdown"); width: menuContainer.width
mainStack.pop(); height: menuContainer.width * 0.65
} else if (config.observing) { onClicked: {
ClientInstance.notifyServer("QuitRoom", "[]"); if (config.replaying) {
} else { Backend.controlReplayer("shutdown");
quitDialog.open(); mainStack.pop();
} } else if (config.observing) {
}
}
MessageDialog {
id: quitDialog
title: Backend.translate("Quit")
informativeText: Backend.translate("Are you sure to quit?")
buttons: MessageDialog.Ok | MessageDialog.Cancel
onButtonClicked: function (button) {
switch (button) {
case MessageDialog.Ok: {
ClientInstance.notifyServer("QuitRoom", "[]"); ClientInstance.notifyServer("QuitRoom", "[]");
break; } else {
quitDialog.open();
} }
case MessageDialog.Cancel: { }
quitDialog.close(); }
MessageDialog {
id: quitDialog
title: Backend.translate("Quit")
informativeText: Backend.translate("Are you sure to quit?")
buttons: MessageDialog.Ok | MessageDialog.Cancel
onButtonClicked: function (button) {
switch (button) {
case MessageDialog.Ok: {
ClientInstance.notifyServer("QuitRoom", "[]");
break;
}
case MessageDialog.Cancel: {
quitDialog.close();
}
} }
} }
} }
Button {
id: surrenderButton
enabled: !config.observing && !config.replaying
text: Backend.translate("Surrender")
font.pixelSize: 28
Layout.fillWidth: true
width: menuContainer.width
height: menuContainer.width * 0.65
onClicked: {
if (isStarted && !getPhoto(Self.id).dead) {
const surrenderCheck = JSON.parse(Backend.callLuaFunction('CheckSurrenderAvailable', [miscStatus.playedTime]));
if (!surrenderCheck.length) {
surrenderDialog.informativeText = Backend.translate('Surrender is disabled in this mode');
} else {
surrenderDialog.informativeText = surrenderCheck.map(str => `${Backend.translate(str.text)}${str.passed ? '√' : '×'}`).join('<br>');
}
surrenderDialog.open();
}
}
}
MessageDialog {
id: surrenderDialog
title: Backend.translate("Surrender")
informativeText: ''
buttons: MessageDialog.Ok | MessageDialog.Cancel
onButtonClicked: function (button, role) {
switch (button) {
case MessageDialog.Ok: {
const surrenderCheck = JSON.parse(Backend.callLuaFunction('CheckSurrenderAvailable', [miscStatus.playedTime]));
if (surrenderCheck.length && !surrenderCheck.find(check => !check.passed)) {
ClientInstance.notifyServer("PushRequest", [
"surrender", true
]);
}
surrenderDialog.close();
break;
}
case MessageDialog.Cancel: {
surrenderDialog.close();
}
}
}
}
Button {
id: volumeButton
text: Backend.translate("Audio Settings")
font.pixelSize: 28
Layout.fillWidth: true
width: menuContainer.width
height: menuContainer.width * 0.65
onClicked: {
volumeDialog.open();
}
}
} }
} }
} }
@ -518,6 +554,7 @@ Item {
onCardSelected: function(card) { onCardSelected: function(card) {
Logic.enableTargets(card); Logic.enableTargets(card);
roomScene.resetPrompt();
if (typeof card === "number" && card !== -1 && roomScene.state === "playing" if (typeof card === "number" && card !== -1 && roomScene.state === "playing"
&& JSON.parse(Backend.callLuaFunction("GetPlayerHandcards", [Self.id])).includes(card)) { && JSON.parse(Backend.callLuaFunction("GetPlayerHandcards", [Self.id])).includes(card)) {
@ -527,6 +564,14 @@ Item {
skills.unshift("_normal_use"); skills.unshift("_normal_use");
} }
specialCardSkills.model = skills; specialCardSkills.model = skills;
const skillName = Backend.callLuaFunction("GetCardSkill", [card]);
const prompt = JSON.parse(Backend.callLuaFunction(
"ActiveSkillPrompt",
[skillName, card, selected_targets]
));
if (prompt !== "") {
roomScene.setPrompt(processPrompt(prompt));
}
} else { } else {
specialCardSkills.model = []; specialCardSkills.model = [];
} }
@ -692,13 +737,28 @@ Item {
text: Backend.translate(modelData) text: Backend.translate(modelData)
checked: index === 0 checked: index === 0
onCheckedChanged: { onCheckedChanged: {
roomScene.resetPrompt();
const card = dashboard.selected_card;
let prompt = ""
if (modelData === "_normal_use") { if (modelData === "_normal_use") {
Logic.enableTargets(dashboard.selected_card); Logic.enableTargets(card);
const skillName = Backend.callLuaFunction("GetCardSkill", [card]);
prompt = JSON.parse(Backend.callLuaFunction(
"ActiveSkillPrompt",
[skillName, card, selected_targets]
));
} else { } else {
Logic.enableTargets(JSON.stringify({ Logic.enableTargets(JSON.stringify({
skill: modelData, skill: modelData,
subcards: [dashboard.selected_card], subcards: [card],
})); }));
prompt = JSON.parse(Backend.callLuaFunction(
"ActiveSkillPrompt",
[modelData, card, selected_targets]
));
}
if (prompt !== "") {
roomScene.setPrompt(processPrompt(prompt));
} }
} }
} }
@ -928,6 +988,60 @@ Item {
anchors.fill: parent anchors.fill: parent
} }
Dialog {
id: volumeDialog
title: Backend.translate("Audio Settings")
anchors.centerIn: roomScene
ColumnLayout {
RowLayout {
anchors.rightMargin: 8
spacing: 16
Text {
text: Backend.translate("BGM Volume")
}
Slider {
Layout.rightMargin: 16
Layout.fillWidth: true
from: 0
to: 100
value: config.bgmVolume
onValueChanged: config.bgmVolume = value;
}
}
RowLayout {
anchors.rightMargin: 8
spacing: 16
Text {
text: Backend.translate("Effect Volume")
}
Slider {
Layout.rightMargin: 16
Layout.fillWidth: true
from: 0
to: 100
value: Backend.volume
onValueChanged: Backend.volume = value;
}
}
Switch {
text: Backend.translate("Disable message audio")
checked: config.disableMsgAudio
onCheckedChanged: config.disableMsgAudio = checked;
}
Switch {
text: Backend.translate("Hide unselectable cards")
checked: config.hideUseless
onCheckedChanged: {
config.hideUseless = checked;
}
}
}
}
Rectangle { Rectangle {
anchors.fill: dashboard anchors.fill: dashboard
visible: config.observing && !config.replaying visible: config.observing && !config.replaying
@ -1039,6 +1153,18 @@ Item {
onActivated: Logic.doCancelButton(); onActivated: Logic.doCancelButton();
} }
function processPrompt(prompt) {
const data = prompt.split(":");
let raw = Backend.translate(data[0]);
const src = parseInt(data[1]);
const dest = parseInt(data[2]);
if (raw.match("%src")) raw = raw.replace(/%src/g, Backend.translate(getPhoto(src).general));
if (raw.match("%dest")) raw = raw.replace(/%dest/g, Backend.translate(getPhoto(dest).general));
if (raw.match("%arg2")) raw = raw.replace(/%arg2/g, Backend.translate(data[4]));
if (raw.match("%arg")) raw = raw.replace(/%arg/g, Backend.translate(data[3]));
return raw;
}
function getCurrentCardUseMethod() { function getCurrentCardUseMethod() {
if (specialCardSkills.count === 1 && specialCardSkills.model[0] !== "_normal_use") { if (specialCardSkills.count === 1 && specialCardSkills.model[0] !== "_normal_use") {
return specialCardSkills.model[0]; return specialCardSkills.model[0];

View File

@ -576,9 +576,9 @@ function enableTargets(card) { // card: int | { skill: string, subcards: int[] }
if (roomScene.extra_data instanceof Object) { if (roomScene.extra_data instanceof Object) {
const must = roomScene.extra_data.must_targets; const must = roomScene.extra_data.must_targets;
const included = roomScene.extra_data.include_targets; const included = roomScene.extra_data.include_targets;
const exclusived = roomScene.extra_data.exclusive_targets; const exclusive = roomScene.extra_data.exclusive_targets;
if (exclusived instanceof Array) { if (exclusive instanceof Array) {
if (exclusived.indexOf(id) === -1) photo.selectable = false; if (exclusive.indexOf(id) === -1) photo.selectable = false;
} }
if (must instanceof Array) { if (must instanceof Array) {
if (must.filter((val) => { if (must.filter((val) => {
@ -654,9 +654,9 @@ function updateSelectedTargets(playerid, selected) {
if (roomScene.extra_data instanceof Object) { if (roomScene.extra_data instanceof Object) {
const must = roomScene.extra_data.must_targets; const must = roomScene.extra_data.must_targets;
const included = roomScene.extra_data.include_targets; const included = roomScene.extra_data.include_targets;
const exclusived = roomScene.extra_data.exclusive_targets; const exclusive = roomScene.extra_data.exclusive_targets;
if (exclusived instanceof Array) { if (exclusive instanceof Array) {
if (exclusived.indexOf(id) === -1) photo.selectable = false; if (exclusive.indexOf(id) === -1) photo.selectable = false;
} }
if (must instanceof Array) { if (must instanceof Array) {
if (must.filter((val) => { if (must.filter((val) => {

View File

@ -123,10 +123,7 @@ function GetCardData(id, virtualCardForm)
end end
function GetCardExtensionByName(cardName) function GetCardExtensionByName(cardName)
local card = table.find(Fk.cards, function(card) local card = Fk.all_card_types[cardName]
return card.name == cardName
end)
return card and card.package.extensionName or "" return card and card.package.extensionName or ""
end end
@ -220,6 +217,10 @@ function GetCards(pack_name)
return json.encode(ret) return json.encode(ret)
end end
function GetCardSkill(cid)
return Fk:getCardById(cid).skill and Fk:getCardById(cid).skill.name or ""
end
function GetCardSpecialSkills(cid) function GetCardSpecialSkills(cid)
return json.encode(Fk:getCardById(cid).special_skills or Util.DummyTable) return json.encode(Fk:getCardById(cid).special_skills or Util.DummyTable)
end end

View File

@ -89,6 +89,8 @@ Fk:loadTranslationTable{
["Cards Overview"] = "卡牌一览", ["Cards Overview"] = "卡牌一览",
["Special card skills:"] = "<b>卡牌的特殊用法:</b>", ["Special card skills:"] = "<b>卡牌的特殊用法:</b>",
["Every suit & number:"] = "<b>所有的花色和点数:</b>", ["Every suit & number:"] = "<b>所有的花色和点数:</b>",
["Male Audio"] = "男性音效",
["Female Audio"] = "女性音效",
["Scenarios Overview"] = "玩法一览", ["Scenarios Overview"] = "玩法一览",
["Replay"] = "录像", ["Replay"] = "录像",
["Replay Manager"] = "来欣赏潇洒的录像吧!", ["Replay Manager"] = "来欣赏潇洒的录像吧!",

View File

@ -428,7 +428,7 @@ end
--- 比较两张卡牌的花色是否相同 --- 比较两张卡牌的花色是否相同
---@param anotherCard Card @ 另一张卡牌 ---@param anotherCard Card @ 另一张卡牌
---@param diff? boolean @ 比较二者相同还是不同 ---@param diff? boolean @ 比较二者不同
---@return boolean 返回比较结果 ---@return boolean 返回比较结果
function Card:compareSuitWith(anotherCard, diff) function Card:compareSuitWith(anotherCard, diff)
if self ~= anotherCard and table.contains({ self.suit, anotherCard.suit }, Card.NoSuit) then if self ~= anotherCard and table.contains({ self.suit, anotherCard.suit }, Card.NoSuit) then
@ -444,8 +444,8 @@ end
--- 比较两张卡牌的颜色是否相同 --- 比较两张卡牌的颜色是否相同
---@param anotherCard Card @ 另一张卡牌 ---@param anotherCard Card @ 另一张卡牌
---@param diff boolean @ 比较二者相同还是不同 ---@param diff? boolean @ 比较二者不同
---@return boolean 返回比较结果 ---@return boolean @ 返回比较结果
function Card:compareColorWith(anotherCard, diff) function Card:compareColorWith(anotherCard, diff)
if self ~= anotherCard and table.contains({ self.color, anotherCard.color }, Card.NoColor) then if self ~= anotherCard and table.contains({ self.color, anotherCard.color }, Card.NoColor) then
return false return false
@ -460,8 +460,8 @@ end
--- 比较两张卡牌的点数是否相同 --- 比较两张卡牌的点数是否相同
---@param anotherCard Card @ 另一张卡牌 ---@param anotherCard Card @ 另一张卡牌
---@param diff boolean @ 比较二者相同还是不同 ---@param diff? boolean @ 比较二者不同
---@return boolean 返回比较结果 ---@return boolean @ 返回比较结果
function Card:compareNumberWith(anotherCard, diff) function Card:compareNumberWith(anotherCard, diff)
if self ~= anotherCard and self.number < 1 or anotherCard.number < 1 then if self ~= anotherCard and self.number < 1 or anotherCard.number < 1 then
return false return false

View File

@ -293,6 +293,7 @@ function Engine:addCard(card)
cardId = cardId + 1 cardId = cardId + 1
table.insert(self.cards, card) table.insert(self.cards, card)
if self.all_card_types[card.name] == nil then if self.all_card_types[card.name] == nil then
self.skills[card.skill.name] = card.skill
self.all_card_types[card.name] = card self.all_card_types[card.name] = card
end end
end end

View File

@ -451,7 +451,7 @@ function Player:getMaxCards()
return math.max(baseValue, 0) return math.max(baseValue, 0)
end end
--- 获取玩家攻击距离 --- 获取玩家攻击范围
function Player:getAttackRange() function Player:getAttackRange()
local weapon = Fk:getCardById(self:getEquipment(Card.SubtypeWeapon)) local weapon = Fk:getCardById(self:getEquipment(Card.SubtypeWeapon))
local baseAttackRange = math.max(weapon and weapon.attack_range or 1, 0) local baseAttackRange = math.max(weapon and weapon.attack_range or 1, 0)
@ -544,7 +544,7 @@ function Player:distanceTo(other, mode, ignore_dead)
return math.max(ret, 1) return math.max(ret, 1)
end end
--- 获取其他玩家是否在玩家的攻击距离内。 --- 获取其他玩家是否在玩家的攻击范围内。
---@param other Player @ 其他玩家 ---@param other Player @ 其他玩家
---@param fixLimit? integer @ 卡牌距离限制增加专用 ---@param fixLimit? integer @ 卡牌距离限制增加专用
function Player:inMyAttackRange(other, fixLimit) function Player:inMyAttackRange(other, fixLimit)
@ -596,7 +596,7 @@ end
---@return ServerPlayer ---@return ServerPlayer
function Player:getLastAlive(ignoreRemoved, num) function Player:getLastAlive(ignoreRemoved, num)
num = num or 1 num = num or 1
local index = ignoreRemoved and #Fk:currentRoom().alive_players or #table.filter(Fk:currentRoom().alive_players, function(p) return not p:isRemoved() end) - num local index = (ignoreRemoved and #Fk:currentRoom().alive_players or #table.filter(Fk:currentRoom().alive_players, function(p) return not p:isRemoved() end)) - num
return self:getNextAlive(ignoreRemoved, index) return self:getNextAlive(ignoreRemoved, index)
end end
@ -1047,4 +1047,19 @@ function Player:isBuddy(other)
return self.id == id or table.contains(self.buddy_list, id) return self.id == id or table.contains(self.buddy_list, id)
end end
--- 比较两名角色的性别是否相同。
---@param other Player @ 另一名角色
---@param diff? bool @ 比较二者不同
---@return boolean @ 返回比较结果
function Player:compareGenderWith(other, diff)
if self == other then return not diff end
if self.gender == General.Agender or other.gender == General.Agender then return false end
if self.gender == General.Bigender or other.gender == General.Bigender then return true end
if diff then
return self.gender ~= other.gender
else
return self.gender == other.gender
end
end
return Player return Player

View File

@ -445,6 +445,9 @@ local defaultCardSkill = fk.CreateActiveSkill{
local defaultEquipSkill = fk.CreateActiveSkill{ local defaultEquipSkill = fk.CreateActiveSkill{
name = "default_equip_skill", name = "default_equip_skill",
prompt = function(_, selected_cards, _)
return "#default_equip_skill:::" .. Fk:getCardById(selected_cards).name .. ":" .. Fk:getCardById(selected_cards):getSubtypeString()
end,
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
return #Fk:currentRoom():getPlayerById(to_select):getAvailableEquipSlots(card.sub_type) > 0 return #Fk:currentRoom():getPlayerById(to_select):getAvailableEquipSlots(card.sub_type) > 0
end, end,

View File

@ -12,10 +12,10 @@ function RandomAI:useActiveSkill(skill, card)
local filter_func = skill.cardFilter local filter_func = skill.cardFilter
if card then if card then
filter_func = function() return false end filter_func = Util.FalseFunc
end end
if self.command == "PlayCard" and card and (not player:canUse(card) or player:prohibitUse(card)) then if self.command == "PlayCard" and card and (not skill:canUse(player, card) or player:prohibitUse(card)) then
return "" return ""
end end
@ -28,7 +28,7 @@ function RandomAI:useActiveSkill(skill, card)
local max_card = skill:getMaxCardNum() local max_card = skill:getMaxCardNum()
for _ = 0, max_try_times do for _ = 0, max_try_times do
if skill:feasible(selected_targets, selected_cards, self.player, card) then break end if skill:feasible(selected_targets, selected_cards, self.player, card) then break end
local avail_targets = table.filter(self.room:getAlivePlayers(), function(p) local avail_targets = table.filter(room:getAlivePlayers(), function(p)
local ret = skill:targetFilter(p.id, selected_targets, selected_cards, card or Fk:cloneCard'zixing') local ret = skill:targetFilter(p.id, selected_targets, selected_cards, card or Fk:cloneCard'zixing')
if ret and card then if ret and card then
if player:isProhibited(p, card) then if player:isProhibited(p, card) then

View File

@ -125,6 +125,7 @@ fk.AfterSkillEffect = 82
fk.AreaAborted = 87 fk.AreaAborted = 87
fk.AreaResumed = 88 fk.AreaResumed = 88
fk.GeneralShown = 95
fk.GeneralRevealed = 89 fk.GeneralRevealed = 89
fk.GeneralHidden = 90 fk.GeneralHidden = 90
@ -134,4 +135,4 @@ fk.BeforePropertyChange = 92
fk.PropertyChange = 93 fk.PropertyChange = 93
fk.AfterPropertyChange = 94 fk.AfterPropertyChange = 94
fk.NumOfEvents = 95 fk.NumOfEvents = 96

View File

@ -28,11 +28,9 @@ local playCardEmotionAndSound = function(room, player, card)
soundName = "./packages/" .. card.package.extensionName .. "/audio/card/" soundName = "./packages/" .. card.package.extensionName .. "/audio/card/"
.. (player.gender == General.Male and "male/" or "female/") .. card.name .. (player.gender == General.Male and "male/" or "female/") .. card.name
if not FileIO.exists(soundName .. ".mp3") then if not FileIO.exists(soundName .. ".mp3") then
for _, dir in ipairs(FileIO.ls("./packages/")) do local orig = Fk.all_card_types[card.name]
soundName = "./packages/" .. dir .. "/audio/card/" soundName = "./packages/" .. orig.package.extensionName .. "/audio/card/"
.. (player.gender == General.Male and "male/" or "female/") .. card.name .. (player.gender == General.Male and "male/" or "female/") .. orig.name
if FileIO.exists(soundName .. ".mp3") then break end
end
end end
end end
room:broadcastPlaySound(soundName) room:broadcastPlaySound(soundName)

View File

@ -446,7 +446,7 @@ function GameLogic:getEventsOfScope(eventType, n, func, scope)
elseif scope == Player.HistoryPhase then elseif scope == Player.HistoryPhase then
start_event = event:findParent(GameEvent.Phase, true) start_event = event:findParent(GameEvent.Phase, true)
end end
if not start_event then return {} end
return start_event:searchEvents(eventType, n, func) return start_event:searchEvents(eventType, n, func)
end end

View File

@ -310,7 +310,7 @@ function Room:getPlayerById(id)
return nil return nil
end end
--- 将房间中的玩家按照座位顺序重新排序。 --- 将房间中的玩家按照行动顺序重新排序。
---@param playerIds integer[] @ 玩家id列表这个数组会被这个函数排序 ---@param playerIds integer[] @ 玩家id列表这个数组会被这个函数排序
function Room:sortPlayersByAction(playerIds, isTargetGroup) function Room:sortPlayersByAction(playerIds, isTargetGroup)
table.sort(playerIds, function(prev, next) table.sort(playerIds, function(prev, next)
@ -1273,19 +1273,12 @@ function Room:askForCard(player, minNum, maxNum, includeEquip, skillName, cancel
chosenCards = ret.cards chosenCards = ret.cards
else else
if cancelable then return {} end if cancelable then return {} end
local hands = player:getCardIds(Player.Hand) local cards = player:getCardIds("he&")
if includeEquip then
table.insertTable(hands, player:getCardIds(Player.Equip))
end
local exp = Exppattern:Parse(pattern) local exp = Exppattern:Parse(pattern)
hands = table.filter(hands, function(cid) cards = table.filter(cards, function(cid)
return exp:match(Fk:getCardById(cid)) return exp:match(Fk:getCardById(cid))
end) end)
for _ = 1, minNum do chosenCards = table.random(cards, minNum)
local randomId = hands[math.random(1, #hands)]
table.insert(chosenCards, randomId)
table.removeOne(hands, randomId)
end
end end
return chosenCards return chosenCards
@ -2873,14 +2866,14 @@ function Room:drawCards(player, num, skillName, fromPlace)
end end
--- 将一张或多张牌移动到某处 --- 将一张或多张牌移动到某处
---@param card integer | Card | Card[] @ 要移动的牌 ---@param card integer | integer[] | Card | Card[] @ 要移动的牌
---@param to_place integer @ 移动的目标位置 ---@param to_place integer @ 移动的目标位置
---@param target ServerPlayer @ 移动的目标玩家 ---@param target? ServerPlayer @ 移动的目标角色
---@param reason? integer @ 移动时使用的移牌原因 ---@param reason? integer @ 移动时使用的移牌原因
---@param skill_name? string @ 技能名 ---@param skill_name? string @ 技能名
---@param special_name? string @ 私人牌堆名 ---@param special_name? string @ 私人牌堆名
---@param visible? boolean @ 是否明置 ---@param visible? boolean @ 是否明置
---@param proposer? integer ---@param proposer? integer @ 移动操作者的id
function Room:moveCardTo(card, to_place, target, reason, skill_name, special_name, visible, proposer) function Room:moveCardTo(card, to_place, target, reason, skill_name, special_name, visible, proposer)
reason = reason or fk.ReasonJustMove reason = reason or fk.ReasonJustMove
skill_name = skill_name or "" skill_name = skill_name or ""
@ -3268,10 +3261,15 @@ function Room:useSkill(player, skill, effect_cb)
player:revealBySkillName(skill.name) player:revealBySkillName(skill.name)
if not skill.mute then if not skill.mute then
if skill.attached_equip then if skill.attached_equip then
local equip = Fk:cloneCard(skill.attached_equip) local equip = Fk.all_card_types[skill.attached_equip]
local pkgPath = "./packages/" .. equip.package.extensionName local pkgPath = "./packages/" .. equip.package.extensionName
local soundName = pkgPath .. "/audio/card/" .. equip.name local soundName = pkgPath .. "/audio/card/" .. equip.name
self:broadcastPlaySound(soundName) self:broadcastPlaySound(soundName)
self:sendLog{
type = "#InvokeSkill",
from = player.id,
arg = skill.name,
}
self:setEmotion(player, pkgPath .. "/image/anim/" .. equip.name) self:setEmotion(player, pkgPath .. "/image/anim/" .. equip.name)
else else
player:broadcastSkillInvoke(skill.name) player:broadcastSkillInvoke(skill.name)

View File

@ -38,6 +38,7 @@ function ServerPlayer:initialize(_self)
self.reply_cancel = false self.reply_cancel = false
self.phases = {} self.phases = {}
self.skipped_phases = {} self.skipped_phases = {}
self.phase_state = {}
self._fake_skills = {} self._fake_skills = {}
self._manually_fake_skills = {} self._manually_fake_skills = {}
@ -469,11 +470,13 @@ function ServerPlayer:changePhase(from_phase, to_phase)
return false return false
end end
---@param phase Phase
---@param delay? boolean
function ServerPlayer:gainAnExtraPhase(phase, delay) function ServerPlayer:gainAnExtraPhase(phase, delay)
local room = self.room local room = self.room
delay = (delay == nil) and true or delay delay = (delay == nil) and true or delay
local logic = room.logic
if delay then if delay then
local logic = room.logic
local turn = logic:getCurrentEvent():findParent(GameEvent.Phase, true) local turn = logic:getCurrentEvent():findParent(GameEvent.Phase, true)
if turn then if turn then
turn:prependExitFunc(function() self:gainAnExtraPhase(phase, false) end) turn:prependExitFunc(function() self:gainAnExtraPhase(phase, false) end)
@ -482,16 +485,43 @@ function ServerPlayer:gainAnExtraPhase(phase, delay)
end end
local current = self.phase local current = self.phase
local phase_change = {
from = current,
to = phase
}
local skip = logic:trigger(fk.EventPhaseChanging, self, phase_change)
phase = phase_change.to
self.phase = phase self.phase = phase
room:broadcastProperty(self, "phase") room:broadcastProperty(self, "phase")
room:sendLog{ local cancel_skip = true
type = "#GainAnExtraPhase", if phase ~= Player.NotActive and (skip) then
from = self.id, cancel_skip = logic:trigger(fk.EventPhaseSkipping, self)
arg = phase_name_table[phase], end
} if (not skip) or (cancel_skip) then
room:sendLog{
type = "#GainAnExtraPhase",
from = self.id,
arg = phase_name_table[phase],
}
GameEvent(GameEvent.Phase, self, self.phase):exec() GameEvent(GameEvent.Phase, self, self.phase):exec()
phase_change = {
from = phase,
to = current
}
logic:trigger(fk.EventPhaseChanging, self, phase_change)
else
room:sendLog{
type = "#PhaseSkipped",
from = self.id,
arg = phase_name_table[phase],
}
end
self.phase = current self.phase = current
room:broadcastProperty(self, "phase") room:broadcastProperty(self, "phase")
@ -592,6 +622,7 @@ function ServerPlayer:endPlayPhase()
-- TODO: send log -- TODO: send log
end end
---@param delay? boolean
function ServerPlayer:gainAnExtraTurn(delay) function ServerPlayer:gainAnExtraTurn(delay)
local room = self.room local room = self.room
delay = (delay == nil) and true or delay delay = (delay == nil) and true or delay
@ -624,10 +655,13 @@ function ServerPlayer:gainAnExtraTurn(delay)
room.current = current room.current = current
end end
--- 当前是否处于额外的回合。
--- @return boolean
function ServerPlayer:insideExtraTurn() function ServerPlayer:insideExtraTurn()
return self.tag["_extra_turn_count"] and #self.tag["_extra_turn_count"] > 0 return self.tag["_extra_turn_count"] and #self.tag["_extra_turn_count"] > 0
end end
--- 当前额外回合的技能原因。
---@return string ---@return string
function ServerPlayer:getCurrentExtraTurnReason() function ServerPlayer:getCurrentExtraTurnReason()
local ex_tag = self.tag["_extra_turn_count"] local ex_tag = self.tag["_extra_turn_count"]
@ -637,13 +671,18 @@ function ServerPlayer:getCurrentExtraTurnReason()
return ex_tag[#ex_tag] return ex_tag[#ex_tag]
end end
--- 角色摸牌。
---@param num integer @ 摸牌数
---@param skillName? string @ 技能名
---@param fromPlace? string @ 摸牌的位置,"top" 或者 "bottom"
---@return integer[] @ 摸到的牌
function ServerPlayer:drawCards(num, skillName, fromPlace) function ServerPlayer:drawCards(num, skillName, fromPlace)
return self.room:drawCards(self, num, skillName, fromPlace) return self.room:drawCards(self, num, skillName, fromPlace)
end end
---@param pile_name string ---@param pile_name string
---@param card integer|Card ---@param card integer|Card
---@param visible boolean ---@param visible? boolean
---@param skillName? string ---@param skillName? string
function ServerPlayer:addToPile(pile_name, card, visible, skillName) function ServerPlayer:addToPile(pile_name, card, visible, skillName)
local room = self.room local room = self.room
@ -923,13 +962,21 @@ function ServerPlayer:revealGeneral(isDeputy, no_trigger)
arg2 = generalName, arg2 = generalName,
} }
local data = {[isDeputy and "d" or "m"] = generalName}
room.logic:trigger(fk.GeneralShown, self, data)
if not no_trigger then if not no_trigger then
local current_event = room.logic:getCurrentEvent() local current_event = room.logic:getCurrentEvent()
if table.contains({GameEvent.Round, GameEvent.Turn, GameEvent.Phase}, current_event.event) then if table.contains({GameEvent.Round, GameEvent.Turn, GameEvent.Phase}, current_event.event) then
room.logic:trigger(fk.GeneralRevealed, self, {[isDeputy and "d" or "m"] = generalName}) room.logic:trigger(fk.GeneralRevealed, self, data)
else else
if current_event.parent then
repeat
if table.contains({GameEvent.Round, GameEvent.Turn, GameEvent.Phase}, current_event.parent.event) then break end
current_event = current_event.parent
until (not current_event.parent)
end
current_event:addExitFunc(function () current_event:addExitFunc(function ()
room.logic:trigger(fk.GeneralRevealed, self, {[isDeputy and "d" or "m"] = generalName}) room.logic:trigger(fk.GeneralRevealed, self, data)
end) end)
end end
end end
@ -940,11 +987,18 @@ function ServerPlayer:revealGenerals()
self:revealGeneral(true, true) self:revealGeneral(true, true)
local room = self.room local room = self.room
local current_event = room.logic:getCurrentEvent() local current_event = room.logic:getCurrentEvent()
local data = {["m"] = self:getMark("__heg_general"), ["d"] = self:getMark("__heg_deputy")}
if table.contains({GameEvent.Round, GameEvent.Turn, GameEvent.Phase}, current_event.event) then if table.contains({GameEvent.Round, GameEvent.Turn, GameEvent.Phase}, current_event.event) then
room.logic:trigger(fk.GeneralRevealed, self, {["m"] = self:getMark("__heg_general"), ["d"] = self:getMark("__heg_deputy")}) room.logic:trigger(fk.GeneralRevealed, self, data)
else else
if current_event.parent then
repeat
if table.contains({GameEvent.Round, GameEvent.Turn, GameEvent.Phase}, current_event.parent.event) then break end
current_event = current_event.parent
until (not current_event.parent)
end
current_event:addExitFunc(function () current_event:addExitFunc(function ()
room.logic:trigger(fk.GeneralRevealed, self, {["m"] = self:getMark("__heg_general"), ["d"] = self:getMark("__heg_deputy")}) room.logic:trigger(fk.GeneralRevealed, self, data)
end) end)
end end
end end

View File

@ -3,27 +3,36 @@ return {
["thunder__slash"] = "Thunder Slash", ["thunder__slash"] = "Thunder Slash",
[":thunder__slash"] = "Thunder Slash (basic card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player within your ATK range<br /><b>Effect</b>: Deal 1 Thunder DMG to the targets.<br/><b>Note</b>: You can only use 1 Slash per action phase.", [":thunder__slash"] = "Thunder Slash (basic card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player within your ATK range<br /><b>Effect</b>: Deal 1 Thunder DMG to the targets.<br/><b>Note</b>: You can only use 1 Slash per action phase.",
["#thunder__slash_skill"] = "Choose 1 player within your ATK range, deal 1 Thunder DMG to him",
["#thunder__slash_skill_multi"] = "Choose up to %arg players within your ATK range. Deal 1 Thunder DMG to them",
["fire__slash"] = "Fire Slash", ["fire__slash"] = "Fire Slash",
[":fire__slash"] = "Fire Slash (basic card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player within your ATK range<br /><b>Effect</b>: Deal 1 Fire DMG to the targets.<br/><b>Note</b>: You can only use 1 Slash per action phase.", [":fire__slash"] = "Fire Slash (basic card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player within your ATK range<br /><b>Effect</b>: Deal 1 Fire DMG to the targets.<br/><b>Note</b>: You can only use 1 Slash per action phase.",
["#fire__slash_skill"] = "Choose 1 player within your ATK range, deal 1 Fire DMG to him",
["#fire__slash_skill_multi"] = "Choose up to %arg players within your ATK range. Deal 1 Fire DMG to them",
["analeptic"] = "Alcohol", ["analeptic"] = "Alcohol",
[":analeptic"] = "Alcohol (basic card)<br /><b>Phase</b>: 1. Action phase 2. When you are dying<br /><b>Target</b>: Yourself<br /><b>Effect</b>: 1. the DMG of the next Slash you use this turn is increased by +1. (This effect can only be used once per turn) 2. You heal 1 HP.", [":analeptic"] = "Alcohol (basic card)<br /><b>Phase</b>: 1. Action phase 2. When you are dying<br /><b>Target</b>: Yourself<br /><b>Effect</b>: 1. the DMG of the next Slash you use this turn is increased by +1. (This effect can only be used once per turn) 2. You heal 1 HP.",
["#analeptic_skill"] = "the DMG of the next Slash you use this turn is increased by +1",
["iron_chain"] = "Iron Chain", ["iron_chain"] = "Iron Chain",
[":iron_chain"] = "Iron Chain (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: 1~2 players<br /><b>Effect</b>: Change chain state of the targets.", [":iron_chain"] = "Iron Chain (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: 1~2 players<br /><b>Effect</b>: Change chain state of the targets.",
["#iron_chain_skill"] = "Choose 1~2 players. Change their chain states",
["_normal_use"] = "Normally use", ["_normal_use"] = "Normally use",
["recast"] = "Recast", ["recast"] = "Recast",
[":recast"] = "Put this card into discard pile, then draw 1 card.", [":recast"] = "Put this card into discard pile, then draw 1 card.",
["#recast"] = "Put this card into discard pile, then draw 1 card",
["fire_attack"] = "Fire Attack", ["fire_attack"] = "Fire Attack",
["fire_attack_skill"] = "Fire Attack", ["fire_attack_skill"] = "Fire Attack",
[":fire_attack"] = "Fire Attack (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: A player with hand cards<br /><b>Effect</b>: That player shows 1 hand card; then, if you discard 1 card with the same suit, you deal 1 Fire DMG to him.", [":fire_attack"] = "Fire Attack (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: A player with hand cards<br /><b>Effect</b>: The target player shows 1 hand card; then, if you discard 1 card with the same suit, you deal 1 Fire DMG to him.",
["#fire_attack-show"] = "%src used Fire Attack to you, please show 1 hand card", ["#fire_attack-show"] = "%src used Fire Attack to you, please show 1 hand card",
["#fire_attack-discard"] = "You can discard 1 %arg hand card, then deal 1 Fire DMG to %src", ["#fire_attack-discard"] = "You can discard 1 %arg hand card, then deal 1 Fire DMG to %src",
["#fire_attack_skill"] = "Choose a player with hand cards. He shows 1 hand card;<br />then, if you discard 1 card with the same suit, you deal 1 Fire DMG to him",
["supply_shortage"] = "Supply Shortage", ["supply_shortage"] = "Supply Shortage",
[":supply_shortage"] = "Supply Shortage (delayed trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player at distance 1<br /><b>Effect</b>: Place this card in target's judgement area. He performs a judgement in his judge phase: if result is not club, he skips his draw phase.", [":supply_shortage"] = "Supply Shortage (delayed trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player at distance 1<br /><b>Effect</b>: Place this card in target's judgement area. He performs a judgement in his judge phase: if result is not ♣, he skips his draw phase.",
["#supply_shortage_skill"] = "Place this card in another player's judgement area. He performs a judgement in his judge phase:<br />If result is not ♣, he skips his draw phase",
["guding_blade"] = "Ancient Scimitar", ["guding_blade"] = "Ancient Scimitar",
[":guding_blade"] = "Ancient Scimitar (equip card, weapon)<br /><b>ATK range</b>: 2<br /><b>Weapon skill</b>: When your used Slash is about to cause DMG, if the target player has no hand cards: the DMG is increased by +1.", [":guding_blade"] = "Ancient Scimitar (equip card, weapon)<br /><b>ATK range</b>: 2<br /><b>Weapon skill</b>: When your used Slash is about to cause DMG, if the target player has no hand cards: the DMG is increased by +1.",

View File

@ -6,6 +6,19 @@ local slash = Fk:cloneCard("slash")
local thunderSlashSkill = fk.CreateActiveSkill{ local thunderSlashSkill = fk.CreateActiveSkill{
name = "thunder__slash_skill", name = "thunder__slash_skill",
prompt = function(self, selected_cards)
local card = Fk:cloneCard("thunder__slash")
card.subcards = Card:getIdList(selected_cards)
local max_num = self:getMaxTargetNum(Self, card)
if max_num > 1 then
local num = #table.filter(Fk:currentRoom().alive_players, function (p)
return p ~= Self and not Self:isProhibited(p, card)
end)
max_num = math.min(num, max_num)
end
card.subcards = {}
return max_num > 1 and "#thunder__slash_skill_multi:::" .. max_num or "#thunder__slash_skill"
end,
max_phase_use_time = 1, max_phase_use_time = 1,
target_num = 1, target_num = 1,
can_use = slash.skill.canUse, can_use = slash.skill.canUse,
@ -45,6 +58,19 @@ extension:addCards{
local fireSlashSkill = fk.CreateActiveSkill{ local fireSlashSkill = fk.CreateActiveSkill{
name = "fire__slash_skill", name = "fire__slash_skill",
prompt = function(self, selected_cards)
local card = Fk:cloneCard("fire__slash")
card.subcards = Card:getIdList(selected_cards)
local max_num = self:getMaxTargetNum(Self, card)
if max_num > 1 then
local num = #table.filter(Fk:currentRoom().alive_players, function (p)
return p ~= Self and not Self:isProhibited(p, card)
end)
max_num = math.min(num, max_num)
end
card.subcards = {}
return max_num > 1 and "#fire__slash_skill_multi:::" .. max_num or "#fire__slash_skill"
end,
max_phase_use_time = 1, max_phase_use_time = 1,
target_num = 1, target_num = 1,
can_use = slash.skill.canUse, can_use = slash.skill.canUse,
@ -80,8 +106,9 @@ extension:addCards{
local analepticSkill = fk.CreateActiveSkill{ local analepticSkill = fk.CreateActiveSkill{
name = "analeptic_skill", name = "analeptic_skill",
prompt = "#analeptic_skill",
max_turn_use_time = 1, max_turn_use_time = 1,
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = function(self, to_select, _, _, card, _)
return self:withinTimesLimit(Fk:currentRoom():getPlayerById(to_select), Player.HistoryTurn, card, "analeptic", Fk:currentRoom():getPlayerById(to_select)) and return self:withinTimesLimit(Fk:currentRoom():getPlayerById(to_select), Player.HistoryTurn, card, "analeptic", Fk:currentRoom():getPlayerById(to_select)) and
not table.find(Fk:currentRoom().alive_players, function(p) not table.find(Fk:currentRoom().alive_players, function(p)
return p.dying return p.dying
@ -90,7 +117,7 @@ local analepticSkill = fk.CreateActiveSkill{
can_use = function(self, player, card) can_use = function(self, player, card)
return self:withinTimesLimit(player, Player.HistoryTurn, card, "analeptic", player) return self:withinTimesLimit(player, Player.HistoryTurn, card, "analeptic", player)
end, end,
on_use = function(self, room, use) on_use = function(_, _, use)
if not use.tos or #TargetGroup:getRealTargets(use.tos) == 0 then if not use.tos or #TargetGroup:getRealTargets(use.tos) == 0 then
use.tos = { { use.from } } use.tos = { { use.from } }
end end
@ -99,7 +126,7 @@ local analepticSkill = fk.CreateActiveSkill{
use.extraUse = true use.extraUse = true
end end
end, end,
on_effect = function(self, room, effect) on_effect = function(_, room, effect)
local to = room:getPlayerById(effect.to) local to = room:getPlayerById(effect.to)
if effect.extra_data and effect.extra_data.analepticRecover then if effect.extra_data and effect.extra_data.analepticRecover then
room:recover({ room:recover({
@ -120,7 +147,7 @@ local analepticEffect = fk.CreateTriggerSkill{
global = true, global = true,
priority = 0, -- game rule priority = 0, -- game rule
events = { fk.PreCardUse, fk.EventPhaseStart }, events = { fk.PreCardUse, fk.EventPhaseStart },
can_trigger = function(self, event, target, player, data) can_trigger = function(_, event, target, player, data)
if target ~= player then if target ~= player then
return false return false
end end
@ -131,7 +158,7 @@ local analepticEffect = fk.CreateTriggerSkill{
return target.phase == Player.NotActive return target.phase == Player.NotActive
end end
end, end,
on_trigger = function(self, event, target, player, data) on_trigger = function(_, event, _, player, data)
local room = player.room local room = player.room
if event == fk.PreCardUse then if event == fk.PreCardUse then
data.additionalDamage = (data.additionalDamage or 0) + player.drank data.additionalDamage = (data.additionalDamage or 0) + player.drank
@ -168,8 +195,9 @@ extension:addCards({
local recast = fk.CreateActiveSkill{ local recast = fk.CreateActiveSkill{
name = "recast", name = "recast",
prompt = "#recast",
target_num = 0, target_num = 0,
on_use = function(self, room, effect) on_use = function(_, room, effect)
room:recastCard(effect.cards, room:getPlayerById(effect.from)) room:recastCard(effect.cards, room:getPlayerById(effect.from))
end end
} }
@ -177,17 +205,16 @@ Fk:addSkill(recast)
local ironChainCardSkill = fk.CreateActiveSkill{ local ironChainCardSkill = fk.CreateActiveSkill{
name = "iron_chain_skill", name = "iron_chain_skill",
prompt = "#iron_chain_skill",
min_target_num = 1, min_target_num = 1,
max_target_num = 2, max_target_num = 2,
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = Util.TrueFunc,
return true
end,
target_filter = function(self, to_select, selected, _, card) target_filter = function(self, to_select, selected, _, card)
if #selected < self:getMaxTargetNum(Self, card) then if #selected < self:getMaxTargetNum(Self, card) then
return self:modTargetFilter(to_select, selected, Self.id, card) return self:modTargetFilter(to_select, selected, Self.id, card)
end end
end, end,
on_effect = function(self, room, cardEffectEvent) on_effect = function(_, room, cardEffectEvent)
local to = room:getPlayerById(cardEffectEvent.to) local to = room:getPlayerById(cardEffectEvent.to)
to:setChainState(not to.chained) to:setChainState(not to.chained)
end, end,
@ -210,8 +237,9 @@ extension:addCards{
local fireAttackSkill = fk.CreateActiveSkill{ local fireAttackSkill = fk.CreateActiveSkill{
name = "fire_attack_skill", name = "fire_attack_skill",
prompt = "#fire_attack_skill",
target_num = 1, target_num = 1,
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = function(_, to_select, _, _, _, _)
local to = Fk:currentRoom():getPlayerById(to_select) local to = Fk:currentRoom():getPlayerById(to_select)
return not to:isKongcheng() return not to:isKongcheng()
end, end,
@ -256,8 +284,9 @@ extension:addCards{
local supplyShortageSkill = fk.CreateActiveSkill{ local supplyShortageSkill = fk.CreateActiveSkill{
name = "supply_shortage_skill", name = "supply_shortage_skill",
prompt = "#supply_shortage_skill",
distance_limit = 1, distance_limit = 1,
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = function(self, to_select, _, user, card, distance_limited)
local player = Fk:currentRoom():getPlayerById(to_select) local player = Fk:currentRoom():getPlayerById(to_select)
local from = Fk:currentRoom():getPlayerById(user) local from = Fk:currentRoom():getPlayerById(user)
return from ~= player and not (distance_limited and not self:withinDistanceLimit(from, false, card, player)) return from ~= player and not (distance_limited and not self:withinDistanceLimit(from, false, card, player))
@ -302,8 +331,8 @@ local gudingSkill = fk.CreateTriggerSkill{
attached_equip = "guding_blade", attached_equip = "guding_blade",
frequency = Skill.Compulsory, frequency = Skill.Compulsory,
events = {fk.DamageCaused}, events = {fk.DamageCaused},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, _, target, player, data)
return target == player and player:hasSkill(self.name) and return target == player and player:hasSkill(self) and
data.to:isKongcheng() and data.card and data.card.trueName == "slash" and data.to:isKongcheng() and data.card and data.card.trueName == "slash" and
not data.chain not data.chain
end, end,
@ -326,8 +355,8 @@ local fanSkill = fk.CreateTriggerSkill{
name = "#fan_skill", name = "#fan_skill",
attached_equip = "fan", attached_equip = "fan",
events = { fk.AfterCardUseDeclared }, events = { fk.AfterCardUseDeclared },
can_trigger = function(self, event, target, player, data) can_trigger = function(self, _, target, player, data)
return target == player and player:hasSkill(self.name) and data.card.name == "slash" return target == player and player:hasSkill(self) and data.card.name == "slash"
end, end,
on_use = function(_, _, _, _, data) on_use = function(_, _, _, _, data)
local card = Fk:cloneCard("fire__slash") local card = Fk:cloneCard("fire__slash")
@ -356,15 +385,15 @@ local vineSkill = fk.CreateTriggerSkill{
events = {fk.PreCardEffect, fk.DamageInflicted}, events = {fk.PreCardEffect, fk.DamageInflicted},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
if event == fk.DamageInflicted then if event == fk.DamageInflicted then
return target == player and player:hasSkill(self.name) and return target == player and player:hasSkill(self) and
data.damageType == fk.FireDamage data.damageType == fk.FireDamage
end end
local effect = data ---@type CardEffectEvent local effect = data ---@type CardEffectEvent
return player.id == effect.to and player:hasSkill(self.name) and return player.id == effect.to and player:hasSkill(self) and
(effect.card.name == "slash" or effect.card.name == "savage_assault" or (effect.card.name == "slash" or effect.card.name == "savage_assault" or
effect.card.name == "archery_attack") effect.card.name == "archery_attack")
end, end,
on_use = function(self, event, target, player, data) on_use = function(_, event, _, player, data)
local room = player.room local room = player.room
if event == fk.DamageInflicted then if event == fk.DamageInflicted then
room:broadcastPlaySound("./packages/maneuvering/audio/card/vineburn") room:broadcastPlaySound("./packages/maneuvering/audio/card/vineburn")
@ -392,8 +421,8 @@ local silverLionSkill = fk.CreateTriggerSkill{
attached_equip = "silver_lion", attached_equip = "silver_lion",
frequency = Skill.Compulsory, frequency = Skill.Compulsory,
events = {fk.DamageInflicted}, events = {fk.DamageInflicted},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, _, target, player, data)
return target == player and player:hasSkill(self.name) and data.damage > 1 return target == player and player:hasSkill(self) and data.damage > 1
end, end,
on_use = function(_, _, _, _, data) on_use = function(_, _, _, _, data)
data.damage = 1 data.damage = 1
@ -456,31 +485,50 @@ Fk:loadTranslationTable{
["thunder__slash"] = "雷杀", ["thunder__slash"] = "雷杀",
[":thunder__slash"] = "基本牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:攻击范围内的一名角色<br /><b>效果</b>对目标角色造成1点雷电伤害。", [":thunder__slash"] = "基本牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:攻击范围内的一名角色<br /><b>效果</b>对目标角色造成1点雷电伤害。",
["#thunder__slash_skill"] = "选择攻击范围内的一名角色对其造成1点雷电伤害",
["#thunder__slash_skill_multi"] = "选择攻击范围内的至多%arg名角色对这些角色各造成1点雷电伤害",
["fire__slash"] = "火杀", ["fire__slash"] = "火杀",
[":fire__slash"] = "基本牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:攻击范围内的一名角色<br /><b>效果</b>对目标角色造成1点火焰伤害。", [":fire__slash"] = "基本牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:攻击范围内的一名角色<br /><b>效果</b>对目标角色造成1点火焰伤害。",
["#fire__slash_skill"] = "选择攻击范围内的一名角色对其造成1点火焰伤害",
["#fire__slash_skill_multi"] = "选择攻击范围内的至多%arg名角色对这些角色各造成1点火焰伤害",
["analeptic"] = "", ["analeptic"] = "",
[":analeptic"] = "基本牌<br /><b>时机</b>:出牌阶段/你处于濒死状态时<br /><b>目标</b>:你<br /><b>效果</b>:目标角色本回合使用的下一张【杀】将要造成的伤害+1/目标角色回复1点体力。", [":analeptic"] = "基本牌<br /><b>时机</b>:出牌阶段/你处于濒死状态时<br /><b>目标</b>:你<br /><b>效果</b>:目标角色本回合使用的下一张【杀】将要造成的伤害+1/目标角色回复1点体力。",
["#analeptic_skill"] = "你于此回合内使用的下一张【杀】的伤害值基数+1",
["iron_chain"] = "铁锁连环", ["iron_chain"] = "铁锁连环",
[":iron_chain"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:一至两名角色<br /><b>效果</b>:横置或重置目标角色的武将牌。", [":iron_chain"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:一至两名角色<br /><b>效果</b>:横置或重置目标角色的武将牌。",
["#iron_chain_skill"] = "选择一至两名角色,这些角色横置或重置",
["_normal_use"] = "正常使用", ["_normal_use"] = "正常使用",
["recast"] = "重铸", ["recast"] = "重铸",
[":recast"] = "你可以将此牌置入弃牌堆,然后摸一张牌。", [":recast"] = "你可以将此牌置入弃牌堆,然后摸一张牌。",
["#recast"] = "将此牌置入弃牌堆,然后摸一张牌",
["fire_attack"] = "火攻", ["fire_attack"] = "火攻",
["fire_attack_skill"] = "火攻", ["fire_attack_skill"] = "火攻",
[":fire_attack"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:一名有手牌的角色<br /><b>效果</b>:目标角色展示一张手牌,然后你可以弃置一张与所展示牌花色相同的手牌令其受到1点火焰伤害。", [":fire_attack"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:一名有手牌的角色<br /><b>效果</b>:目标角色展示一张手牌,然后你可以弃置一张与此牌花色相同的手牌对其造成1点火焰伤害。",
["#fire_attack-show"] = "%src 对你使用了火攻,请展示一张手牌", ["#fire_attack-show"] = "%src 对你使用了火攻,请展示一张手牌",
["#fire_attack-discard"] = "你可弃置一张 %arg 手牌,对 %src 造成1点火属性伤害", ["#fire_attack-discard"] = "你可弃置一张 %arg 手牌,对 %src 造成1点火属性伤害",
["#fire_attack_skill"] = "选择一名有手牌的角色,令其展示一张手牌,<br />然后你可以弃置一张与此牌花色相同的手牌对其造成1点火焰伤害",
["supply_shortage"] = "兵粮寸断", ["supply_shortage"] = "兵粮寸断",
[":supply_shortage"] = "延时锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>距离1的一名其他角色<br /><b>效果</b>:将此牌置于目标角色判定区内。其判定阶段进行判定:若结果不为梅花,其跳过摸牌阶段。然后将【兵粮寸断】置入弃牌堆。", [":supply_shortage"] = "延时锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>距离1的一名其他角色<br /><b>效果</b>:将此牌置于目标角色判定区内。其判定阶段进行判定:若结果不为♣,其跳过摸牌阶段。然后将【兵粮寸断】置入弃牌堆。",
["#supply_shortage_skill"] = "选择距离1的一名角色将此牌置于其判定区内。其判定阶段判定<br />若结果不为♣,其跳过摸牌阶段",
["guding_blade"] = "古锭刀", ["guding_blade"] = "古锭刀",
[":guding_blade"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:锁定技。每当你使用【杀】对目标角色造成伤害时,若该角色没有手牌,此伤害+1。", [":guding_blade"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:锁定技。每当你使用【杀】对目标角色造成伤害时,若该角色没有手牌,此伤害+1。",
["fan"] = "朱雀羽扇", ["fan"] = "朱雀羽扇",
[":fan"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:你可以将一张普通【杀】当火【杀】使用。", [":fan"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:你可以将一张普通【杀】当火【杀】使用。",
["#fan_skill"] = "朱雀羽扇", ["#fan_skill"] = "朱雀羽扇",
["vine"] = "藤甲", ["vine"] = "藤甲",
[":vine"] = "装备牌·防具<br /><b>防具技能</b>:锁定技。【南蛮入侵】、【万箭齐发】和普通【杀】对你无效。每当你受到火焰伤害时,此伤害+1。", [":vine"] = "装备牌·防具<br /><b>防具技能</b>:锁定技。【南蛮入侵】、【万箭齐发】和普通【杀】对你无效。每当你受到火焰伤害时,此伤害+1。",
["silver_lion"] = "白银狮子", ["silver_lion"] = "白银狮子",
[":silver_lion"] = "装备牌·防具<br /><b>防具技能</b>锁定技。每当你受到伤害时若此伤害大于1点防止多余的伤害。每当你失去装备区里的【白银狮子】后你回复1点体力。", [":silver_lion"] = "装备牌·防具<br /><b>防具技能</b>锁定技。每当你受到伤害时若此伤害大于1点防止多余的伤害。每当你失去装备区里的【白银狮子】后你回复1点体力。",
["hualiu"] = "骅骝", ["hualiu"] = "骅骝",
[":hualiu"] = "装备牌·坐骑<br /><b>坐骑技能</b>:其他角色与你的距离+1。", [":hualiu"] = "装备牌·坐骑<br /><b>坐骑技能</b>:其他角色与你的距离+1。",
} }

View File

@ -15,8 +15,8 @@ Fk:loadTranslationTable({
["jianxiong"] = "Villainous Hero", ["jianxiong"] = "Villainous Hero",
[":jianxiong"] = "After you suffer DMG: you can take the card(s) that caused it.", [":jianxiong"] = "After you suffer DMG: you can take the card(s) that caused it.",
["hujia"] = "Royal Escort", ["hujia"] = "Royal Escort",
[":hujia"] = "<b>Lord skill</b>, when you need to use/play Dodge: you can ask other Wei characters to play Dodge, which is regard as you use/play that.", [":hujia"] = "(lord) When you need to use/play Dodge: you can ask other Wei characters to play Dodge, which is regard as you use/play that.",
["#hujia-ask"] = "Royal Escort: you can play a jink, which is regarded as %src uses/plays", ["#hujia-ask"] = "Royal Escort: you can play a Dodge, which is regarded as %src uses/plays",
["simayi"] = "Sima Yi", ["simayi"] = "Sima Yi",
["guicai"] = "Demonic Talent", ["guicai"] = "Demonic Talent",
@ -57,7 +57,7 @@ Fk:loadTranslationTable({
["rende"] = "Benevolence", ["rende"] = "Benevolence",
[":rende"] = "In your Action Phase: you can give any # of hand cards to other players; then, if you have given a total of 2 or more cards, you heal 1 HP (only once).", [":rende"] = "In your Action Phase: you can give any # of hand cards to other players; then, if you have given a total of 2 or more cards, you heal 1 HP (only once).",
["jijiang"] = "Rouse", ["jijiang"] = "Rouse",
[":jijiang"] = "<b>Lord skill</b>, when you need to use/play Slash: you can ask other Shu characters to play Slash, which is regard as you use/play that.", [":jijiang"] = "(lord) When you need to use/play Slash: you can ask other Shu characters to play Slash, which is regard as you use/play that.",
["#jijiang-ask"] = "Rouse: you can play a Slash, which is regarded as %src uses/plays", ["#jijiang-ask"] = "Rouse: you can play a Slash, which is regarded as %src uses/plays",
["guanyu"] = "Guan Yu", ["guanyu"] = "Guan Yu",
@ -66,13 +66,13 @@ Fk:loadTranslationTable({
["zhangfei"] = "Zhang Fei", ["zhangfei"] = "Zhang Fei",
["paoxiao"] = "Roar", ["paoxiao"] = "Roar",
[":paoxiao"] = "<b>Compulsory skill</b>, you can use any # of Slash.", [":paoxiao"] = "(forced) You can use any # of Slash.",
["zhugeliang"] = "Zhuge Liang", ["zhugeliang"] = "Zhuge Liang",
["guanxing"] = "Stargaze", ["guanxing"] = "Stargaze",
[":guanxing"] = "In your Beginning Phase: you can examine X cards from the deck; then, you can place any # of them at the top of the deck and the rest at the bottom. (X = # of living players, max. 5)", [":guanxing"] = "In your Beginning Phase: you can examine X cards from the deck; then, you can place any # of them at the top of the deck and the rest at the bottom. (X = # of living players, max. 5)",
["kongcheng"] = "Empty Fort", ["kongcheng"] = "Empty Fort",
[":kongcheng"] = "<b>Compulsory skill</b>, if you dont have hand cards, you cannot be the target of Sha or Duel.", [":kongcheng"] = "(forced) If you dont have hand cards, you cannot be the target of Sha or Duel.",
["zhaoyun"] = "Zhao Yun", ["zhaoyun"] = "Zhao Yun",
["longdan"] = "Dragon Heart", ["longdan"] = "Dragon Heart",
@ -80,7 +80,7 @@ Fk:loadTranslationTable({
["machao"] = "Ma Chao", ["machao"] = "Ma Chao",
["mashu"] = "Horsemanship", ["mashu"] = "Horsemanship",
[":mashu"] = "<b>Compulsory skill</b>, the distance from you to other players is reduced by -1.", [":mashu"] = "(forced) The distance from you to other players is reduced by -1.",
["tieqi"] = "Iron Cavalry", ["tieqi"] = "Iron Cavalry",
[":tieqi"] = "After you use Slash to target a player: you can perform a judgment; if its red, he can't use Dodge.", [":tieqi"] = "After you use Slash to target a player: you can perform a judgment; if its red, he can't use Dodge.",
@ -88,19 +88,19 @@ Fk:loadTranslationTable({
["jizhi"] = "Wisdom", ["jizhi"] = "Wisdom",
[":jizhi"] = "When you use a non-delay trick card, you can draw 1 card.", [":jizhi"] = "When you use a non-delay trick card, you can draw 1 card.",
["qicai"] = "Genius", ["qicai"] = "Genius",
[":qicai"] = "<b>Compulsory skill</b>, your trick cards have unlimited range.", [":qicai"] = "(forced) Your trick cards have unlimited range.",
["sunquan"] = "Sun Quan", ["sunquan"] = "Sun Quan",
["zhiheng"] = "Balance of Power", ["zhiheng"] = "Balance of Power",
[":zhiheng"] = "Once per Action Phase: you can discard any # of cards; then, draw the same # of cards.", [":zhiheng"] = "Once per Action Phase: you can discard any # of cards; then, draw the same # of cards.",
["jiuyuan"] = "Rescued", ["jiuyuan"] = "Rescued",
[":jiuyuan"] = "<b>Lord skill, compulsory skill</b>, when another Wu character uses Peach to you, you heal +1 HP.", [":jiuyuan"] = "(lord, forced) When another Wu character uses Peach to you, you heal +1 HP.",
["ganning"] = "Gan Ning", ["ganning"] = "Gan Ning",
["qixi"] = "Surprise Raid", ["qixi"] = "Surprise Raid",
[":qixi"] = "You can use any black card as Dismantlement.", [":qixi"] = "You can use any black card as Dismantlement.",
["lvmeng"] = "Lv Meng", ["lvmeng"] = "Lü Meng",
["keji"] = "Self Mastery", ["keji"] = "Self Mastery",
[":keji"] = "If you haven't used/played Slash in your Action Phase, you can skip your Discard Phase.", [":keji"] = "If you haven't used/played Slash in your Action Phase, you can skip your Discard Phase.",
@ -123,7 +123,7 @@ Fk:loadTranslationTable({
["luxun"] = "Lu Xun", ["luxun"] = "Lu Xun",
["qianxun"] = "Humility", ["qianxun"] = "Humility",
[":qianxun"] = "<b>Compulsory skill</b>, you can't be the target of Snatch or Indulgence.", [":qianxun"] = "(forced) You can't be the target of Snatch or Indulgence.",
["lianying"] = "One After Another", ["lianying"] = "One After Another",
[":lianying"] = "When you lose your last hand card: you can draw 1 card.", [":lianying"] = "When you lose your last hand card: you can draw 1 card.",
@ -139,9 +139,9 @@ Fk:loadTranslationTable({
["jijiu"] = "First Aid", ["jijiu"] = "First Aid",
[":jijiu"] = "Outside of your turn: you can use any red card as Peach.", [":jijiu"] = "Outside of your turn: you can use any red card as Peach.",
["lvbu"] = "Lv Bu", ["lvbu"] = "Lü Bu",
["wushuang"] = "Without Equal", ["wushuang"] = "Without Equal",
[":wushuang"] = "<b>Compulsory skill</b>, if you use Slash to target a player, the target needs to use 2 Dodge to evade it. During Duel, the opponent must play 2 Slash per round.", [":wushuang"] = "(forced) If you use Slash to target a player, the target needs to use 2 Dodge to evade it. During Duel, the opponent must play 2 Slash per round.",
["diaochan"] = "Diao Chan", ["diaochan"] = "Diao Chan",
["lijian"] = "Seed of Animosity", ["lijian"] = "Seed of Animosity",
@ -199,7 +199,17 @@ Fk:loadTranslationTable({
["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",
[":reveal_skill"] = "In action phase, you can reveal a character who has Compulsory skills.", [":reveal_skill"] = "In action phase, you can reveal a character who has Forced skills.",
["game_rule"] = "Discard", ["game_rule"] = "Discard",
}, "en_US") }, "en_US")
-- init
Fk:loadTranslationTable({
["left lord and loyalist alive"] = "You're the only surviving Renegade and all others alive are lord and loyalists.",
["left one rebel alive"] = "You're the only surviving Rebel and there's no surviving Renegade.",
["left you alive"] = "No surviving loyalists and only another fraction remains.",
["loyalist never surrender"] = "Loyalist never surrender!",
["anjiang"] = "Hidden Char.",
}, "en_US")

View File

@ -55,7 +55,7 @@ Fk:loadTranslationTable{
["$luoyi1"] = "脱!", ["$luoyi1"] = "脱!",
["$luoyi2"] = "谁来与我大战三百回合?", ["$luoyi2"] = "谁来与我大战三百回合?",
["luoyi"] = "裸衣", ["luoyi"] = "裸衣",
[":luoyi"] = "摸牌阶段,你可以少摸一张牌,若如此做,本回合你使用【杀】或【决斗】对目标角色造成伤害时,此伤害+1。", [":luoyi"] = "摸牌阶段,你可以少摸一张牌,然后本回合你使用【杀】或【决斗】对目标角色造成伤害时,此伤害+1。",
["guojia"] = "郭嘉", ["guojia"] = "郭嘉",
["~guojia"] = "咳,咳……", ["~guojia"] = "咳,咳……",
@ -66,7 +66,7 @@ Fk:loadTranslationTable{
["$yiji1"] = "也好。", ["$yiji1"] = "也好。",
["$yiji2"] = "罢了。", ["$yiji2"] = "罢了。",
["yiji"] = "遗计", ["yiji"] = "遗计",
[":yiji"] = "当你受到1点伤害后你可以观看牌堆顶的两张牌并任意分配它们。", [":yiji"] = "当你受到1点伤害后你可以观看牌堆顶的两张牌并任意分配它们。",
["yiji_active"] = "遗计", ["yiji_active"] = "遗计",
["#yiji-give"] = "遗计:你可以将这些牌分配给任意角色,点“取消”自己保留", ["#yiji-give"] = "遗计:你可以将这些牌分配给任意角色,点“取消”自己保留",
@ -75,7 +75,7 @@ Fk:loadTranslationTable{
["$luoshen1"] = "髣髴兮若轻云之蔽月。", ["$luoshen1"] = "髣髴兮若轻云之蔽月。",
["$luoshen2"] = "飘飖兮若流风之回雪。", ["$luoshen2"] = "飘飖兮若流风之回雪。",
["luoshen"] = "洛神", ["luoshen"] = "洛神",
[":luoshen"] = "准备阶段开始时,你可以进行判定:若结果为黑色,判定牌生效后你获得之,然后你可以再次发动“洛神”", [":luoshen"] = "准备阶段开始时,你可以进行判定:若结果为黑色,判定牌生效后你获得之,然后你可以重复此流程",
["#luoshen_obtain"] = "洛神", ["#luoshen_obtain"] = "洛神",
["$qingguo1"] = "凌波微步,罗袜生尘。", ["$qingguo1"] = "凌波微步,罗袜生尘。",
["$qingguo2"] = "体迅飞凫,飘忽若神。", ["$qingguo2"] = "体迅飞凫,飘忽若神。",
@ -129,27 +129,27 @@ Fk:loadTranslationTable{
["machao"] = "马超", ["machao"] = "马超",
["~machao"] = "(马蹄远去声)", ["~machao"] = "(马蹄远去声)",
["mashu"] = "马术", ["mashu"] = "马术",
[":mashu"] = "锁定技你与其他角色的距离-1。", [":mashu"] = "锁定技你与其他角色的距离-1。",
["$tieqi1"] = "全军突击!", ["$tieqi1"] = "全军突击!",
["$tieqi2"] = "(马蹄、马嘶声)", ["$tieqi2"] = "(马蹄、马嘶声)",
["tieqi"] = "铁骑", ["tieqi"] = "铁骑",
[":tieqi"] = "当你指定【杀】的目标后,你可以进行判定:若结果为红色,该角色不能使用【闪】响应此【杀】。", [":tieqi"] = "当你指定【杀】的目标后,你可以进行判定:若结果为红色,该角色不能使用【闪】响应此【杀】。",
["huangyueying"] = "黄月英", ["huangyueying"] = "黄月英",
["~huangyueying"] = "亮……", ["~huangyueying"] = "亮……",
["$jizhi1"] = "哼哼~", ["$jizhi1"] = "哼哼~",
["$jizhi2"] = "哼~", ["$jizhi2"] = "哼~",
["jizhi"] = "集智", ["jizhi"] = "集智",
[":jizhi"] = "每当你使用一张非延时锦囊牌时,你可以摸一张牌。", [":jizhi"] = "当你使用非转化的普通锦囊牌时,你可摸一张牌。",
["qicai"] = "奇才", ["qicai"] = "奇才",
[":qicai"] = "锁定技你使用锦囊牌无距离限制。", [":qicai"] = "锁定技你使用锦囊牌无距离限制。",
["sunquan"] = "孙权", ["sunquan"] = "孙权",
["~sunquan"] = "父亲,大哥,仲谋愧矣……", ["~sunquan"] = "父亲,大哥,仲谋愧矣……",
["$zhiheng1"] = "容我三思。", ["$zhiheng1"] = "容我三思。",
["$zhiheng2"] = "且慢。", ["$zhiheng2"] = "且慢。",
["zhiheng"] = "制衡", ["zhiheng"] = "制衡",
[":zhiheng"] = "阶段技,你可以弃置至少一张牌然后摸等量的牌。", [":zhiheng"] = "出牌阶段限一次,你可以弃置至少一张牌然后摸等量的牌。",
["$jiuyuan1"] = "有汝辅佐,甚好!", ["$jiuyuan1"] = "有汝辅佐,甚好!",
["$jiuyuan2"] = "好舒服啊。", ["$jiuyuan2"] = "好舒服啊。",
["jiuyuan"] = "救援", ["jiuyuan"] = "救援",
@ -196,7 +196,7 @@ Fk:loadTranslationTable{
["$liuli1"] = "交给你了。", ["$liuli1"] = "交给你了。",
["$liuli2"] = "你来嘛~", ["$liuli2"] = "你来嘛~",
["liuli"] = "流离", ["liuli"] = "流离",
[":liuli"] = "当你成为【杀】的目标时,你可以弃置一张牌并选择你攻击范围内为此【杀】合法目标(无距离限制)的一名角色:若如此做,该角色代替你成为此【杀】的目标。", [":liuli"] = "当你成为【杀】的目标时,你可以弃置一张牌并选择你攻击范围内为此【杀】合法目标(无距离限制)的一名角色:若如此做,该角色代替你成为此【杀】的目标。",
["#liuli-target"] = "流离:你可以弃置一张牌,将【杀】的目标转移给一名其他角色", ["#liuli-target"] = "流离:你可以弃置一张牌,将【杀】的目标转移给一名其他角色",
["luxun"] = "陆逊", ["luxun"] = "陆逊",
@ -208,25 +208,25 @@ Fk:loadTranslationTable{
["$lianying1"] = "牌不是万能的,但是没牌是万万不能的。", ["$lianying1"] = "牌不是万能的,但是没牌是万万不能的。",
["$lianying2"] = "旧的不去,新的不来。", ["$lianying2"] = "旧的不去,新的不来。",
["lianying"] = "连营", ["lianying"] = "连营",
[":lianying"] = "当你失去最后的手牌后,你可以摸一张牌。", [":lianying"] = "当你失去最后的手牌后,你可以摸一张牌。",
["sunshangxiang"] = "孙尚香", ["sunshangxiang"] = "孙尚香",
["~sunshangxiang"] = "不,还不可以死……", ["~sunshangxiang"] = "不,还不可以死……",
["$xiaoji1"] = "哼!", ["$xiaoji1"] = "哼!",
["$xiaoji2"] = "看我的厉害!", ["$xiaoji2"] = "看我的厉害!",
["xiaoji"] = "枭姬", ["xiaoji"] = "枭姬",
[":xiaoji"] = "当你失去一张装备区的装备牌后,你可以摸两张牌。", [":xiaoji"] = "当你失去一张装备区的装备牌后,你可以摸两张牌。",
["$jieyin1"] = "夫君,身体要紧。", ["$jieyin1"] = "夫君,身体要紧。",
["$jieyin2"] = "他好,我也好。", ["$jieyin2"] = "他好,我也好。",
["jieyin"] = "结姻", ["jieyin"] = "结姻",
[":jieyin"] = "阶段技你可以弃置两张手牌并选择一名已受伤的男性角色若如此做你和该角色各回复1点体力。", [":jieyin"] = "出牌阶段限一次你可以弃置两张手牌并选择一名已受伤的男性角色若如此做你和该角色各回复1点体力。",
["huatuo"] = "华佗", ["huatuo"] = "华佗",
["~huatuo"] = "医者……不能自医啊……", ["~huatuo"] = "医者……不能自医啊……",
["$qingnang1"] = "早睡早起,方能养生。", ["$qingnang1"] = "早睡早起,方能养生。",
["$qingnang2"] = "越老越要补啊。", ["$qingnang2"] = "越老越要补啊。",
["qingnang"] = "青囊", ["qingnang"] = "青囊",
[":qingnang"] = "阶段技你可以弃置一张手牌并选择一名已受伤的角色若如此做该角色回复1点体力。", [":qingnang"] = "出牌阶段限一次你可以弃置一张手牌并选择一名已受伤的角色若如此做该角色回复1点体力。",
["$jijiu1"] = "别紧张,有老夫呢。", ["$jijiu1"] = "别紧张,有老夫呢。",
["$jijiu2"] = "救人一命,胜造七级浮屠。", ["$jijiu2"] = "救人一命,胜造七级浮屠。",
["jijiu"] = "急救", ["jijiu"] = "急救",
@ -244,7 +244,7 @@ Fk:loadTranslationTable{
["$lijian1"] = "嗯呵呵~~呵呵~~", ["$lijian1"] = "嗯呵呵~~呵呵~~",
["$lijian2"] = "夫君,你要替妾身作主啊……", ["$lijian2"] = "夫君,你要替妾身作主啊……",
["lijian"] = "离间", ["lijian"] = "离间",
[":lijian"] = "阶段技,你可以弃置一张牌并选择两名其他男性角色,后选择的角色视为对先选择的角色使用了一张不能被无懈可击的决斗。", [":lijian"] = "出牌阶段限一次,你可以弃置一张牌并选择两名其他男性角色,后选择的角色视为对先选择的角色使用了一张不能被无懈可击的决斗。",
["$biyue1"] = "失礼了~", ["$biyue1"] = "失礼了~",
["$biyue2"] = "羡慕吧~", ["$biyue2"] = "羡慕吧~",
["biyue"] = "闭月", ["biyue"] = "闭月",

View File

@ -10,7 +10,7 @@ local jianxiong = fk.CreateTriggerSkill{
anim_type = "masochism", anim_type = "masochism",
events = {fk.Damaged}, events = {fk.Damaged},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
if target == player and player:hasSkill(self.name) and data.card then if target == player and player:hasSkill(self) and data.card then
local room = player.room local room = player.room
local subcards = data.card:isVirtual() and data.card.subcards or {data.card.id} local subcards = data.card:isVirtual() and data.card.subcards or {data.card.id}
return #subcards>0 and table.every(subcards, function(id) return room:getCardArea(id) == Card.Processing end) return #subcards>0 and table.every(subcards, function(id) return room:getCardArea(id) == Card.Processing end)
@ -78,7 +78,7 @@ local guicai = fk.CreateTriggerSkill{
anim_type = "control", anim_type = "control",
events = {fk.AskForRetrial}, events = {fk.AskForRetrial},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return player:hasSkill(self.name) and not player:isKongcheng() return player:hasSkill(self) and not player:isKongcheng()
end, end,
on_cost = function(self, event, target, player, data) on_cost = function(self, event, target, player, data)
local room = player.room local room = player.room
@ -98,7 +98,7 @@ local fankui = fk.CreateTriggerSkill{
anim_type = "masochism", anim_type = "masochism",
events = {fk.Damaged}, events = {fk.Damaged},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
if target == player and player:hasSkill(self.name) and data.from and not data.from.dead then if target == player and player:hasSkill(self) and data.from and not data.from.dead then
if data.from == player then if data.from == player then
return #player.player_cards[Player.Equip] > 0 return #player.player_cards[Player.Equip] > 0
else else
@ -122,9 +122,6 @@ local ganglie = fk.CreateTriggerSkill{
name = "ganglie", name = "ganglie",
anim_type = "masochism", anim_type = "masochism",
events = {fk.Damaged}, events = {fk.Damaged},
can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name)
end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
local room = player.room local room = player.room
local from = data.from local from = data.from
@ -156,13 +153,13 @@ local tuxi = fk.CreateTriggerSkill{
anim_type = "control", anim_type = "control",
events = {fk.EventPhaseStart}, events = {fk.EventPhaseStart},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and player.phase == Player.Draw and return target == player and player:hasSkill(self) and player.phase == Player.Draw and
table.find(player.room:getOtherPlayers(player), function(p) return not p:isKongcheng() end) table.find(player.room:getOtherPlayers(player), function(p) return not p:isKongcheng() end)
end, end,
on_cost = function(self, event, target, player, data) on_cost = function(self, event, target, player, data)
local room = player.room local room = player.room
local targets = table.map(table.filter(room:getOtherPlayers(player), function(p) local targets = table.map(table.filter(room:getOtherPlayers(player), function(p)
return not p:isKongcheng() end), function (p) return p.id end) return not p:isKongcheng() end), Util.IdMapper)
local result = room:askForChoosePlayers(player, targets, 1, 2, "#tuxi-ask", self.name) local result = room:askForChoosePlayers(player, targets, 1, 2, "#tuxi-ask", self.name)
if #result > 0 then if #result > 0 then
@ -191,7 +188,7 @@ local luoyi = fk.CreateTriggerSkill{
anim_type = "offensive", anim_type = "offensive",
events = {fk.DrawNCards}, events = {fk.DrawNCards},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and data.n > 0 return target == player and player:hasSkill(self) and data.n > 0
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
data.n = data.n - 1 data.n = data.n - 1
@ -205,9 +202,7 @@ local luoyi_trigger = fk.CreateTriggerSkill{
return target == player and player:usedSkillTimes("luoyi", Player.HistoryTurn) > 0 and return target == player and player:usedSkillTimes("luoyi", Player.HistoryTurn) > 0 and
not data.chain and data.card and (data.card.trueName == "slash" or data.card.name == "duel") not data.chain and data.card and (data.card.trueName == "slash" or data.card.name == "duel")
end, end,
on_cost = function(self, event, target, player, data) on_cost = Util.TrueFunc,
return true
end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
local room = player.room local room = player.room
player:broadcastSkillInvoke("luoyi") player:broadcastSkillInvoke("luoyi")
@ -224,7 +219,7 @@ local tiandu = fk.CreateTriggerSkill{
anim_type = "drawcard", anim_type = "drawcard",
events = {fk.FinishJudge}, events = {fk.FinishJudge},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and player.room:getCardArea(data.card) == Card.Processing return target == player and player:hasSkill(self) and player.room:getCardArea(data.card) == Card.Processing
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
player.room:obtainCard(player.id, data.card, true, fk.ReasonJustMove) player.room:obtainCard(player.id, data.card, true, fk.ReasonJustMove)
@ -332,7 +327,7 @@ local luoshen = fk.CreateTriggerSkill{
anim_type = "drawcard", anim_type = "drawcard",
events = {fk.EventPhaseStart}, events = {fk.EventPhaseStart},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and player.phase == Player.Start return target == player and player:hasSkill(self) and player.phase == Player.Start
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
local room = player.room local room = player.room
@ -419,9 +414,7 @@ local jijiang = fk.CreateViewAsSkill{
name = "jijiang$", name = "jijiang$",
anim_type = "offensive", anim_type = "offensive",
pattern = "slash", pattern = "slash",
card_filter = function(self, to_select, selected) card_filter = Util.FalseFunc,
return false
end,
view_as = function(self, cards) view_as = function(self, cards)
if #cards ~= 0 then if #cards ~= 0 then
return nil return nil
@ -517,7 +510,7 @@ local paoxiaoAudio = fk.CreateTriggerSkill{
visible = false, visible = false,
refresh_events = {fk.CardUsing}, refresh_events = {fk.CardUsing},
can_refresh = function(self, event, target, player, data) can_refresh = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and return target == player and player:hasSkill(self) and
data.card.trueName == "slash" and data.card.trueName == "slash" and
player:usedCardTimes("slash") > 1 player:usedCardTimes("slash") > 1
end, end,
@ -534,7 +527,7 @@ local paoxiao = fk.CreateTargetModSkill{
name = "paoxiao", name = "paoxiao",
frequency = Skill.Compulsory, frequency = Skill.Compulsory,
bypass_times = function(self, player, skill, scope) bypass_times = function(self, player, skill, scope)
if player:hasSkill(self.name) and skill.trueName == "slash_skill" if player:hasSkill(self) and skill.trueName == "slash_skill"
and scope == Player.HistoryPhase then and scope == Player.HistoryPhase then
return true return true
end end
@ -549,7 +542,7 @@ local guanxing = fk.CreateTriggerSkill{
anim_type = "control", anim_type = "control",
events = {fk.EventPhaseStart}, events = {fk.EventPhaseStart},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and return target == player and player:hasSkill(self) and
player.phase == Player.Start player.phase == Player.Start
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
@ -561,7 +554,7 @@ local kongchengAudio = fk.CreateTriggerSkill{
name = "#kongchengAudio", name = "#kongchengAudio",
refresh_events = {fk.AfterCardsMove}, refresh_events = {fk.AfterCardsMove},
can_refresh = function(self, event, target, player, data) can_refresh = function(self, event, target, player, data)
if not player:hasSkill(self.name) then return end if not player:hasSkill(self) then return end
if not player:isKongcheng() then return end if not player:isKongcheng() then return end
for _, move in ipairs(data) do for _, move in ipairs(data) do
if move.from == player.id then if move.from == player.id then
@ -582,7 +575,7 @@ local kongcheng = fk.CreateProhibitSkill{
name = "kongcheng", name = "kongcheng",
frequency = Skill.Compulsory, frequency = Skill.Compulsory,
is_prohibited = function(self, from, to, card) is_prohibited = function(self, from, to, card)
if to:hasSkill(self.name) and to:isKongcheng() then if to:hasSkill(self) and to:isKongcheng() then
return card.trueName == "slash" or card.trueName == "duel" return card.trueName == "slash" or card.trueName == "duel"
end end
end, end,
@ -631,7 +624,7 @@ local mashu = fk.CreateDistanceSkill{
name = "mashu", name = "mashu",
frequency = Skill.Compulsory, frequency = Skill.Compulsory,
correct_func = function(self, from, to) correct_func = function(self, from, to)
if from:hasSkill(self.name) then if from:hasSkill(self) then
return -1 return -1
end end
end, end,
@ -641,7 +634,7 @@ local tieqi = fk.CreateTriggerSkill{
anim_type = "offensive", anim_type = "offensive",
events = {fk.TargetSpecified}, events = {fk.TargetSpecified},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and return target == player and player:hasSkill(self) and
data.card.trueName == "slash" data.card.trueName == "slash"
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
@ -666,7 +659,7 @@ local jizhi = fk.CreateTriggerSkill{
anim_type = "drawcard", anim_type = "drawcard",
events = {fk.CardUsing}, events = {fk.CardUsing},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and data.card:isCommonTrick() and return target == player and player:hasSkill(self) and data.card:isCommonTrick() and
(not data.card:isVirtual() or #data.card.subcards == 0) (not data.card:isVirtual() or #data.card.subcards == 0)
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
@ -677,7 +670,7 @@ local qicai = fk.CreateTargetModSkill{
name = "qicai", name = "qicai",
frequency = Skill.Compulsory, frequency = Skill.Compulsory,
bypass_distances = function(self, player, skill, card) bypass_distances = function(self, player, skill, card)
return player:hasSkill(self.name) and card and card.type == Card.TypeTrick return player:hasSkill(self) and card and card.type == Card.TypeTrick
end, end,
} }
local huangyueying = General:new(extension, "huangyueying", "shu", 3, 3, General.Female) local huangyueying = General:new(extension, "huangyueying", "shu", 3, 3, General.Female)
@ -690,11 +683,11 @@ local zhiheng = fk.CreateActiveSkill{
can_use = function(self, player) can_use = function(self, player)
return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
end, end,
card_filter = function(self, to_select, selected)
return not Self:prohibitDiscard(Fk:getCardById(to_select))
end,
target_num = 0, target_num = 0,
min_card_num = 1, min_card_num = 1,
card_filter = function(self, to_select)
return not Self:prohibitDiscard(Fk:getCardById(to_select))
end,
on_use = function(self, room, effect) on_use = function(self, room, effect)
local from = room:getPlayerById(effect.from) local from = room:getPlayerById(effect.from)
room:throwCard(effect.cards, self.name, from, from) room:throwCard(effect.cards, self.name, from, from)
@ -712,7 +705,7 @@ local jiuyuan = fk.CreateTriggerSkill{
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return return
target == player and target == player and
player:hasSkill(self.name) and player:hasSkill(self) and
data.card and data.card and
data.card.trueName == "peach" and data.card.trueName == "peach" and
data.recoverBy and data.recoverBy and
@ -754,7 +747,7 @@ local keji = fk.CreateTriggerSkill{
anim_type = "defensive", anim_type = "defensive",
events = {fk.EventPhaseChanging}, events = {fk.EventPhaseChanging},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
if target == player and player:hasSkill(self.name) and data.to == Player.Discard then if target == player and player:hasSkill(self) and data.to == Player.Discard then
local room = player.room local room = player.room
local logic = room.logic local logic = room.logic
local e = logic:getCurrentEvent():findParent(GameEvent.Turn, true) local e = logic:getCurrentEvent():findParent(GameEvent.Turn, true)
@ -866,7 +859,7 @@ local liuli = fk.CreateTriggerSkill{
anim_type = "defensive", anim_type = "defensive",
events = {fk.TargetConfirming}, events = {fk.TargetConfirming},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
local ret = target == player and player:hasSkill(self.name) and local ret = target == player and player:hasSkill(self) and
data.card.trueName == "slash" data.card.trueName == "slash"
if ret then if ret then
local room = player.room local room = player.room
@ -912,7 +905,7 @@ local qianxun = fk.CreateProhibitSkill{
name = "qianxun", name = "qianxun",
frequency = Skill.Compulsory, frequency = Skill.Compulsory,
is_prohibited = function(self, from, to, card) is_prohibited = function(self, from, to, card)
if to:hasSkill(self.name) then if to:hasSkill(self) then
return card.name == "indulgence" or card.name == "snatch" return card.name == "indulgence" or card.name == "snatch"
end end
end, end,
@ -922,7 +915,7 @@ local lianying = fk.CreateTriggerSkill{
anim_type = "drawcard", anim_type = "drawcard",
events = {fk.AfterCardsMove}, events = {fk.AfterCardsMove},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
if not player:hasSkill(self.name) then return end if not player:hasSkill(self) then return end
if not player:isKongcheng() then return end if not player:isKongcheng() then return end
for _, move in ipairs(data) do for _, move in ipairs(data) do
if move.from == player.id then if move.from == player.id then
@ -947,7 +940,7 @@ local xiaoji = fk.CreateTriggerSkill{
anim_type = "drawcard", anim_type = "drawcard",
events = {fk.AfterCardsMove}, events = {fk.AfterCardsMove},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
if not player:hasSkill(self.name) then return end if not player:hasSkill(self) then return end
for _, move in ipairs(data) do for _, move in ipairs(data) do
if move.from == player.id then if move.from == player.id then
for _, info in ipairs(move.moveInfo) do for _, info in ipairs(move.moveInfo) do
@ -992,7 +985,7 @@ local jieyin = fk.CreateActiveSkill{
return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
end, end,
card_filter = function(self, to_select, selected) card_filter = function(self, to_select, selected)
return #selected < 2 and Fk:currentRoom():getCardArea(to_select) == Player.Hand return #selected < 2 and Fk:currentRoom():getCardArea(to_select) == Player.Hand and not Self:prohibitDiscard(Fk:getCardById(to_select))
end, end,
target_filter = function(self, to_select, selected) target_filter = function(self, to_select, selected)
local target = Fk:currentRoom():getPlayerById(to_select) local target = Fk:currentRoom():getPlayerById(to_select)
@ -1090,7 +1083,7 @@ local wushuang = fk.CreateTriggerSkill{
frequency = Skill.Compulsory, frequency = Skill.Compulsory,
events = {fk.TargetSpecified, fk.TargetConfirmed}, events = {fk.TargetSpecified, fk.TargetConfirmed},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
if not player:hasSkill(self.name) then if not player:hasSkill(self) then
return false return false
end end
@ -1150,7 +1143,7 @@ local biyue = fk.CreateTriggerSkill{
anim_type = "drawcard", anim_type = "drawcard",
events = {fk.EventPhaseStart}, events = {fk.EventPhaseStart},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) return target == player and player:hasSkill(self)
and player.phase == Player.Finish and player.phase == Player.Finish
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
@ -1346,7 +1339,7 @@ local role_mode = fk.CreateGameMode{
} }
extension:addGameMode(role_mode) extension:addGameMode(role_mode)
Fk:loadTranslationTable{ Fk:loadTranslationTable{
["time limitation: 5 sec"] = "游戏时长达到5秒测试用", ["time limitation: 5 min"] = "游戏时长达到5分钟",
["left lord and loyalist alive"] = "仅剩你和主忠方存活", ["left lord and loyalist alive"] = "仅剩你和主忠方存活",
["left one rebel alive"] = "反贼仅剩你存活且不存在存活内奸", ["left one rebel alive"] = "反贼仅剩你存活且不存在存活内奸",
["left you alive"] = "主忠方仅剩你存活且其他阵营仅剩一方", ["left you alive"] = "主忠方仅剩你存活且其他阵营仅剩一方",

View File

@ -28,7 +28,9 @@ Fk:loadTranslationTable({
-- ["weapon"] = "武器牌", -- ["weapon"] = "武器牌",
-- ["armor"] = "防具牌", -- ["armor"] = "防具牌",
["defensive_horse"] = "+1 horse", ["defensive_horse"] = "+1 horse",
["defensive_ride"] = "+1 horse",
["offensive_horse"] = "-1 horse", ["offensive_horse"] = "-1 horse",
["offensive_ride"] = "-1 horse",
["equip_horse"] = "horse", ["equip_horse"] = "horse",
-- ["treasure"] = "宝物牌", -- ["treasure"] = "宝物牌",
["delayed_trick"] = "delayed trick", ["delayed_trick"] = "delayed trick",
@ -50,53 +52,67 @@ Fk:loadTranslationTable({
["slash"] = "Slash", ["slash"] = "Slash",
[":slash"] = "Slash (basic card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player within your ATK range<br /><b>Effect</b>: Deal 1 DMG to the targets.<br/><b>Note</b>: You can only use 1 Slash per action phase.", [":slash"] = "Slash (basic card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player within your ATK range<br /><b>Effect</b>: Deal 1 DMG to the targets.<br/><b>Note</b>: You can only use 1 Slash per action phase.",
["#slash-jink"] = "%src used Slash to you, please use %arg Dodge(s)", ["#slash-jink"] = "%src used Slash to you, please use %arg Dodge(s)",
["#slash_skill"] = "Choose 1 player within your ATK range, deal 1 DMG to him",
["#slash_skill_multi"] = "Choose up to %arg players within your ATK range. Deal 1 DMG to them",
["jink"] = "Dodge", ["jink"] = "Dodge",
[":jink"] = "Dodge (basic card)<br /><b>Phase</b>: When Slash is about to effect on you<br /><b>Target</b>: This Slash<br /><b>Effect</b>: Counter the target Slash.", [":jink"] = "Dodge (basic card)<br /><b>Phase</b>: When Slash is about to effect on you<br /><b>Target</b>: This Slash<br /><b>Effect</b>: Counter the target Slash.",
["peach"] = "Peach", ["peach"] = "Peach",
[":peach"] = "Peach (basic card)<br /><b>Phase</b>: 1. Action phase 2. When a player is dying<br /><b>Target</b>: Wounded yourself/the player who is dying<br /><b>Effect</b>: The target heals 1 HP.", [":peach"] = "Peach (basic card)<br /><b>Phase</b>: 1. Action phase 2. When a player is dying<br /><b>Target</b>: Wounded yourself/the player who is dying<br /><b>Effect</b>: The target heals 1 HP.",
["#peach_skill"] = "You heal 1 HP",
["dismantlement"] = "Dismantlement", ["dismantlement"] = "Dismantlement",
[":dismantlement"] = "Dismantlement (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player with cards in any area<br /><b>Effect</b>: Discard 1 card in one of the areas of the target player.", [":dismantlement"] = "Dismantlement (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player with cards in any area<br /><b>Effect</b>: Discard 1 card in one of the areas of the target player.",
["dismantlement_skill"] = "Dismantlement", ["dismantlement_skill"] = "Dismantlement",
["#dismantlement_skill"] = "Choose another player with cards in any area. Discard 1 card in one of his areas",
["snatch"] = "Snatch", ["snatch"] = "Snatch",
[":snatch"] = "Snatch (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player at distance 1 with cards in any area<br /><b>Effect</b>: Take 1 card in one of the areas of the target player.", [":snatch"] = "Snatch (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player at distance 1 with cards in any area<br /><b>Effect</b>: Take 1 card in one of the areas of the target player.",
["snatch_skill"] = "Snatch", ["snatch_skill"] = "Snatch",
["#snatch_skill"] = "Choose another player at distance 1 with cards in any area. Take 1 card in one of his areas",
["duel"] = "Duel", ["duel"] = "Duel",
[":duel"] = "Duel (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player<br /><b>Effect</b>: In turns (starting with the target player), both of you play Slash successively. The first player who doesn't play Slash suffers 1 DMG from the other player.", [":duel"] = "Duel (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player<br /><b>Effect</b>: In turns (starting with the target player), both of you play Slash successively. The first player who doesn't play Slash suffers 1 DMG from the other player.",
["#duel_skill"] = "Choose another player. In turns (starting with the target player), both of you play Slash successively.<br />The first player who doesn't play Slash suffers 1 DMG from the other player",
["collateral"] = "Collateral", ["collateral"] = "Collateral",
[":collateral"] = "Collateral (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player with an equipped weapon (Player A)<br /><b>Sub-target</b>: A player within Player A's ATK range (Player B)<br /><b>Effect</b>: Unless A uses Slash to B, he gives you his equipped weapon.", [":collateral"] = "Collateral (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player with an equipped weapon (Player A)<br /><b>Sub-target</b>: A player within Player A's ATK range (Player B)<br /><b>Effect</b>: Unless A uses Slash to B, he gives you his equipped weapon.",
["#collateral-slash"] = "Collateral: You shall use Slash to %dest , or %src takes your weapon", ["#collateral-slash"] = "Collateral: You shall use Slash to %dest , or give your weapon to %src",
["#collateral_skill"] = "Choose another player with an equipped weapon (Player A),<br />then choose another player within Player A's ATK range (Player B).<br />Unless A uses Slash to B, he gives you his equipped weapon",
["ex_nihilo"] = "Ex Nihilo", ["ex_nihilo"] = "Ex Nihilo",
[":ex_nihilo"] = "Ex Nihilo (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Yourself<br /><b>Effect</b>: The target draws 2 cards.", [":ex_nihilo"] = "Ex Nihilo (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Yourself<br /><b>Effect</b>: The target draws 2 cards.",
["#ex_nihilo_skill"] = "You draw 2 cards",
["nullification"] = "Nullification", ["nullification"] = "Nullification",
[":nullification"] = "Nullification (trick card)<br /><b>Phase</b>: When a trick card is about to take effect (including Nullification itself)<br /><b>Target</b>: This trick card<br /><b>Effect</b>: Counter the target trick card.", [":nullification"] = "Nullification (trick card)<br /><b>Phase</b>: When a trick card is about to take effect (including Nullification itself)<br /><b>Target</b>: This trick card<br /><b>Effect</b>: Counter the target trick card.",
["savage_assault"] = "Savage Assault", ["savage_assault"] = "Savage Assault",
[":savage_assault"] = "Savage Assault (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: All other players<br /><b>Effect</b>: Each target player needs to play Slash, otherwise they suffer 1 DMG from you.", [":savage_assault"] = "Savage Assault (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: All other players<br /><b>Effect</b>: Each target player needs to play Slash, otherwise they suffer 1 DMG from you.",
["#savage_assault_skill"] = "Each other players needs to play Slash, otherwise they suffer 1 DMG from you",
["archery_attack"] = "Archery Attack", ["archery_attack"] = "Archery Attack",
[":archery_attack"] = "Archery Attack (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: All other players<br /><b>Effect</b>: Each target player needs to play Dodge, otherwise they suffer 1 DMG from you.", [":archery_attack"] = "Archery Attack (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: All other players<br /><b>Effect</b>: Each target player needs to play Dodge, otherwise they suffer 1 DMG from you.",
["#archery_attack_skill"] = "Each other players needs to play Dodge, otherwise they suffer 1 DMG from you",
["god_salvation"] = "God Salvation", ["god_salvation"] = "God Salvation",
[":god_salvation"] = "God Salvation (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: All players<br /><b>Effect</b>: Each target player heals 1 HP.", [":god_salvation"] = "God Salvation (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: All players<br /><b>Effect</b>: Each target player heals 1 HP.",
["#god_salvation_skill"] = "Each players heals 1 HP",
["amazing_grace"] = "Amazing Grace", ["amazing_grace"] = "Amazing Grace",
[":amazing_grace"] = "Amazing Grace (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: All players<br /><b>Effect</b>: Reveal as many cards from the draw pile as target players; then, each target player takes 1 of those cards.", [":amazing_grace"] = "Amazing Grace (trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: All players<br /><b>Effect</b>: Reveal as many cards from the draw pile as target players; then, each target player takes 1 of those cards.",
["amazing_grace_skill"] = "AG", ["amazing_grace_skill"] = "AG",
["Please choose cards"] = "Please choose a card", ["Please choose cards"] = "Please choose a card",
["#amazing_grace_skill"] = "Reveal as many cards from the draw pile as all players;<br />then, each player takes 1 of those cards",
["lightning"] = "Lightning", ["lightning"] = "Lightning",
[":lightning"] = "Lightning (delayed trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Yourself<br /><b>Effect</b>: Place this card in target's judgement area. He performs a judgement in his judge phase: If the judgement result is 2-9♠, he suffers 3 Thunder DMG, otherwise move Lightning to his next player's judgement area.", [":lightning"] = "Lightning (delayed trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Yourself<br /><b>Effect</b>: Place this card in target's judgement area. He performs a judgement in his judge phase: If the judgement result is 2-9♠, he suffers 3 Thunder DMG, otherwise move Lightning to his next player's judgement area.",
["#lightning_skill"] = "Place this card in your judgement area. Target player performs a judgement in his judge phase:<br />If the judgement result is 2-9♠, he suffers 3 Thunder DMG, otherwise move Lightning to his next player's judgement area",
["indulgence"] = "Indulgence", ["indulgence"] = "Indulgence",
[":indulgence"] = "Indulgence (delayed trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player<br /><b>Effect</b>: Place this card in target's judgement area. He performs a judgement in his judge phase: if result is not heart, he skips his action phase.", [":indulgence"] = "Indulgence (delayed trick card)<br /><b>Phase</b>: Action phase<br /><b>Target</b>: Another player<br /><b>Effect</b>: Place this card in target's judgement area. He performs a judgement in his judge phase: if result is not <font color='#CC3131'>♥</font>, he skips his action phase.",
["#indulgence_skill"] = "Place this card in another player's judgement area. He performs a judgement in his judge phase:<br />If result is not <font color='#CC3131'>♥</font>, he skips his action phase",
["crossbow"] = "Crossbow", ["crossbow"] = "Crossbow",
[":crossbow"] = "Crossbow (equip card, weapon)<br /><b>ATK range</b>: 1<br /><b>Weapon skill</b>: You can use any amount of Slash in your action phase.", [":crossbow"] = "Crossbow (equip card, weapon)<br /><b>ATK range</b>: 1<br /><b>Weapon skill</b>: You can use any amount of Slash in your action phase.",
@ -122,6 +138,7 @@ Fk:loadTranslationTable({
[":spear"] = "Spear (equip card, weapon)<br /><b>ATK range</b>: 3<br /><b>Weapon skill</b>: You can use/play 2 hand cards as Slash.", [":spear"] = "Spear (equip card, weapon)<br /><b>ATK range</b>: 3<br /><b>Weapon skill</b>: You can use/play 2 hand cards as Slash.",
["spear_skill"] = "Spear", ["spear_skill"] = "Spear",
[":spear_skill"] = "You can use/play 2 hand cards as Slash.", [":spear_skill"] = "You can use/play 2 hand cards as Slash.",
["#spear_skill"] = "You can use/play 2 hand cards as Slash",
["axe"] = "Axe", ["axe"] = "Axe",
[":axe"] = "Axe (equip card, weapon)<br /><b>ATK range</b>: 3<br /><b>Weapon skill</b>: When your used Slash is countered by Dodge, you can discard 2 cards (except equipped Axe), then make this Slash still effective to the target.", [":axe"] = "Axe (equip card, weapon)<br /><b>ATK range</b>: 3<br /><b>Weapon skill</b>: When your used Slash is countered by Dodge, you can discard 2 cards (except equipped Axe), then make this Slash still effective to the target.",
@ -159,4 +176,6 @@ Fk:loadTranslationTable({
["zixing"] = "Zi Xing", ["zixing"] = "Zi Xing",
[":zixing"] = "Zi Xing (equip card, horse)<br /><b>Horse skill</b>: The distance from you to other players is reduced by -1.", [":zixing"] = "Zi Xing (equip card, horse)<br /><b>Horse skill</b>: The distance from you to other players is reduced by -1.",
["#default_equip_skill"] = "Equip %arg2 %arg",
}, "en_US") }, "en_US")

View File

@ -28,7 +28,9 @@ Fk:loadTranslationTable{
["weapon"] = "武器牌", ["weapon"] = "武器牌",
["armor"] = "防具牌", ["armor"] = "防具牌",
["defensive_horse"] = "防御坐骑牌", ["defensive_horse"] = "防御坐骑牌",
["defensive_ride"] = "防御坐骑牌",
["offensive_horse"] = "进攻坐骑牌", ["offensive_horse"] = "进攻坐骑牌",
["offensive_ride"] = "进攻坐骑牌",
["equip_horse"] = "坐骑牌", ["equip_horse"] = "坐骑牌",
["treasure"] = "宝物牌", ["treasure"] = "宝物牌",
["delayed_trick"] = "延时类锦囊牌", ["delayed_trick"] = "延时类锦囊牌",
@ -48,73 +50,87 @@ Fk:loadTranslationTable{
["method_discard"] = "弃置", ["method_discard"] = "弃置",
["slash"] = "", ["slash"] = "",
[":slash"] = "基本牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:攻击范围内的一名其他角色<br /><b>效果</b>对目标角色造成1点伤害。", [":slash"] = "基本牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:攻击范围内的一名角色<br /><b>效果</b>对目标角色造成1点伤害。",
["#slash-jink"] = "%src 对你使用了杀,请使用 %arg 张闪", ["#slash-jink"] = "%src 对你使用了杀,请使用 %arg 张闪",
["#slash_skill"] = "选择攻击范围内的一名角色对其造成1点伤害",
["#slash_skill_multi"] = "选择攻击范围内的至多%arg名角色对这些角色各造成1点伤害",
["jink"] = "", ["jink"] = "",
[":jink"] = "基本牌<br /><b>时机</b>:【杀】对你生效时<br /><b>目标</b>:此【杀】<br /><b>效果</b>:抵消此【杀】的效果。", [":jink"] = "基本牌<br /><b>时机</b>:【杀】对你生效时<br /><b>目标</b>:此【杀】<br /><b>效果</b>:抵消此【杀】的效果。",
["peach"] = "", ["peach"] = "",
[":peach"] = "基本牌<br /><b>时机</b>:出牌阶段/一名角色处于濒死状态时<br /><b>目标</b>:已受伤的你/处于濒死状态的角色<br /><b>效果</b>目标角色回复1点体力。", [":peach"] = "基本牌<br /><b>时机</b>:出牌阶段/一名角色处于濒死状态时<br /><b>目标</b>:已受伤的你/处于濒死状态的角色<br /><b>效果</b>目标角色回复1点体力。",
["#peach_skill"] = "你回复1点体力",
["dismantlement"] = "过河拆桥", ["dismantlement"] = "过河拆桥",
[":dismantlement"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:一名区域内有牌的其他角色。<br /><b>效果</b>:你弃置目标角色区域内的一张牌。", [":dismantlement"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:一名区域内有牌的其他角色。<br /><b>效果</b>:你弃置目标角色区域内的一张牌。",
["dismantlement_skill"] = "过河拆桥", ["dismantlement_skill"] = "过河拆桥",
["#dismantlement_skill"] = "选择一名区域内有牌的其他角色,你弃置其区域内的一张牌",
["snatch"] = "顺手牵羊", ["snatch"] = "顺手牵羊",
[":snatch"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>距离1的一名区域内有牌的角色<br /><b>效果</b>:你获得目标角色区域内的一张牌。", [":snatch"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>距离1的一名区域内有牌的角色<br /><b>效果</b>:你获得目标角色区域内的一张牌。",
["snatch_skill"] = "顺手牵羊", ["snatch_skill"] = "顺手牵羊",
["#snatch_skill"] = "选择距离1的区域内有牌的角色你获得其区域内的一张牌",
["duel"] = "决斗", ["duel"] = "决斗",
[":duel"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:一名其他角色<br /><b>效果</b>由目标角色开始你与其轮流打出一张【杀】否则受到对方的1点伤害并结束此牌结算。", [":duel"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:一名其他角色<br /><b>效果</b>由目标角色开始其与你轮流打出一张【杀】直到其与你中的一名角色未打出【杀】。未打出【杀】的角色受到其与你中的另一名角色造成的1点伤害。",
["#duel_skill"] = "选择一名其他角色,由其开始,其与你轮流打出一张【杀】,直到其与你中的一名角色未打出【杀】。<br />未打出【杀】的角色受到其与你中的另一名角色造成的1点伤害",
["collateral"] = "借刀杀人", ["collateral"] = "借刀杀人",
[":collateral"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>装备区内有武器牌且攻击范围内有【杀】的合法目标的一名其他角色A你需要选择一名A攻击范围内的【杀】的合法目标B<br /><b>效果</b>A须对B使用一张【杀】否则你获得A装备区内的武器牌。", [":collateral"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>装备区里有武器牌且攻击范围内有【杀】的合法目标的一名其他角色A你需要选择一名A攻击范围内的【杀】的合法目标B<br /><b>效果</b>A需对B使用一张【杀】否则将装备区里的武器牌交给你。",
["#collateral-slash"] = "借刀杀人:你需对 %dest 使用【杀】,否则 %src 获得你的武器", ["#collateral-slash"] = "借刀杀人:你需对 %dest 使用【杀】,否则将你的装备区里的武器牌交给 %src",
["#collateral_skill"] = "选择装备区里有武器牌且攻击范围内有【杀】的合法目标的一名其他角色A<br />再选择一名A攻击范围内的【杀】的合法目标B。A需对B使用【杀】否则将装备区里的武器牌交给你",
["ex_nihilo"] = "无中生有", ["ex_nihilo"] = "无中生有",
[":ex_nihilo"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:你<br /><b>效果</b>:目标角色摸两张牌。", [":ex_nihilo"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:你<br /><b>效果</b>:目标角色摸两张牌。",
["#ex_nihilo_skill"] = "你摸两张牌",
["nullification"] = "无懈可击", ["nullification"] = "无懈可击",
[":nullification"] = "锦囊牌<br /><b>时机</b>:锦囊牌对目标角色生效前,或一张【无懈可击】生效前<br /><b>目标</b>:该锦囊牌<br /><b>效果</b>:抵消该锦囊牌对该角色产生的效果,或抵消另一张【无懈可击】产生的效果。", [":nullification"] = "锦囊牌<br /><b>时机</b>:锦囊牌对目标角色生效前,或一张【无懈可击】生效前<br /><b>目标</b>:该锦囊牌<br /><b>效果</b>:抵消该锦囊牌对该角色产生的效果,或抵消另一张【无懈可击】产生的效果。",
["savage_assault"] = "南蛮入侵", ["savage_assault"] = "南蛮入侵",
[":savage_assault"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:所有其他角色<br /><b>效果</b>每名目标角色须打出一张【杀】否则受到1点伤害。", [":savage_assault"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:所有其他角色<br /><b>效果</b>每名目标角色需打出一张【杀】否则受到1点伤害。",
["#savage_assault_skill"] = "所有其他角色需打出一张【杀】否则受到1点伤害",
["archery_attack"] = "万箭齐发", ["archery_attack"] = "万箭齐发",
[":archery_attack"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:所有其他角色<br /><b>效果</b>每名目标角色须打出一张【闪】否则受到1点伤害。", [":archery_attack"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:所有其他角色<br /><b>效果</b>每名目标角色需打出一张【闪】否则受到1点伤害。",
["#archery_attack_skill"] = "所有其他角色需打出一张【闪】否则受到1点伤害",
["god_salvation"] = "桃园结义", ["god_salvation"] = "桃园结义",
[":god_salvation"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:所有角色<br /><b>效果</b>每名目标角色回复1点体力。", [":god_salvation"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:所有角色<br /><b>效果</b>每名目标角色回复1点体力。",
["#god_salvation_skill"] = "所有角色回复1点体力",
["amazing_grace"] = "五谷丰登", ["amazing_grace"] = "五谷丰登",
[":amazing_grace"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:所有角色<br /><b>效果</b>亮出牌堆顶等于角色数的牌,每名目标角色获得其中一张牌,后将其余的牌置入弃牌堆。", [":amazing_grace"] = "锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:所有角色<br /><b>效果</b>亮出牌堆顶等于目标角色数的牌,每名目标角色获得其中一张牌,结算结束后将其余的牌置入弃牌堆。",
["amazing_grace_skill"] = "五谷选牌", ["amazing_grace_skill"] = "五谷选牌",
["Please choose cards"] = "请选择一张卡牌", ["Please choose cards"] = "请选择一张卡牌",
["#amazing_grace_skill"] = "亮出牌堆顶等于所有角色数的牌,每名角色获得其中一张牌",
["lightning"] = "闪电", ["lightning"] = "闪电",
[":lightning"] = "延时锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:你<br /><b>效果</b>将此牌置于目标角色判定区内。其判定阶段进行判定若结果为黑桃2-9其受到3点雷电伤害并将【闪电】置入弃牌堆否则将【闪电】移动至其下家判定区内。", [":lightning"] = "延时锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:你<br /><b>效果</b>将此牌置于目标角色判定区内。其判定阶段进行判定若结果为♠2-9其受到3点雷电伤害并将【闪电】置入弃牌堆否则将【闪电】移动至其下家判定区内。",
["#lightning_skill"] = "将此牌置于你的判定区内。目标角色判定阶段判定:<br />若结果为♠2-9其受到3点雷电伤害并将【闪电】置入弃牌堆否则将【闪电】移动至其下家判定区内",
["indulgence"] = "乐不思蜀", ["indulgence"] = "乐不思蜀",
[":indulgence"] = "延时锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:一名其他角色<br /><b>效果</b>:将此牌置于目标角色判定区内。其判定阶段进行判定:若结果不为红桃,其跳过出牌阶段。然后将【乐不思蜀】置入弃牌堆。", [":indulgence"] = "延时锦囊牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:一名其他角色<br /><b>效果</b>:将此牌置于目标角色判定区内。其判定阶段进行判定:若结果不为<font color='#CC3131'>♥</font>,其跳过出牌阶段。然后将【乐不思蜀】置入弃牌堆。",
["#indulgence_skill"] = "选择一名其他角色,将此牌置于其判定区内。其判定阶段判定:<br />若结果不为<font color='#CC3131'>♥</font>,其跳过出牌阶段",
["crossbow"] = "诸葛连弩", ["crossbow"] = "诸葛连弩",
[":crossbow"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:锁定技你于出牌阶段内使用【杀】无次数限制。", [":crossbow"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:锁定技你于出牌阶段内使用【杀】无次数限制。",
["qinggang_sword"] = "青釭剑", ["qinggang_sword"] = "青釭剑",
[":qinggang_sword"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:锁定技你的【杀】无视目标角色的防具。", [":qinggang_sword"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:锁定技你的【杀】无视目标角色的防具。",
["ice_sword"] = "寒冰剑", ["ice_sword"] = "寒冰剑",
[":ice_sword"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>当你使用【杀】对目标角色造成伤害时,若该角色有牌,你可以防止此伤害,然后依次弃置其两张牌。", [":ice_sword"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>当你使用【杀】对目标角色造成伤害时,若该角色有牌,你可以防止此伤害,然后依次弃置其两张牌。",
["#ice_sword_skill"] = "寒冰剑", ["#ice_sword_skill"] = "寒冰剑",
["double_swords"] = "雌雄双股剑", ["double_swords"] = "雌雄双股剑",
[":double_swords"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>当你指定异性角色为【杀】的目标后,你可以令其选择一项:弃置一张手牌,或令你摸一张牌。", [":double_swords"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>当你指定异性角色为【杀】的目标后,你可以令其选择一项:弃置一张手牌,或令你摸一张牌。",
["#double_swords_skill"] = "雌雄双股剑", ["#double_swords_skill"] = "雌雄双股剑",
["#double_swords-invoke"] = "雌雄双股剑:你需弃置一张手牌,否则 %src 摸一张牌", ["#double_swords-invoke"] = "雌雄双股剑:你需弃置一张手牌,否则 %src 摸一张牌",
["blade"] = "青龙偃月刀", ["blade"] = "青龙偃月刀",
[":blade"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>当你使用的【杀】被【闪】抵消后,你可以对该角色再使用一张【杀】(无距离限制且不能选择额外目标)。", [":blade"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>当你使用的【杀】被【闪】抵消后,你可以对该角色再使用一张【杀】(无距离限制且不能选择额外目标)。",
["#blade_skill"] = "青龙偃月刀", ["#blade_skill"] = "青龙偃月刀",
["#blade_slash"] = "青龙偃月刀:你可以对 %src 再使用一张【杀】", ["#blade_slash"] = "青龙偃月刀:你可以对 %src 再使用一张【杀】",
@ -122,21 +138,22 @@ Fk:loadTranslationTable{
[":spear"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:你可以将两张手牌当【杀】使用或打出。", [":spear"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:你可以将两张手牌当【杀】使用或打出。",
["spear_skill"] = "丈八矛", ["spear_skill"] = "丈八矛",
[":spear_skill"] = "你可以将两张手牌当【杀】使用或打出。", [":spear_skill"] = "你可以将两张手牌当【杀】使用或打出。",
["#spear_skill"] = "你可以将两张手牌当【杀】使用或打出",
["axe"] = "贯石斧", ["axe"] = "贯石斧",
[":axe"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>当你使用的【杀】被【闪】抵消后,你可以弃置两张牌,则此【杀】继续造成伤害。", [":axe"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>当你使用的【杀】被【闪】抵消后,你可以弃置两张牌,则此【杀】继续造成伤害。",
["#axe_skill"] = "贯石斧", ["#axe_skill"] = "贯石斧",
["#axe-invoke"] = "贯石斧:你可以弃置两张牌,令你对 %dest 使用的【杀】依然生效", ["#axe-invoke"] = "贯石斧:你可以弃置两张牌,令你对 %dest 使用的【杀】依然生效",
["halberd"] = "方天画戟", ["halberd"] = "方天画戟",
[":halberd"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:锁定技你使用最后的手牌【杀】可以额外选择至多两名目标。", [":halberd"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>:锁定技你使用最后的手牌【杀】可以额外选择至多两名目标。",
["kylin_bow"] = "麒麟弓", ["kylin_bow"] = "麒麟弓",
[":kylin_bow"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>当你使用【杀】对目标角色造成伤害时,你可以弃置其装备区的一张坐骑牌。", [":kylin_bow"] = "装备牌·武器<br /><b>攻击范围</b><br /><b>武器技能</b>当你使用【杀】对目标角色造成伤害时,你可以弃置其装备区的一张坐骑牌。",
["#kylin_bow_skill"] = "麒麟弓", ["#kylin_bow_skill"] = "麒麟弓",
["eight_diagram"] = "八卦阵", ["eight_diagram"] = "八卦阵",
[":eight_diagram"] = "装备牌·防具<br /><b>防具技能</b>当你需要使用或打出一张【闪】时,你可以进行判定:若结果为红色,视为你使用或打出了一张【闪】。", [":eight_diagram"] = "装备牌·防具<br /><b>防具技能</b>当你需要使用或打出一张【闪】时,你可以进行判定:若结果为红色,视为你使用或打出了一张【闪】。",
["#eight_diagram_skill"] = "八卦阵", ["#eight_diagram_skill"] = "八卦阵",
["nioh_shield"] = "仁王盾", ["nioh_shield"] = "仁王盾",
@ -159,4 +176,6 @@ Fk:loadTranslationTable{
["zixing"] = "紫骍", ["zixing"] = "紫骍",
[":zixing"] = "装备牌·坐骑<br /><b>坐骑技能</b>:你与其他角色的距离-1。", [":zixing"] = "装备牌·坐骑<br /><b>坐骑技能</b>:你与其他角色的距离-1。",
["#default_equip_skill"] = "装备%arg2【%arg】",
} }

View File

@ -5,6 +5,19 @@ extension.metadata = require "packages.standard_cards.metadata"
local slashSkill = fk.CreateActiveSkill{ local slashSkill = fk.CreateActiveSkill{
name = "slash_skill", name = "slash_skill",
prompt = function(self, selected_cards)
local slash = Fk:cloneCard("slash")
slash.subcards = Card:getIdList(selected_cards)
local max_num = self:getMaxTargetNum(Self, slash) -- halberd
if max_num > 1 then
local num = #table.filter(Fk:currentRoom().alive_players, function (p)
return p ~= Self and not Self:isProhibited(p, slash)
end)
max_num = math.min(num, max_num)
end
slash.subcards = {}
return max_num > 1 and "#slash_skill_multi:::" .. max_num or "#slash_skill"
end,
max_phase_use_time = 1, max_phase_use_time = 1,
target_num = 1, target_num = 1,
can_use = function(self, player, card) can_use = function(self, player, card)
@ -86,9 +99,7 @@ extension:addCards({
local jinkSkill = fk.CreateActiveSkill{ local jinkSkill = fk.CreateActiveSkill{
name = "jink_skill", name = "jink_skill",
can_use = function() can_use = Util.FalseFunc,
return false
end,
on_effect = function(self, room, effect) on_effect = function(self, room, effect)
if effect.responseToEvent then if effect.responseToEvent then
effect.responseToEvent.isCancellOut = true effect.responseToEvent.isCancellOut = true
@ -123,6 +134,7 @@ extension:addCards({
local peachSkill = fk.CreateActiveSkill{ local peachSkill = fk.CreateActiveSkill{
name = "peach_skill", name = "peach_skill",
prompt = "#peach_skill",
mod_target_filter = function(self, to_select) mod_target_filter = function(self, to_select)
return Fk:currentRoom():getPlayerById(to_select):isWounded() and return Fk:currentRoom():getPlayerById(to_select):isWounded() and
not table.find(Fk:currentRoom().alive_players, function(p) not table.find(Fk:currentRoom().alive_players, function(p)
@ -171,6 +183,7 @@ extension:addCards({
local dismantlementSkill = fk.CreateActiveSkill{ local dismantlementSkill = fk.CreateActiveSkill{
name = "dismantlement_skill", name = "dismantlement_skill",
prompt = "#dismantlement_skill",
target_num = 1, target_num = 1,
mod_target_filter = function(self, to_select, selected, user, card) mod_target_filter = function(self, to_select, selected, user, card)
local player = Fk:currentRoom():getPlayerById(to_select) local player = Fk:currentRoom():getPlayerById(to_select)
@ -209,6 +222,7 @@ extension:addCards({
local snatchSkill = fk.CreateActiveSkill{ local snatchSkill = fk.CreateActiveSkill{
name = "snatch_skill", name = "snatch_skill",
prompt = "#snatch_skill",
distance_limit = 1, distance_limit = 1,
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
local player = Fk:currentRoom():getPlayerById(to_select) local player = Fk:currentRoom():getPlayerById(to_select)
@ -247,6 +261,7 @@ extension:addCards({
local duelSkill = fk.CreateActiveSkill{ local duelSkill = fk.CreateActiveSkill{
name = "duel_skill", name = "duel_skill",
prompt = "#duel_skill",
mod_target_filter = function(self, to_select, selected, user, card) mod_target_filter = function(self, to_select, selected, user, card)
return user ~= to_select return user ~= to_select
end, end,
@ -332,6 +347,7 @@ extension:addCards({
local collateralSkill = fk.CreateActiveSkill{ local collateralSkill = fk.CreateActiveSkill{
name = "collateral_skill", name = "collateral_skill",
prompt = "#collateral_skill",
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
local player = Fk:currentRoom():getPlayerById(to_select) local player = Fk:currentRoom():getPlayerById(to_select)
return user ~= to_select and player:getEquipment(Card.SubtypeWeapon) return user ~= to_select and player:getEquipment(Card.SubtypeWeapon)
@ -374,9 +390,7 @@ local collateralSkill = fk.CreateActiveSkill{
use.extraUse = true use.extraUse = true
room:useCard(use) room:useCard(use)
else else
room:obtainCard(effect.from, room:moveCardTo(to:getEquipment(Card.SubtypeWeapon), Card.PlayerHand, room:getPlayerById(effect.from), fk.ReasonGive, "collateral", nil, true, to.id)
room:getPlayerById(effect.to):getEquipment(Card.SubtypeWeapon),
true, fk.ReasonGive)
end end
end end
} }
@ -394,9 +408,8 @@ extension:addCards({
local exNihiloSkill = fk.CreateActiveSkill{ local exNihiloSkill = fk.CreateActiveSkill{
name = "ex_nihilo_skill", name = "ex_nihilo_skill",
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) prompt = "#ex_nihilo_skill",
return true mod_target_filter = Util.TrueFunc,
end,
can_use = function(self, player, card) can_use = function(self, player, card)
return not player:isProhibited(player, card) return not player:isProhibited(player, card)
end, end,
@ -427,9 +440,7 @@ extension:addCards({
local nullificationSkill = fk.CreateActiveSkill{ local nullificationSkill = fk.CreateActiveSkill{
name = "nullification_skill", name = "nullification_skill",
can_use = function() can_use = Util.FalseFunc,
return false
end,
on_use = function() RoomInstance:delay(1200) end, on_use = function() RoomInstance:delay(1200) end,
on_effect = function(self, room, effect) on_effect = function(self, room, effect)
if effect.responseToEvent then if effect.responseToEvent then
@ -455,6 +466,7 @@ extension:addCards({
local savageAssaultSkill = fk.CreateActiveSkill{ local savageAssaultSkill = fk.CreateActiveSkill{
name = "savage_assault_skill", name = "savage_assault_skill",
prompt = "#savage_assault_skill",
can_use = Util.AoeCanUse, can_use = Util.AoeCanUse,
on_use = Util.AoeOnUse, on_use = Util.AoeOnUse,
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
@ -498,6 +510,7 @@ extension:addCards({
local archeryAttackSkill = fk.CreateActiveSkill{ local archeryAttackSkill = fk.CreateActiveSkill{
name = "archery_attack_skill", name = "archery_attack_skill",
prompt = "#archery_attack_skill",
can_use = Util.AoeCanUse, can_use = Util.AoeCanUse,
on_use = Util.AoeOnUse, on_use = Util.AoeOnUse,
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
@ -539,11 +552,10 @@ extension:addCards({
local godSalvationSkill = fk.CreateActiveSkill{ local godSalvationSkill = fk.CreateActiveSkill{
name = "god_salvation_skill", name = "god_salvation_skill",
prompt = "#god_salvation_skill",
can_use = Util.GlobalCanUse, can_use = Util.GlobalCanUse,
on_use = Util.GlobalOnUse, on_use = Util.GlobalOnUse,
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = Util.TrueFunc,
return true
end,
about_to_effect = function(self, room, effect) about_to_effect = function(self, room, effect)
if not room:getPlayerById(effect.to):isWounded() then if not room:getPlayerById(effect.to):isWounded() then
return true return true
@ -577,11 +589,10 @@ extension:addCards({
local amazingGraceSkill = fk.CreateActiveSkill{ local amazingGraceSkill = fk.CreateActiveSkill{
name = "amazing_grace_skill", name = "amazing_grace_skill",
prompt = "#amazing_grace_skill",
can_use = Util.GlobalCanUse, can_use = Util.GlobalCanUse,
on_use = Util.GlobalOnUse, on_use = Util.GlobalOnUse,
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = Util.TrueFunc,
return true
end,
on_effect = function(self, room, effect) on_effect = function(self, room, effect)
local to = room:getPlayerById(effect.to) local to = room:getPlayerById(effect.to)
if not (effect.extra_data and effect.extra_data.AGFilled) then if not (effect.extra_data and effect.extra_data.AGFilled) then
@ -664,9 +675,8 @@ extension:addCards({
local lightningSkill = fk.CreateActiveSkill{ local lightningSkill = fk.CreateActiveSkill{
name = "lightning_skill", name = "lightning_skill",
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) prompt = "#lightning_skill",
return true mod_target_filter = Util.TrueFunc,
end,
can_use = function(self, player, card) can_use = function(self, player, card)
return not player:isProhibited(player, card) return not player:isProhibited(player, card)
end, end,
@ -737,6 +747,7 @@ extension:addCards({
local indulgenceSkill = fk.CreateActiveSkill{ local indulgenceSkill = fk.CreateActiveSkill{
name = "indulgence_skill", name = "indulgence_skill",
prompt = "#indulgence_skill",
mod_target_filter = function(self, to_select, selected, user, card, distance_limited) mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
return user ~= to_select return user ~= to_select
end, end,
@ -783,20 +794,25 @@ local crossbowAudio = fk.CreateTriggerSkill{
name = "#crossbowAudio", name = "#crossbowAudio",
refresh_events = {fk.CardUsing}, refresh_events = {fk.CardUsing},
can_refresh = function(self, event, target, player, data) can_refresh = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and player.phase == Player.Play and return target == player and player:hasSkill(self) and player.phase == Player.Play and
data.card.trueName == "slash" and player:usedCardTimes("slash", Player.HistoryPhase) > 1 data.card.trueName == "slash" and player:usedCardTimes("slash", Player.HistoryPhase) > 1
end, end,
on_refresh = function(self, event, target, player, data) on_refresh = function(self, event, target, player, data)
local room = player.room local room = player.room
room:broadcastPlaySound("./packages/standard_cards/audio/card/crossbow") room:broadcastPlaySound("./packages/standard_cards/audio/card/crossbow")
room:setEmotion(player, "./packages/standard_cards/image/anim/crossbow") room:setEmotion(player, "./packages/standard_cards/image/anim/crossbow")
room:sendLog{
type = "#InvokeSkill",
from = player.id,
arg = "crossbow",
}
end, end,
} }
local crossbowSkill = fk.CreateTargetModSkill{ local crossbowSkill = fk.CreateTargetModSkill{
name = "#crossbow_skill", name = "#crossbow_skill",
attached_equip = "crossbow", attached_equip = "crossbow",
bypass_times = function(self, player, skill, scope) bypass_times = function(self, player, skill, scope)
if player:hasSkill(self.name) and skill.trueName == "slash_skill" if player:hasSkill(self) and skill.trueName == "slash_skill"
and scope == Player.HistoryPhase then and scope == Player.HistoryPhase then
return true return true
end end
@ -841,7 +857,7 @@ local qingGangSkill = fk.CreateTriggerSkill{
frequency = Skill.Compulsory, frequency = Skill.Compulsory,
events = { fk.TargetSpecified }, events = { fk.TargetSpecified },
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and return target == player and player:hasSkill(self) and
data.card and data.card.trueName == "slash" data.card and data.card.trueName == "slash"
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
@ -874,7 +890,7 @@ local iceSwordSkill = fk.CreateTriggerSkill{
attached_equip = "ice_sword", attached_equip = "ice_sword",
events = {fk.DamageCaused}, events = {fk.DamageCaused},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and (not data.chain) and return target == player and player:hasSkill(self) and (not data.chain) and
data.card and data.card.trueName == "slash" and not data.to:isNude() data.card and data.card.trueName == "slash" and not data.to:isNude()
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
@ -907,11 +923,10 @@ local doubleSwordsSkill = fk.CreateTriggerSkill{
attached_equip = "double_swords", attached_equip = "double_swords",
events = {fk.TargetSpecified}, events = {fk.TargetSpecified},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
if target == player and player:hasSkill(self.name) and if target == player and player:hasSkill(self) and
data.card and data.card.trueName == "slash" then data.card and data.card.trueName == "slash" then
local to = player.room:getPlayerById(data.to) local target = player.room:getPlayerById(data.to)
if player.gender == General.Agender or to.gender == General.Agender then return false end return player:compareGenderWith(target, true)
return to.gender ~= player.gender or player.gender == General.Bigender or to.gender == General.Bigender
end end
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
@ -945,7 +960,7 @@ local bladeSkill = fk.CreateTriggerSkill{
attached_equip = "blade", attached_equip = "blade",
events = {fk.CardEffectCancelledOut}, events = {fk.CardEffectCancelledOut},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return player:hasSkill(self.name) and data.from == player.id and data.card.trueName == "slash" and not player.room:getPlayerById(data.to).dead return player:hasSkill(self) and data.from == player.id and data.card.trueName == "slash" and not player.room:getPlayerById(data.to).dead
end, end,
on_cost = function(self, event, target, player, data) on_cost = function(self, event, target, player, data)
local room = player.room local room = player.room
@ -976,6 +991,7 @@ extension:addCards({
local spearSkill = fk.CreateViewAsSkill{ local spearSkill = fk.CreateViewAsSkill{
name = "spear_skill", name = "spear_skill",
prompt = "#spear_skill",
attached_equip = "spear", attached_equip = "spear",
pattern = "slash", pattern = "slash",
card_filter = function(self, to_select, selected) card_filter = function(self, to_select, selected)
@ -1010,7 +1026,7 @@ local axeSkill = fk.CreateTriggerSkill{
attached_equip = "axe", attached_equip = "axe",
events = {fk.CardEffectCancelledOut}, events = {fk.CardEffectCancelledOut},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return player:hasSkill(self.name) and data.from == player.id and data.card.trueName == "slash" and not player.room:getPlayerById(data.to).dead return player:hasSkill(self) and data.from == player.id and data.card.trueName == "slash" and not player.room:getPlayerById(data.to).dead
end, end,
on_cost = function(self, event, target, player, data) on_cost = function(self, event, target, player, data)
local room = player.room local room = player.room
@ -1049,7 +1065,7 @@ local halberdAudio = fk.CreateTriggerSkill{
name = "#halberdAudio", name = "#halberdAudio",
refresh_events = {fk.CardUsing}, refresh_events = {fk.CardUsing},
can_refresh = function(self, event, target, player, data) can_refresh = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and return target == player and player:hasSkill(self) and
data.card.trueName == "slash" and #TargetGroup:getRealTargets(data.tos) > 1 data.card.trueName == "slash" and #TargetGroup:getRealTargets(data.tos) > 1
end, end,
on_refresh = function(self, event, target, player, data) on_refresh = function(self, event, target, player, data)
@ -1062,7 +1078,7 @@ local halberdSkill = fk.CreateTargetModSkill{
name = "#halberd_skill", name = "#halberd_skill",
attached_equip = "halberd", attached_equip = "halberd",
extra_target_func = function(self, player, skill, card) extra_target_func = function(self, player, skill, card)
if player:hasSkill(self.name) and skill.trueName == "slash_skill" then if player:hasSkill(self) and skill.trueName == "slash_skill" then
local cards = card:isVirtual() and card.subcards or {card.id} local cards = card:isVirtual() and card.subcards or {card.id}
local handcards = player:getCardIds(Player.Hand) local handcards = player:getCardIds(Player.Hand)
if #cards == #handcards and table.every(cards, function(id) return table.contains(handcards, id) end) then if #cards == #handcards and table.every(cards, function(id) return table.contains(handcards, id) end) then
@ -1090,7 +1106,7 @@ local kylinBowSkill = fk.CreateTriggerSkill{
attached_equip = "kylin_bow", attached_equip = "kylin_bow",
events = {fk.DamageCaused}, events = {fk.DamageCaused},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
local ret = target == player and player:hasSkill(self.name) and local ret = target == player and player:hasSkill(self) and
data.card and data.card.trueName == "slash" and (not data.chain) data.card and data.card.trueName == "slash" and (not data.chain)
if ret then if ret then
---@type ServerPlayer ---@type ServerPlayer
@ -1135,7 +1151,7 @@ local eightDiagramSkill = fk.CreateTriggerSkill{
attached_equip = "eight_diagram", attached_equip = "eight_diagram",
events = {fk.AskForCardUse, fk.AskForCardResponse}, events = {fk.AskForCardUse, fk.AskForCardResponse},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
return target == player and player:hasSkill(self.name) and return target == player and player:hasSkill(self) and
(data.cardName == "jink" or (data.pattern and Exppattern:Parse(data.pattern):matchExp("jink|0|nosuit|none"))) (data.cardName == "jink" or (data.pattern and Exppattern:Parse(data.pattern):matchExp("jink|0|nosuit|none")))
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
@ -1188,10 +1204,10 @@ local niohShieldSkill = fk.CreateTriggerSkill{
events = {fk.PreCardEffect}, events = {fk.PreCardEffect},
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
local effect = data ---@type CardEffectEvent local effect = data ---@type CardEffectEvent
return player.id == effect.to and player:hasSkill(self.name) and return player.id == effect.to and player:hasSkill(self) and
effect.card.trueName == "slash" and effect.card.color == Card.Black effect.card.trueName == "slash" and effect.card.color == Card.Black
end, end,
on_use = function() return true end, on_use = Util.TrueFunc,
} }
Fk:addSkill(niohShieldSkill) Fk:addSkill(niohShieldSkill)
local niohShield = fk.CreateArmor{ local niohShield = fk.CreateArmor{

View File

@ -7,12 +7,8 @@ local cheat = fk.CreateActiveSkill{
name = "cheat", name = "cheat",
anim_type = "drawcard", anim_type = "drawcard",
prompt = "#cheat", prompt = "#cheat",
can_use = function(self, player) can_use = Util.TrueFunc,
return true card_filter = Util.FalseFunc,
end,
card_filter = function(self, card)
return false
end,
target_num = 0, target_num = 0,
on_use = function(self, room, effect) on_use = function(self, room, effect)
local from = room:getPlayerById(effect.from) local from = room:getPlayerById(effect.from)
@ -64,16 +60,8 @@ local test_filter = fk.CreateFilterSkill{
local control = fk.CreateActiveSkill{ local control = fk.CreateActiveSkill{
name = "control", name = "control",
anim_type = "control", anim_type = "control",
can_use = function(self, player) can_use = Util.TrueFunc,
return true card_filter = Util.FalseFunc,
end,
card_filter = function(self, card)
-- if self.interaction.data == "joy" then
--local c = Fk:getCardById(card)
--return Self:getPileNameOfId(card) == self.name and c.color == Card.Red
return false
-- end
end,
card_num = 0, card_num = 0,
target_filter = function(self, to_select) target_filter = function(self, to_select)
return to_select ~= Self.id return to_select ~= Self.id
@ -225,12 +213,8 @@ local damage_maker = fk.CreateActiveSkill{
name = "damage_maker", name = "damage_maker",
anim_type = "offensive", anim_type = "offensive",
prompt = "#damage_maker", prompt = "#damage_maker",
can_use = function(self, player) can_use = Util.TrueFunc,
return true card_filter = Util.FalseFunc,
end,
card_filter = function(self, card)
return false
end,
card_num = 0, card_num = 0,
target_filter = function(self, to_select, selected) target_filter = function(self, to_select, selected)
if self.interaction.data == "revive" then return false end if self.interaction.data == "revive" then return false end
@ -300,12 +284,8 @@ local damage_maker = fk.CreateActiveSkill{
} }
local change_hero = fk.CreateActiveSkill{ local change_hero = fk.CreateActiveSkill{
name = "change_hero", name = "change_hero",
can_use = function(self, player) can_use = Util.TrueFunc,
return true card_filter = Util.FalseFunc,
end,
card_filter = function(self, card)
return false
end,
card_num = 0, card_num = 0,
target_filter = function(self, to_select, selected) target_filter = function(self, to_select, selected)
return #selected < 1 return #selected < 1
@ -344,12 +324,8 @@ local test_zhenggong = fk.CreateTriggerSkill{
} }
local test_feichu = fk.CreateActiveSkill{ local test_feichu = fk.CreateActiveSkill{
name = "test_feichu", name = "test_feichu",
can_use = function(self, player) can_use = Util.TrueFunc,
return true card_filter = Util.FalseFunc,
end,
card_filter = function(self, card)
return false
end,
card_num = 0, card_num = 0,
target_filter = function(self, to_select, selected) target_filter = function(self, to_select, selected)
return #selected < 1 return #selected < 1