From 075419dc3a9355a0f00a09f6725939c86d3e0217 Mon Sep 17 00:00:00 2001
From: xxyheaven <1433191064@qq.com>
Date: Sun, 28 Jan 2024 22:42:06 +0800
Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=94=BB=E5=87=BB=E8=8C=83=E5=9B=B4?=
=?UTF-8?q?=E7=8A=B6=E6=80=81=E6=8A=80=E7=B1=BB=E6=96=B0=E5=A2=9E=E5=9F=BA?=
=?UTF-8?q?=E7=A1=80=E5=80=BC=E4=BF=AE=E6=AD=A3=E5=87=BD=E6=95=B0=202?=
=?UTF-8?q?=E3=80=81=E4=BC=A4=E5=AE=B3=E5=80=BC=E5=9C=A8=E4=B8=80=E4=B8=AA?=
=?UTF-8?q?=E6=8A=80=E8=83=BD=E5=A4=84=E7=90=86=E5=90=8E=E5=B0=8F=E4=BA=8E?=
=?UTF-8?q?1=E4=BC=9A=E7=BB=88=E6=AD=A2=E5=BD=93=E5=89=8D=E4=BA=8B?=
=?UTF-8?q?=E4=BB=B6=203=E3=80=81=E4=B8=8D=E5=90=91=E4=B8=8D=E8=83=BD?=
=?UTF-8?q?=E4=BD=BF=E7=94=A8=E3=80=90=E6=97=A0=E6=87=88=E5=8F=AF=E5=87=BB?=
=?UTF-8?q?=E3=80=91=E7=9A=84=E8=A7=92=E8=89=B2=E8=AF=A2=E9=97=AE=E4=BD=BF?=
=?UTF-8?q?=E7=94=A8=E3=80=90=E6=97=A0=E6=87=88=E5=8F=AF=E5=87=BB=E3=80=91?=
=?UTF-8?q?=204=E3=80=81=E4=BF=AE=E6=AD=A3=E5=9C=A8=E6=BF=92=E6=AD=BB?=
=?UTF-8?q?=E6=8F=92=E7=BB=93=E4=B8=AD=E6=9C=89=E4=BA=BA=E6=AD=BB=E4=BA=A1?=
=?UTF-8?q?=E5=90=8E=E4=BB=8D=E7=84=B6=E4=BC=9A=E5=90=91=E8=AF=A5=E8=A7=92?=
=?UTF-8?q?=E8=89=B2=E6=B1=82=E6=A1=83=E7=9A=84=E6=83=85=E5=86=B5=205?=
=?UTF-8?q?=E3=80=81=E5=B0=86PreCardUse=E5=92=8CPreCardRespond=E6=97=B6?=
=?UTF-8?q?=E6=9C=BA=E7=A7=BB=E8=87=B3=E5=AE=9E=E4=BD=93=E7=89=8C=E7=A7=BB?=
=?UTF-8?q?=E5=8A=A8=E4=B9=8B=E5=89=8D=206=E3=80=81=E8=B0=83=E6=95=B4?=
=?UTF-8?q?=E6=94=B9=E5=88=A4=E5=87=BD=E6=95=B0=E5=8E=9F=E5=88=A4=E5=AE=9A?=
=?UTF-8?q?=E7=89=8C=E7=BD=AE=E5=85=A5=E5=BC=83=E7=89=8C=E5=A0=86=E7=9A=84?=
=?UTF-8?q?=E5=8E=9F=E5=9B=A0=206=E3=80=81=E4=BF=AE=E6=AD=A3=E3=80=90?=
=?UTF-8?q?=E6=9C=B1=E9=9B=80=E7=BE=BD=E6=89=87=E3=80=91=E3=80=81=E3=80=90?=
=?UTF-8?q?=E5=80=9F=E5=88=80=E6=9D=80=E4=BA=BA=E3=80=91=E3=80=81=E3=80=90?=
=?UTF-8?q?=E9=85=92=E3=80=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
lua/core/player.lua | 22 ++++++++---
lua/core/skill_type/attack_range.lua | 6 +++
lua/core/skill_type/distance.lua | 2 +-
lua/fk_ex.lua | 6 ++-
lua/server/events/death.lua | 6 ++-
lua/server/events/usecard.lua | 16 ++++----
lua/server/gamelogic.lua | 4 +-
lua/server/room.lua | 59 ++++++++++++++++------------
packages/maneuvering/init.lua | 17 +++++---
packages/standard/game_rule.lua | 2 +-
packages/standard_cards/init.lua | 31 ++++++++++-----
11 files changed, 112 insertions(+), 59 deletions(-)
diff --git a/lua/core/player.lua b/lua/core/player.lua
index e54dcfe..8a9fe44 100644
--- a/lua/core/player.lua
+++ b/lua/core/player.lua
@@ -457,16 +457,28 @@ end
--- 获取玩家攻击范围。
function Player:getAttackRange()
- local weapon = Fk:getCardById(self:getEquipment(Card.SubtypeWeapon))
- local baseAttackRange = math.max(weapon and weapon.attack_range or 1, 0)
+ local baseValue = 1
+ local weapons = self:getEquipments(Card.SubtypeWeapon)
+ if #weapons > 0 then
+ baseValue = 0
+ for _, id in ipairs(weapons) do
+ local weapon = Fk:getCardById(id)
+ baseValue = math.max(baseValue, weapon.attack_range or 1)
+ end
+ end
local status_skills = Fk:currentRoom().status_skills[AttackRangeSkill] or Util.DummyTable
+ local max_fixed, correct = nil, 0
for _, skill in ipairs(status_skills) do
- local correct = skill:getCorrect(self)
- baseAttackRange = baseAttackRange + (correct or 0)
+ local f = skill:getFixed(self)
+ if f ~= nil then
+ max_fixed = max_fixed and math.max(max_fixed, f) or f
+ end
+ local c = skill:getCorrect(self)
+ correct = correct + (c or 0)
end
- return math.max(baseAttackRange, 0)
+ return math.max(math.max(baseValue, (max_fixed or 0)) + correct, 0)
end
--- 获取角色是否被移除。
diff --git a/lua/core/skill_type/attack_range.lua b/lua/core/skill_type/attack_range.lua
index 6a64653..aa48de0 100644
--- a/lua/core/skill_type/attack_range.lua
+++ b/lua/core/skill_type/attack_range.lua
@@ -9,6 +9,12 @@ function AttackRangeSkill:getCorrect(from)
return 0
end
+---@param from Player
+---@return integer|nil
+function AttackRangeSkill:getFixed(from)
+ return nil
+end
+
function AttackRangeSkill:withinAttackRange(from, to)
return false
end
diff --git a/lua/core/skill_type/distance.lua b/lua/core/skill_type/distance.lua
index 681dfc0..b0d6db4 100644
--- a/lua/core/skill_type/distance.lua
+++ b/lua/core/skill_type/distance.lua
@@ -12,7 +12,7 @@ end
---@param from Player
---@param to Player
----@return integer
+---@return integer|nil
function DistanceSkill:getFixed(from, to)
return nil
end
diff --git a/lua/fk_ex.lua b/lua/fk_ex.lua
index 1cf0d06..f0a9eb0 100644
--- a/lua/fk_ex.lua
+++ b/lua/fk_ex.lua
@@ -320,19 +320,23 @@ end
---@class AttackRangeSpec: StatusSkillSpec
---@field public correct_func? fun(self: AttackRangeSkill, from: Player, to: Player): number?
+---@field public fixed_func? fun(self: AttackRangeSkill, player: Player): number?
---@field public within_func? fun(self: AttackRangeSkill, from: Player, to: Player): boolean?
---@param spec AttackRangeSpec
---@return AttackRangeSkill
function fk.CreateAttackRangeSkill(spec)
assert(type(spec.name) == "string")
- assert(type(spec.correct_func) == "function" or type(spec.within_func) == "function")
+ assert(type(spec.correct_func) == "function" or type(spec.fixed_func) == "function" or type(spec.within_func) == "function")
local skill = AttackRangeSkill:new(spec.name)
readStatusSpecToSkill(skill, spec)
if spec.correct_func then
skill.getCorrect = spec.correct_func
end
+ if spec.fixed_func then
+ skill.getFixed = spec.fixed_func
+ end
if spec.within_func then
skill.withinAttackRange = spec.within_func
end
diff --git a/lua/server/events/death.lua b/lua/server/events/death.lua
index 6765276..884b775 100644
--- a/lua/server/events/death.lua
+++ b/lua/server/events/death.lua
@@ -17,8 +17,10 @@ GameEvent.functions[GameEvent.Dying] = function(self)
-- room.logic:trigger(fk.Dying, dyingPlayer, dyingStruct)
local savers = room:getAlivePlayers()
for _, p in ipairs(savers) do
- if dyingPlayer.hp > 0 or dyingPlayer.dead or logic:trigger(fk.AskForPeaches, p, dyingStruct) then
- break
+ if not p.dead then
+ if dyingPlayer.hp > 0 or dyingPlayer.dead or logic:trigger(fk.AskForPeaches, p, dyingStruct) then
+ break
+ end
end
end
logic:trigger(fk.AskForPeachesDone, dyingPlayer, dyingStruct)
diff --git a/lua/server/events/usecard.lua b/lua/server/events/usecard.lua
index b540c3b..e0300b9 100644
--- a/lua/server/events/usecard.lua
+++ b/lua/server/events/usecard.lua
@@ -170,6 +170,10 @@ GameEvent.functions[GameEvent.UseCard] = function(self)
local _card = sendCardEmotionAndLog(room, cardUseEvent)
+ if logic:trigger(fk.PreCardUse, room:getPlayerById(cardUseEvent.from), cardUseEvent) then
+ logic:breakEvent()
+ end
+
room:moveCardTo(cardUseEvent.card, Card.Processing, nil, fk.ReasonUse)
local card = cardUseEvent.card
@@ -196,10 +200,6 @@ GameEvent.functions[GameEvent.UseCard] = function(self)
end
end
- if logic:trigger(fk.PreCardUse, room:getPlayerById(cardUseEvent.from), cardUseEvent) then
- logic:breakEvent()
- end
-
if not cardUseEvent.extraUse then
room:getPlayerById(cardUseEvent.from):addCardUseHistory(cardUseEvent.card.trueName, 1)
end
@@ -270,6 +270,10 @@ GameEvent.functions[GameEvent.RespondCard] = function(self)
playCardEmotionAndSound(room, room:getPlayerById(from), card)
+ if logic:trigger(fk.PreCardRespond, room:getPlayerById(cardResponseEvent.from), cardResponseEvent) then
+ logic:breakEvent()
+ end
+
room:moveCardTo(card, Card.Processing, nil, fk.ReasonResonpse)
if #cardIds > 0 then
room:sendFootnote(cardIds, {
@@ -281,10 +285,6 @@ GameEvent.functions[GameEvent.RespondCard] = function(self)
end
end
- if logic:trigger(fk.PreCardRespond, room:getPlayerById(cardResponseEvent.from), cardResponseEvent) then
- logic:breakEvent()
- end
-
logic:trigger(fk.CardResponding, room:getPlayerById(cardResponseEvent.from), cardResponseEvent)
end
diff --git a/lua/server/gamelogic.lua b/lua/server/gamelogic.lua
index ed174f2..e1c7213 100644
--- a/lua/server/gamelogic.lua
+++ b/lua/server/gamelogic.lua
@@ -395,7 +395,9 @@ function GameLogic:trigger(event, target, data, refresh_only)
skill_names = table.map(table.filter(skills, filter_func), Util.NameMapper)
broken = broken or (event == fk.AskForPeaches
- and room:getPlayerById(data.who).hp > 0) or cur_event.killed
+ and room:getPlayerById(data.who).hp > 0) or
+ (table.contains({fk.PreDamage, fk.DamageCaused, fk.DamageInflicted}, event) and data.damage < 1) or
+ cur_event.killed
if broken then break end
end
diff --git a/lua/server/room.lua b/lua/server/room.lua
index 571859e..f28fd8f 100644
--- a/lua/server/room.lua
+++ b/lua/server/room.lua
@@ -2760,27 +2760,13 @@ function Room:handleCardEffect(event, cardEffectEvent)
then
local players = {}
Fk.currentResponsePattern = "nullification"
+ local cardCloned = Fk:cloneCard("nullification")
for _, p in ipairs(self.alive_players) do
- local cards = p:getHandlyIds()
- for _, cid in ipairs(cards) do
- if
- Fk:getCardById(cid).trueName == "nullification" and
- not (
- table.contains(cardEffectEvent.disresponsiveList or Util.DummyTable, p.id) or
- table.contains(cardEffectEvent.unoffsetableList or Util.DummyTable, p.id)
- )
- then
- table.insert(players, p)
- break
- end
- end
- if not table.contains(players, p) then
- Self = p -- for enabledAtResponse
- for _, s in ipairs(table.connect(p.player_skills, p._fake_skills)) do
+ if not p:prohibitUse(cardCloned) then
+ local cards = p:getHandlyIds()
+ for _, cid in ipairs(cards) do
if
- s.pattern and
- Exppattern:Parse("nullification"):matchExp(s.pattern) and
- not (s.enabledAtResponse and not s:enabledAtResponse(p)) and
+ Fk:getCardById(cid).trueName == "nullification" and
not (
table.contains(cardEffectEvent.disresponsiveList or Util.DummyTable, p.id) or
table.contains(cardEffectEvent.unoffsetableList or Util.DummyTable, p.id)
@@ -2790,6 +2776,23 @@ function Room:handleCardEffect(event, cardEffectEvent)
break
end
end
+ if not table.contains(players, p) then
+ Self = p -- for enabledAtResponse
+ for _, s in ipairs(table.connect(p.player_skills, p._fake_skills)) do
+ if
+ s.pattern and
+ Exppattern:Parse("nullification"):matchExp(s.pattern) and
+ not (s.enabledAtResponse and not s:enabledAtResponse(p)) and
+ not (
+ table.contains(cardEffectEvent.disresponsiveList or Util.DummyTable, p.id) or
+ table.contains(cardEffectEvent.unoffsetableList or Util.DummyTable, p.id)
+ )
+ then
+ table.insert(players, p)
+ break
+ end
+ end
+ end
end
end
@@ -3176,12 +3179,6 @@ function Room:retrial(card, player, judge, skillName, exchange)
local rebyre = judge.retrial_by_response
judge.retrial_by_response = player
- local move2 = {} ---@type CardsMoveInfo
- move2.ids = { oldJudge:getEffectiveId() }
- move2.toArea = exchange and Card.PlayerHand or Card.DiscardPile
- move2.moveReason = fk.ReasonJustMove
- move2.to = exchange and player.id or nil
-
self:sendLog{
type = "#ChangedJudge",
from = player.id,
@@ -3190,8 +3187,18 @@ function Room:retrial(card, player, judge, skillName, exchange)
arg = skillName,
}
- self:moveCards(move2)
Fk:filterCard(judge.card.id, judge.who, judge)
+
+ exchange = exchange and not player.dead
+
+ local move2 = {} ---@type CardsMoveInfo
+ move2.ids = { oldJudge:getEffectiveId() }
+ move2.toArea = exchange and Card.PlayerHand or Card.DiscardPile
+ move2.moveReason = exchange and fk.ReasonJustMove or fk.ReasonJudge
+ move2.to = exchange and player.id or nil
+ move2.skillName = skillName
+
+ self:moveCards(move2)
end
--- 弃置一名角色的牌。
diff --git a/packages/maneuvering/init.lua b/packages/maneuvering/init.lua
index cdcf2f2..0283fcd 100644
--- a/packages/maneuvering/init.lua
+++ b/packages/maneuvering/init.lua
@@ -146,7 +146,7 @@ local analepticEffect = fk.CreateTriggerSkill{
name = "analeptic_effect",
global = true,
priority = 0, -- game rule
- events = { fk.PreCardUse, fk.EventPhaseStart },
+ events = { fk.PreCardUse, fk.AfterTurnEnd },
can_trigger = function(_, event, target, player, data)
if target ~= player then
return false
@@ -155,7 +155,7 @@ local analepticEffect = fk.CreateTriggerSkill{
if event == fk.PreCardUse then
return data.card.trueName == "slash" and player.drank > 0
else
- return target.phase == Player.NotActive
+ return true
end
end,
on_trigger = function(_, event, _, player, data)
@@ -360,9 +360,16 @@ local fanSkill = fk.CreateTriggerSkill{
return target == player and player:hasSkill(self) and data.card.name == "slash"
end,
on_use = function(_, _, _, _, data)
- local card = Fk:cloneCard("fire__slash")
+ local card = Fk:cloneCard("fire__slash", data.card.suit, data.card.number)
+ for k, v in pairs(data.card) do
+ if card[k] == nil then
+ card[k] = v
+ end
+ end
+ if not data.card:isVirtual() then
+ card.id = data.card.id
+ end
card.skillName = "fan"
- card:addSubcard(data.card)
data.card = card
end,
}
@@ -522,7 +529,7 @@ Fk:loadTranslationTable{
["#guding_blade_skill"] = "古锭刀",
["fan"] = "朱雀羽扇",
- [":fan"] = "装备牌·武器
攻击范围:4
武器技能:你可以将一张普通【杀】当火【杀】使用。",
+ [":fan"] = "装备牌·武器
攻击范围:4
武器技能:当你声明使用普【杀】后,你可以将此【杀】改为火【杀】。",
["#fan_skill"] = "朱雀羽扇",
["vine"] = "藤甲",
diff --git a/packages/standard/game_rule.lua b/packages/standard/game_rule.lua
index 3cc23b4..e893d2b 100644
--- a/packages/standard/game_rule.lua
+++ b/packages/standard/game_rule.lua
@@ -39,7 +39,7 @@ GameRule = fk.CreateTriggerSkill{
switch(event, {
[fk.AskForPeaches] = function()
local dyingPlayer = room:getPlayerById(data.who)
- while dyingPlayer.hp < 1 do
+ while not (player.dead or dyingPlayer.dead) and dyingPlayer.hp < 1 do
local cardNames = {"peach"}
local prompt = "#AskForPeaches:" .. dyingPlayer.id .. "::" .. tostring(1 - dyingPlayer.hp)
if player == dyingPlayer then
diff --git a/packages/standard_cards/init.lua b/packages/standard_cards/init.lua
index abfacd0..8038ae1 100644
--- a/packages/standard_cards/init.lua
+++ b/packages/standard_cards/init.lua
@@ -352,18 +352,22 @@ local collateralSkill = fk.CreateActiveSkill{
prompt = "#collateral_skill",
mod_target_filter = function(self, to_select, selected, user, card, distance_limited)
local player = Fk:currentRoom():getPlayerById(to_select)
- return user ~= to_select and player:getEquipment(Card.SubtypeWeapon)
+ if #selected == 0 then
+ return user ~= to_select and player:getEquipment(Card.SubtypeWeapon) and not player:prohibitUse(Fk:cloneCard("slash"))
+ elseif #selected == 1 then
+ local target = Fk:currentRoom():getPlayerById(to_select)
+ local from = Fk:currentRoom():getPlayerById(selected[1])
+ return from:inMyAttackRange(target) and not from:isProhibited(player, Fk:cloneCard("slash"))
+ end
end,
target_filter = function(self, to_select, selected, _, card)
if #selected >= (self:getMaxTargetNum(Self, card) - 1) * 2 then
return false--修改借刀的目标选择
elseif #selected % 2 == 0 then
- return self:modTargetFilter(to_select, selected, Self.id, card)
+ return self:modTargetFilter(to_select, {}, Self.id, card)
else
- local player = Fk:currentRoom():getPlayerById(to_select)
- local from = Fk:currentRoom():getPlayerById(selected[#selected])
- return self:modTargetFilter(selected[#selected], selected, Self.id, card)
- and from:inMyAttackRange(player) and not from:isProhibited(player, Fk:cloneCard("slash"))
+ return self:modTargetFilter(selected[#selected], {}, Self.id, card)
+ and self:modTargetFilter(to_select, {selected[#selected]}, Self.id, card)
end
end,
target_num = 2,
@@ -382,17 +386,26 @@ local collateralSkill = fk.CreateActiveSkill{
end,
on_effect = function(self, room, effect)
local to = room:getPlayerById(effect.to)
- if to.dead or not to:getEquipment(Card.SubtypeWeapon) then return end
+ if to.dead then return end
local prompt = "#collateral-slash:"..effect.from..":"..effect.subTargets[1]
if #effect.subTargets > 1 then
prompt = nil
end
- local use = room:askForUseCard(to, "slash", nil, prompt, nil, { must_targets = effect.subTargets }, effect)
+ local extra_data = {
+ must_targets = effect.subTargets,
+ bypass_times = true,
+ }
+ local use = room:askForUseCard(to, "slash", nil, prompt, nil, extra_data, effect)
if use then
use.extraUse = true
room:useCard(use)
else
- room:moveCardTo(to:getEquipment(Card.SubtypeWeapon), Card.PlayerHand, room:getPlayerById(effect.from), fk.ReasonGive, "collateral", nil, true, to.id)
+ local from = room:getPlayerById(effect.from)
+ if from.dead then return end
+ local weapons = to:getEquipments(Card.SubtypeWeapon)
+ if #weapons > 0 then
+ room:moveCardTo(weapons, Card.PlayerHand, from, fk.ReasonGive, "collateral", nil, true, to.id)
+ end
end
end
}
--
Gitee