bugfix (#229)
- 为需要无视描述的请求添加-tmp标签(……) - 修改铁索相关描述 - 修复了可以通过取消目标以跳过exclusive_targets的bug - 修复了观星只控顶时还有底部标签的bug - 修复了没有correct_func时的报错 - 修复了一个人且未分胜负时无限循环的bug - 将AOE的函数调到了Util内方便其他DIY快速调用 - 将AskForAddTarget转正 - 主动技添加modTargetFilter,负责重新定义目标(借刀摆烂了) - 游戏模式添加countInFunc(room),负责检测本局游戏是否可以纳入胜率统计(默认true) --------- Co-authored-by: Nyutanislavsky <nyutanislavsky@qq.com>
This commit is contained in:
parent
21fee5537a
commit
7fd39264ee
|
@ -551,6 +551,12 @@ function updateSelectedTargets(playerid, selected) {
|
|||
[card, id, selected_targets]
|
||||
));
|
||||
photo.selectable = ret;
|
||||
if (roomScene.extra_data instanceof Object) {
|
||||
const exclusived = roomScene.extra_data.exclusive_targets;
|
||||
if (exclusived instanceof Array) {
|
||||
if (exclusived.indexOf(id) === -1) photo.selectable = false;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
okButton.enabled = JSON.parse(Backend.callLuaFunction(
|
||||
|
@ -835,9 +841,15 @@ callbacks["AskForGuanxing"] = (jsonData) => {
|
|||
box.areaLimits = [min_bottom_cards];
|
||||
box.areaNames = [Backend.translate(bottom_area_name)];
|
||||
} else {
|
||||
box.areaCapacities = [max_top_cards, max_bottom_cards];
|
||||
box.areaLimits = [min_top_cards, min_bottom_cards];
|
||||
box.areaNames = [Backend.translate(top_area_name), Backend.translate(bottom_area_name)];
|
||||
if (max_bottom_cards === 0) {
|
||||
box.areaCapacities = [max_top_cards];
|
||||
box.areaLimits = [min_top_cards];
|
||||
box.areaNames = [Backend.translate(top_area_name)];
|
||||
} else {
|
||||
box.areaCapacities = [max_top_cards, max_bottom_cards];
|
||||
box.areaLimits = [min_top_cards, min_bottom_cards];
|
||||
box.areaNames = [Backend.translate(top_area_name), Backend.translate(bottom_area_name)];
|
||||
}
|
||||
}
|
||||
box.cards = cards;
|
||||
box.arrangeCards();
|
||||
|
@ -906,7 +918,7 @@ callbacks["AskForChoice"] = (jsonData) => {
|
|||
box.skill_name = skill_name;
|
||||
box.all_options = all_choices;
|
||||
box.accepted.connect(() => {
|
||||
replyToServer(choices[box.result]);
|
||||
replyToServer(all_choices[box.result]);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ MetroButton {
|
|||
box.options = choices;
|
||||
box.all_options = all_choices;
|
||||
box.accepted.connect(() => {
|
||||
answer = choices[box.result];
|
||||
answer = all_choices[box.result];
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -276,8 +276,8 @@ Fk:loadTranslationTable{
|
|||
["phase_finish"] = "结束阶段",
|
||||
|
||||
["chained"] = "横置",
|
||||
["un-chained"] = "竖置",
|
||||
["reset-general"] = "重置",
|
||||
["un-chained"] = "重置",
|
||||
["reset-general"] = "复原",
|
||||
|
||||
["yang"] = "阳",
|
||||
["yin"] = "阴",
|
||||
|
@ -391,7 +391,6 @@ Fk:loadTranslationTable{
|
|||
["#GuanxingResult"] = "%from 的观星结果为 %arg 上 %arg2 下",
|
||||
["#ChainStateChange"] = "%from %arg 了武将牌",
|
||||
["#ChainDamage"] = "%from 处于连环状态,将受到传导的伤害",
|
||||
["#ResetGeneral"] = "%from 复原了武将牌",
|
||||
}
|
||||
|
||||
-- card footnote
|
||||
|
|
|
@ -61,4 +61,10 @@ function GameMode:surrenderFunc(playedTime)
|
|||
return {}
|
||||
end
|
||||
|
||||
---@param room Room @ 游戏房间
|
||||
---@return boolean
|
||||
function GameMode:countInFunc(room)
|
||||
return true
|
||||
end
|
||||
|
||||
return GameMode
|
||||
|
|
|
@ -50,6 +50,17 @@ function ActiveSkill:targetFilter(to_select, selected, selected_cards, card)
|
|||
return false
|
||||
end
|
||||
|
||||
--- Determine whether a target can be selected by this skill(in modifying targets)
|
||||
--- only used in skill of players
|
||||
---@param to_select integer @ id of the target
|
||||
---@param selected integer[] @ ids of selected targets
|
||||
---@param user integer @ id of the userdata
|
||||
---@param card Card @ helper
|
||||
---@param distance_limited boolean @ is limited by distance
|
||||
function ActiveSkill:modTargetFilter(to_select, selected, user, card, distance_limited)
|
||||
return false
|
||||
end
|
||||
|
||||
function ActiveSkill:getMinTargetNum()
|
||||
local ret
|
||||
if self.target_num then ret = self.target_num
|
||||
|
|
|
@ -35,13 +35,15 @@ function UsableSkill:withinTimesLimit(player, scope, card, card_name, to)
|
|||
if skill:bypassTimesCheck(player, self, scope, card, to) then return true end
|
||||
end
|
||||
card_name = card_name or card.trueName
|
||||
local temp_suf = table.simpleClone(MarkEnum.TempMarkSuffix)
|
||||
table.insert(temp_suf, "-tmp")
|
||||
return player:usedCardTimes(card_name, scope) < self:getMaxUseTime(player, scope, card, to) or
|
||||
(player:getMark(MarkEnum.BypassTimesLimit) ~= 0 or
|
||||
table.find(MarkEnum.TempMarkSuffix, function(s)
|
||||
table.find(temp_suf, function(s)
|
||||
return player:getMark(MarkEnum.BypassTimesLimit .. s) ~= 0
|
||||
end)) or
|
||||
(to:getMark(MarkEnum.BypassTimesLimitTo) ~= 0 or
|
||||
table.find(MarkEnum.TempMarkSuffix, function(s)
|
||||
table.find(temp_suf, function(s)
|
||||
return to:getMark(MarkEnum.BypassTimesLimitTo .. s) ~= 0
|
||||
end))
|
||||
end
|
||||
|
@ -55,13 +57,15 @@ function UsableSkill:withinDistanceLimit(player, isattack, card, to)
|
|||
for _, skill in ipairs(status_skills) do
|
||||
if skill:bypassDistancesCheck(player, self, card, to) then return true end
|
||||
end
|
||||
local temp_suf = table.simpleClone(MarkEnum.TempMarkSuffix)
|
||||
table.insert(temp_suf, "-tmp")
|
||||
return isattack and player:inMyAttackRange(to, self:getDistanceLimit(player, card, to)) or player:distanceTo(to) <= self:getDistanceLimit(player, card, to) or
|
||||
(player:getMark(MarkEnum.BypassDistancesLimit) ~= 0 or
|
||||
table.find(MarkEnum.TempMarkSuffix, function(s)
|
||||
table.find(temp_suf, function(s)
|
||||
return player:getMark(MarkEnum.BypassDistancesLimit .. s) ~= 0
|
||||
end)) or
|
||||
(to:getMark(MarkEnum.BypassDistancesLimitTo) ~= 0 or
|
||||
table.find(MarkEnum.TempMarkSuffix, function(s)
|
||||
table.find(temp_suf, function(s)
|
||||
return to:getMark(MarkEnum.BypassDistancesLimitTo .. s) ~= 0
|
||||
end))
|
||||
end
|
||||
|
|
|
@ -103,6 +103,47 @@ Util.NameMapper = function(e) return e.name end
|
|||
Util.Name2GeneralMapper = function(e) return Fk.generals[e] end
|
||||
Util.Name2SkillMapper = function(e) return Fk.skills[e] end
|
||||
|
||||
-- for card preset
|
||||
Util.GlobalCanUse = function(self, player, card)
|
||||
local room = Fk:currentRoom()
|
||||
for _, p in ipairs(room.alive_players) do
|
||||
if not (card and player:isProhibited(p, card)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Util.AoeCanUse = function(self, player, card)
|
||||
local room = Fk:currentRoom()
|
||||
for _, p in ipairs(room.alive_players) do
|
||||
if p ~= player and not (card and player:isProhibited(p, card)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Util.GlobalOnUse = function(self, room, cardUseEvent)
|
||||
if not cardUseEvent.tos or #TargetGroup:getRealTargets(cardUseEvent.tos) == 0 then
|
||||
cardUseEvent.tos = {}
|
||||
for _, player in ipairs(room:getAlivePlayers()) do
|
||||
if not room:getPlayerById(cardUseEvent.from):isProhibited(player, cardUseEvent.card) then
|
||||
TargetGroup:pushTargets(cardUseEvent.tos, player.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Util.AoeOnUse = function(self, room, cardUseEvent)
|
||||
if not cardUseEvent.tos or #TargetGroup:getRealTargets(cardUseEvent.tos) == 0 then
|
||||
cardUseEvent.tos = {}
|
||||
for _, player in ipairs(room:getOtherPlayers(room:getPlayerById(cardUseEvent.from))) do
|
||||
if not room:getPlayerById(cardUseEvent.from):isProhibited(player, cardUseEvent.card) then
|
||||
TargetGroup:pushTargets(cardUseEvent.tos, player.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@generic T
|
||||
---@param self T[]
|
||||
---@return T[]
|
||||
|
|
|
@ -170,6 +170,7 @@ end
|
|||
---@field public about_to_effect fun(self: ActiveSkill, room: Room, cardEffectEvent: CardEffectEvent): boolean|nil
|
||||
---@field public on_effect fun(self: ActiveSkill, room: Room, cardEffectEvent: CardEffectEvent): boolean|nil
|
||||
---@field public on_nullified fun(self: ActiveSkill, room: Room, cardEffectEvent: CardEffectEvent): boolean|nil
|
||||
---@field public mod_target_filter fun(self: ActiveSkill, to_select: integer, selected: integer[], user: integer, card: Card, distance_limited: boolean): boolean|nil
|
||||
---@field public prompt fun(self: ActiveSkill, selected: integer[], selected_cards: integer[]): string
|
||||
|
||||
---@param spec ActiveSkillSpec
|
||||
|
@ -186,6 +187,7 @@ function fk.CreateActiveSkill(spec)
|
|||
end
|
||||
if spec.card_filter then skill.cardFilter = spec.card_filter end
|
||||
if spec.target_filter then skill.targetFilter = spec.target_filter end
|
||||
if spec.mod_target_filter then skill.modTargetFilter = spec.mod_target_filter end
|
||||
if spec.feasible then
|
||||
print(spec.name .. ": feasible is deprecated. Use target_num and card_num instead.")
|
||||
skill.feasible = spec.feasible
|
||||
|
@ -274,7 +276,7 @@ end
|
|||
---@return DistanceSkill
|
||||
function fk.CreateDistanceSkill(spec)
|
||||
assert(type(spec.name) == "string")
|
||||
assert(type(spec.correct_func) == "function")
|
||||
assert(type(spec.correct_func) == "function" or type(spec.fixed_func) == "function")
|
||||
|
||||
local skill = DistanceSkill:new(spec.name)
|
||||
readStatusSpecToSkill(skill, spec)
|
||||
|
@ -556,5 +558,9 @@ function fk.CreateGameMode(spec)
|
|||
assert(type(spec.surrender_func) == "function")
|
||||
ret.surrenderFunc = spec.surrender_func
|
||||
end
|
||||
if spec.is_counted then
|
||||
assert(type(spec.is_counted) == "function")
|
||||
ret.countInFunc = spec.is_counted
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
|
|
@ -155,7 +155,7 @@ GameEvent.functions[GameEvent.Round] = function(self)
|
|||
GameEvent(GameEvent.Turn):exec()
|
||||
if room.game_finished then break end
|
||||
room.current = room.current:getNextAlive()
|
||||
until p.seat > p:getNextAlive().seat
|
||||
until p.seat >= p:getNextAlive().seat
|
||||
|
||||
logic:trigger(fk.RoundEnd, p)
|
||||
end
|
||||
|
|
|
@ -105,23 +105,7 @@ function GameLogic:chooseGenerals()
|
|||
end
|
||||
|
||||
room:setPlayerGeneral(lord, lord_general, true)
|
||||
if lord.kingdom == "god" or Fk.generals[lord_general].subkingdom then
|
||||
local allKingdoms = {}
|
||||
if lord.kingdom == "god" then
|
||||
allKingdoms = table.simpleClone(Fk.kingdoms)
|
||||
|
||||
local exceptedKingdoms = { "god" }
|
||||
for _, kingdom in ipairs(exceptedKingdoms) do
|
||||
table.removeOne(allKingdoms, kingdom)
|
||||
end
|
||||
else
|
||||
local curGeneral = Fk.generals[lord_general]
|
||||
allKingdoms = { curGeneral.kingdom, curGeneral.subkingdom }
|
||||
end
|
||||
|
||||
lord.kingdom = room:askForChoice(lord, allKingdoms, "AskForKingdom", "#ChooseInitialKingdom")
|
||||
room:broadcastProperty(lord, "kingdom")
|
||||
end
|
||||
room:askForChooseKingdom({lord})
|
||||
room:broadcastProperty(lord, "general")
|
||||
room:setDeputyGeneral(lord, deputy)
|
||||
room:broadcastProperty(lord, "deputyGeneral")
|
||||
|
|
|
@ -19,18 +19,18 @@ MarkEnum.MinusMaxCards = "MinusMaxCards"
|
|||
--于本回合内减少标记值数量的手牌上限
|
||||
MarkEnum.MinusMaxCardsInTurn = "MinusMaxCards-turn"
|
||||
|
||||
--使用牌无次数限制,可带清除标记后缀
|
||||
---使用牌无次数限制,可带清除标记后缀(-tmp为请求专用)
|
||||
MarkEnum.BypassTimesLimit = "BypassTimesLimit"
|
||||
--使用牌无距离限制,可带清除标记后缀
|
||||
---使用牌无距离限制,可带清除标记后缀(-tmp为请求专用)
|
||||
MarkEnum.BypassDistancesLimit = "BypassDistancesLimit"
|
||||
--对其使用牌无次数限制,可带清除标记后缀
|
||||
---对其使用牌无次数限制,可带清除标记后缀
|
||||
MarkEnum.BypassTimesLimitTo = "BypassTimesLimitTo"
|
||||
--对其使用牌无距离限制,可带清除标记后缀
|
||||
---对其使用牌无距离限制,可带清除标记后缀
|
||||
MarkEnum.BypassDistancesLimitTo = "BypassDistancesLimitTo"
|
||||
--非锁定技失效,可带清除标记后缀
|
||||
---非锁定技失效,可带清除标记后缀
|
||||
MarkEnum.UncompulsoryInvalidity = "UncompulsoryInvalidity"
|
||||
|
||||
--各种清除标记后缀
|
||||
---各种清除标记后缀
|
||||
MarkEnum.TempMarkSuffix = { "-phase", "-turn", "-round" }
|
||||
|
||||
---卡牌标记版本的清除标记后缀
|
||||
|
|
|
@ -1453,6 +1453,60 @@ function Room:askForSkillInvoke(player, skill_name, data, prompt)
|
|||
return invoked
|
||||
end
|
||||
|
||||
--枚举法为使用牌重选目标(无距离限制)
|
||||
---@param player ServerPlayer @ 执行的玩家
|
||||
---@param targets ServerPlayer[] @ 可选的目标范围
|
||||
---@param num integer @ 可选的目标数
|
||||
---@param can_minus boolean @ 是否可减少
|
||||
---@param distance_limited boolean @ 是否受距离限制
|
||||
---@param prompt string @ 提示信息
|
||||
---@param skillName string @ 技能名
|
||||
---@param data CardUseStruct @ 使用数据
|
||||
function Room:askForAddTarget(player, targets, num, can_minus, distance_limited, prompt, skillName, data)
|
||||
num = num or 1
|
||||
can_minus = can_minus or false
|
||||
prompt = prompt or ""
|
||||
skillName = skillName or ""
|
||||
local room = player.room
|
||||
local tos = {}
|
||||
local orig_tos = table.simpleClone(AimGroup:getAllTargets(data.tos))
|
||||
if can_minus and #orig_tos > 1 then --默认不允许减目标至0
|
||||
tos = table.map(table.filter(targets, function(p)
|
||||
return table.contains(AimGroup:getAllTargets(data.tos), p.id) end), Util.IdMapper)
|
||||
end
|
||||
for _, p in ipairs(targets) do
|
||||
if not table.contains(AimGroup:getAllTargets(data.tos), p.id) and not room:getPlayerById(data.from):isProhibited(p, data.card) then
|
||||
if data.card.skill:modTargetFilter(p.id, orig_tos, player.id, data.card, distance_limited) then
|
||||
table.insertIfNeed(tos, p.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
if #tos > 0 then
|
||||
tos = room:askForChoosePlayers(player, tos, 1, num, prompt, skillName, true)
|
||||
--借刀……!
|
||||
if data.card.name ~= "collateral" then
|
||||
return tos
|
||||
else
|
||||
local result = {}
|
||||
for _, id in ipairs(tos) do
|
||||
local to = room:getPlayerById(id)
|
||||
local target = room:askForChoosePlayers(player, table.map(table.filter(room:getOtherPlayers(player), function(v)
|
||||
return to:inMyAttackRange(v) end), function(p) return p.id end), 1, 1,
|
||||
"#collateral-choose::"..to.id..":"..data.card:toLogString(), "collateral_skill", true)
|
||||
if #target > 0 then
|
||||
table.insert(result, {id, target[1]})
|
||||
end
|
||||
end
|
||||
if #result > 0 then
|
||||
return result
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
end
|
||||
return {}
|
||||
end
|
||||
|
||||
-- TODO: guanxing type
|
||||
--- 询问玩家对若干牌进行观星。
|
||||
---
|
||||
|
@ -1462,7 +1516,7 @@ end
|
|||
---@param top_limit integer[]|nil @ 置于牌堆顶的牌的限制(下限,上限),不填写则不限
|
||||
---@param bottom_limit integer[]|nil @ 置于牌堆底的牌的限制(下限,上限),不填写则不限
|
||||
---@param customNotify string|null @ 自定义读条操作提示
|
||||
--@param prompt string|null @ 观星框的标题(暂时雪藏)
|
||||
---param prompt string|null @ 观星框的标题(暂时雪藏)
|
||||
---@param noPut boolean|null @ 是否进行放置牌操作
|
||||
---@param areaNames string[]|null @ 左侧提示信息
|
||||
---@return table<"top"|"bottom", integer[]>
|
||||
|
@ -1666,10 +1720,10 @@ function Room:askForUseCard(player, card_name, pattern, prompt, cancelable, extr
|
|||
|
||||
if extra_data then
|
||||
if extra_data.bypass_distances then
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit, 1)
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit .. "-tmp", 1)
|
||||
end
|
||||
if extra_data.bypass_times then
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit, 1)
|
||||
if extra_data.bypass_times == nil or extra_data.bypass_times then
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit .. "-tmp", 1)
|
||||
end
|
||||
end
|
||||
local command = "AskForUseCard"
|
||||
|
@ -1689,8 +1743,8 @@ function Room:askForUseCard(player, card_name, pattern, prompt, cancelable, extr
|
|||
self.logic:trigger(fk.AskForCardUse, player, askForUseCardData)
|
||||
|
||||
if askForUseCardData.result and type(askForUseCardData.result) == 'table' then
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit, 0)
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit, 0)
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit .. "-tmp", 0)
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit .. "-tmp", 0)
|
||||
return askForUseCardData.result
|
||||
else
|
||||
local data = {card_name, pattern, prompt, cancelable, extra_data}
|
||||
|
@ -1700,13 +1754,13 @@ function Room:askForUseCard(player, card_name, pattern, prompt, cancelable, extr
|
|||
Fk.currentResponsePattern = nil
|
||||
|
||||
if result ~= "" then
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit, 0)
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit, 0)
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit .. "-tmp", 0)
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit .. "-tmp", 0)
|
||||
return self:handleUseCardReply(player, result)
|
||||
end
|
||||
end
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit, 0)
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit, 0)
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassDistancesLimit .. "-tmp", 0)
|
||||
player.room:setPlayerMark(player, MarkEnum.BypassTimesLimit .. "-tmp", 0)
|
||||
return nil
|
||||
end
|
||||
|
||||
|
@ -2970,10 +3024,6 @@ end
|
|||
|
||||
---@param room Room
|
||||
local function shouldUpdateWinRate(room)
|
||||
if room.settings.gameMode == "heg_mode" then return false end
|
||||
if room.settings.gameMode == "aaa_role_mode" and #room.players < 5 then
|
||||
return false
|
||||
end
|
||||
if room.settings.enableFreeAssign then
|
||||
return false
|
||||
end
|
||||
|
@ -2983,7 +3033,7 @@ local function shouldUpdateWinRate(room)
|
|||
for _, p in ipairs(room.players) do
|
||||
if p.id < 0 then return false end
|
||||
end
|
||||
return true
|
||||
return Fk.game_modes[room.settings.gameMode]:countInFunc(room)
|
||||
end
|
||||
|
||||
--- 结束一局游戏。
|
||||
|
|
|
@ -661,8 +661,9 @@ end
|
|||
|
||||
function ServerPlayer:reset()
|
||||
self.room:sendLog{
|
||||
type = "#ResetGeneral",
|
||||
type = "#ChainStateChange",
|
||||
from = self.id,
|
||||
arg = "reset-general"
|
||||
}
|
||||
self:setChainState(false)
|
||||
if not self.faceup then self:turnOver() end
|
||||
|
|
|
@ -9,6 +9,7 @@ local thunderSlashSkill = fk.CreateActiveSkill{
|
|||
max_phase_use_time = 1,
|
||||
target_num = 1,
|
||||
can_use = slash.skill.canUse,
|
||||
mod_target_filter = slash.skill.modTargetFilter,
|
||||
target_filter = slash.skill.targetFilter,
|
||||
on_effect = function(self, room, effect)
|
||||
local to = effect.to
|
||||
|
@ -47,6 +48,7 @@ local fireSlashSkill = fk.CreateActiveSkill{
|
|||
max_phase_use_time = 1,
|
||||
target_num = 1,
|
||||
can_use = slash.skill.canUse,
|
||||
mod_target_filter = slash.skill.modTargetFilter,
|
||||
target_filter = slash.skill.targetFilter,
|
||||
on_effect = function(self, room, effect)
|
||||
local to = effect.to
|
||||
|
@ -79,8 +81,14 @@ extension:addCards{
|
|||
local analepticSkill = fk.CreateActiveSkill{
|
||||
name = "analeptic_skill",
|
||||
max_turn_use_time = 1,
|
||||
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
|
||||
return self:withinTimesLimit(Fk:currentRoom():getPlayerById(to_select), Player.HistoryTurn, card, "analeptic", Fk:currentRoom():getPlayerById(to_select)) and
|
||||
not table.find(Fk:currentRoom().players, function(p)
|
||||
return p.dying
|
||||
end)
|
||||
end,
|
||||
can_use = function(self, player, card)
|
||||
return self:withinTimesLimit(player, Player.HistoryTurn, card, "analeptic", player)
|
||||
return self:modTargetFilter(player.id, Util.DummyTable, player.id, card)
|
||||
end,
|
||||
on_use = function(self, room, use)
|
||||
if not use.tos or #TargetGroup:getRealTargets(use.tos) == 0 then
|
||||
|
@ -171,6 +179,9 @@ local ironChainCardSkill = fk.CreateActiveSkill{
|
|||
name = "iron_chain_skill",
|
||||
min_target_num = 1,
|
||||
max_target_num = 2,
|
||||
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
|
||||
return true
|
||||
end,
|
||||
target_filter = function() return true end,
|
||||
on_effect = function(self, room, cardEffectEvent)
|
||||
local to = room:getPlayerById(cardEffectEvent.to)
|
||||
|
@ -196,9 +207,12 @@ extension:addCards{
|
|||
local fireAttackSkill = fk.CreateActiveSkill{
|
||||
name = "fire_attack_skill",
|
||||
target_num = 1,
|
||||
target_filter = function(self, to_select)
|
||||
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
|
||||
return not Fk:currentRoom():getPlayerById(to_select):isKongcheng()
|
||||
end,
|
||||
target_filter = function(self, to_select)
|
||||
return self:modTargetFilter(to_select)
|
||||
end,
|
||||
on_effect = function(self, room, cardEffectEvent)
|
||||
local from = room:getPlayerById(cardEffectEvent.from)
|
||||
local to = room:getPlayerById(cardEffectEvent.to)
|
||||
|
|
|
@ -362,6 +362,7 @@ heg = fk.CreateGameMode{
|
|||
maxPlayer = 8,
|
||||
rule = heg_rule,
|
||||
logic = heg_getlogic,
|
||||
countInFunc = Util.FalseFunc
|
||||
}
|
||||
|
||||
Fk:loadTranslationTable{
|
||||
|
|
|
@ -52,7 +52,7 @@ Fk:loadTranslationTable{
|
|||
|
||||
["xuchu"] = "许褚",
|
||||
["~xuchu"] = "冷,好冷啊……",
|
||||
["$luoyi1"] = "破!",
|
||||
["$luoyi1"] = "脱!",
|
||||
["$luoyi2"] = "谁来与我大战三百回合?",
|
||||
["luoyi"] = "裸衣",
|
||||
[":luoyi"] = "摸牌阶段,你可以少摸一张牌,若如此做,本回合你使用【杀】或【决斗】对目标角色造成伤害时,此伤害+1。",
|
||||
|
|
|
@ -1075,6 +1075,9 @@ local role_mode = fk.CreateGameMode{
|
|||
name = "aaa_role_mode", -- just to let it at the top of list
|
||||
minPlayer = 2,
|
||||
maxPlayer = 8,
|
||||
countInFunc = function(self, room)
|
||||
return #room.players >= 5
|
||||
end,
|
||||
surrender_func = function(self, playedTime)
|
||||
local roleCheck = false
|
||||
local roleText = ""
|
||||
|
|
|
@ -16,7 +16,7 @@ Fk:loadTranslationTable{
|
|||
["diamond"] = "方块",
|
||||
["suit"] = "花色",
|
||||
["color"] = "颜色",
|
||||
["figure"] = "点数",
|
||||
["number"] = "点数",
|
||||
|
||||
["basic_char"] = "基",
|
||||
["trick_char"] = "锦",
|
||||
|
|
|
@ -3,46 +3,6 @@
|
|||
local extension = Package:new("standard_cards", Package.CardPack)
|
||||
extension.metadata = require "packages.standard_cards.metadata"
|
||||
|
||||
local global_can_use = function(self, player, card)
|
||||
local room = Fk:currentRoom()
|
||||
for _, p in ipairs(room.alive_players) do
|
||||
if not (card and player:isProhibited(p, card)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local aoe_can_use = function(self, player, card)
|
||||
local room = Fk:currentRoom()
|
||||
for _, p in ipairs(room.alive_players) do
|
||||
if p ~= player and not (card and player:isProhibited(p, card)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local global_on_use = function(self, room, cardUseEvent)
|
||||
if not cardUseEvent.tos or #TargetGroup:getRealTargets(cardUseEvent.tos) == 0 then
|
||||
cardUseEvent.tos = {}
|
||||
for _, player in ipairs(room:getAlivePlayers()) do
|
||||
if not room:getPlayerById(cardUseEvent.from):isProhibited(player, cardUseEvent.card) then
|
||||
TargetGroup:pushTargets(cardUseEvent.tos, player.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local aoe_on_use = function(self, room, cardUseEvent)
|
||||
if not cardUseEvent.tos or #TargetGroup:getRealTargets(cardUseEvent.tos) == 0 then
|
||||
cardUseEvent.tos = {}
|
||||
for _, player in ipairs(room:getOtherPlayers(room:getPlayerById(cardUseEvent.from))) do
|
||||
if not room:getPlayerById(cardUseEvent.from):isProhibited(player, cardUseEvent.card) then
|
||||
TargetGroup:pushTargets(cardUseEvent.tos, player.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local slashSkill = fk.CreateActiveSkill{
|
||||
name = "slash_skill",
|
||||
max_phase_use_time = 1,
|
||||
|
@ -53,10 +13,15 @@ local slashSkill = fk.CreateActiveSkill{
|
|||
return self:withinTimesLimit(player, Player.HistoryPhase, card, "slash", p)
|
||||
end)
|
||||
end,
|
||||
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
|
||||
local player = Fk:currentRoom():getPlayerById(to_select)
|
||||
local from = Fk:currentRoom():getPlayerById(user)
|
||||
return from ~= player and not (distance_limited and not self:withinDistanceLimit(from, true, card, player))
|
||||
end,
|
||||
target_filter = function(self, to_select, selected, _, card)
|
||||
if #selected < self:getMaxTargetNum(Self, card) then
|
||||
local player = Fk:currentRoom():getPlayerById(to_select)
|
||||
return Self ~= player and self:withinDistanceLimit(Self, true, card, player) and
|
||||
return self:modTargetFilter(to_select, selected, Self.id, true, card) and
|
||||
(#selected > 0 or self:withinTimesLimit(Self, Player.HistoryPhase, card, "slash", player))
|
||||
end
|
||||
end,
|
||||
|
@ -158,6 +123,12 @@ extension:addCards({
|
|||
|
||||
local peachSkill = fk.CreateActiveSkill{
|
||||
name = "peach_skill",
|
||||
mod_target_filter = function(self, to_select)
|
||||
return Fk:currentRoom():getPlayerById(to_select):isWounded() and
|
||||
not table.find(Fk:currentRoom().players, function(p)
|
||||
return p.dying
|
||||
end)
|
||||
end,
|
||||
can_use = function(self, player)
|
||||
return player:isWounded()
|
||||
end,
|
||||
|
@ -201,10 +172,13 @@ extension:addCards({
|
|||
local dismantlementSkill = fk.CreateActiveSkill{
|
||||
name = "dismantlement_skill",
|
||||
target_num = 1,
|
||||
mod_target_filter = function(self, to_select, selected, user)
|
||||
local player = Fk:currentRoom():getPlayerById(to_select)
|
||||
return Fk:currentRoom():getPlayerById(user) ~= player and not player:isAllNude()
|
||||
end,
|
||||
target_filter = function(self, to_select, selected)
|
||||
if #selected < self:getMaxTargetNum(Self) then
|
||||
local player = Fk:currentRoom():getPlayerById(to_select)
|
||||
return Self ~= player and not player:isAllNude()
|
||||
return self:modTargetFilter(to_select, selected, Self.id)
|
||||
end
|
||||
end,
|
||||
on_effect = function(self, room, effect)
|
||||
|
@ -236,13 +210,14 @@ extension:addCards({
|
|||
local snatchSkill = fk.CreateActiveSkill{
|
||||
name = "snatch_skill",
|
||||
distance_limit = 1,
|
||||
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
|
||||
local player = Fk:currentRoom():getPlayerById(to_select)
|
||||
local from = Fk:currentRoom():getPlayerById(user)
|
||||
return from ~= player and not (player:isAllNude() or (distance_limited and not self:withinDistanceLimit(from, true, card, player)))
|
||||
end,
|
||||
target_filter = function(self, to_select, selected, _, card)
|
||||
if #selected == 0 then
|
||||
local player = Fk:currentRoom():getPlayerById(to_select)
|
||||
return
|
||||
Self ~= player and
|
||||
self:withinDistanceLimit(Self, false, card, player) and -- for no distance limit for snatch
|
||||
not player:isAllNude()
|
||||
return self:modTargetFilter(to_select, selected, Self.id, card, true)
|
||||
end
|
||||
end,
|
||||
target_num = 1,
|
||||
|
@ -272,10 +247,12 @@ extension:addCards({
|
|||
|
||||
local duelSkill = fk.CreateActiveSkill{
|
||||
name = "duel_skill",
|
||||
mod_target_filter = function(self, to_select, selected, user)
|
||||
return user ~= to_select
|
||||
end,
|
||||
target_filter = function(self, to_select, selected)
|
||||
if #selected == 0 then
|
||||
local player = Fk:currentRoom():getPlayerById(to_select)
|
||||
return Self ~= player
|
||||
return self:modTargetFilter(to_select, selected, Self.id)
|
||||
end
|
||||
end,
|
||||
target_num = 1,
|
||||
|
@ -355,6 +332,10 @@ extension:addCards({
|
|||
|
||||
local collateralSkill = fk.CreateActiveSkill{
|
||||
name = "collateral_skill",
|
||||
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
|
||||
local player = Fk:currentRoom():getPlayerById(to_select)
|
||||
return user ~= player.id and player:getEquipment(Card.SubtypeWeapon)
|
||||
end,
|
||||
target_filter = function(self, to_select, selected)
|
||||
local player = Fk:currentRoom():getPlayerById(to_select)
|
||||
if #selected == 0 then
|
||||
|
@ -399,6 +380,9 @@ extension:addCards({
|
|||
|
||||
local exNihiloSkill = fk.CreateActiveSkill{
|
||||
name = "ex_nihilo_skill",
|
||||
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
|
||||
return true
|
||||
end,
|
||||
on_use = function(self, room, cardUseEvent)
|
||||
if not cardUseEvent.tos or #TargetGroup:getRealTargets(cardUseEvent.tos) == 0 then
|
||||
cardUseEvent.tos = { { cardUseEvent.from } }
|
||||
|
@ -453,8 +437,11 @@ extension:addCards({
|
|||
|
||||
local savageAssaultSkill = fk.CreateActiveSkill{
|
||||
name = "savage_assault_skill",
|
||||
can_use = aoe_can_use,
|
||||
on_use = aoe_on_use,
|
||||
can_use = Util.AoeCanUse,
|
||||
on_use = Util.AoeOnUse,
|
||||
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
|
||||
return user ~= to_select
|
||||
end,
|
||||
on_effect = function(self, room, effect)
|
||||
local cardResponded = room:askForResponse(room:getPlayerById(effect.to), 'slash', nil, nil, false, nil, effect)
|
||||
|
||||
|
@ -493,8 +480,11 @@ extension:addCards({
|
|||
|
||||
local archeryAttackSkill = fk.CreateActiveSkill{
|
||||
name = "archery_attack_skill",
|
||||
can_use = aoe_can_use,
|
||||
on_use = aoe_on_use,
|
||||
can_use = Util.AoeCanUse,
|
||||
on_use = Util.AoeOnUse,
|
||||
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
|
||||
return user ~= to_select
|
||||
end,
|
||||
on_effect = function(self, room, effect)
|
||||
local cardResponded = room:askForResponse(room:getPlayerById(effect.to), 'jink', nil, nil, false, nil, effect)
|
||||
|
||||
|
@ -531,8 +521,11 @@ extension:addCards({
|
|||
|
||||
local godSalvationSkill = fk.CreateActiveSkill{
|
||||
name = "god_salvation_skill",
|
||||
can_use = global_can_use,
|
||||
on_use = global_on_use,
|
||||
can_use = Util.GlobalCanUse,
|
||||
on_use = Util.GlobalOnUse,
|
||||
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
|
||||
return true
|
||||
end,
|
||||
about_to_effect = function(self, room, effect)
|
||||
if not room:getPlayerById(effect.to):isWounded() then
|
||||
return true
|
||||
|
@ -566,8 +559,11 @@ extension:addCards({
|
|||
|
||||
local amazingGraceSkill = fk.CreateActiveSkill{
|
||||
name = "amazing_grace_skill",
|
||||
can_use = global_can_use,
|
||||
on_use = global_on_use,
|
||||
can_use = Util.GlobalCanUse,
|
||||
on_use = Util.GlobalOnUse,
|
||||
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
|
||||
return true
|
||||
end,
|
||||
on_effect = function(self, room, effect)
|
||||
local to = room:getPlayerById(effect.to)
|
||||
if not (effect.extra_data and effect.extra_data.AGFilled) then
|
||||
|
|
Loading…
Reference in New Issue